Lesson 18: Anatomy of a docker-compose.yml File
Let's create a functional compose.yml file for a simple application consisting of a web service (using a custom Dockerfile) and a PostgreSQL database.
Project Setup
Create a directory structure:
my-app-stack/ ├── Dockerfile (For the web app) ├── server.py (Your application code) └── docker-compose.yml
The docker-compose.yml Content
yaml version: '3.8'
services: web: # 1. Build the image using the local Dockerfile build: . # 2. Map host port 80 to container port 5000 ports: - "80:5000" # 3. Define environment variables for the web app environment: DB_HOST: db DB_PORT: 5432 # 4. Mount the current directory for development speed volumes: - .:/code
db: # 1. Pull the official Postgres image image: postgres:15-alpine # 2. Define environment variables required by Postgres environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: mydb # 3. Use a named volume for persistent data volumes: - postgres_data:/var/lib/postgresql/data # 4. Restart Policy: always try to restart if it fails restart: always
volumes: postgres_data: # Define the persistent volume
By default, compose creates a network called 'my-app-stack_default'
and all services are connected to it.
Key Learnings:
- The
webservice usesbuild: .to find its Dockerfile locally. - The
dbservice uses theimage:key to pull from Docker Hub. - The services reference each other by their name (
dbis the hostname for the database connection from thewebservice). - The
postgres_datavolume is defined globally and then mounted in thedbservice.