Docker Deployment
Infrarust ships a minimal Docker image built from scratch. The image contains a statically linked binary, CA certificates, and nothing else. It supports x86_64, aarch64, and armv7.
Directory structure
Infrarust inside Docker expects a config volume mounted at /app/config. The layout:
config/
├── infrarust.toml
└── servers/
└── survival.toml2
3
4
Set servers_dir in your infrarust.toml to the path inside the container:
bind = "0.0.0.0:25565"
servers_dir = "/app/config/servers"2
Running with docker run
docker run -d \
--name infrarust \
-p 25565:25565 \
-v ./config:/app/config \
ghcr.io/shadowner/infrarust:latest \
--config /app/config/infrarust.toml2
3
4
5
6
The --config flag tells Infrarust where to find infrarust.toml inside the container. If you don't pass it, the binary looks for infrarust.toml in the working directory (/app).
Docker Compose
A minimal docker-compose.yml:
services:
infrarust:
image: ghcr.io/shadowner/infrarust:latest
command: ["--config", "/app/config/infrarust.toml"]
ports:
- "25565:25565"
volumes:
- ./config:/app/config
restart: unless-stopped2
3
4
5
6
7
8
9
Environment variables
Infrarust reads one environment variable at runtime:
| Variable | Description |
|---|---|
RUST_LOG | Log level filter. Overrides the --log-level CLI flag. Accepts trace, debug, info, warn, error, or module-level filters like infrarust_core=debug. |
Set it in your Compose file or docker run:
docker run -d \
--name infrarust \
-p 25565:25565 \
-e RUST_LOG=debug \
-v ./config:/app/config \
ghcr.io/shadowner/infrarust:latest \
--config /app/config/infrarust.toml2
3
4
5
6
7
Or in Compose:
services:
infrarust:
image: ghcr.io/shadowner/infrarust:latest
command: ["--config", "/app/config/infrarust.toml"]
ports:
- "25565:25565"
volumes:
- ./config:/app/config
environment:
RUST_LOG: "info"
restart: unless-stopped2
3
4
5
6
7
8
9
10
11
CLI flags
These flags are passed after the image name in docker run, or in the command field of Compose:
| Flag | Default | Description |
|---|---|---|
-c, --config <PATH> | infrarust.toml | Path to the proxy configuration file |
-b, --bind <ADDR> | from config | Override the bind address |
-l, --log-level <LEVEL> | info | Log level filter (overridden by RUST_LOG) |
Auto-discovery with Docker labels
When Infrarust runs alongside your Minecraft servers in Docker, it can discover them automatically through container labels. No static server config files needed.
Add a [docker] section to your infrarust.toml:
servers_dir = "/app/config/servers"
[docker]2
3
Then label your Minecraft containers:
services:
infrarust:
image: ghcr.io/shadowner/infrarust:latest
command: ["--config", "/app/config/infrarust.toml"]
ports:
- "25565:25565"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config:/app/config
restart: unless-stopped
survival:
image: itzg/minecraft-server
environment:
EULA: "TRUE"
TYPE: "PAPER"
labels:
infrarust.enable: "true"
infrarust.domains: "survival.example.com"
restart: unless-stopped2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Infrarust scans for containers with infrarust.enable=true, reads their labels, resolves their network address, and registers them as backend servers. When containers start or stop, the routing table updates in real time.
WARNING
Mounting the Docker socket (/var/run/docker.sock) gives Infrarust read access to all containers on the host. Mount it read-only (:ro) and understand the security implications before deploying this in production.
The full set of container labels and provider options is documented in Docker Provider.
Networking
When Infrarust and your Minecraft servers share a Docker network, containers communicate by internal IP. This is the recommended setup because it avoids port publishing on the host for backend servers.
networks:
minecraft:
driver: bridge
services:
infrarust:
image: ghcr.io/shadowner/infrarust:latest
command: ["--config", "/app/config/infrarust.toml"]
ports:
- "25565:25565"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config:/app/config
networks:
- minecraft
restart: unless-stopped
survival:
image: itzg/minecraft-server
environment:
EULA: "TRUE"
labels:
infrarust.enable: "true"
infrarust.domains: "survival.example.com"
networks:
- minecraft
restart: unless-stopped2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Tell Infrarust which Docker network to prefer for address resolution:
[docker]
network = "minecraft"2
Without this setting, Infrarust picks the first available network IP from each container. If your containers are on multiple networks, set network to avoid resolving to the wrong IP.
Building the image yourself
The included Dockerfile uses a multi-stage build: Alpine + Rust for compilation, scratch for the final image.
docker build -t infrarust .The build detects the host architecture and targets it automatically. Cross-compilation is handled through Docker buildx:
docker buildx build --platform linux/amd64,linux/arm64 -t infrarust .Connecting to external servers
If your Minecraft servers run outside Docker (bare metal, VMs, another host), you don't need the Docker provider or socket mount. Use static server config files instead:
services:
infrarust:
image: ghcr.io/shadowner/infrarust:latest
command: ["--config", "/app/config/infrarust.toml"]
ports:
- "25565:25565"
volumes:
- ./config:/app/config
restart: unless-stopped2
3
4
5
6
7
8
9
Define your servers as .toml files in config/servers/:
# config/servers/survival.toml
domains = ["survival.example.com"]
addresses = ["192.168.1.50:25565"]2
3
Infrarust watches the servers/ directory and picks up new or changed files without a restart.