Container images for self-hosting TurboWarp components. Each component is a git submodule pointing at the upstream TurboWarp source, wrapped in its own multi-stage Docker build.
Note
Since these use the stock TurboWarp GUI, packager, extension gallery, and cloud server, most links go to https://*.turbowarp.org, not a self-hosted URL. This is being fixed.
| Directory | Submodule (upstream) | Image behavior |
|---|---|---|
gui/ |
TurboWarp/scratch-gui |
Builds the TurboWarp-edited Scratch editor and serves it as static files via nginx |
packager/ |
turbowarp/packager |
Builds the TurboWarp packager and serves it as static files via nginx |
cloud-server/ |
turbowarp/cloud-server |
Runs the TurboWarp cloud server as a Node.js service on port 9080 |
extensions/ |
turbowarp/extensions |
Builds the TurboWarp extensions website and serves it as static files via nginx |
The gui, packager, and extensions images use a common pattern:
- A multi-stage build stage (
node:22) installs dependencies withnpm ciand runs the project's production build. - The build output is copied into an
nginx:alpineruntime image.
The cloud server is optional: it provides cloud-variable hosting when the frontend is configured to use it, but the static sites do not require a running cloud server to function.
cloud-server differs: it runs directly on node:22 and serves the API via an Express-style server listening on port 9080, rather than static nginx files.
Each frontend image carries its own component-specific nginx configuration, such as the nginx.conf copied in by gui/Dockerfile, rather than a single shared nginx.conf.
Submodules must be initialized and updated first:
git submodule update --init --recursiveThen build any component and run it:
docker build -t turbowarp-gui ./gui
docker run -p 8080:80 turbowarp-guiFor the cloud server:
docker build -t turbowarp-cloud-server ./cloud-server
docker run -p 127.0.0.1:9080:9080 turbowarp-cloud-serverThe cloud server does not terminate TLS itself; in production, expose it through a reverse proxy that terminates TLS for the frontend.
- CI (
.github/workflows/ci.yml) runs on PRs and lints everyDockerfilewith hadolint and validates everynginx.confsyntax, discovering files dynamically. - CD (
.github/workflows/cd.yml) runs on tags matching*-v*.*.*. The tag is parsed into a service name and version, then the component is built and pushed to GHCR asghcr.io/<owner>/<repo>/<service>:<version>plus a:latesttag. - Dependabot (
.github/dependabot.yml) checks daily for submodule updates.
turbowarp-docker is under the MIT license.