codebash
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:

codebash
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:

codebash
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:

codebash
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:

codebash
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.