0
0
DockerHow-ToBeginner · 4 min read

Docker Compose for Full Stack Application: Setup and Example

Use docker-compose.yml to define all parts of your full stack app like frontend, backend, and database as services. Run docker-compose up to start them together with one command.
📐

Syntax

A docker-compose.yml file defines multiple services for your app. Each service has a name and specifies the Docker image, ports, volumes, and environment variables it needs.

Key parts:

  • version: Compose file format version.
  • services: List of app parts like frontend, backend, database.
  • image/build: Docker image or build context for each service.
  • ports: Map container ports to host ports.
  • volumes: Share files between host and container.
  • environment: Set environment variables inside containers.
yaml
version: '3.8'
services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
  backend:
    build: ./backend
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=mydb
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data: {}
💻

Example

This example shows a full stack app with three services: a React frontend, a Node.js backend, and a PostgreSQL database. The frontend runs on port 3000, backend on 5000, and the database stores data persistently.

yaml
version: '3.8'
services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - backend
  backend:
    build: ./backend
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
    depends_on:
      - db
  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=mydb
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data: {}
Output
Creating network "project_default" with the default driver Creating volume "project_db-data" with default driver Creating project_db_1 ... done Creating project_backend_1 ... done Creating project_frontend_1 ... done
⚠️

Common Pitfalls

Common mistakes include:

  • Not specifying depends_on to control startup order, causing services to fail if dependencies are not ready.
  • Forgetting to map ports, so services are not accessible from outside.
  • Missing environment variables needed for database connections.
  • Not using volumes for databases, losing data on container restart.
yaml
version: '3.8'
services:
  backend:
    build: ./backend
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=mydb

# Missing depends_on and volumes

--- Corrected version ---

version: '3.8'
services:
  backend:
    build: ./backend
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
    depends_on:
      - db
  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=mydb
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data: {}
📊

Quick Reference

Tips for Docker Compose full stack apps:

  • Use depends_on to ensure services start in the right order.
  • Map ports to access services from your machine.
  • Use volumes for databases to keep data safe.
  • Set environment variables for configuration like database URLs.
  • Run docker-compose up --build to rebuild images if code changes.

Key Takeaways

Define all parts of your full stack app as services in a single docker-compose.yml file.
Use depends_on to control service startup order and avoid connection errors.
Map ports and use volumes to make services accessible and data persistent.
Set environment variables for service configuration like database connections.
Run docker-compose up --build to start and rebuild your full stack app easily.