Skip to content
GuidesContainersIntermediate

Docker Compose Best Practices for Home Servers

Structure stacks, volumes, networks, secrets and updates so your Compose homelab stays clean, secure and easy to rebuild.

by HomeServersGuide TeamUpdated July 16, 20263 min read

Why conventions matter

A home server can easily grow to 30+ containers. Without a consistent structure, you end up with mystery volumes, :latest tags that broke six months ago, and no idea how to rebuild after a disk failure. These practices keep your Docker homelab maintainable and reproducible.

1. One folder (and stack) per app group

Give each service or logically-related group its own directory with its own compose.yaml:

~/docker/
  nextcloud/compose.yaml
  media/compose.yaml        # jellyfin + arr stack together
  monitoring/compose.yaml   # grafana + prometheus

This isolates failures, makes updates independent, and lets you back up or move one app without touching the rest.

2. Keep everything in version control

Store your compose files (and non-secret config) in a Git repository. This gives you history, easy rollbacks, and a documented source of truth. Commit after every change; your future self will thank you when rebuilding.

3. Always use named volumes or bind mounts

Never let important data live only inside a container — it vanishes when the container is recreated. Mount persistent data explicitly:

services:
  app:
    image: my/app
    volumes:
      - ./config:/config          # bind mount, easy to back up
      - app_data:/var/lib/app     # named volume, managed by Docker
volumes:
  app_data:

Bind mounts (like ./config) are the easiest to back up because you can see them in the filesystem.

4. Pin image tags — avoid :latest

:latest means "whatever is newest today", which makes builds unpredictable and upgrades surprising. Pin a specific major/minor version:

    image: nextcloud:29-apache   # not nextcloud:latest

Update deliberately by bumping the tag, reading release notes, and testing — not by accident.

5. Handle secrets safely

Don't hard-code passwords in compose.yaml (which lives in Git). Use an .env file that is git-ignored:

    environment:
      - DB_PASSWORD=${DB_PASSWORD}
# .env  (add to .gitignore)
DB_PASSWORD=super-secret-value

For higher security, use Docker secrets or a secrets manager.

6. Set restart policies and healthchecks

Make services resilient across reboots and crashes:

    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      retries: 3

A healthcheck lets Docker (and dependencies) know a container is truly ready, not just running.

7. Use explicit networks and a reverse proxy

Create a shared network for web apps and put a reverse proxy in front instead of publishing a dozen ports:

networks:
  proxy:
    external: true

Containers reach each other by name on the same network; you expose only 80/443 to your LAN. See Docker networking explained.

8. Pin resource limits where needed

Stop one runaway container from starving the host:

    deploy:
      resources:
        limits:
          memory: 1g

9. Plan updates and cleanup

  • Update images intentionally: docker compose pull && docker compose up -d.
  • Read release notes for anything with a database.
  • Prune periodically: docker image prune reclaims space from old layers.
  • Back up volumes before major upgrades.

10. Make rebuilds boring

The end goal: if your server died today, you could restore from Git (compose files) plus your volume backups and be running again in under an hour. Test that assumption occasionally — a backup you've never restored is just a hope.

Next steps

Apply these patterns as you deploy services like Nextcloud, the *arr stack, and monitoring, and manage them visually with Portainer.

Related articles

GuidesContainersIntermediate

Docker Networking Explained for Home Servers

Understand bridge, host and macvlan networks, container DNS, and how to expose services safely behind a reverse proxy.

2 min read
TutorialsContainersBeginner

How to Install Docker on Ubuntu

A step-by-step tutorial to install Docker Engine and Docker Compose on Ubuntu Server, then run your first container.

1 min read
ArticlesContainersBeginner

Docker Basics for Self-Hosting

Learn images, containers, volumes and Docker Compose so you can deploy self-hosted applications with confidence.

1 min read