I spend way too much time typing long docker commands. Every time I need to rebuild a container, I end up scrolling through my bash history trying to find that one command with the right flags. Last week I got tired of it and decided to move all my docker workflow into a Makefile, and honestly I wish I had done it sooner.
Here is how I set it up.
The Makefile
.PHONY: up down build rebuild logs shell clean
# Container and image names
CONTAINER := my-app
IMAGE := my-app-image
# Docker compose file (if you use it)
COMPOSE := docker-compose.yml
up:
docker compose -f $(COMPOSE) up -d
down:
docker compose -f $(COMPOSE) down
build:
docker build -t $(IMAGE) .
rebuild: down build up
logs:
docker compose -f $(COMPOSE) logs -f $(CONTAINER)
shell:
docker exec -it $(CONTAINER) /bin/bash
clean:
docker compose -f $(COMPOSE) down -v --rmi allThat's it. No 200-line makefiles with conditionals and includes. Just the stuff I actually use.
Why this works for me
I used to have aliases in my .bashrc for all of this, the problem is that every project had different container names and different compose files, so the aliases kept clashing with each other. With a Makefile per project, each one is self-contained.
The rebuild target is the one I use the most, it stops everything, rebuilds the image and starts it back up. One command instead of three.
A couple of things I learned
If you have multiple services in your compose file, you can pass the service name as a variable:
SERVICE ?= web
shell:
docker exec -it $(CONTAINER)_$(SERVICE) /bin/bash
logs:
docker compose -f $(COMPOSE) logs -f $(SERVICE)Now make shell SERVICE=redis drops you into the redis container instead of the web one. The ?= means it defaults to web if you don't specify anything.
I also added a backup target for the database:
backup:
docker exec $(CONTAINER)_db pg_dump -U postgres mydb > backup_$$(date +%Y%m%d).sqlThe double $$ is important, make uses a single $ for its own variables so you need two for shell commands.
Conclusion
This is not rocket science, it's just a Makefile that saves me from typing the same docker commands over and over. If you're managing containers on your own hardware ( like I do ) this is probably the simplest improvement you can make to your workflow.
The full Makefile is here.