Deployment
This page describes, at a conceptual level, how the hosted Lighthouse CI server is run in production. It's meant to give you a mental model of the deployment shape rather than a step-by-step runbook — the operational details (credentials, service configuration, DNS) live outside this public site.
The shape of it
The server runs as a containerized service on a general-purpose hosting platform, built straight from a Dockerfile rather than a platform-specific buildpack. That keeps the build reproducible: whatever runs in the container locally is exactly what runs in production, with no divergence between "how I built it" and "how the platform built it."
Persistent data — registered projects and their Lighthouse run history — lives in a managed Postgres database, provisioned separately from the compute layer. Separating storage from compute this way means the service container itself is disposable: it can be rebuilt, redeployed, or moved without touching the data, because nothing important is stored on the container's local filesystem.
A gotcha worth knowing about
Managed Postgres providers commonly offer more than one way to connect — typically a direct connection and one or more pooled connection modes, each exposed as a different connection string with different host and port combinations. They are not interchangeable, and the failure mode when you pick the wrong one is not always obvious from the error message alone.
The general rule of thumb: pick the pooling mode that matches how your hosting platform's network egress behaves, and match your database client's SSL/TLS expectations to what the provider's certificate chain actually supports. Getting this pairing wrong tends to surface as either a refused connection at the network layer, or a certificate-verification failure at the TLS layer — both of which look like "the database is down" even though the database is fine. If you hit either, the connection string's pooling mode and SSL parameters are the first thing to check, not the database itself.
Deploy sequence, conceptually
Standing up a new environment follows roughly this order:
- Provision the database. Create a dedicated Postgres instance for this service rather than sharing one with an unrelated app — it keeps the data lifecycle independent of anything else you run.
- Connect the source repository to the hosting platform. The platform watches a branch and builds the container image whenever it changes.
- Apply the deploy configuration. A small, version-controlled config file describes the service — how it's built (Docker), what plan/tier it runs on — so the shape of the deployment is defined in code rather than configured by hand each time.
- Set the required secrets. Database connection strings, access credentials, and any API keys the service needs are entered directly into the hosting platform's environment configuration. They are never committed to the repository and never baked into the container image — the deploy config only declares which variables are needed, not their values.
- Deploy. The platform builds the image and starts the container. The service creates its own database tables on first boot, so there's no separate migration step to run.
- Register each repository you want tracked. Once the service is live, each project that wants Lighthouse CI history gets registered against it individually — see Getting Started for that workflow.
That's the whole shape: a stateless, container-built service in front of a managed, independently-provisioned database, wired together by a handful of secrets set once at deploy time.