Skip to main content

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 over docker-compose.yml per spec).
  • Use compose.override.yaml for local overrides (gitignored).

3.2. Service Definitions​

  • Restart Policy: Always set restart: unless-stopped (Compose) or deploy.restart_policy (Swarm).
  • Logging: Configure json-file logging 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.conf or 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)​

  1. SSH into the target server (via NetBird).
  2. Navigate to the project directory: /opt/polaris/clients/<client-name>.
  3. Pull latest changes:
    git pull origin main
  4. Deploy the stack:
    docker compose up -d --remove-orphans

4.2. Portainer Deployment (If available)​

  1. Login to the client's Portainer instance.
  2. Go to Stacks.
  3. Pull and redeploy the stack using the "Git Repository" reference.