Last active
September 30, 2025 13:25
-
-
Save githubfoam/6d8765827c21e9677254a29cd876b162 to your computer and use it in GitHub Desktop.
docker-compose cheat sheet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #===================================================================== | |
| services: # Define the services (containers) in this Compose file | |
| nagios: # Service name: nagios | |
| image: nagios459-debian12:latest # Use the pre-built Nagios Debian 12 image | |
| container_name: nagios # Assign a custom container name for easier reference | |
| restart: unless-stopped # Restart policy: restart container unless explicitly stopped | |
| environment: # Define environment variables for the container | |
| NAGIOS_FQDN: nagios.example.com # Fully Qualified Domain Name for Nagios | |
| NAGIOSADMIN_USER: nagiosadmin # Admin username for Nagios web interface | |
| NAGIOSADMIN_PASS: nagios # Admin password for Nagios web interface | |
| DEBIAN_FRONTEND: noninteractive # Avoid interactive prompts during apt installs | |
| ports: # Map container ports to host ports | |
| - "80:80" # Host port 80 → container port 80 for Nagios web interface | |
| - "5667:5667" # Host port 5667 → container port 5667 for NRPE checks | |
| volumes: # Mount persistent volumes to container paths | |
| - nagios_var:/opt/nagios/var # Nagios runtime data | |
| - nagios_etc:/opt/nagios/etc # Nagios configuration files | |
| - apache_logs:/var/log/apache2 # Apache log files | |
| - nagios_plugins:/opt/Custom-Nagios-Plugins # Custom Nagios plugins | |
| - nagiosgraph_var:/opt/nagiosgraph/var # NagiosGraph runtime data | |
| - nagiosgraph_etc:/opt/nagiosgraph/etc # NagiosGraph configuration files | |
| tty: true # Allocate a pseudo-TTY (useful for interactive shell) | |
| stdin_open: true # Keep STDIN open for interactive sessions | |
| volumes: # Define named Docker volumes (persistent storage) | |
| nagios_var: # Volume for Nagios runtime data | |
| nagios_etc: # Volume for Nagios configuration | |
| apache_logs: # Volume for Apache logs | |
| nagios_plugins: # Volume for custom Nagios plugins | |
| nagiosgraph_var: # Volume for NagiosGraph runtime data | |
| nagiosgraph_etc: # Volume for NagiosGraph configuration | |
| #===================================================================== | |
| You’re using named volumes like nagios_var, nagios_etc, etc., under the volumes: section. | |
| Named volumes are managed by Docker, not tied to a specific host directory. | |
| Docker will automatically create these volumes the first time you run docker-compose up. | |
| Paths inside the container (e.g., /opt/nagios/var) will be populated by Docker when the container starts. | |
| If you wanted to bind a host directory instead of a Docker volume, you would use a host path like: | |
| volumes: | |
| - ./nagios_var:/opt/nagios/var | |
| In that case, the ./nagios_var directory must exist on the host (Docker won’t create it automatically). | |
| ✅ Summary: With your current docker-compose.yml using named volumes, Docker handles creation automatically. You can just run: | |
| docker-compose -f docker-compose.yml.debian up -d | |
| and it will create the necessary volumes and start the Nagios container. | |
| #===================================================================== | |
| # 1️⃣ Build the image from the Dockerfile | |
| docker-compose -f docker-compose.yml.debian build | |
| # -f docker-compose.yml.debian : specify the Compose file | |
| # build : build the Docker image defined in the Compose file | |
| # This step creates the 'nagios459-debian12:latest' image if not already built | |
| # 2️⃣ Start the container in detached mode | |
| docker-compose -f docker-compose.yml.debian up -d | |
| # up : start the services defined in the Compose file | |
| # -d : run in detached mode (in background) | |
| # Creates and starts the 'nagios' container, applies volumes, environment variables, and port mappings | |
| # 3️⃣ View container logs (optional) | |
| docker-compose -f docker-compose.yml.debian logs -f nagios | |
| # logs -f : follow the logs in real-time | |
| # nagios : view logs of the Nagios service | |
| # 4️⃣ Access an interactive shell inside the running container | |
| docker-compose -f docker-compose.yml.debian exec nagios bash | |
| # exec : execute a command inside a running container | |
| # bash : start a Bash shell for manual inspection or troubleshooting | |
| # 5️⃣ Stop the container | |
| docker-compose -f docker-compose.yml.debian stop | |
| # stop : stop the running container gracefully | |
| # Container still exists on disk, volumes are preserved | |
| # 6️⃣ Restart the container (if needed) | |
| docker-compose -f docker-compose.yml.debian restart | |
| # restart : stop and immediately start the container again | |
| # 7️⃣ Remove the container without deleting volumes | |
| docker-compose -f docker-compose.yml.debian rm -f nagios | |
| # rm : remove the container | |
| # -f : force removal without confirmation | |
| # Volumes are preserved unless explicitly removed | |
| # 8️⃣ Tear down everything including networks and optionally volumes | |
| docker-compose -f docker-compose.yml.debian down -v | |
| # down : stop and remove containers, networks, and default Docker Compose setup | |
| # -v : also remove associated named volumes | |
| # Use this to completely reset the environment | |
| #===================================================================== | |
| Docker Compose Commands | |
| Build the image (if you want Compose to build from Dockerfile): | |
| docker-compose -f docker-compose.yml.debian build | |
| Since you already built nagios459-debian12:latest, this step is optional unless you change the Dockerfile. | |
| Start container: | |
| docker-compose -f docker-compose.yml.debian up -d | |
| -d → detached mode (runs in background). | |
| View logs (Nagios output, Apache logs): | |
| docker-compose -f docker-compose.yml.debian logs -f | |
| Stop container: | |
| docker-compose -f docker-compose.yml.debian stop | |
| Restart container: | |
| docker-compose -f docker-compose.yml.debian restart | |
| Destroy container and volumes: | |
| docker-compose -f docker-compose.yml.debian down -v | |
| -v deletes all associated volumes (nagios_var, nagios_etc, etc.) | |
| down removes the container and network created by Compose. | |
| Extra Tips | |
| To enter the container interactively: | |
| docker exec -it nagios bash | |
| To rebuild after Dockerfile changes: | |
| docker-compose -f docker-compose.yml.debian build --no-cache | |
| docker-compose -f docker-compose.yml.debian up -d | |
| #===================================================================== | |
| To clean up all dangling images: | |
| Run: | |
| docker image prune | |
| You'll be prompted to confirm. | |
| To skip the prompt: | |
| docker image prune -f | |
| If you only want to remove dangling images (those with <none> tag): | |
| docker images -f "dangling=true" | |
| To delete them: | |
| docker rmi $(docker images -f "dangling=true" -q) | |
| If any containers are still using these images (even stopped ones), Docker will refuse to delete them. | |
| To check if an image is still in use: | |
| docker ps -a --filter "ancestor=<IMAGE_ID>" | |
| Best Practice for Local Dev Environments | |
| Use docker compose down --volumes to reset state only when needed. | |
| Use docker volume prune regularly to clean up dangling volumes. | |
| Use docker image prune -a or docker builder prune to clean up old images/cache. | |
| #===================================================================== | |
| ports: | |
| - target: 8000 | |
| published: 7778 | |
| protocol: tcp | |
| target: 8000 = the internal port inside the container where LibreNMS runs its web server. | |
| published: 7778 = the external host port you want to expose to access LibreNMS in the browser. | |
| This maps http://<your-host>:7778 → container's :8000. | |
| #===================================================================== | |
| Restart containers after changes | |
| docker compose down -v | |
| docker compose up -d --build | |
| Rebuild and restart the container | |
| From the top-level directory where docker-compose.yml is: | |
| docker compose down | |
| docker compose build librenms | |
| docker compose up | |
| #===================================================================== | |
| docker volume rm librenms-logs | |
| Option 3: Check for processes locking the volume on host | |
| If you use a bind mount or named volume mapped to host directory, check if some host process (e.g. another container or file handle) is locking the directory. | |
| On Linux, you can check: | |
| lsof +D /path/to/mounted/logs | |
| #===================================================================== | |
| When and How Volume Orphaning Happens | |
| The Problem | |
| Anonymous Docker volumes get created and orphaned when: | |
| Using docker run without named volumes | |
| # Creates anonymous volume each time | |
| docker run -v /data myapp | |
| Removing containers without cleanup | |
| docker rm container_name # Volume remains! | |
| docker run -v /data myapp # Creates NEW anonymous volume | |
| Using docker-compose up/down incorrectly | |
| docker-compose down # OK - preserves volumes | |
| docker rm container_name # Then manually running | |
| docker-compose up # May create new volumes | |
| How to Detect and Identify Orphaned Volumes | |
| You'll see many volumes with random hash names | |
| docker volume ls | |
| Inspect Specific Volumes | |
| # Check what created a volume | |
| docker volume inspect 0c1d2203957be01c8957b8aefae1e8e286de1d9ce1f152357376d153ea109268 | |
| # Find which containers use a volume | |
| docker ps -a --filter volume=VOLUME_NAME | |
| Check Volume Usage | |
| # See volumes with their mount points | |
| docker system df -v | |
| # This shows: | |
| # - Volume name | |
| # - Links (number of containers using it) | |
| # - Size | |
| Proper Volume Re-use with Examples | |
| Example 1: Named Volumes (Recommended) | |
| # docker-compose.yml | |
| version: '3.8' | |
| services: | |
| app: | |
| image: myapp | |
| volumes: | |
| - app-data:/data # Named volume | |
| - logs:/var/log/app # Named volume | |
| volumes: | |
| app-data: # Defined named volume | |
| logs: # Defined named volume | |
| Benefits: | |
| Volumes persist across container recreation | |
| Easy to identify: docker volume ls shows projectname_app-data | |
| Automatically reused when you run docker-compose up again | |
| Example 2: Avoiding Anonymous Volumes | |
| # ❌ BAD - Creates anonymous volume | |
| docker run -v /data myapp | |
| # ✅ GOOD - Uses named volume | |
| docker run -v mydata:/data myapp | |
| # Stopping and restarting reuses the same volume | |
| docker stop container_name | |
| docker rm container_name | |
| docker run -v mydata:/data myapp # Reuses 'mydata' volume | |
| Example 3: Docker Compose with Explicit Volume Names | |
| version: '3.8' | |
| services: | |
| librenms: | |
| image: librenms/librenms | |
| volumes: | |
| - librenms-data:/data | |
| - librenms-logs:/opt/librenms/logs | |
| - librenms-rrd:/opt/librenms/rrd | |
| volumes: | |
| librenms-data: | |
| name: librenms_data # Explicit name | |
| librenms-logs: | |
| name: librenms_logs | |
| librenms-rrd: | |
| name: librenms_rrd | |
| Docker Cleanup Without Leaving Orphaned Volumes | |
| Method 1: Docker Compose Cleanup | |
| # Remove containers but KEEP volumes (safe) | |
| docker-compose down | |
| # Remove containers AND volumes (clean slate) | |
| docker-compose down -v | |
| # Remove specific service's containers and volumes | |
| docker-compose rm -v -s -f service_name | |
| Method 2: Safe Container Removal | |
| # Remove container AND its anonymous volumes | |
| docker rm -v container_name | |
| # Remove all stopped containers with their volumes | |
| docker container prune -f | |
| Method 3: Clean Up Orphaned Volumes | |
| # Remove all unused volumes (CAREFUL!) | |
| docker volume prune | |
| # With confirmation | |
| docker volume prune -f | |
| # Remove specific volume | |
| docker volume rm volume_name | |
| # Remove multiple volumes | |
| docker volume rm $(docker volume ls -qf dangling=true) | |
| Method 4: Complete Cleanup Script | |
| #!/bin/bash | |
| # Safe cleanup script | |
| # Stop all containers | |
| docker-compose down | |
| # Remove stopped containers with volumes | |
| docker container prune -f | |
| # Remove dangling volumes only | |
| docker volume prune -f | |
| # Restart with fresh setup | |
| docker-compose up -d | |
| Recommended Workflow for Your LibreNMS Setup | |
| # 1. Check current volume usage | |
| docker system df -v | |
| # 2. Stop containers properly | |
| cd ~/librenms/docker-master/examples/compose | |
| docker-compose down | |
| # 3. Clean up orphaned volumes | |
| docker volume prune -f | |
| # 4. Verify named volumes exist in docker-compose.yml | |
| cat docker-compose.yml | grep -A 5 "volumes:" | |
| # 5. Start with proper volume configuration | |
| docker-compose up -d | |
| # 6. Verify only named volumes exist | |
| docker volume ls | grep librenms | |
| Prevention Best Practices | |
| Always use named volumes in docker-compose.yml | |
| Never use docker rm without -v flag | |
| Use docker-compose down instead of manual container removal | |
| Regularly audit volumes: docker volume ls and docker system df -v | |
| Schedule cleanup: Set up periodic docker volume prune -f (weekly/monthly) | |
| #===================================================================== | |
| If you want to clean up orphan containers, run: | |
| docker compose down --remove-orphans -v | |
| #===================================================================== | |
| Why the user and data persisted despite docker compose down -v | |
| Even though you used docker compose down -v (which does delete named or anonymous volumes created by Docker Compose), your docker-compose.yml includes this line | |
| volumes: | |
| - "./librenms:/data" | |
| The ./librenms folder on your host stores LibreNMS data. | |
| When you did docker compose down -v, Docker: | |
| Removed volumes it manages (like the db volume, if it's named). | |
| Did not touch bind-mounted folders like ./librenms. | |
| So when you brought the containers up again with docker compose up -d --build, the container saw: | |
| "Oh, the /data directory already has previous config, users, etc." | |
| #===================================================================== | |
| docker compose exec librenms mysql -h db -u librenms -p | |
| #===================================================================== | |
| $ docker compose up -d --build | |
| #===================================================================== | |
| docker compose up -d --build | |
| write /var/lib/docker/tmp/GetImageBlob1490303091: no space left on device | |
| df -h | |
| /dev/sda8 71G 11G 57G 16% /home | |
| /dev/sda5 6.4G 6.3G 0 100% /var | |
| explain how to fix this, there is much space on /home | |
| Docker stores all its images, containers, volumes, and temporary files under /var/lib/docker by default. Since /var is a small (6.4 GB) and full partition, Docker cannot proceed — even though /home has plenty of space | |
| Solution: Move Docker storage to /home | |
| We will move Docker's storage location from /var/lib/docker to /home/docker-data (or another directory with more space). | |
| tep-by-step Instructions | |
| 1. Stop Docker | |
| sudo systemctl stop docker | |
| 2. Create a new directory on /home | |
| sudo mkdir -p /home/docker-data | |
| 3. Move existing Docker data (if any) | |
| sudo rsync -aP /var/lib/docker/ /home/docker-data/ | |
| 4. Configure Docker to use the new location | |
| Create or edit Docker’s daemon config: | |
| sudo mkdir -p /etc/docker | |
| sudo nano /etc/docker/daemon.json | |
| Add: | |
| { | |
| "data-root": "/home/docker-data" | |
| } | |
| 5. Restart Docker | |
| sudo systemctl start docker | |
| 6. Verify | |
| Run: | |
| docker info | grep "Docker Root Dir" | |
| You should see: | |
| Docker Root Dir: /home/docker-data | |
| 💡 Optional: Clean up old data | |
| Once you're sure everything works, you can delete the old directory: | |
| sudo rm -rf /var/lib/docker | |
| #===================================================================== | |
| docker compose -f docker-compose.json up #use JSON instead of YAML compose file | |
| #===================================================================== | |
| docker compose -f ~/hello_world/docker-compose.yml build | |
| docker compose -f ~/hello_world/docker-compose.yml up -d | |
| docker compose ps # Lists containers. | |
| docker compose stop | |
| docker compose start # Starts existing containers for a service. | |
| docker compose stop # Stops running containers without removing them. | |
| docker compose pause # Pauses running containers of a service. | |
| docker compose unpause # Unpauses paused containers of a service | |
| docker compose up #Builds, (re)creates, starts, and attaches to containers for a service | |
| docker compose up -d #Create docker image and run container in the background | |
| docker compose down # Stops containers and removes containers, networks, volumes, and images created by up. | |
| docker compose down -v # tear down the containers and volumes | |
| docker compose --version | |
| docker compose ps | |
| docker compose images #List images used by the created containers | |
| docker compose stop | |
| docker compose run web | |
| docker compose down | |
| docker compose -f docker-compose-dev.yml up -d app1 | |
| docker compose -f docker-compose-test-local.yml run --rm unit | |
| docker compose -f docker-compose-test-local.yml build app -> as an alternative, define build arguments inside a Docker Compose file | |
| docker compose build | |
| docker compose config | |
| docker compose -f docker-compose-test-local.yml up -d staging-dep | |
| docker compose -f docker-compose-test-local.yml ps | |
| docker compose -f docker-compose-test-local.yml run --rm staging | |
| docker compose -f docker-compose-test-local.yml down | |
| docker compose -f docker-compose-local.yml up -d registry | |
| #===================================================================== | |
| docker compose logs | |
| docker compose logs -f initializer #track progress | |
| docker compose logs initializer | grep "Admin password:" #obtain admin credentials | |
| stream logs in real-time, use the -f (follow) flag: | |
| docker compose -f librenms/docker-master/examples/compose/compose.yml logs -f | |
| limit the number of lines displayed using the --tail option | |
| docker compose -f librenms/docker-master/examples/compose/compose.yml logs --tail=100 | |
| docker compose -f librenms/docker-master/examples/compose/compose.yml logs --timestamps | |
| for a specific service | |
| docker compose -f librenms/docker-master/examples/compose/compose.yml logs --timestamps web | |
| View logs for all services | |
| docker-compose logs | |
| View logs for Nginx (web) | |
| docker-compose logs web | |
| save logs for analysis, redirect output | |
| docker-compose logs web > web_logs.txt | |
| Checking Logs of a Specific Container | |
| docker ps | |
| docker logs -f <container_id> | |
| Use docker compose logs -f librenms-app to monitor LibreNMS logs. | |
| docker logs librenms-app | |
| docker logs librenms-app --tail 50 --follow | |
| #===================================================================== | |
| docker compose up -d #Create docker image and run container in the background | |
| docker compose exec kali /bin/bash #Create docker image and run container in the background | |
| #===================================================================== | |
| docker build -t kalicmd . --file=/vagrant/dockerfiles/kalilinux/toolkali | |
| docker compose --file /vagrant/dockerfiles/kalilinux/docker-compose.yml run kali-service | |
| docker compose --file /vagrant/dockerfiles/kalilinux/docker-compose.yml ps #Lists containers | |
| cat docker-compose.yml | |
| version: '3' | |
| services: | |
| kali-service: | |
| image: "kalicmd" | |
| volumes: | |
| - /mnt/share-kali:/share | |
| - /mnt/share-kali/.bash_history:/root/.bash_history | |
| #===================================================================== | |
| docker compose build --no-cache #Force the execution of each step/instruction in the Dockerfile | |
| docker compose build --no-cache && docker compose up -d --force-recreate #t recreate all containers | |
| docker build --pull --no-cache --tag myimage:version #force rebuilding of layers already available | |
| #===================================================================== | |
| #===================================================================== | |
| WINDOWS | |
| #===================================================================== | |
| docker compose version | |
| #===================================================================== | |
| #===================================================================== | |
| #===================================================================== | |
| #===================================================================== | |
| #environment variable, non-default dockere file name | |
| #docker-compose.yaml | |
| version: '3.8' | |
| services: | |
| myservice: | |
| build: | |
| context: . | |
| dockerfile: ./docker/Dockerfile.myservice | |
| image: myself/myservice | |
| env_file: | |
| - ./var.env | |
| environment: | |
| - VAR_C=C | |
| - VAR_D=D | |
| volumes: | |
| - $HOME/myfolder:/myfolder | |
| ports: | |
| - "5000:5000" | |
| #===================================================================== | |
| cat Dockerfile.test | |
| cat docker-compose.test.yml | |
| docker compose -f ~/hello_world/docker-compose.test.yml -p ci build | |
| docker compose -f ~/hello_world/docker-compose.test.yml -p ci up -d | |
| docker compose -p ci stop | |
| #===================================================================== | |
| Docker Compose v2 Docker compose v3 | |
| Multi-host No Yes | |
| Start services docker compose up -d docker stack deploy --compose-file=docker-compose.yml | |
| Scale service docker compose scale = docker service scale = | |
| Shutdown docker compose down docker stack rm | |
| #===================================================================== | |
| # docker-compose.yml | |
| version: '3' | |
| services: | |
| web: | |
| build: . | |
| # build from Dockerfile | |
| context: ./Path | |
| dockerfile: Dockerfile | |
| ports: | |
| - "5000:5000" | |
| volumes: | |
| - .:/code | |
| redis: | |
| image: redis | |
| #===================================================================== | |
| # Builds, (re)creates, starts, and attaches to containers for a service. | |
| docker compose up | |
| # Stops containers and removes containers, networks, volumes, and images created by up. | |
| docker compose down | |
| #===================================================================== | |
| web: | |
| # build from Dockerfile | |
| build: . | |
| #===================================================================== | |
| # build from custom Dockerfile | |
| build: | |
| context: ./dir | |
| dockerfile: Dockerfile.dev | |
| #===================================================================== | |
| # build from image | |
| image: ubuntu | |
| #===================================================================== | |
| ports: | |
| - "3000" | |
| - "8000:80" # guest:host | |
| #===================================================================== | |
| # expose ports to linked services (not to host) | |
| expose: ["3000"] | |
| #===================================================================== | |
| # command to execute | |
| command: bundle exec thin -p 3000 | |
| command: [bundle, exec, thin, -p, 3000] | |
| #===================================================================== | |
| # override the entrypoint | |
| entrypoint: /app/start.sh | |
| entrypoint: [php, -d, vendor/bin/phpunit] | |
| #===================================================================== | |
| volumes: | |
| - /var/lib/mysql | |
| - ./_data:/var/lib/mysql | |
| version: '2' | |
| services: | |
| cms: | |
| image: <IMAGE>:<TAG> | |
| ports: | |
| - <LOCAL_PORT>:<CONTAINER_PORT> | |
| volumes: | |
| - <LOCAL_PATH>:<CONTAINER_PATH> | |
| #===================================================================== | |
| # join a pre-existing network | |
| networks: | |
| default: | |
| external: | |
| name: frontend | |
| #===================================================================== | |
| # creates a custom network called `frontend` | |
| networks: | |
| frontend: | |
| #===================================================================== | |
| # makes the `db` service available as the hostname `database` | |
| # (implies depends_on) | |
| links: | |
| - db:database | |
| - redis | |
| #===================================================================== | |
| # make sure `db` is alive before starting | |
| depends_on: | |
| - db | |
| #===================================================================== | |
| services: | |
| web: | |
| dns: 8.8.8.8 | |
| dns: | |
| - 8.8.8.8 | |
| - 8.8.4.4 | |
| #===================================================================== | |
| a Bash script to automate the creation of a superuser for NetBox using Docker Compose. It uses the provided username, email, and password, and bypasses the password validation prompt. | |
| #!/bin/bash | |
| # Variables | |
| USERNAME="admin" | |
| EMAIL="[email protected]" | |
| PASSWORD="Netbox2025!" | |
| # Run the createsuperuser command non-interactively | |
| sudo docker compose -f netbox-docker/docker-compose.yml exec netbox /opt/netbox/netbox/manage.py createsuperuser \ | |
| --username "$USERNAME" \ | |
| --email "$EMAIL" \ | |
| --no-input || true | |
| # Set password using Django shell | |
| sudo docker compose -f netbox-docker/docker-compose.yml exec netbox /opt/netbox/netbox/manage.py shell -c " | |
| from django.contrib.auth import get_user_model; | |
| User = get_user_model(); | |
| user = User.objects.get(username='$USERNAME'); | |
| user.set_password('$PASSWORD'); | |
| user.save(); | |
| print('✅ Superuser created successfully with provided password.') | |
| " | |
| echo "🎉 NetBox superuser created with username '$USERNAME' and email '$EMAIL'" | |
| #===================================================================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment