# Deployment - **Docker** — PullApprove5 is distributed as a Docker image - **PostgreSQL 16+** — used for data storage and as the background job queue - **No license key or activation** — once deployed, your instance is fully functional ![Self-hosted architecture](/assets/docs/img/self-hosted-architecture.520ef20.svg) > A single PullApprove instance can integrate with one GitHub instance (and/or one GitLab instance). Connecting to multiple GitHub instances (e.g., both github.com and a GHES server) from a single PullApprove instance is not currently supported. ## 1. Load the Docker Image Docker images are provided as `.tar.gz` files. Load the image and push it to your private container registry: ```bash # Load the image docker load < pullapprove5-5.x.x.tar.gz # Tag for your registry docker tag pullapprove5:5.x.x your-registry.example.com/pullapprove5:5.x.x # Push to your registry docker push your-registry.example.com/pullapprove5:5.x.x ``` ## 2. Set Up PostgreSQL No special extensions are required. Database size depends on your pull request volume but is generally modest — plan for tens of gigabytes rather than hundreds. [Contact us](https://www.pullapprove.com/support/) if you need to use connection pooling (e.g., PgBouncer). ## 3. Configure and Deploy All configuration is done through environment variables. It is easiest to set the same env vars on all container instances, regardless of which command they run. You'll need a `server` container (HTTP on port 8000) and a `worker` container. See [Proxy Configuration](/docs/self-hosted/operations/#proxy-configuration) for TLS termination and [Container Commands](/docs/self-hosted/operations/#container-commands) for the full command reference. The following Kubernetes manifests can give you an idea of the setup — adapt to your platform. Environment variables: ```yaml apiVersion: v1 kind: Secret metadata: name: pullapprove-env stringData: # The full URL where your PullApprove5 instance is hosted PULLAPPROVE_BASE_URL: "https://pullapprove5.example.com" # Random secret key (at least 50 characters) # Generate with: python -c "import secrets; print(secrets.token_urlsafe(50))" PULLAPPROVE_SECRET_KEY: "your-random-secret-key" # JSON array of allowed hostnames PULLAPPROVE_ALLOWED_HOSTS: '["pullapprove5.example.com"]' # PostgreSQL connection string DATABASE_URL: "postgresql://user:pass@host:5432/dbname" # Git provider env vars go here too (see GitHub/GitLab setup guides) # ... ``` Run database migrations on install and update (or during release/pre-deploy): ```yaml apiVersion: batch/v1 kind: Job metadata: name: pullapprove-migrate spec: template: spec: containers: - name: migrate image: your-registry.example.com/pullapprove5:5.x.x args: ["migrate"] envFrom: - secretRef: name: pullapprove-env restartPolicy: Never ``` Server (~1 GB memory, minimal CPU) — serves the UI and receives webhooks: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: pullapprove-server spec: replicas: 1 selector: matchLabels: app: pullapprove component: server template: metadata: labels: app: pullapprove component: server spec: containers: - name: server image: your-registry.example.com/pullapprove5:5.x.x args: ["server"] ports: - containerPort: 8000 livenessProbe: httpGet: path: /up/ port: 8000 readinessProbe: httpGet: path: /up/ port: 8000 envFrom: - secretRef: name: pullapprove-env ``` Worker (~1 GB memory, minimal CPU) — processes pull requests in the background: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: pullapprove-worker spec: replicas: 1 selector: matchLabels: app: pullapprove component: worker template: metadata: labels: app: pullapprove component: worker spec: containers: - name: worker image: your-registry.example.com/pullapprove5:5.x.x args: ["worker"] envFrom: - secretRef: name: pullapprove-env ``` ## 4. Verify Once your containers are running, you can verify the deployment by visiting the `/` URL. Before connecting a Git provider, the login page will show the PullApprove logo with no login options — this is expected. ![Login page before connecting a Git provider](/assets/docs/img/self-hosted-no-providers.6ac4fda.png) ## Next Steps Connect your Git provider — each guide covers the required environment variables and webhook configuration: - [**GitHub**](/docs/self-hosted/github/) - [**GitLab**](/docs/self-hosted/gitlab/) For logging, monitoring, proxy configuration, and other operational topics, see the [**operations guide**](/docs/self-hosted/operations/). For a security review, see the [**security guide**](/docs/self-hosted/security/).