> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pullbase.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

> Deploy the Pullbase central server to coordinate your Linux server fleet.

Pullbase consists of two components:

1. **Central Server** — Coordinates environments, monitors Git, serves the dashboard.
2. **Agents** — Run on each managed Linux server.

This guide covers deploying the **Central Server**. For installing agents on your servers, see [Agent Operations](/agent-operations).

## Prerequisites

* **Docker** (v24.0+) with Docker Compose
* **Git** repository for your configuration
* **Database:** SQLite (default) or PostgreSQL (production)

## Choose Your Database

Pullbase supports two database backends. Choose the one that fits your needs:

| Feature         | SQLite (Default)                 | PostgreSQL (Recommended)        |
| :-------------- | :------------------------------- | :------------------------------ |
| **Best for**    | Testing, POCs, Small deployments | Production, High Availability   |
| **Setup**       | Zero configuration               | Requires Postgres container/RDS |
| **Storage**     | Single file on disk              | External volume/service         |
| **Performance** | Good for \< 100 agents           | Scales to thousands             |

## Quick Start (SQLite)

The easiest way to get started is using the default SQLite database. This requires zero external dependencies and is perfect for testing.

<Steps>
  <Step title="Create docker-compose.yml">
    Create a file named `docker-compose.yml` with the following content:

    ```yaml docker-compose.yml theme={null}
    services:
      central-server:
        image: pullbaseio/pullbase:latest
        restart: unless-stopped
        ports:
          - "8080:8080"
        environment:
          # Database
          - PULLBASE_DB_TYPE=sqlite
          - PULLBASE_DB_PATH=/data/pullbase.db
          # Security
          # ⚠️ IMPORTANT: Generate secure random strings for production use
          - PULLBASE_JWT_SECRET=change-this-to-a-secure-random-string
          - PULLBASE_WEBHOOK_SECRET_KEY=change-this-to-a-secure-random-string
          - PULLBASE_BOOTSTRAP_SECRET_FILE=/app/secrets/bootstrap.secret
          # Logging (optional)
          - PULLBASE_LOG_FORMAT=json   # json or text (default: text)
          - PULLBASE_LOG_LEVEL=info    # debug, info, warn, error (default: info)
        volumes:
          - pullbase_data:/data
          - pullbase_secrets:/app/secrets

    volumes:
      pullbase_data:
      pullbase_secrets:
    ```
  </Step>

  <Step title="Start the server">
    ```bash theme={null}
    docker compose up -d
    ```
  </Step>

  <Step title="Verify installation">
    Check if the server is running:

    ```bash theme={null}
    curl http://localhost:8080/api/v1/healthz
    # Output: {"status":"ok"}
    ```
  </Step>

  <Step title="Bootstrap the Admin">
    You need to create your first admin user to access the UI.
    Follow the **[CLI Guide](/guides/pullbasectl#authentication)** to bootstrap your admin account using the secret file.
  </Step>
</Steps>

## Production Setup (PostgreSQL)

For production environments, we recommend using PostgreSQL for better performance, reliability, and concurrency.

<Steps>
  <Step title="Create docker-compose.yml">
    Use this configuration to spin up Pullbase with a dedicated PostgreSQL container.

    ```yaml docker-compose.yml theme={null}
    services:
      db:
        image: postgres:16-alpine
        restart: unless-stopped
        environment:
          POSTGRES_USER: ${PULLBASE_DB_USER:-pullbaseuser}
          POSTGRES_PASSWORD: ${PULLBASE_DB_PASSWORD}
          POSTGRES_DB: ${PULLBASE_DB_NAME:-pullbasedb}
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
          interval: 10s
          timeout: 5s
          retries: 5

      central-server:
        image: pullbaseio/pullbase:latest
        restart: unless-stopped
        depends_on:
          db:
            condition: service_healthy
        ports:
          - "8080:8080"
        environment:
          # Database Connection
          - PULLBASE_DB_TYPE=postgres
          - PULLBASE_DB_HOST=db
          - PULLBASE_DB_PORT=5432
          - PULLBASE_DB_USER=pullbaseuser
          - PULLBASE_DB_NAME=pullbasedb
          # Security
          - PULLBASE_JWT_SECRET=${PULLBASE_JWT_SECRET}
          - PULLBASE_WEBHOOK_SECRET_KEY=${PULLBASE_WEBHOOK_SECRET_KEY}
          - PULLBASE_BOOTSTRAP_SECRET_FILE=/app/secrets/bootstrap.secret
          # Logging (optional)
          - PULLBASE_LOG_FORMAT=json   # json recommended for production
          - PULLBASE_LOG_LEVEL=info
        volumes:
          - pullbase_secrets:/app/secrets

    volumes:
      postgres_data:
      pullbase_secrets:
    ```
  </Step>

  <Step title="Configure Secrets">
    Create a `.env` file to store your sensitive secrets. **Do not commit this file to Git.**

    ```bash .env theme={null}
    PULLBASE_JWT_SECRET=generate-a-long-random-string-here
    PULLBASE_WEBHOOK_SECRET_KEY=generate-another-random-string
    PULLBASE_DB_PASSWORD=generate-a-secure-database-password
    ```
  </Step>

  <Step title="Start the stack">
    ```bash theme={null}
    docker compose up -d
    ```
  </Step>
</Steps>

## Next Steps

Now that your server is running:

1. **[Bootstrap the Admin](/guides/pullbasectl#authentication)** to create your first user.
2. **[Login to the Dashboard](/web-ui)** at `http://localhost:8080`.
3. **[Secure your installation](/security-hardening)** with TLS before going to production.
