Skip to content

Instantly share code, notes, and snippets.

@KEINOS
Last active June 23, 2024 04:34
Show Gist options
  • Save KEINOS/c8d91d9436fa5603c031724aae1c1fbe to your computer and use it in GitHub Desktop.
Save KEINOS/c8d91d9436fa5603c031724aae1c1fbe to your computer and use it in GitHub Desktop.
Simple docker-compose.yml example to scale up containers

Scaling Up Docker Containers and Load Balancing

Simple example to scaling up Docker containers (spawning multiple containers) and load balancing them using Nginx and Traefik.

Scaling up

To scale myapp service up to 3 containers, use --scale.

docker compose up --scale myapp=3 --detach

To provide this service as one (expose as one port), you need a load balancer such as Nginx or Traefik.

Note: the myapp service is a container that simply returns its current host name.

https://github.com/KEINOS/imhost @ GitHub

Nginx as load balancer

docker compose --file docker-compose-nginx.yml up --scale myapp=3 --detach

Nginx will listen to 8080 port and transfers the request to one of myapp's 80 port by load balancing using round-robin.

$ curl -sS http://localhost:8080
Hello from host: 7daed9e183ee

$ curl -sS http://localhost:8080
Hello from host: e2bcc4860c92

Traefik as load balancer

docker compose --file docker-compose-traefik.yml up --scale myapp=3 --detach

Traefik will listen to 8080 port and transfers the request to one of myapp's 80 port by load balancing using round-robin.

$ curl -sS http://localhost:8080
Hello from host: 7daed9e183ee

$ curl -sS http://localhost:8080
Hello from host: e2bcc4860c92

Benchmarking

Note: Increasing the number of containers serving a service, does not always lead to an increase in performance.

This is because performance depends not only on CPU speed, but also on a number of other factors, such as the number of threads (cores) that can be processed, RAM capacity, etc.

If the hardware cannot be changed, it is advisable to first measure the maximum access volume by benchmarking in order to understand the limits.

$ ab -V
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

$ docker compose up --scale myapp=3 --detach
**snip**

$ curl -sS http://localhost:8080/
Hello from host: e2bcc4860c92


$ # Expect 100 users (-c=100) requesting 1 request at the same time (-n=100=100x1)
$ ab -n 100 -c 100 http://localhost:8080/
**snip**
Failed requests:        0
**snip**
Requests per second:    1608.18 [#/sec] (mean)
**snip**

$ # Expect 100 users (-c=100) requesting 10 request at the same time (-n=1000=100x10)
$ ab -n 1000 -c 100 http://localhost:8080/
**snip**
Failed requests:        0
**snip**
Requests per second:    1064.04 [#/sec] (mean)
**snip**
services:
myapp:
build:
context: https://github.com/KEINOS/imhost.git
expose:
- "80"
restart: unless-stopped
nginx:
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "service", "nginx", "status"]
start_period: 15s
interval: 5m
timeout: 15s
retries: 3
restart: unless-stopped
services:
myapp:
build:
context: https://github.com/KEINOS/imhost.git
expose:
- "80"
restart: unless-stopped
labels:
# Settings for Traefik (172.111.111.111 is the global IP of the host)
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`localhost`, `127.0.0.1`, `172.111.111.111`, `your.example.com`)"
- "traefik.http.routers.myapp.entrypoints=web"
traefik:
image: traefik:latest
command:
- "--log.level=DEBUG"
- "--api.insecure=false"
- "--api.dashboard=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "8080:80"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
restart: unless-stopped
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location / {
proxy_pass http://myapp:80;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment