Purpose of this page
Know the handful of commands needed to build, run, debug, and tidy up containers — and which ones you'll actually type while working on this project.
Building an image docker build
Turns a Dockerfile plus a build context into an image stored locally.
docker build --tag metals-api:local --file metals_api/Dockerfile .
- --tag (or -t) names the result, as repository:tag. Without it you get an untagged image identified only by a hash.
- --file (or -f) points at the Dockerfile. Omit it and Docker looks for Dockerfile in the context directory.
- The trailing . is the build context — easy to forget, and the cause of the classic "docker build" requires exactly 1 argument error.
--no-cache forces every layer to rebuild, which is how you prove a caching problem rather than guess at one. --progress=plain prints full build output instead of the collapsing summary view — invaluable when a RUN step fails and you need to see why.
Running a container docker run
Creates and starts a container from an image. Nearly every flag exists to connect the container to something outside itself — a port, a variable, a folder.
| Flag | What it does |
|---|---|
-d | Detached — run in the background and return the prompt instead of streaming output. |
-p 8080:8080 | Publishes a port: host:container. The left number is what you type in a browser; the right is what the app listens on inside. |
-e KEY=value | Sets an environment variable, overriding any ENV default baked into the image. |
--name metals-ui-test | Gives the container a memorable name, so later commands don't need the generated hash. |
--rm | Deletes the container automatically when it stops — ideal for one-off test runs. |
-v pgdata:/var/lib/postgresql/data | Mounts a volume, so data written to that path survives the container being removed. |
Seeing what's happening debugging
When something doesn't work, these four answer “is it running?”, “what did it say?”, and “what does it look like in there?”
| Command | What it tells you |
|---|---|
docker ps | Containers currently running, with their ports and health status. Add -a to include stopped ones — essential when a container exited immediately and has vanished from the default list. |
docker logs -f <name> | Everything the container wrote to standard output. -f follows live. This is the first place to look for a crash on startup. |
docker exec -it <name> sh | Opens a shell inside a running container, to check that files landed where you expect or that a config rendered correctly. |
docker images | Images stored locally, with their tags and sizes — useful for confirming a build actually produced what you meant. |
Cleaning up reclaiming disk
Docker never deletes anything on its own. Old images, stopped containers, and orphaned build cache accumulate quietly until a disk fills up.
| Command | What it removes |
|---|---|
docker stop <name> | Stops a running container, leaving it around to inspect or restart. |
docker rm <name> | Deletes a stopped container. Add -f to stop and delete in one step. |
docker rmi <image> | Deletes an image, provided no container still references it. |
docker system prune | Bulk cleanup: stopped containers, unused networks, dangling images, and build cache. |
The Compose equivalents several containers at once
docker compose reads docker-compose.yml and applies the same operations across every service defined in it, so you don't hand-manage three containers and a network. Run these from the folder containing the compose file.
| Command | What it does |
|---|---|
docker compose up -d | Creates the network, then builds anything missing and starts every service in the background. |
docker compose up -d --build | Same, but rebuilds images first — the one to use after editing application code or a Dockerfile. |
docker compose ps | Status and health of just this project's services. |
docker compose logs -f api | Follows one service's logs; drop the name to interleave all of them. |
docker compose down | Stops and removes the containers and network, keeping named volumes. |
docker compose down -v | The same, plus deletes the volumes — the full database reset covered in the database tutorial. |
The commands for this project copy these
Everything above, applied to this repository. All commands run from the project root.
| # | Goal | Command |
|---|---|---|
| 1 | Start the whole stack (db + API + UI) | docker compose up -d --build |
| 2 | Check everything came up healthy | docker compose ps |
| 3 | Watch the API's logs | docker compose logs -f api |
| 4 | Build just the API image by hand | docker build -t metals-api:local -f metals_api/Dockerfile . |
| 5 | Build just the UI image by hand | docker build -t metals-ui:local metals_ui |
| 6 | Stop everything, keep the data | docker compose down |
| 7 | Stop everything and wipe the database | docker compose down -v |