Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Docker Syntax Compose Services

  • 8 installs
  • 9 repo stars
  • Updated July 8, 2026
  • openaec-foundation/docker-claude-skill-package

Helps with devops & ci/cd tasks.

About

docker-syntax-compose-services is a Claude Code skill for devops & ci/cd. It helps solo builders move faster with AI-assisted development.

  • docker-syntax-compose-services
  • DevOps & CI/CD
  • AI-coding skill

Docker Syntax Compose Services by the numbers

  • 8 all-time installs (skills.sh)
  • Ranked #1,044 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/docker-claude-skill-package --skill docker-syntax-compose-services

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs8
repo stars9
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/docker-claude-skill-package

What it does

Helps with devops & ci/cd tasks.

Files

SKILL.mdMarkdownGitHub ↗

docker-syntax-compose-services

Quick Reference

Service Definition Structure

services:
  service-name:
    image: registry/image:tag        # Container image
    build: ./path                    # Build from Dockerfile
    command: ["executable", "arg"]   # Override CMD
    entrypoint: ["executable"]       # Override ENTRYPOINT
    ports:                           # Port mappings
      - "8080:80"
    environment:                     # Environment variables
      KEY: value
    volumes:                         # Data mounts
      - data:/app/data
    depends_on:                      # Service dependencies
      db:
        condition: service_healthy
    healthcheck:                     # Health monitoring
      test: ["CMD", "curl", "-f", "http://localhost"]
    deploy:                          # Resource limits and replicas
      resources:
        limits:
          memory: 512M
    restart: unless-stopped          # Restart policy

Critical Warnings

NEVER use depends_on without condition: service_healthy when your service requires the dependency to be fully ready. The default service_started condition only waits for the container to start, NOT for the application inside to be ready.

NEVER set container_name on services you intend to scale. Container names must be unique -- setting a fixed name prevents docker compose up --scale.

NEVER hardcode secrets in environment. ALWAYS use Docker secrets or .env files with interpolation for sensitive values.

NEVER expose ports to all interfaces ("8080:80") in production. ALWAYS bind to a specific interface ("127.0.0.1:8080:80") unless the service must be publicly accessible.

ALWAYS combine restart: always or restart: unless-stopped with deploy.resources.limits to prevent a crash-looping container from consuming all system resources.

ALWAYS declare named volumes in the top-level volumes: section. Anonymous volumes are destroyed on docker compose down.

---

Image and Build

Image Source

services:
  web:
    image: nginx:1.25-alpine              # Tag-based
    image: redis@sha256:0ed5d592...       # Digest-pinned
    image: registry.example.com:5000/app  # Private registry

Build Configuration

services:
  app:
    build:
      context: .                    # Build context directory
      dockerfile: prod.Dockerfile   # Custom Dockerfile path
      target: production            # Multi-stage target
      args:
        GIT_COMMIT: ${GIT_COMMIT}   # Build arguments
      cache_from:
        - type=gha                  # GitHub Actions cache
      secrets:
        - db_password               # Build-time secrets
      platforms:
        - linux/amd64
        - linux/arm64

When both build and image are set, pull_policy determines precedence. Without pull_policy, Compose attempts pulling before building.

---

Command and Entrypoint

FormSyntaxShell Processing
Stringcommand: bundle exec thin -p 3000Passed to /bin/sh -c
List (exec)command: ["php", "-d", "memory=-1"]Executed directly

Set to null to use image default. Set to [] or '' to clear.

---

Ports

Short vs Long Syntax Comparison

FeatureShort SyntaxLong Syntax
Basic mapping"8080:80"target: 80, published: "8080"
Interface bind"127.0.0.1:8080:80"host_ip: 127.0.0.1
Protocol"6060:6060/udp"protocol: udp
Port range"9090-9091:8080-8081"Not supported
Named portNot supportedname: web
App protocolNot supportedapp_protocol: http
Random host port"3000"Omit published

Short Syntax

ports:
  - "8080:80"                  # HOST:CONTAINER
  - "127.0.0.1:8001:8001"     # Bind to localhost
  - "9090-9091:8080-8081"     # Port range
  - "6060:6060/udp"           # UDP protocol
  - "3000"                     # Random host port

Long Syntax

ports:
  - name: web
    target: 80
    published: "8080"
    host_ip: 127.0.0.1
    protocol: tcp
    app_protocol: http
    mode: host

ALWAYS use long syntax when you need named ports or explicit interface binding for clarity.

---

Environment Variables

Precedence (Highest to Lowest)

1. docker compose run -e CLI flag 2. Shell interpolation in environment/env_file 3. environment attribute (static values) 4. env_file attribute 5. Dockerfile ENV directive

Configuration

environment:
  RACK_ENV: development           # Map syntax
  DB_PASSWORD: ${DB_PASSWORD:?Required}  # Fail if unset

env_file:
  - path: ./default.env
    required: false               # Don't error if missing

ALWAYS use ${VAR:?message} for required variables to fail fast with a clear error.

