For a more advanced and modern setup consider lklacar/q3js - it's a modern and feature-rich implementation.
For simplicity: This project provides a single-container solution that's perfect for smaller setups.
A fully self-contained, Dockerized QuakeJS server running on Debian 13 and Node.js 22.x LTS
Try it live: gibs.oldschoolfrag.com
This project provides a completely local QuakeJS server that runs entirely in Docker. No external dependencies, no content servers, no proxies - just pure Quake III Arena gaming in your browser.
Key improvements in this fork:
- Updated to a Docker Hardened Base Image (Debian)
- Updated NPM packages where possible
- Upgraded to Node.js 22.x LTS
- Nginx-light web server multiplexing Web and Game traffic over a single port
- Native HTTPS proxy support without altering game client files
- Runs as non-root user
- Small size ~280MB
podman run -d \
--name quakejs \
-p 8080:8080 \
docker.io/awakenedpower/quakejs-rootless:latestdocker run -d \
--name quakejs \
-p 8080:8080 \
docker.io/awakenedpower/quakejs-rootless:latestThen open your browser and navigate to http://localhost:8080 to start playing!
Create a docker-compose.yml file:
version: '3.8'
services:
quakejs:
container_name: quakejs
# To use the pre-built image:
image: awakenedpower/quakejs-rootless:latest
# Or to build directly from the repository source, uncomment the following line and comment out 'image' above:
# build: https://github.com/JackBrenn/quakejs-rootless.git
ports:
- '8080:8080'
restart: unless-stoppedThen run:
docker-compose up -d- Clone the repository:
git clone https://github.com/JackBrenn/quakejs-rootless.git
cd quakejs-rootless- Build the image:
podman build -t quakejs-rootless:latest .- Run the container:
podman run -d \
--name quakejs \
-p 8080:8080 \
quakejs-rootless:latest- Clone the repository:
git clone https://github.com/JackBrenn/quakejs-rootless.git
cd quakejs-rootless- Build the image:
docker build -t quakejs-rootless:latest .- Run the container:
docker run -d \
--name quakejs \
-p 8080:8080 \
quakejs-rootless:latestThe server configuration can be customized by modifying server.cfg.
You can inject environment variables to easily tune the QuakeJS server performance. The most important setting is SV_FPS, which dictates the server's simulation tick rate.
SV_FPS- Server framerate/tick rate. Default is20. Setting this to125will drastically reduce input delay and ping times (125Hz = 125 FPS server-side logic).SV_MAXRATE- Maximum bytes per second the server will send to a single client. Default is engine-dependent, but25000is recommended for broadband connections.
Example with Podman/Docker:
podman run -d \
--name quakejs \
-p 8080:8080 \
-e SV_FPS=125 \
-e SV_MAXRATE=25000 \
docker.io/awakenedpower/quakejs-rootless:latestThe web client can be dynamically configured just by appending settings to the URL. Because the default engine settings were designed for 56k dial-up modems in 1999, using these URL overrides will result in a significantly smoother and more modern experience!
-
Standard Connection (Engine Defaults)
http://<your-server-ip>:8080/ -
Competitive/Broadband Connection (Highly Recommended)
http://<your-server-ip>:8080/?set%20rate%2025000&set%20cl_maxpackets%20125&set%20cg_predictItems%201What this does:rate 25000- Tells the server your internet can handle high bandwidth updates.cl_maxpackets 125- Syncs your client's upload rate to match a 125Hz server.cg_predictItems 1- Eliminates the visual delay when picking up weapons or health on higher ping connections.
-
High Ping / Unstable Connection
http://<your-server-ip>:8080/?set%20cl_maxpackets%2060&set%20snaps%2040What this does: Trades maximum update frequency for stability on jittery network connections.
- 8080 - Multiplexed Web interface and Game server port. Web requests are handled by Nginx directly, while WebSocket game traffic is seamlessly forwarded internally. This makes proxying behind SSL natively supported via a single port.
This fork builds upon the excellent work of @treyyoder/quakejs-docker with the following updates:
| Component | Original | This Fork |
|---|---|---|
| Base OS | Ubuntu 20.04 | Debian 13 Docker Hardened Image |
| Node.js | 14.x | 22.x LTS |
| Web Server | Apache 2 | Nginx Light |
| Container User | root | non-root |
| Networking | Dual Port | Single Port Multiplexed via Nginx |
This wouldn't be possible without these projects:
- @treyyoder - Original quakejs-docker implementation that made fully local QuakeJS servers possible
- @nerosketch - QuakeJS fork with local server capabilities
- @inolen - Original QuakeJS project
MIT
For best security: Rootless container + Podman + Nginx + firewall + regular updates