Back to course

Lesson 18: Anatomy of a docker-compose.yml File

Docker Zero to Hero: The Complete Containerization Course for Beginners

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 web service uses build: . to find its Dockerfile locally.
  • The db service uses the image: key to pull from Docker Hub.
  • The services reference each other by their name (db is the hostname for the database connection from the web service).
  • The postgres_data volume is defined globally and then mounted in the db service.