Feedback

Chat Icon

Painless Docker - 2nd Edition

A Comprehensive Guide to Mastering Docker and its Ecosystem

Docker Compose: A Mini Orchestration Tool for Local Development
58%

Scaling Docker Compose Services

Docker Compose is a mini orchestration tool that provides a way to orchestrate multi-container applications. An interesting feature it offers is the ability to scale services. Let's take an example: imagine you're running an application that uses PHP and you've anticipated higher traffic. Instead of running a single PHP container, you want to run 5 of them behind an NGINX web server. Docker Compose lets you do this with a simple command: docker compose alpha scale php=5. By executing this, you'd have a total of 5 PHP containers up and running. And because NGINX is linked to this PHP service, it can load-balance between these PHP instances.

However, a challenge arises when you consider scaling services like NGINX in this setup. If you recall, the NGINX service maps its internal port 80 to the host's port 8000. This is a 1-to-1 mapping. So if you tried to scale NGINX, the newly spawned container would also attempt to bind to the host's port 8000, resulting in a conflict. This is because a host port can only be bound to by one service at a time. As a result, in Docker Compose, scaling a service that uses port mapping directly to the host can introduce issues.

Now, keeping this in mind, let's discuss the following Docker Compose setup:

services:
   db:
     image: mysql:9.6.0
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: mypassword
       MYSQL_DATABASE: wordpress
       MYSQL_USER: user
       MYSQL_PASSWORD: mypassword

   wordpress:
     depends_on:
       - db
     image: wordpress:6.9.0-apache
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: user
       WORDPRESS_DB_PASSWORD: mypassword

volumes:
    db_data:

In this setup, we're running a WordPress service that depends on a MySQL database. If you wanted to scale the WordPress service, you'd face the same challenge as discussed earlier with NGINX. The WordPress service is mapping its internal port 80 to the host's port 8000.

The solution to this problem is as simple as using a range of ports on the host instead of a single port. Instead of "8000:80", we can use "8000-8002:80". This way, when we scale the WordPress service to 3 instances, Docker Compose will map:

  • The first instance to port 8000.
  • The second instance to port 8001.
  • The third instance to port 8002.

To explore this further, create a new folder and a new docker-compose.yml file with the updated port mapping:

mkdir -p $HOME/wordpress-scaled && cd $HOME/wordpress-scaled

cat << EOF > $HOME/wordpress-scaled/docker-compose.yml
services:
  db:
    image: mysql:9.6.0
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: mypassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: user
      MYSQL_PASSWORD: mypassword
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
  wordpress:
    image: wordpress:6.9.0-apache
    ports:
      # Use a range of ports on the host to map to port 80 in the container
      - "8000-8002:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST

Painless Docker - 2nd Edition

A Comprehensive Guide to Mastering Docker and its Ecosystem

Enroll now to unlock all content and receive all future updates for free.

Unlock now  $31.99$25.59

Hurry! This limited time offer ends in:

To redeem this offer, copy the coupon code below and apply it at checkout:

Learn More