SSD Nodes Learn 8GB RAM — $66/yr
How to do am Matt ConnorBy Matt Connor · Updated 2026-08-02

Docker Compose commands wey you need for server

See the Docker Compose V2 commands you go use daily for servers, from up and down to logs, shells, networks, volumes, updates, and safe cleanup.

Compose commands wey you go really use

Docker Compose releases more than forty subcommands. Daily work for server dey use about twelve. This page groups dem according to the work wey you dey do, gives one clear reason for each one, and points you to the detailed explanation when command get hidden problem.

Everything here dey use Compose V2: docker compose with a space, no be the old docker-compose script. V2 na Go plugin wey dey install together with Docker Engine, and V1 no dey available for current packages again. So, if you run docker-compose: command not found for fresh Ubuntu box as of July 2026, na expected result, no be error. Check am with docker compose version. If e print nothing, install docker-compose-plugin package.

Every command below must run from the directory wey hold your compose.yaml, because Compose dey take the project name from that directory and dey find the file relative to am. If you run the same command one level up, Compose go stop with no configuration file provided: not found. If the file format still new to you, start with your first Compose file for VPS and come back here for the commands.

Lifecycle: the four wey you dey type, and the one wey dey remove containers

docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose down

up -d dey create the network, create the containers, start dem, then e return. E dey return immediately the containers don create, na why deploy script wey run curl probe after am dey often fail for the first try. up -d --wait dey wait until every service wey declare healthcheck report say e healthy, and e dey exit with non-zero if any one no ever reach that state. The flag only fit work as well as the check behind am, so write healthcheck wey Compose fit trust before you depend on am for automation.

stop dey stop the containers and keep dem, so start dey bring back the same containers with the same writable layer. down dey stop dem, then remove the containers and the project network. Anything wey dem write inside the container and outside a volume go disappear with dem. Na the most costly misunderstanding for Compose be this, and the complete difference between down and stop explain where e dey cause problem.

restart no be reload. E dey stop and start the same container with the configuration wey e already get, so changed environment variable, new image tag or edited port mapping no go get any effect. To apply file change, run up -d again. Compose dey compare each service with the container wey dey run, and e dey recreate only the ones wey configuration don change.

Apply change: recreate, pull, or rebuild

docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build web

up -d no dey do anything by itself when nothing change, and na wetin make am safe to run many times. --force-recreate dey override that comparison and replace every container even when the configuration dey identical, so na the fastest way to clear strange state inside container.

To update image, you need two commands because dem dey do different things. pull downloads the latest image for each tag wey dem name for the file. up -d then sees say the service image ID no longer match the container wey dey run and recreates am. If you skip the pull, up -d go keep last month's latest running without error.

build dey apply to services wey declare a build: section instead of a image:. up -d --build builds and starts for one step, and na the normal loop when you dey change code. Use --no-cache only when e clear say a cached layer don stale, because e rebuilds every layer from scratch.

Wetin dey run

docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose ls

ps dey list only containers wey dey run. Service wey crash during startup no go show there until you add -a. So, if container no dey ps but ps -a show am as Exited (1), na the normal sign say startup fail. Read the exit code, then read the logs.

logs -f dey follow every service at once and put service name for front of each line. Na this view you need when services dey communicate with each other and event order matter. Put service name to narrow am. --tail=100 matter for container wey don dey up for one month, because the default go print the complete history and fill the terminal. --since 15m answer the question wey you usually get: wetin happen during the restart wey you just do.

top dey list the processes inside each container. This one separate “the container dey run” from “the process inside am dey run”. ls comot from the current directory and list every Compose project for the host with the status, so you fit find the stack wey you start three months ago.

Service inside shell open

docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web sh

exec dey run command inside container wey don dey up. run dey start new container from the same service definition. Na dis one you need when service no dey stay up long enough make you exec inside am. Always pair run with --rm, because if you no do am, every invocation go leave stopped container behind. Dem go pile up until docker compose ps -a no fit read again.

Try sh before bash. Alpine based images no get bash, and the error message go show exec: "bash": executable file not found in $PATH. If you add --no-deps to run, e go skip the service dependencies. Dis one stops quick config check from booting your whole database.

run --rm web env na the fastest way to see the environment wey service really get, after every .env file, environment: block and shell variable don merge. When value no correct, na usually the merge order cause am. how Compose dey resolve env files and secrets explain which source dey win.

Networks, ports, and name resolution

docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networks

