Left 4 Dead 2 Auto Scaler
10K+
Left 4 Dead 2 Auto Scaler.
L4D2AS is a small Docker autoscaler for Left 4 Dead 2 dedicated servers. It watches a template server container, checks active player counts with A2S, and creates or removes extra server containers as needed.
The goal is simple: keep one empty spare server online, and remove extra empty servers after a grace period.
docker run.L4D2AS reads a template service from a Docker Compose file.
For example, a template container named l4d2c00 can generate:
l4d2c01
l4d2c02
l4d2c03
If the template has hostname RS CASUAL 00, generated containers get:
RS CASUAL 01
RS CASUAL 02
RS CASUAL 03
If the template exposes 192.168.8.220:51000:51000/udp, generated containers get:
192.168.8.220:51001:51001/udp
192.168.8.220:51002:51002/udp
192.168.8.220:51003:51003/udp
If the template uses static IP 172.20.1.100, generated containers get:
172.20.1.101
172.20.1.102
172.20.1.103
L4D2AS needs access to the Docker daemon.
The autoscaler container must be able to run Docker commands and inspect/create/remove containers.
Usually this means mounting the Docker socket:
- /var/run/docker.sock:/var/run/docker.sock
The autoscaler also needs read access to the Compose file, env files, and bind mount paths used by the template service.
l4d2as:local
or:
ribas89/l4d2as:latest
L4D2AS_SETTINGS_FILEPath to the Python settings file inside the container.
L4D2AS_SETTINGS_FILE: /config/l4d2as_settings.py
L4D2AS_LOG_LEVELLog level.
L4D2AS_LOG_LEVEL: INFO
Supported values:
DEBUG
INFO
WARNING
ERROR
L4D2AS uses a Python settings file.
Example:
MAX_PLAYERS = 8
CHECK_INTERVAL_SECONDS = 30
EMPTY_GRACE_SECONDS = 300
SERVICE_NAME = "l4d2c00"
COMPOSE_FILE = "/compose/docker-compose.yml"
MAX_REPLICAS = 5
REMOVE_CONTAINERS_WHEN_STOPPED = True
REMOVE_CONTAINERS_NOT_IN_ROOMS = True
MAX_PLAYERSMaximum expected player count.
MAX_PLAYERS = 8
CHECK_INTERVAL_SECONDSHow often the autoscaler checks server state.
CHECK_INTERVAL_SECONDS = 30
EMPTY_GRACE_SECONDSHow long an extra empty server must stay empty before it is removed.
EMPTY_GRACE_SECONDS = 300
SERVICE_NAMEThe Compose service used as the template.
SERVICE_NAME = "l4d2c00"
COMPOSE_FILEPath to the Compose file inside the autoscaler container.
COMPOSE_FILE = "/compose/docker-compose.yml"
MAX_REPLICASMaximum number of generated containers.
If the template is l4d2c00 and MAX_REPLICAS = 5, L4D2AS manages:
l4d2c01
l4d2c02
l4d2c03
l4d2c04
l4d2c05
REMOVE_CONTAINERS_WHEN_STOPPEDKept for backward compatibility.
The current lifecycle is ephemeral, so unused containers are removed instead of only stopped.
REMOVE_CONTAINERS_WHEN_STOPPED = True
REMOVE_CONTAINERS_NOT_IN_ROOMSWhen enabled, removes managed autoscaled containers that are no longer inside the configured room range.
REMOVE_CONTAINERS_NOT_IN_ROOMS = True
The template Compose service must define an image:
image: l4d2:local
The container name must end with a number:
container_name: l4d2c00
The service must expose at least one UDP port:
ports:
- "192.168.8.220:51000:51000/udp"
The service must use dictionary-style network config with a static IPv4 address:
networks:
gamenet:
ipv4_address: 172.20.1.100
The service can define environment variables:
environment:
HOSTNAME: "RS CASUAL 00"
PORT: 51000
The service can use env files:
env_file:
- ./l4d2casual/common.env
The service can use bind mounts:
volumes:
- ./l4d2casual/addons/:/addons
- ./l4d2casual/cfg/:/cfg
Relative bind mount paths are resolved relative to the Compose file directory.
Generated containers are created with labels:
l4d2as.managed=true
l4d2as.template_service=<template-service>
l4d2as.room=<container-name>
l4d2as.index=<index>
These labels are used to identify autoscaled containers.
On every tick, L4D2AS:
docker build -t l4d2as:local .
docker run --rm -e L4D2AS_SETTINGS_FILE=/config/l4d2as_settings.py -e L4D2AS_LOG_LEVEL=INFO -v /var/run/docker.sock:/var/run/docker.sock -v ./l4d2as_settings.py:/config/l4d2as_settings.py:ro -v ./docker-compose.yml:/compose/docker-compose.yml:ro ribas89/l4d2as:latest
l4d2as:
image: ribas89/l4d2as:latest
container_name: l4d2as
restart: unless-stopped
environment:
L4D2AS_SETTINGS_FILE: /config/l4d2as_settings.py
L4D2AS_LOG_LEVEL: INFO
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./l4d2as_settings.py:/config/l4d2as_settings.py:ro
- ./docker-compose.yml:/compose/docker-compose.yml:ro
Make sure the Docker socket is mounted:
- /var/run/docker.sock:/var/run/docker.sock
Check L4D2AS_SETTINGS_FILE.
L4D2AS_SETTINGS_FILE: /config/l4d2as_settings.py
Check SERVICE_NAME and COMPOSE_FILE.
SERVICE_NAME = "l4d2c00"
COMPOSE_FILE = "/compose/docker-compose.yml"
The template service needs at least one port mapping.
ports:
- "192.168.8.220:51000:51000/udp"
The template service needs networks.<name>.ipv4_address.
networks:
gamenet:
ipv4_address: 172.20.1.100
Check that the generated server is reachable at the expected host and port.
Also check that the L4D2 server is listening on the generated PORT.
All generated containers up to MAX_REPLICAS are already running.
Increase MAX_REPLICAS.
MAX_REPLICAS = 10
Mounting /var/run/docker.sock gives this container control over the Docker daemon.
Only run L4D2AS in an environment you trust.
MIT
Content type
Image
Digest
sha256:4195548be…
Size
63.9 MB
Last updated
4 months ago
docker pull ribas89/l4d2as