---

Volumes

Short vs Long Syntax

volumes:
  # Short syntax
  - db-data:/var/lib/postgresql/data        # Named volume
  - ./config:/app/config:ro                 # Bind mount, read-only

  # Long syntax
  - type: volume
    source: db-data
    target: /var/lib/data
    volume:
      nocopy: true
  - type: bind
    source: ./config
    target: /app/config
    read_only: true
    bind:
      create_host_path: true
  - type: tmpfs
    target: /tmp
    tmpfs:
      size: 100M

ALWAYS use long syntax for production configurations -- it makes mount type, access mode, and options explicit.

---

depends_on

Condition Comparison Table

ConditionWaits ForRequiresUse Case
service_startedContainer startedNothingNon-critical dependencies
service_healthyHealthcheck passeshealthcheck on targetDatabases, APIs that need warmup
service_completed_successfullyExit code 0Service exitsMigrations, seed scripts

Configuration

depends_on:
  db:
    condition: service_healthy
    restart: true              # Restart when dependency updates
  migration:
    condition: service_completed_successfully
    required: false            # Warning instead of error if missing
  redis:
    condition: service_started

ALWAYS use condition: service_healthy for database dependencies. A started container does NOT mean the database is accepting connections.

---

Healthcheck

Pattern Template

healthcheck:
  test: ["CMD-SHELL", "<check-command>"]
  interval: 30s          # Time between checks
  timeout: 10s           # Max time for single check
  retries: 3             # Failures before unhealthy
  start_period: 30s      # Grace period at startup
  start_interval: 5s     # Interval during start_period

Common Healthcheck Commands

ServiceTest Command
PostgreSQLpg_isready -U postgres
MySQLmysqladmin ping -h localhost
Redisredis-cli ping
HTTP APIcurl -f http://localhost:8080/health
TCP portnc -z localhost 5432

Set test: NONE to disable a healthcheck inherited from the image.

---

Deploy and Resource Limits

deploy:
  replicas: 3
  resources:
    limits:
      cpus: '0.50'
      memory: 512M
      pids: 100
    reservations:
      cpus: '0.25'
      memory: 256M
      devices:
        - capabilities: [gpu]
          driver: nvidia
          count: 1
  restart_policy:
    condition: on-failure
    delay: 5s
    max_attempts: 3
    window: 120s

ALWAYS set resources.limits.memory for every production service. Without limits, a memory leak in one container can crash the entire host.

---

Restart Policies

PolicyBehavior
"no"Never restart (default). ALWAYS quote -- unquoted no is YAML boolean false
alwaysRestart unconditionally, including after daemon restart
on-failure[:max]Restart only on non-zero exit. Optional max retries (on-failure:3)
unless-stoppedLike always, but NOT after manual docker stop

ALWAYS use unless-stopped for production services -- it respects manual stops while surviving daemon restarts.

---

Security Configuration

services:
  app:
    read_only: true              # Read-only root filesystem
    user: "1000:1000"            # Non-root user
    cap_drop:
      - ALL                      # Drop all capabilities
    cap_add:
      - NET_BIND_SERVICE         # Add back only what's needed
    security_opt:
      - no-new-privileges:true

ALWAYS drop all capabilities with cap_drop: [ALL] and add back only what the service requires. NEVER use privileged: true unless absolutely necessary.

---

Profiles

services:
  app:                           # No profile = ALWAYS enabled
    image: myapp
  debug-tools:
    image: debug-toolkit
    profiles: [debug]            # Only with --profile debug
  monitoring:
    profiles: [monitoring, production]

Activate with: docker compose --profile debug up or COMPOSE_PROFILES=debug.

Services WITHOUT profiles are ALWAYS started. ALWAYS assign profiles to development-only or optional services.

---

Extends

services:
  web:
    extends:
      file: common-services.yml
      service: webapp
    environment:
      API_KEY: ${API_KEY}        # Local values override extended

Local attributes ALWAYS override extended values. Relative paths in extended files are automatically converted.

---

Additional Attributes

AttributePurposeKey Constraint
container_nameFixed container namePrevents scaling
hostnameContainer hostnameRFC 1123 compliant
platformTarget platformFormat: os[/arch[/variant]]
pull_policyImage pull strategyalways, never, missing, build
loggingLog driver and optionsDriver must be available
labelsContainer metadataReverse-DNS notation recommended
init: truePID 1 init processProper signal forwarding
stop_grace_periodTime before SIGKILLDefault: 10s

---

Reference Links

  • references/attributes.md -- Complete service attribute reference with all options and syntax variants
  • references/examples.md -- Common service configurations for web, database, cache, and worker services
  • references/anti-patterns.md -- Service configuration mistakes with explanations and corrections

Official Sources

  • https://docs.docker.com/compose/compose-file/05-services/
  • https://docs.docker.com/compose/compose-file/build/
  • https://docs.docker.com/compose/compose-file/deploy/
  • https://docs.docker.com/compose/how-tos/environment-variables/

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.