
Docker Deployment
Deploy Muti Metroo using Docker and Docker Compose.
Docker Image
Build Image
# From repository root
docker build -t muti-metroo .
# With version tag
docker build -t muti-metroo:v1.0.0 .
Dockerfile
The included Dockerfile uses multi-stage build:
# Build stage
FROM golang:1.23-alpine AS builder
WORKDIR /build
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o muti-metroo ./cmd/muti-metroo
# Runtime stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /build/muti-metroo .
ENTRYPOINT ["./muti-metroo"]
CMD ["run", "-c", "/app/config.yaml"]
Running a Single Container
Basic Run
docker run -d --name muti-metroo \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/data:/app/data \
-v $(pwd)/certs:/app/certs \
-p 1080:1080 \
-p 4433:4433/udp \
-p 8080:8080 \
muti-metroo
With Environment Variables
docker run -d --name muti-metroo \
-e LOG_LEVEL=debug \
-e SOCKS_ADDR=0.0.0.0:1080 \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/data:/app/data \
-v $(pwd)/certs:/app/certs \
-p 1080:1080 \
-p 4433:4433/udp \
-p 8080:8080 \
muti-metroo
With Secrets
docker run -d --name muti-metroo \
--env-file .env \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/data:/app/data \
-v $(pwd)/certs:/app/certs \
-p 1080:1080 \
-p 4433:4433/udp \
-p 8080:8080 \
muti-metroo
Docker Compose
Basic Setup
# docker-compose.yml
version: '3.8'
services:
agent:
build: .
restart: unless-stopped
ports:
- "1080:1080" # SOCKS5
- "4433:4433/udp" # QUIC
- "8080:8080" # HTTP API
volumes:
- ./config.yaml:/app/config.yaml:ro
- ./data:/app/data
- ./certs:/app/certs:ro
environment:
- LOG_LEVEL=info
Multi-Agent Testbed
# docker-compose.yml
version: '3.8'
services:
# Ingress agent
agent1:
build: .
restart: unless-stopped
ports:
- "1081:1080"
- "8081:8080"
- "4433:4433/udp"
volumes:
- ./configs/agent1.yaml:/app/config.yaml:ro
- ./data/agent1:/app/data
- ./certs:/app/certs:ro
networks:
- mesh
# Transit agent
agent2:
build: .
restart: unless-stopped
ports:
- "1082:1080"
- "8082:8080"
- "4434:4433/udp"
volumes:
- ./configs/agent2.yaml:/app/config.yaml:ro
- ./data/agent2:/app/data
- ./certs:/app/certs:ro
networks:
- mesh
# Exit agent
agent3:
build: .
restart: unless-stopped
ports:
- "1083:1080"
- "8083:8080"
- "4435:4433/udp"
volumes:
- ./configs/agent3.yaml:/app/config.yaml:ro
- ./data/agent3:/app/data
- ./certs:/app/certs:ro
networks:
- mesh
networks:
mesh:
driver: bridge
With Health Checks
services:
agent:
build: .
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
Configuration for Docker
Agent Config
agent:
id: "auto"
display_name: "${HOSTNAME:-docker-agent}"
data_dir: "/app/data"
log_level: "${LOG_LEVEL:-info}"
log_format: "json"
listeners:
- transport: quic
address: "0.0.0.0:4433"
tls:
cert: "/app/certs/agent.crt"
key: "/app/certs/agent.key"
socks5:
enabled: true
address: "0.0.0.0:1080"
http:
enabled: true
address: "0.0.0.0:8080"
Docker-Internal Networking
Use container names for peer addresses:
# agent1.yaml
peers:
- id: "${AGENT2_ID}"
transport: quic
address: "agent2:4433"
tls:
ca: "/app/certs/ca.crt"
# agent2.yaml
peers:
- id: "${AGENT3_ID}"
transport: quic
address: "agent3:4433"
tls:
ca: "/app/certs/ca.crt"
Docker Commands
Build and Start
# Build images
docker compose build
# Start all agents
docker compose up -d
# Start specific agents
docker compose up -d agent1 agent2
# View logs
docker compose logs -f agent1
# Stop all
docker compose down
Inspect and Debug
# Container status
docker compose ps
# Enter container shell
docker compose exec agent1 sh
# View agent logs
docker compose logs agent1
# Follow logs
docker compose logs -f --tail=100 agent1
# Check health
docker compose exec agent1 wget -q -O - http://localhost:8080/health
Certificate Management
# Generate certs on host, mount to container
muti-metroo cert ca -n "Docker Mesh CA" -o ./certs
muti-metroo cert agent -n "agent1" -o ./certs
Production Considerations
Resource Limits
services:
agent:
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
Logging
services:
agent:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Secrets Management
services:
agent:
secrets:
- tls_cert
- tls_key
- ca_cert
secrets:
tls_cert:
file: ./certs/agent.crt
tls_key:
file: ./certs/agent.key
ca_cert:
file: ./certs/ca.crt
Networking
services:
agent:
network_mode: host # For better UDP performance (QUIC)
Or use bridge with explicit port mapping:
services:
agent:
ports:
- "4433:4433/udp"
networks:
- mesh
Troubleshooting
Container Won't Start
# Check logs
docker compose logs agent1
# Check config syntax
docker compose config
# Test config
docker compose run --rm agent1 ./muti-metroo validate -c /app/config.yaml
Network Issues
# Check port bindings
docker compose ps
# Test internal connectivity
docker compose exec agent1 nc -zv agent2 4433
# Check DNS resolution
docker compose exec agent1 nslookup agent2
Permission Issues
# Check file permissions
docker compose exec agent1 ls -la /app/
# Fix data directory permissions
docker compose exec agent1 chown -R 1000:1000 /app/data
Next Steps
- Kubernetes Deployment - Deploy on K8s
- System Service - Native installation
- Monitoring - Prometheus setup