docker-infrastructure
Guide for Docker containerization and Traefik reverse proxy configuration. Use this when modifying Docker Compose files, adding new services, configuring Traefik routing, or managing container infrastructure.
Installation
Suivez les instructions du dépôt pour votre agent. Consultez les fichiers et dépendances avant l’installation.
Voir la source ↗GuidesInstructions
Docker & Infrastructure
This skill covers the Docker containerization and Traefik reverse proxy setup for this homelab project.
Technology Stack
- Docker - Container runtime
- Docker Compose - Multi-container orchestration
- Traefik v2.10 - Reverse proxy and load balancer
- Redis - In-memory cache (Alpine image)
- NFS Volumes - Network storage from Synology NAS
Compose Files
Development (compose.dev.yml)
Full development configuration with hot-reloading and all services.
# Start all development services
docker compose -f compose.dev.yml up
# Start specific service
docker compose -f compose.dev.yml up api dashboard
# Rebuild and start
docker compose -f compose.dev.yml up --build
# View logs
docker compose -f compose.dev.yml logs -f [service_name]
Production (compose.pro.yml)
Production overrides extending development config.
# Start production stack
docker compose -f compose.dev.yml -f compose.pro.yml up -d
Services Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Traefik (:81, :8080) │
│ Reverse Proxy/Router │
└─────────────────┬────────────────┬────────────────┬─────────────┘
│ │ │
┌────────▼────────┐ ┌─────▼─────┐ ┌───────▼──────┐
│ api (:8000) │ │ dashboard │ │ diagnostics │
│ FastAPI │ │ (:5173) │ │ api (:8000)│
└────────┬────────┘ └───────────┘ └──────────────┘
│
┌────────▼────────┐
│ cache (:6379) │
│ Redis │
└─────────────────┘
Adding a New Service
1. Create Dockerfile
FROM python:3.14-bookworm
WORKDIR /app
COPY ./requirements.txt /app/requirements.txt
RUN pip3 install --no-cache-dir -r /app/requirements.txt
2. Add to compose.dev.yml
services:
my_service:
container_name: my_service
build:
context: ./my_service
command: 'python3 main.py'
volumes:
- ./my_service:/app/my_service
environment:
SERVER_IP: '${SERVER_IP}'
restart: 'unless-stopped'
# If service needs Traefik routing:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.my_service.entrypoints=web'
- 'traefik.http.routers.my_service.rule=Host(`${SERVER_IP}`) && PathPrefix(`/my_service`)'
3. Add Traefik Labels (if web-accessible)
For services that need HTTP routing through Traefik:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.ROUTER_NAME.entrypoints=web'
- 'traefik.http.routers.ROUTER_NAME.rule=Host(`${SERVER_IP}`) && PathPrefix(`/PREFIX`)'
# Optional: Strip prefix before forwarding to service
- 'traefik.http.routers.ROUTER_NAME.middlewares=ROUTER_NAME-stripprefix'
- 'traefik.http.middlewares.ROUTER_NAME-stripprefix.stripprefix.prefixes=/PREFIX'
Traefik Configuration
Traefik is configured via command-line arguments in compose.dev.yml:
traefik:
command:
- '--log.level=INFO' # Logging level
- '--api.insecure=true' # Enable API/Dashboard (dev only)
- '--api.dashboard=true' # Enable web dashboard
- '--providers.docker=true' # Use Docker as provider
- '--providers.docker.exposedbydefault=false' # Require explicit labels
- '--entrypoints.web.address=:81' # HTTP entrypoint
Traefik Dashboard
Access at http://${SERVER_IP}:8080/dashboard in development.
Routing Rules
Common Traefik routing patterns used in this project:
# Host + Path prefix
'traefik.http.routers.api.rule=Host(`${SERVER_IP}`) && PathPrefix(`/api`)'
# Path prefix only
'traefik.http.routers.whoami.rule=PathPrefix(`/whoami`)'
Environment Variables
Environment variables are defined in .env (see .env.template):
SERVER_IP=192.168.x.x
LEETCODE_USERNAME=username
GITHUB_USERNAME=username
NAS_IP=192.168.x.x
NAS_PORT=5000
# ... etc
Secrets Management
Secrets are mounted from the ./secrets/ directory:
secrets:
pihole_password:
file: './secrets/pihole_password.txt'
slack_bot_token:
file: './secrets/slack_bot_token.txt'
Access in services via /run/secrets/SECRET_NAME.
NFS Volumes
The project uses NFS volumes to mount media from Synology NAS:
volumes:
media:
driver_opts:
type: 'nfs'
o: 'addr=${NAS_IP},nolock,soft,rw'
device: ':/volume1/media/'
Available Tools
Container Management
# View running containers
docker compose -f compose.dev.yml ps
# View all containers (including stopped)
docker compose -f compose.dev.yml ps -a
# Stop all services
docker compose -f compose.dev.yml down
# Stop and remove volumes
docker compose -f compose.dev.yml down -v
# Rebuild specific service
docker compose -f compose.dev.yml build my_service
# View container logs
docker compose -f compose.dev.yml logs -f my_service
# Execute command in running container
docker compose -f compose.dev.yml exec my_service bash
Debugging
# Check Traefik routing
curl http://localhost:8080/api/http/routers
# Test service directly (bypassing Traefik)
docker compose -f compose.dev.yml exec api curl http://localhost:8000/
# Check container health
docker compose -f compose.dev.yml ps
Best Practices
-
Use
restart: unless-stoppedfor production services - Mount source code as volumes in development for hot-reloading
- Use named volumes for persistent data
- Expose only necessary ports - let Traefik handle external routing
- Use environment variables for configuration that varies between environments
-
Store secrets in
./secrets/directory, never commit them -
Use
exposeinstead ofportsfor internal services routed through Traefik
Service-Specific Notes
API Service
- Runs on port 8000 internally
- Accessible via
/apithrough Traefik - Connected to Redis cache
Dashboard
- Development: Vite dev server on port 5173
- Production: Static build served via
serve
Redis Cache
- Persists data every 60 seconds with at least 1 change
- Port 6379 exposed for development debugging
Exemples
Consultez les exemples du dépôt source.
Voir la source ↗Historique source
- Date d’indexation
- 2026-01-20
- Mise à jour de l’index
- 2026-01-26
- Branch
- main
Les dates concernent ce répertoire. Consultez le dépôt pour l’historique du code.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!