Deployment
Releases and images
Section titled “Releases and images”Every gritz release publishes:
- Binaries for Linux,
gritz-linux-amd64andgritz-linux-arm64, attached to the GitHub release. ghcr.io/gritzapp/server, which runsgritz serverand listens on port6464. The Web UI is built into the binary.ghcr.io/gritzapp/runner, which runsgritz runner. It includes the Docker CLI and both driver binaries (GRITZ_PREBUILT_DIR=/app/prebuilt).
Images are built for linux/amd64 and tagged with the version (1.2.3), the
minor (1.2) and major (1) versions, and latest. Pin a version in
production.
Server
Section titled “Server”The server needs a PostgreSQL database and the settings described in Server. With Docker Compose:
services: postgres: image: postgres:18-alpine environment: POSTGRES_USER: gritz POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: gritz volumes: - postgres_data:/var/lib/postgresql/data
server: image: ghcr.io/gritzapp/server:1 ports: - "6464:6464" environment: GRITZ_BASE_URL: https://gritz.example.com GRITZ_DATABASE_URL: postgres://gritz:${POSTGRES_PASSWORD}@postgres:5432/gritz GRITZ_AUTH_DOMAIN: instance.zitadel.cloud GRITZ_AUTH_CLIENT_ID: ${GRITZ_AUTH_CLIENT_ID} GRITZ_AUTH_CLIENT_SECRET: ${GRITZ_AUTH_CLIENT_SECRET} GRITZ_AUTH_ENCRYPTION_KEY: ${GRITZ_AUTH_ENCRYPTION_KEY} GRITZ_AUTH_APP_KEY: ${GRITZ_AUTH_APP_KEY} GRITZ_ARCHIVE_POLL: 1m depends_on: - postgres
volumes: postgres_data:Keep the credentials in an .env file next to docker-compose.yml, or in your
platform’s secret store, rather than in the file itself. Put a TLS-terminating
proxy in front of port 6464, and point health checks at /healthz.
Runner as a Docker Compose service
Section titled “Runner as a Docker Compose service”The runner image drives the host’s Docker daemon through its socket, so task containers run next to the runner rather than inside it:
services: runner: image: ghcr.io/gritzapp/runner:1 restart: unless-stopped environment: GRITZ_SERVER: https://gritz.example.com GRITZ_API_KEY: ${GRITZ_API_KEY} GRITZ_RUNNER_ID: example-runner GRITZ_CONFIG_DIR: /etc/gritz # Read by ${env:} references in workspaces.yaml. CLAUDE_CODE_OAUTH_TOKEN: ${CLAUDE_CODE_OAUTH_TOKEN} volumes: - /var/run/docker.sock:/var/run/docker.sock - ./config:/etc/gritz - runner_state:/var/lib/gritz
volumes: runner_state:./config/workspaces.yamlis the workspace config.${env:}references in it read the runner container’s environment, and${sh:}commands run inside the runner container.runner_statekeeps the runner’s state database across restarts and upgrades.- Task containers join Docker’s default bridge network unless a workspace sets
networks:ornetwork_mode:.
gritzapp/workspaces has a complete example with a pull-through registry cache, so task images aren’t downloaded again for every container, and the sysbox runtime, so agents can run Docker inside their sandbox.
Upgrades
Section titled “Upgrades”The server, runner and driver ship together and change together: a release makes no promise of compatibility with another release’s server, runner or driver. Upgrade them as one:
- Upgrade the server. It applies its database migrations when it starts.
- Upgrade every runner to the same release. A runner that installed driver
binaries with
gritz downloadneeds to download them again; the runner image already has the matching ones. - For the Lambda MicroVMs backend, rebuild the MicroVM image with the new
gritzbinary and update the workspaces’image_identifier.
A sandbox keeps the driver it was created with: the Docker backend copies the binary in when it creates the container, and a MicroVM runs the one in its image. Tasks that were created before an upgrade keep their old driver until they are archived.