pnpm docker:setup # or: ./deploy-kit/setup prod after extracting a deploy kit
docker-compose pull
docker-compose up -d
docker-compose ps
Required Traefik inputs are STUDIO_DOMAIN,
TRAEFIK_NETWORK, TRAEFIK_ENTRYPOINT, and
TRAEFIK_CERT_RESOLVER; the wizard asks for all of them. TLS router
labels live in deploy/compose.tls.yml, selected by the
COMPOSE_FILE variable in the prod .env. No Traefik
container is included. Public services use labels and expose; only the
optional local database Compose file publishes a loopback port.
On a fresh hosted database, plain docker-compose up -d is sufficient:
web and worker wait for the migration container to finish successfully for the
current image tag before accepting traffic. If they remain unavailable, inspect
docker-compose logs studio-migrate; do not remove database volumes to
retry.
Hosted web and worker processes use separate network namespaces. Set
STUDIO_RUNTIME_INTERNAL_HOST on the web service to the worker's
internal DNS name (studio-worker in the supplied Compose stack).
Server-side state, command, log, and Vite health requests use that internal
hostname. Browser runtime HTTP and WebSocket traffic stays on
STUDIO_PUBLIC_URL below /api/live/runtime/<port>/…;
Traefik authenticates it through the web app and forwards it to the worker's
fixed port 3003. The dynamic runtime ports remain internal and must not
be published on the host. The supplied compose.yml configures this
automatically.
#Git-backed source checkouts
Set STUDIO_ALLOWED_PROJECT_ROOTS to at least one canonical container
path that is writable by both the web service and worker. Git-backed projects and
GEngine are cloned below the first root. The SSH overlay uses the persistent named
Docker volume studio-projects for this root, so existing host
directories cannot collide with a fresh clone.
For private self-hosted GitLab repositories, use the optional SSH Compose overlay.
Create a dedicated directory containing only a read-only deploy key and its verified
known_hosts file:
install -d -m 700 .local/ssh
ssh-keygen -t ed25519 -f .local/ssh/id_ed25519 -C gengine-studio
ssh-keyscan -H gitlab.example.com > .local/ssh/known_hosts
chmod 600 .local/ssh/id_ed25519
chmod 644 .local/ssh/known_hosts
For an SSH remote using a non-default port, scan that port explicitly; OpenSSH
records it as a bracketed host such as [gitlab.example.com]:2222:
ssh-keyscan -p 2222 -H gitlab.example.com > .local/ssh/known_hosts
Verify the Git server fingerprint before trusting known_hosts, then add
.local/ssh/id_ed25519.pub to the repository as a read-only deploy key.
The SSH overlay copies the files into a private Docker volume with the correct UID
and restrictive modes; the host-side private key does not need to be made readable
by other host users.
The Sourcefab production template defaults this setup prompt to
[gitlab.sourcefab.net]:2222. Setup refuses to proceed with an empty
known_hosts file. Re-running deploy/setup.sh prod checks
the SSH material again even when you keep the existing .env.
When GitLab shares the Docker host, the SSH overlay maps
gitlab.sourcefab.net to Docker's host gateway in Studio
containers. This lets the canonical external
ssh://git@gitlab.sourcefab.net:2222/... URL reach the host-published
GitLab SSH endpoint rather than GitLab's internal port 22.
This mapping is only correct when GitLab is actually colocated with the Docker host
— true for the Sourcefab prod deployment, not for a developer's own machine.
Since compose.ssh.yml applies to every environment and defaults
STUDIO_GIT_SSH_HOSTNAME to gitlab.sourcefab.net whenever
it's unset, dev and test templates pin it to an unused placeholder
(git-ssh-colocation-disabled.invalid) so the override doesn't
shadow the real DNS record there — otherwise Git clones/fetches on a dev machine
fail with "connection refused" on port 2222, because nothing listens on
that port on the developer's own host gateway.
If the directory is elsewhere, set STUDIO_SSH_DIR to its absolute path
in .env. Start the stack with the overlay:
docker compose -f compose.yml -f compose.ssh.yml up -d --build
The overlay mounts the same checkout volume into web and worker and installs
Git/OpenSSH in both runtime images. With this overlay,
PROJECT_MOUNT_ROOT and GENGINE_MOUNT_PATH are not used as
host bind sources; the named studio-projects volume is used instead.
Never put deploy tokens, passwords, or private keys in a Git URL, project setting,
audit metadata, or client-visible environment variable. Use an SSH URL such as
git@gitlab.example.com:group/repository.git.
When rotating the key, recreate the one-shot initializer so it copies the new files:
docker compose -f compose.yml -f compose.ssh.yml up -d --build --force-recreate studio-ssh-init
docker compose -f compose.yml -f compose.ssh.yml up -d
The web image includes the generated standalone developer manual. After deployment,
verify that https://<STUDIO_DOMAIN>/docs/index.html loads without
external CDN or font requests and that the wizard opens it in a new tab.