SOP: Docker Stacks & Deployment
1. Overview​
We use Docker Swarm (or standalone Docker Compose) as our primary container orchestration standard. This ensures consistency between local development and production deployment.
2. Directory Structure​
Inside a Client Repository (clients/client-name/), the structure MUST be:
client-name/
├── .env.example # Template for environment variables (NO SECRETS)
├── compose.yaml # Main stack definition
├── configs/ # Configuration files mounted into containers
│ ├── nginx/
│ └── prometheus/
└── data/ # (Optional) Local host-bind data, usually gitignored
3. Standards​
3.1. File Naming​
- Use
compose.yaml(preferred overdocker-compose.ymlper spec). - Use
compose.override.yamlfor local overrides (gitignored).
3.2. Service Definitions​
- Restart Policy: Always set
restart: unless-stopped(Compose) ordeploy.restart_policy(Swarm). - Logging: Configure
json-filelogging with limits to prevent disk exhaustion.logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
3.3. Volume Management​
- Persistent Data: Use Named Volumes for databases to decouple storage from the container filesystem.
- Config Files: Use Bind Mounts for
nginx.confor other static configs managed in git.volumes:
- ./configs/nginx:/etc/nginx:ro # Read-only config
- db_data:/var/lib/mysql # Named volume for data
4. Deployment Process​
4.1. Manual Deployment (SSH)​
- SSH into the target server (via NetBird).
- Navigate to the project directory:
/opt/polaris/clients/<client-name>. - Pull latest changes:
git pull origin main - Deploy the stack:
docker compose up -d --remove-orphans
4.2. Portainer Deployment (If available)​
- Login to the client's Portainer instance.
- Go to Stacks.
- Pull and redeploy the stack using the "Git Repository" reference.