Fading Coder

One Final Commit for the Last Sprint

Home > Tools > Content

Orchestrating Multi-Container Applications with Docker Compose

Tools May 13 1

Docker Compose Overview

Problem Statement

When working with Docker, complex applications typically require multiple services running simultaneously. A typical Django project might need MySQL, Redis, and other dependencies. Maanging these as separate containers individual becomes cumbersome and error-prone. Docker Compose solves this problem by providing a tool to define and manage multiple containers as a single application.

Key Capabilities

Docker Compose is a tool for defining and running multi-container Docker applications. It uses YAML files to configure application services and allows you to start and stop all services with a single command.

Container Orchestration Options:

Type Tool
Single-host orchestration Docker Compose
Multi-host orchestration Docker Swarm, Kubernetes

Installation

Download the Docker Compose binary from the official GitHub repository:

wget https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64
sudo cp ./docker-compose-linux-x86_64 /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Add the binary to your system PATH by placing it in /usr/local/bin, enabling execution from any directory.

Permission Model

Owner  Group  Others
 rwx   rwx    rwx

Example permission commands:

chmod 777 filename    # Full permissions for all
chmod +x filename     # Add execute permission
chmod 555 filename    # Read and execute for all

Essential Commands

Command Description
docker-compose up Start services (searches for compose file in current directory)
docker-compose -f <file> up Start services using specified file
docker-compose up -d Run in detached mode (background)
docker-compose up -d --build Rebuild images and start containers
docker-compose stop Stop containers without removal
docker-compose down Stop and remove containers
docker-compose start Start managed containers
docker-compose ps List running containers
docker-compose images List managed images
docker-compose exec <service> /bin/bash Shell into a service container

Docker Installation (CentOS)

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Deploying a Flask Application

Project Structure

A Flask application with Redis requires two containers: the Flask application and the Redis cache.

Application Code (app.py)

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis_client = Redis(host='redis', port=6379)

@app.route('/')
def index():
    redis_client.incr('visits')
    return f'Page visited {redis_client.get("visits").decode()} times\n'

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

Service names in the compose file become hostname aliases. The Flask container can reach Redis using the hostname redis.

Dockerfile

FROM python:3.10
WORKDIR /app
COPY . /app
RUN pip install flask redis -i https://pypi.tuna.tsinghua.edu.cn/simple
EXPOSE 5000
CMD [ "python", "app.py" ]

Docker Compose Configuration

version: "3"
services:
  redis:
    image: redis
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8080:5000
    environment:
      REDIS_HOST: redis

Deployment

docker-compose up

This single command performs the following:

  1. Builds the Flask image from Dockerfile
  2. Pulls the Redis image if not present
  3. Starts both containers on a shared network

Containers can communicate using service names as hostnames. Verify connectivity:

# Enter web container
docker-compose exec web /bin/bash
# Inside container
apt-get update && apt-get install -y inetutils-ping
ping redis

Deploying a Full-Stack Application

Architecture

A complete deployment typically includes:

  • Django API: Python 3.8 runtime with uWSGI
  • Nginx: Web server and reverse proxy
  • MySQL: Database server
  • Redis: Caching layer

Each component runs in its own container.

Project Layout

project/
├── docker-compose.yml
├── docker_config/
│   ├── nginx/
│   ├── redis/
│   └── mysql.env
├── api_service/
│   ├── Dockerfile
│   └── uwsgi.ini
└── frontend/
    └── dist/

API Service Dockerfile

FROM python:3.8
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt -i https://pypi.doubanio.com/simple
CMD ["uwsgi", "./uwsgi.ini"]

Complete Docker Compose Configuration

version: "3"

services:
  nginx:
    image: nginx
    container_name: app_nginx
    ports:
      - "80:80"
      - "8000:8000"
    restart: always
    volumes:
      - ./frontend/dist:/var/www/html
      - ./docker_config/nginx:/etc/nginx/conf.d
    depends_on:
      - django
    networks:
      - frontend_net

  django:
    build:
      context: ./api_service
      dockerfile: Dockerfile
    container_name: app_django
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./api_service:/app
    environment:
      - TZ=Asia/Shanghai
    depends_on:
      - mysql
      - redis
    networks:
      - frontend_net
      - backend_net

  redis:
    image: redis:6.0-alpine
    container_name: app_cache
    ports:
      - "6379:6379"
    volumes:
      - ./docker_config/redis/data:/data
      - ./docker_config/redis/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf
    networks:
      - backend_net

  mysql:
    image: mysql:5.7
    container_name: app_database
    restart: always
    ports:
      - "3306:3306"
    env_file:
      - ./docker_config/mysql.env
    volumes:
      - ./docker_config/mysql/data:/var/lib/mysql
      - ./docker_config/mysql/logs:/var/log/mysql
      - ./docker_config/mysql/conf:/etc/mysql/conf.d
    networks:
      - backend_net

networks:
  frontend_net:
  backend_net:

Deployment Steps

  1. Prepare the frontend build:
cd frontend
npm install
npm run build
  1. Clone and configure on the target server:
git clone <repository>
cd project
docker-compose up -d
  1. Access the application at http://<server-ip>:80

Related Articles

Installing CocoaPods on macOS Catalina (10.15) Using a User-Managed Ruby

System Ruby on macOS 10.15 frequently fails to build native gems required by CocoaPods (for example, ffi), leading to errors like: ERROR: Failed to build gem native extension checking for ffi.h... no...

Resolve PhpStorm "Interpreter is not specified or invalid" on WAMP (Windows)

Symptom PhpStorm displays: "Interpreter is not specified or invalid. Press ‘Fix’ to edit your project configuration." This occurs when the IDE cannot locate a valid PHP CLI executable or when the debu...

Capturing Android Screenshots and Screen Recordings with ADB

Two practical ways to grab images and videos from an Android device: Mirror the phone display to a computer and use desktop tools for screenshots and GIFs Use ADB commands (no UI mirroring required)...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.