Basic Docker Compose Guide for Beginners (Debian/Ubuntu)
Introduction
Docker Compose is a tool for defining and running multi-container Docker applications using a simple YAML file. This beginner-friendly guide explains how to install Docker and Docker Compose on Debian/Ubuntu, create a basic docker-compose.yml file for a web application (Node.js) and database (PostgreSQL), run the application, and manage containers. It’s designed for users new to Docker who want to quickly set up a multi-container app.
What is Docker Compose?
Docker Compose simplifies managing multiple Docker containers by defining services, networks, and volumes in a single docker-compose.yml file. Key features include:
- Multi-Container Apps: Run web apps, databases, and other services together.
- Easy Configuration: Define containers in YAML with minimal commands.
- Use Cases: Development, testing, or simple production setups.
This guide sets up a Node.js web server and a PostgreSQL database as an example.
Prerequisites
- Debian/Ubuntu: Version 20.04+.
- Root Access: Use
sudofor installation and Docker commands. - Internet Access: Required for installing Docker and pulling images.
- Tools:
curlorwgetfor downloading installation scripts. - Basic Knowledge: Familiarity with terminal commands.
Verify system:
uname -a
Example output:
Linux ubuntu 5.15.0-73-generic #80-Ubuntu SMP Mon May 15 15:18:26 UTC 2023 x86_64 GNU/Linux
Critical Warning: Security and Data
How to Use Docker Compose
1. Install Docker and Docker Compose
Install Docker Engine and Docker Compose on Debian/Ubuntu.
2. Create a Project Directory
Create a directory for your Docker Compose project:
mkdir my-app
cd my-app
3. Create a Simple Node.js Application
Create a basic Node.js web server for the example.
Create a
backenddirectory:mkdir backend cd backendCreate
package.json:echo '{"name": "app", "version": "1.0.0", "main": "server.js", "dependencies": {"express": "^4.17.1"}}' > package.jsonCreate
server.js:echo -e 'const express = require("express");\nconst app = express();\napp.get("/", (req, res) => res.send("Hello from Docker Compose!"));\napp.listen(4000, () => console.log("Server running on port 4000"));' > server.jsCreate a
Dockerfile:echo -e 'FROM node:16\nWORKDIR /usr/src/app\nCOPY package.json ./\nRUN npm install\nCOPY . .\nEXPOSE 4000\nCMD ["node", "server.js"]' > DockerfileReturn to the project root:
cd ..
4. Create a docker-compose.yml File
Create a docker-compose.yml file for a Node.js app and PostgreSQL database:
nano docker-compose.yml
Content:
services:
app:
build:
context: ./backend
dockerfile: Dockerfile
container_name: app
ports:
- "4000:4000"
depends_on:
- db
networks:
- app-net
environment:
- DATABASE_URL=postgres://app:secret@db:5432/app_db
db:
image: postgres:16
container_name: db
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: app_db
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-net
networks:
app-net:
driver: bridge
volumes:
db-data:
5. Run the Application
Start the containers:
docker compose up -d
Verify containers are running:
docker compose ps
Example output:
NAME SERVICE STATUS PORTS
app app running 0.0.0.0:4000->4000/tcp
db db running
Test the web app:
curl http://localhost:4000
Example output:
Hello from Docker Compose!
6. Stop and Remove Containers
Stop and remove containers:
docker compose down
Remove volumes (optional):
docker compose down -v
Examples
Example 1: Install Docker and Docker Compose
Install Docker Engine and verify Docker:
docker compose version
Output:
Docker Compose version v2.40.0
Example 2: Create and Run a Docker Compose App
Set up and run the sample app:
mkdir my-app
cd my-app
# Create backend files as shown in Step 3
nano docker-compose.yml # Add the YAML from Step 4
docker compose up -d
curl http://localhost:4000
Output:
Hello from Docker Compose!
Example 3: Check Container Status
Verify running containers:
docker compose ps
Output:
NAME SERVICE STATUS PORTS
app app running 0.0.0.0:4000->4000/tcp
db db running
Example 4: Stop and Clean Up
Stop and remove containers:
docker compose down
Output:
[+] Running 3/3
✔ Container app Removed
✔ Container db Removed
✔ Network app-net Removed
Variants
Using a Different Web Framework
Replace the Node.js app with a Python Flask app:
Create
backend/app.py:from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello from Flask!' if __name__ == '__main__': app.run(host='0.0.0.0', port=4000)Create
backend/requirements.txt:flask==2.0.1Update
backend/Dockerfile:FROM python:3.9 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 4000 CMD ["python", "app.py"]Update
docker-compose.ymlto use the newDockerfile.
Adding a .env File
Create .env for environment variables:
POSTGRES_USER=app
POSTGRES_PASSWORD=secret
POSTGRES_DB=app_db
Update docker-compose.yml:
services:
db:
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
Command Breakdown
- apt install docker-ce docker-compose-plugin: Installs Docker and Compose.
- docker compose up -d: Starts containers in detached mode.
- docker compose ps: Lists running containers.
- docker compose down: Stops and removes containers.
- docker compose build: Builds images from Dockerfiles.
- curl http://localhost:4000: Tests the web app.
Use Cases
- Development: Run local web apps with databases.
- Learning: Experiment with multi-container setups.
- Testing: Test app-database interactions in isolated containers.
Pro Tips
- Run Without sudo: Add your user to the
dockergroup to avoidsudo. - Use Detached Mode: Use
-dwithdocker compose upfor background running. - Check Logs: Use
docker compose logsto debug issues. - Keep Images Updated: Pull latest images with
docker compose pull. - Clean Up: Use
docker compose down -vto remove volumes and avoid clutter.
Troubleshooting
- Docker Command Permission Denied: Add user to
dockergroup or usesudo:sudo usermod -aG docker $USER - Port Already in Use: Check for conflicts with
netstat -tuln | grep 4000and change ports indocker-compose.yml. - Container Exits Immediately: Check logs with
docker compose logs app. - Image Pull Fails: Verify internet access and repository in
docker-compose.yml. - Database Connection Issues: Ensure
DATABASE_URLmatchesPOSTGRES_USER,POSTGRES_PASSWORD, andPOSTGRES_DB.
Resources
Get started with Docker Compose on Debian/Ubuntu to run multi-container apps effortlessly!