Compose dey put every service for one project network, and each service name na DNS name for there. When you run getent hosts db inside web, e go print the container IP if name resolution work, and e no go print anything if e no work. So, e answer “these containers fit see each other?” within two seconds. If the name resolve but the connection dey refused, the process inside db bind to 127.0.0.1 instead of 0.0.0.0. Because of that, e no fit accept packet from another container. You fit read the rest of this model for how Compose networks and service DNS dey work.

port web 80 dey print the host address and port wey container port publish on. This one save you from guessing when variable provide the mapping. Publishing a port also dey write firewall rule wey Docker manage by itself. That rule dey before your own rule, so service wey you think say private fit dey open to the internet. why published Docker ports dey bypass ufw cover this case.

Volumes and data

docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -v

config --volumes go print the named volumes wey the project declare, one for each line. Na dat list you need to back up. cp fit copy file enter or commot from container without opening shell, using the service:path form for the side wey container dey.

down -v go remove those named volumes together with the containers. Na the correct command to tear down test stack, but e wrong for anything wey get data you care about, because e no dey ask for confirmation and you no fit undo am. Bind mounts go survive am, because dem dey for the host filesystem. This difference for blast radius na one reason to choose carefully between bind mounts and named volumes.

Cleanup wey go free disk space without losing data

docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune

--remove-orphans dey delete containers wey belong to the project but dem no dey show again for the file. Na exactly wetin dey happen after you rename a service. If you no use am, those containers go continue to run, but docker compose ps no go show dem.

docker system df dey show where the disk space go before you delete anything. E dey separate images, containers, local volumes, and build cache, plus the reclaimable amount for each one. image prune -a dey remove every image wey no tag dey point to. For server wey don pull several versions of a large image, na usually this one dey free the most space. builder prune dey clear the build cache. This cache dey grow quietly for any server wey dey build its own images.

None of these commands dey touch a named volume. Na only docker volume prune and docker compose down -v dey do that.

File check kor am e go cause wahala

docker compose config --quiet
docker compose config --services
docker compose --dry-run up -d

config --quiet dey validate and e no print anything if e succeed, so put am for pre-deploy step or git hook. Plain config dey print the file wey don fully merge and interpolate, and na so you fit confirm say variable resolve and override file layer the way you expect. If variable no set, e go show as empty value beside the warning The "X" variable is not set. Defaulting to a blank string.

--dry-run na global flag, e no be subcommand flag, so e go come before up. E dey print every action wey Compose for take and e no change anything, so the thirty seconds wey you spend before down for important stack na time well spent.

Work across files, profiles, and projects

docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -d

Multiple -f flags dey merge in order, and files wey come later dey override earlier files key by key. Na the standard way to keep one base file with small production override, but the rules dey different for lists and maps. So read how Compose dey merge multiple files before you debug unexpected result.

--profile dey start services wey get that profile together with the ones wey no get profile. This keeps debug tools comot from normal up. -p dey set the project name, so two copies of one stack fit run side by side with separate networks and separate volume names. To make the stack come back after reboot no be command wey you type by hand. Na unit wey dey run am for you, as described for how to start Compose stacks on boot.

FAQ

Wetin replace docker-compose wey get hyphen?

Compose V2, wey you call as docker compose with space. E be plugin wey Docker Engine bundle, and current packages no longer install the V1 Python tool. If the space form no print anything, install the docker-compose-plugin package for your distribution. Update old scripts to use the space form instead of adding alias, because V2 get flags wey V1 no get.

Why docker compose restart no dey see my config change?

restart dey stop and start the existing container with the configuration wey dem use create am, and e no ever read compose.yaml again. Any change to environment variables, ports, volumes or image tag need docker compose up -d. E dey compare each service with the container wey dey run and recreate the ones wey differ. Add --force-recreate when you want make e replace am even when nothing for the file change.

How I fit update service to newer image?

Run docker compose pull, then docker compose up -d. The pull dey fetch the current image for each tag wey dey the file, and up -d dey recreate any service wey image ID no longer match the container own. If you run up -d alone, e go reuse the image wey already dey disk. Na why stack wey pin to latest fit remain on build wey don old for months without printing error.

Which cleanup commands safe for live server?

docker system df, docker image prune -a and docker builder prune dey remove images and cache only, so services wey dey run go continue to work and named volumes no go change. The dangerous pair na docker compose down -v and docker volume prune, wey dey delete named volumes without prompt. Run docker compose config --volumes first so you go know wetin dey at risk.

I fit run one command without starting the whole stack?

Yes. docker compose run --rm --no-deps web sh dey start one container from the web service definition, skip its dependencies, and remove the container when you exit. Use exec instead when the container don dey run, because exec dey join the live process and show you the state wey the service really dey.