https://github.com/penguinztech/penguin-rust-base
Rust dedicated server with Oxide + umod plugins β community base image
https://github.com/penguinztech/penguin-rust-base
Last synced: about 2 months ago
JSON representation
Rust dedicated server with Oxide + umod plugins β community base image
- Host: GitHub
- URL: https://github.com/penguinztech/penguin-rust-base
- Owner: PenguinzTech
- Created: 2026-04-13T14:48:23.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-13T16:57:59.000Z (2 months ago)
- Last Synced: 2026-04-13T18:25:47.130Z (2 months ago)
- Language: Shell
- Size: 29.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# penguin-rust-base
[](https://github.com/PenguinzTech/penguin-rust-base/pkgs/container/penguin-rust-base)
[](https://github.com/PenguinzTech/penguin-rust-base/actions/workflows/test.yml)
[](https://github.com/PenguinzTech/penguin-rust-base/actions/workflows/security.yml)
[](https://github.com/PenguinzTech/penguin-rust-base/actions/workflows/build-image.yml)
A production-ready Docker image for Rust dedicated game servers with Oxide mod framework and plugins baked in. Game files (~6GB) are baked at build time to eliminate first-boot download waits. Automatically rebuilds every 4 hours when Oxide or Steam updates, with startup-time checks for plugin updates.
Perfect for operators, communities, and teams extending with proprietary plugins via `FROM`.
π **Full configuration reference:** [docs/CONFIGURATION.md](docs/CONFIGURATION.md)
---
## What's Included
- **Rust Dedicated Server** β Steam app 258550, latest version
- **Oxide Mod Framework** β Auto-updated every 4 hours
- **Pre-Installed Plugins** β all plugins published to [penguin-rust-plugins](https://github.com/PenguinzTech/penguin-rust-plugins) are automatically baked in on every image build (no static list to maintain):
- **AdminUtilities** β Admin commands (noclip, god mode, kick, ban, give, spawn)
- **BGrade** β Automatically upgrade building grades
- **CopyPaste** β Copy and paste buildings
- **Vanish** β Admin invisibility toggle
- **RemoverTool** β Remove placed objects
- **UnburnableMeat** β Prevents cooked meat from burning
- **VehicleDecayProtection** β Per-vehicle decay protection permissions
- **NightLantern** β Auto-lights fires/lanterns at night
- **TruePVE** β PvE protection rules
- **StackSizeController** β Customize item stack sizes
- **Whitelist** β Restrict server access to whitelisted players
- **AutoAdmin Plugin** β Custom PenguinzTech plugin that auto-grants all baked and patched plugin permissions to admins on every boot via `RUST_ADMIN_STEAMIDS`; also fires on plugin hot-reload so no manual `oxide.grant` calls are needed
- **PluginManager Plugin** β Runtime `/plugin add|remove|update|list` commands; manage plugins live without a restart (see [docs/plugin-manager.md](docs/plugin-manager.md))
- **Patched Community Plugins** β 10 popular community plugins pre-patched for Oxide API compatibility (removed APIs replaced so they work on current Rust builds): AntiOfflineRaid, BetterChat, BetterChatMute, DynamicPVP, NTeleportation, PlayerAdministration, Quests, TreePlanter, VehicleLicence, ZoneManager β see [docs/ACKNOWLEDGEMENTS.md](docs/ACKNOWLEDGEMENTS.md)
- **WAF Sidecar** β Go-based network-layer firewall that protects the game server from DDoS floods, cheater reconnect storms, RCON brute-force, and packet anomalies β **works in pure vanilla mode** with no Oxide required (see [docs/waf.md](docs/waf.md))
- **Auto-Configuration** β First-boot tuning of `worldSize`/`maxPlayers` based on available CPU/RAM
- **Wipe Scheduler** β Configurable map wipes with in-game RCON warnings (60-minute lead time)
- **DDoS Protection** β Per-source-IP rate limiting via iptables (opt-in, requires `NET_ADMIN`)
- **Debian 12 Bookworm Runtime** β Lightweight, secure, production-hardened container
---
## Quick Start
### Basic Server (auto-tuned world size and player limit)
```bash
docker run -d \
--name rust-server \
-p 28015:28015/udp \
-p 28015:28015/tcp \
-p 28016:28016/tcp \
-e RUST_SERVER_NAME="My Rust Server" \
ghcr.io/penguinztech/penguin-rust-base:latest
```
### With Admin Access + Persistent Volume
```bash
docker run -d \
--name rust-server \
-p 28015:28015/udp \
-p 28015:28015/tcp \
-p 28016:28016/tcp \
-v rust-data:/steamcmd/rust/server \
-e RUST_SERVER_NAME="My Rust Server" \
-e RUST_ADMIN_STEAMIDS="76561198000000000,76561198000000001" \
ghcr.io/penguinztech/penguin-rust-base:latest
```
### Docker Compose
```yaml
services:
rust:
image: ghcr.io/penguinztech/penguin-rust-base:latest
container_name: rust-server
ports:
- "28015:28015/udp"
- "28015:28015/tcp"
- "28016:28016/tcp"
volumes:
- rust-data:/steamcmd/rust/server
environment:
RUST_SERVER_NAME: "My Community Server"
RUST_SERVER_DESCRIPTION: "Weekly wipes, friendly community"
RUST_SERVER_TAGS: "weekly,vanilla,pvp"
WIPE_SCHED: "1w"
WIPE_DAY: "Th"
RUST_ADMIN_STEAMIDS: "76561198000000000"
restart: unless-stopped
volumes:
rust-data:
```
---
## Configuration
All settings are controlled via environment variables. The most commonly set ones:
| Variable | Default | Description |
|---|---|---|
| `RUST_SERVER_NAME` | `Rust Server` | Server name in browser |
| `RUST_SERVER_MAXPLAYERS` | *(auto-detected)* | Max concurrent players |
| `RUST_SERVER_WORLDSIZE` | *(auto-detected)* | Map size in meters |
| `RUST_SERVER_SEED` | `12345` | World seed |
| `RUST_RCON_PASSWORD` | *(auto-generated)* | RCON password; generated and persisted to PVC if unset |
| `RUST_ADMIN_STEAMIDS` | *(none)* | Comma-separated admin Steam IDs |
| `WIPE_SCHED` | *(first Thu of month)* | `1w`, `2w`, `3w`, or `off` |
| `PLUGIN_SOURCE` | `github` | `github` (bakedβGitHubβumod chain), `baked` (no network), or `umod` (always umod.org) |
| `PLUGIN_UMOD_FALLBACK` | `1` | In `github` mode, fall back to umod.org for slugs not in penguin-rust-plugins (`0` to disable) |
π **Everything else** β browser listing (description, tags, URL, logo), server behaviour (PvE, radiation, tickrate), wipe schedule details, DDoS protection, admin provisioning, plugin toggles, auto-config tiers, performance tuning β is documented in **[docs/CONFIGURATION.md](docs/CONFIGURATION.md)**.
Specialist guides:
- **[docs/auto-config.md](docs/auto-config.md)** β first-boot resource detection, lock file behaviour
- **[docs/wipe-schedule.md](docs/wipe-schedule.md)** β wipe cadence, blueprint wipes, warning schedule
- **[docs/ddos-protection.md](docs/ddos-protection.md)** β iptables rate limiting and auto-ban
- **[docs/waf.md](docs/waf.md)** β Go WAF sidecar: vanilla-compatible DDoS/flood/cheat protection, Oxide integration, Prometheus metrics
---
## Image Tags & Versioning
Every build produces two tags:
| Tag | Mutability | Use Case |
|-----|-----------|----------|
| `latest` | Mutable | Development, testing β always get the newest Oxide/Steam updates |
| `` | Immutable | Production, pinning β freeze a known-good build |
```bash
# Pin to a specific build in production
FROM ghcr.io/penguinztech/penguin-rust-base:1747123456
```
List available tags:
```bash
curl -s https://ghcr.io/v2/penguinztech/penguin-rust-base/tags/list | jq '.tags'
```
---
## Extending This Image
```dockerfile
FROM ghcr.io/penguinztech/penguin-rust-base:1747123456
# Custom/proprietary plugins
COPY --chown=rustserver:rustserver my-plugins/ /steamcmd/rust/oxide/plugins/
# Pre-seeded plugin data
COPY --chown=rustserver:rustserver my-data/ /steamcmd/rust/oxide/data/
# Default overrides
ENV RUST_SERVER_NAME="My Custom Server"
```
---
## Plugin Caching
Plugins are baked into the image as gzip-compressed `.cs.gz` files alongside a `.hash` sidecar. This serves two purposes:
**Startup speed** β On every boot, `start.sh` compares the baked hash against the latest release in `penguin-rust-plugins`. If they match, the plugin is decompressed and activated in milliseconds from the local layer β no network round-trip. Only plugins that have been updated since the image was built are downloaded at startup.
**Efficient layer sharing for multi-server providers** β All plugin `.cs.gz` files live in a single immutable Docker layer. Hosts running many Rust server containers (or different server images built `FROM` this base) share that layer on disk and in the registry pull cache. Plugins are only decompressed into the container's writable layer when activated, so the compressed originals remain shared.
```
oxide/plugins/disabled/ β shared, compressed, in image layer
truepve.cs.gz
truepve.hash
whitelist.cs.gz
whitelist.hash
...
oxide/plugins/ β per-container writable layer, uncompressed
TruePVE.cs β only after RUST_PLUGINS=truepve
Whitelist.cs
```
Plugins are disabled by default. Set `RUST_PLUGINS` to activate specific ones:
```bash
-e RUST_PLUGINS="truepve,whitelist,vanish"
```
---
## Automatic Updates
- **Every 4 hours** β check Oxide and Steam for updates, rebuild if changed
- **On dispatch** β manual `gh workflow run build.yml`
- **On startup** β compare baked plugin hashes against latest `penguin-rust-plugins` releases; download updates only when needed
---
## WAF Sidecar (Network-Layer Protection)
The image ships a **Go WAF sidecar** that operates at the network layer β below the Rust game engine. It intercepts all traffic before it reaches the single-threaded C#/Mono game loop and drops malicious packets in Go's concurrent runtime where they are cheap.
**Crucially, this works on pure vanilla servers.** No Oxide, no plugins, no mods required. Every protection below runs at the packet level regardless of server configuration:
| Protection | How it works |
|---|---|
| **DDoS / flood** | Per-IP packet-rate limiter; sustained floods auto-blocked |
| **RCON brute-force** | Failed auth counter; offending IP throttled after N attempts |
| **Ban evasion** | Steam64 ID extracted from handshake; banned player blocked across IP changes |
| **Packet anomalies** | Malformed/oversized packets dropped before game sees them |
| **Aimbot heuristics** | Inter-packet timing CV analysis; bot-like consistency flagged |
When Oxide *is* running, plugins can push runtime rules to the WAF via a loopback REST API β reporting detected cheaters for immediate network-layer enforcement without a game restart.
Enable in Kubernetes (Helm):
```bash
helm install rust-server ./k8s/helm/rust-server --set waf.enabled=true
```
π **Full WAF reference:** [docs/waf.md](docs/waf.md)
---
## Networking
| Port | Protocol | Purpose |
|------|----------|---------|
| `28015` | UDP + TCP | Game server port (connections + queries) |
| `28016` | TCP | RCON / WebRCON |
| `28017` | UDP | Server browser query |
Forward **both UDP and TCP** on port 28015. RCON and query ports are optional.
> **WAF port note:** When the WAF sidecar is enabled, it occupies the public-facing ports (`28015/28016/28017`) and shifts the game server to loopback offsets (`28115/28116/28117`). No change to external port mappings required.
---
## Security
Runs as non-root (`rustserver:rustserver`, UID 1000); no capabilities required unless DDoS protection is enabled. RCON password auto-generated on first boot and persisted to the PVC β never embedded. The WAF sidecar also runs as a dedicated non-root user (`waf:waf`) and adds zero inbound attack surface β its management API listens on loopback only.
Full details β CI scanners, what's not scanned, reporting vulnerabilities: **[docs/SECURITY.md](docs/SECURITY.md)**.
DDoS protection setup: **[docs/ddos-protection.md](docs/ddos-protection.md)**.
WAF sidecar: **[docs/waf.md](docs/waf.md)**.
---
## Troubleshooting
```bash
# Check logs
docker logs rust-server | tail -50
# Server won't start β typical causes:
# - Port conflict on 28015/28016
# - Memory limit below MONO_MAX_HEAP
# - Volume permissions (must be writable by UID 1000)
# Retrieve auto-generated RCON password
docker exec rust-server cat /steamcmd/rust/server/rust_server/.rcon.pw
# Plugin status
docker exec rust-server ls /steamcmd/rust/oxide/plugins/
docker exec rust-server tail -50 /steamcmd/rust/server/oxide/logs/log.txt
```
Full troubleshooting: [docs/CONFIGURATION.md](docs/CONFIGURATION.md)
---
## Contributing
Issues, feature requests, and pull requests welcome on [GitHub](https://github.com/PenguinzTech/penguin-rust-base).
---
## License
- **Container image:** MIT License
- **Bundled plugins:** Their respective authors' licenses (see [umod.org](https://umod.org))
- **Rust / Steam:** Licensed by Facepunch Studios β by using this image you agree to the [Rust Server License](https://www.rust.facepunch.com/)
---
## Support
- [GitHub Issues](https://github.com/PenguinzTech/penguin-rust-base/issues) β image-specific issues
- [Rust Support](https://support.facepunch.com/) β game server issues
- [Oxide Docs](https://umod.org/documentation) β mod framework
- [umod Community](https://umod.org/community) β plugin help
---
**Built by PenguinzTech** β Reliable, production-ready Rust infrastructure.