Hey there! Congrats to making it to day 11. Today we will learn about Docker Compose. Over the last few days, weβve learned about environment variables, networking, and volumes. Letβs look at a typical command we might use to run a container with all these features:
docker run -d \
--name api \
--network myapp-network \
-v mydata:/data \
-e SECRET_MESSAGE="Hello Docker!" \
-e PORT=8080 \
-p 8080:8080 \
hello-world-go
Thatβs quite a lot to remember and type! Now imagine running multiple containers, each with their own configuration. This is where Docker Compose comes in.
What is Docker Compose?
Docker Compose is a tool that helps you define and run multi-container applications. Instead of long docker commands, you write a YAML file that describes your entire application stack.
Letβs convert our previous setup to a Docker Compose file. Create a new file called docker-compose.yml
:
services:
api:
build: .
ports:
- "8080:8080"
environment:
- SECRET_MESSAGE=Hello Docker!
- PORT=8080
volumes:
- mydata:/data
networks:
- myapp-network
volumes:
mydata:
networks:
myapp-network:
Now instead of that long docker command, you can simply run:
docker compose up
Docker Compose will:
- Create the network
- Create the volume
- Build the image (if needed)
- Start the container with all specified configuration
To stop everything:
docker compose down
Letβs add some more complexity to our application. We will add a database and a reverse proxy.
services:
api:
build: .
ports:
- "8080:8080"
environment:
- SECRET_MESSAGE=Hello Docker!
- PORT=8080
volumes:
- mydata:/data
networks:
- myapp-network
depends_on:
- db
db:
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- myapp-network
nginx:
image: nginx
ports:
- "80:80"
networks:
- myapp-network
depends_on:
- api
volumes:
mydata:
postgres_data:
networks:
myapp-network:
What we did here is:
- Added a database service
- Added a reverse proxy service
- Added a dependency to the api service (so it starts after the database)
- Added a dependency to the nginx service (so it starts after the api)
For simplicity sake we hardcoded our secrets here. In a production environment you would of course not want to do that! How you can properly manage secrets is a topic for another day (probably tomorrow).
Basic Docker Compose Commands
Here are the most important commands youβll use:
docker compose up
- Start servicesdocker compose up -d
- Start in detached modedocker compose down
- Stop and remove containersdocker compose ps
- List running servicesdocker compose logs
- View service logsdocker compose build
- Build or rebuild services
Next Steps
This is just the beginning of what Docker Compose can do! Tomorrow we will go a bit deeper and learn about some advanced features.
As always, just by looking at the code you wonβt learn anything. So try converting your existing Docker commands to a compose file. Play around with it and see how it works, and how to break it. If you have any questions, feel free to reach out by email.
Happy coding! π³π
Jonas