Skip to main content

Docker Compose Deployment

Compose Deploy gives you full control by letting you paste a raw Docker Compose YAML file. The panel injects Traefik routing, manages DNS, and monitors health — you define everything else.

How It Works

Step 1: Prepare Your Compose File

Navigate to Deploy > Compose Deploy and enter:

FieldDescription
Service NameName for the service (becomes the subdomain)
CustomerWhich customer owns this service
Docker Compose YAMLYour complete compose configuration

Step 2: Write or Paste Compose YAML

Enter your Docker Compose file in the editor. You can use magic variables for dynamic values:

version: "3.8"
services:
app:
image: myapp:latest
environment:
- DATABASE_URL=postgresql://{{DB_USER}}:{{DB_PASSWORD}}@db:5432/{{DB_NAME}}
- APP_URL=https://{{DOMAIN}}
volumes:
- app-data:/data

db:
image: postgres:16
environment:
- POSTGRES_USER={{DB_USER}}
- POSTGRES_PASSWORD={{DB_PASSWORD}}
- POSTGRES_DB={{DB_NAME}}
volumes:
- db-data:/var/lib/postgresql/data

volumes:
app-data:
db-data:

Step 3: Deploy

Click Deploy. The panel processes your compose file:

  1. Substitutes magic variables with generated or configured values
  2. Injects Traefik labels on the first service (or the service marked with expose):
    labels:
    - "traefik.enable=true"
    - "traefik.http.routers.myapp.rule=Host(`myapp.panel.example.com`)"
    - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
  3. Connects to the aiadminpanel Docker network
  4. Removes any ports: directives (traffic routes through Traefik)
  5. Pulls images and starts containers
  6. Monitors health and reports status

Magic Variables

Magic variables are placeholders in your compose file that the panel substitutes at deploy time:

VariableDescriptionExample Value
{{SERVICE_NAME}}The service name you providedmy-app
{{DOMAIN}}Full domain for the servicemy-app.panel.example.com
{{PASSWORD}}Auto-generated secure password (32 chars)aB3x...
{{DB_USER}}Auto-generated database usernameuser_a1b2c3
{{DB_PASSWORD}}Auto-generated database passwordkL9m...
{{DB_NAME}}Database name (derived from service name)my_app
{{SECRET_KEY}}Auto-generated secret key (64 chars)xY7z...
{{PORT}}The exposed port for Traefik routing8080

You can use the same magic variable multiple times — each occurrence gets the same generated value.

Routing Configuration

By default, Traefik routes to the first service in your compose file on port 80. To customize:

Specify the expose port

Add a label to the service that should receive traffic:

services:
app:
image: myapp:latest
labels:
- "aiadminpanel.expose.port=3000"

Multiple exposed services

If you need to expose multiple services on different subdomains:

services:
frontend:
image: myapp-frontend:latest
labels:
- "aiadminpanel.expose.port=3000"
- "aiadminpanel.expose.subdomain={{SERVICE_NAME}}"

api:
image: myapp-api:latest
labels:
- "aiadminpanel.expose.port=8080"
- "aiadminpanel.expose.subdomain={{SERVICE_NAME}}-api"

This creates two routes:

  • https://my-app.panel.example.com pointing to the frontend
  • https://my-app-api.panel.example.com pointing to the API

Best Practices

  1. Always use named volumes for persistent data — anonymous volumes are lost on redeployment
  2. Never use ports: — Traefik handles all external routing
  3. Use magic variables for secrets — do not hardcode passwords in compose files
  4. Set restart policies — use restart: unless-stopped for production services
  5. Include health checks — either in the compose file or via labels for panel monitoring:
    healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
    interval: 30s
    timeout: 10s
    retries: 3

Limitations

  • Compose files using build: contexts are not supported — use pre-built images
  • Host networking (network_mode: host) is not supported — use Traefik routing
  • Privileged containers require the raw security profile approval
  • Compose file must be valid YAML — the editor validates syntax before deploy