| title | description |
|---|---|
Server Container Deployment |
Run the Pullbase central server using Docker or container orchestrators. |
This guide covers deploying the Pullbase central server using containers. The central server coordinates environments, monitors Git repositories, and serves the web dashboard.
**Agents should run natively on your Linux servers, not in containers.** Container agents require privileged access and have significant limitations. See [Agent Operations](/agent-operations) for native agent installation.This page is for deploying the central server only.
Pullbase publishes a container image for the central server (pullbaseio/pullbase). This guide shows how to deploy it with Docker Compose, but the same environment variables apply if you run the image under Kubernetes, Nomad, or another orchestrator.
- Docker 24.0+ with the Compose plugin (or an equivalent container runtime)
- PostgreSQL 15+ (container service or managed instance)
- Git repository containing your environment configuration (
config.yaml) - (Production) Reverse proxy for TLS termination
/opt/pullbase/
├── docker-compose.yml
├── .env
├── config/
│ └── github-app.pem # optional, mounted read-only
└── logs/ # optional bind mount for log shipping
config/holds the GitHub App private key or other secrets you mount read-only.logs/can be bound if you prefer file-based log collection; otherwise rely ondocker logs.
services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: pullbaseuser
POSTGRES_PASSWORD: pullbasepass
POSTGRES_DB: pullbasedb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U pullbaseuser -d pullbasedb']
interval: 10s
timeout: 5s
retries: 5
pullbase:
image: pullbaseio/pullbase:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
# Database
PULLBASE_DB_HOST: db
PULLBASE_DB_PORT: 5432
PULLBASE_DB_USER: pullbaseuser
PULLBASE_DB_PASSWORD: pullbasepass
PULLBASE_DB_NAME: pullbasedb
PULLBASE_DB_SSLMODE: disable
# Server
PULLBASE_SERVER_PORT: 8080
PULLBASE_SERVER_HOST: 0.0.0.0
# Authentication
PULLBASE_JWT_SECRET: ${PULLBASE_JWT_SECRET}
PULLBASE_JWT_EXPIRY_HOURS: 24
# Webhooks
PULLBASE_WEBHOOK_SECRET_KEY: ${PULLBASE_WEBHOOK_SECRET_KEY}
# Git integration
PULLBASE_GIT_ENABLED: ${PULLBASE_GIT_ENABLED:-false}
PULLBASE_GIT_CLONE_PATH: /app/git-repos
PULLBASE_GIT_POLL_INTERVAL: 60
# GitHub App (when using private repos)
PULLBASE_GITHUB_APP_ID: ${PULLBASE_GITHUB_APP_ID:-}
PULLBASE_GITHUB_APP_PRIVATE_KEY_PATH: /config/github-app.pem
PULLBASE_GITHUB_APP_API_BASE_URL: https://api.github.com
volumes:
- ./config:/config:ro
ports:
- '8080:8080'
volumes:
postgres_data:Populate secrets in .env:
cat <<EOF > .env
PULLBASE_JWT_SECRET=$(openssl rand -hex 32)
PULLBASE_WEBHOOK_SECRET_KEY=$(openssl rand -hex 32)
PULLBASE_GIT_ENABLED=false
EOFPullbase supports two approaches for TLS in production.
Enable native TLS by adding these environment variables to your Compose file:
environment:
PULLBASE_TLS_ENABLED: "true"
PULLBASE_TLS_CERT_PATH: /config/server.crt
PULLBASE_TLS_KEY_PATH: /config/server.keyMount your certificates in the config volume:
volumes:
- ./config:/config:ro # Contains server.crt, server.key, github-app.pemFor development, you can start the server with --generate-dev-certs to auto-generate self-signed certificates.
For existing infrastructure, place Pullbase behind a reverse proxy that handles TLS:
server {
listen 443 ssl http2;
server_name pullbase.example.com;
ssl_certificate /etc/ssl/certs/pullbase.crt;
ssl_certificate_key /etc/ssl/private/pullbase.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://pullbase:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}# Add to docker-compose.yml
traefik:
image: traefik:v3.6.2
command:
- "--providers.docker=true"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
# Add labels to pullbase service
pullbase:
labels:
- "traefik.enable=true"
- "traefik.http.routers.pullbase.rule=Host(`pullbase.example.com`)"
- "traefik.http.routers.pullbase.entrypoints=websecure"
- "traefik.http.routers.pullbase.tls.certresolver=letsencrypt"Using Amazon RDS, Azure Database for PostgreSQL, or another managed service?
- Create the database and grant Pullbase a dedicated user.
- Set
PULLBASE_DB_HOST,PULLBASE_DB_USER,PULLBASE_DB_PASSWORD, andPULLBASE_DB_NAMEto match the instance. - Enable TLS by setting
PULLBASE_DB_SSLMODE=requireorPULLBASE_DB_SSLMODE=verify-full. - Remove the
dbservice fromdocker-compose.yml.
- Pin the image tag (for example,
pullbaseio/pullbase:vX.Y.Z) and update intentionally. - Run
docker compose pull && docker compose up -dto roll forward with minimal downtime. - Review release notes for database migrations and watch container logs during the upgrade.