I started using Docker through a web-based setup, and now more than half of my services run in containers. They currently live under paths such as /srv/docker/jellyfin, but I suspect my organization could be better. What directory layout do you recommend for Compose files, environment variables, bind-mounted configuration, application data, secrets, and backups?
3 Answers
I use a simple structure like /containers/{immich,nextcloud,jellyfin}. Each application gets its own Compose file and subdirectories for its bind mounts. This keeps every stack self-contained, makes it easy to version-control the deployment files without exposing secrets, and avoids putting unrelated volumes in one large directory. On some machines, /containers is on a separate NVMe drive, which also makes migration to another operating-system disk easier.
I give each service or Compose stack its own directory. A typical layout might be /opt/apps/media-stack/ with compose/compose.yml, a local .env file, env/ for container-specific settings and secrets, data/ or bind-mounted service directories, and backups/. Keep sensitive files out of version control with .gitignore, and back up the configuration and persistent data that would be needed to restore the service. I also prefer pinning images to a version or digest instead of relying on :latest, since a tag can change over time.
Another reasonable layout is /opt/compose//, with the Compose file and any service-specific bind-mount directories underneath it. For example, Jellyfin might have its Compose file, configuration directory, cache directory, and media mounts kept clearly separate. You can also use a systemd template unit that points to the relevant application directory, so starting a stack is consistent and each service can be enabled independently.

That separation sounds useful, especially for moving services or restoring them on another machine.