Skip to content

Docker Best Practices

General Rules

  • Always pin image versions — never use latest in production
  • Use named volumes for persistent data, not bind mounts for databases
  • Set restart: unless-stopped on all production containers
  • Set log limits on all containers

Log Configuration

Always set log limits to prevent disk fill:

services:
  myapp:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

Port Assignments — caneast-c1-node2

Port Service
3000 Homepage
3001 Uptime Kuma
3002 Grafana
3003 archon-docs
8086 InfluxDB
9000 Portainer
9100 Node Exporter

Networks

  • Use named networks, not default bridge
  • Services that don't need to talk to each other go on separate networks
  • Never expose management ports (9000, 8086) externally

Secrets

Never use environment variables for secrets in compose files. Use Infisical agent injection or Docker secrets:

# Wrong
environment:
  - DB_PASSWORD=REDACTED

# Right — injected at runtime by Infisical agent
environment:
  - DB_PASSWORD=REDACTED

Image Scanning

Scan every image with Grype before deploying:

grype IMAGE:TAG --fail-on high

Filesystem Fixes

Use busybox for one-off filesystem operations, not alpine:

docker run --rm -v myvolume:/data busybox chown -R 1000:[INTERNAL] /data