Skip to content

Quickstart

This page gets a working server and one connected firewall as fast as possible. It uses plain HTTP and no TLS, so use it on a lab or trusted network only. The tutorials cover the same ground with more explanation, and Day 0 covers production.

You need: a Linux host with Docker and Docker Compose, and a pfSense 2.7 or later firewall that can reach that host.

In the examples the host’s IP address is 192.168.1.50. Replace it with yours.

  1. Create a project folder and a Compose file.

    Terminal window
    mkdir pf-central && cd pf-central
    openssl rand -hex 32 # copy the output; it is your token pepper

    Save this as compose.yaml. Replace the IP address, the database password and the pepper:

    compose.yaml
    services:
    postgres:
    image: postgres:17
    restart: unless-stopped
    environment:
    POSTGRES_DB: pf_central
    POSTGRES_USER: pf_central
    POSTGRES_PASSWORD: change-this-db-password
    volumes:
    - pgdata:/var/lib/postgresql/data
    healthcheck:
    test: ["CMD-SHELL", "pg_isready -U pf_central -d pf_central"]
    interval: 5s
    retries: 10
    pf-central:
    image: ghcr.io/danielmichaels/pf-central:latest
    restart: unless-stopped
    depends_on:
    postgres:
    condition: service_healthy
    ports:
    - "2808:2808" # web UI, API and enrollment
    - "24222:24222" # NATS, for agents
    environment:
    PFCENTRAL_DATABASE_URL: postgres://pf_central:change-this-db-password@postgres:5432/pf_central?sslmode=disable
    PFCENTRAL_SERVER_BASE_URL: http://192.168.1.50:2808
    PFCENTRAL_TRUSTED_ORIGINS: http://192.168.1.50:2808
    PFCENTRAL_COOKIE_SECURE: "false" # plain HTTP only; remove behind HTTPS
    PFCENTRAL_TOKEN_PEPPER_CURRENT: paste-your-pepper-here
    PFCENTRAL_TOKEN_PEPPER_VERSIONS: paste-your-pepper-here
    PFCENTRAL_LOG_JSON: "false"
    PFCENTRAL_LOG_LEVEL: info
    volumes:
    - state:/data
    volumes:
    pgdata:
    state:
  2. Start it.

    Terminal window
    docker compose up -d
    docker compose logs pf-central | grep -A1 "first-run setup"

    The server creates its database tables, its keys and its NATS broker, then prints a one-time setup link:

    ╔══ pf-central first-run setup ══════════════════════╗
    ║ Visit: http://192.168.1.50:2808/setup?token=setup_vafr…
    ║ Expires in 24h; single-use
  3. Create the owner account. Open the link, enter your email and a password of 12 characters or more, and click the button. Then sign in at http://192.168.1.50:2808/login.

  4. Find the firewall’s hardware ID. On the firewall, open Diagnostics → Command Prompt and run:

    Terminal window
    kenv smbios.system.uuid

    Copy the UUID it prints.

  5. Add the device in pfCentral. Click Add in the left rail, paste the UUID, give it a name, and click Add & generate token. Copy the token. It is shown once and expires in one hour.

  6. Install the agent on the firewall. In Diagnostics → Command Prompt (or over SSH as root), run the installer with your server address and the token:

    Terminal window
    fetch -o - https://github.com/danielmichaels/pf-central-artifacts/releases/latest/download/install.sh \
    | NATS_URL=nats://192.168.1.50:24222 \
    ENROLL_URL=http://192.168.1.50:2808/enroll \
    BOOTSTRAP_TOKEN=device_paste_your_token_here \
    sh
  7. Watch it come online. Within a few seconds the device in pfCentral changes from Awaiting enrollment to Online, and the overview starts to show live CPU, memory and traffic.

SymptomLikely cause
The sign-in page reloads with no errorPFCENTRAL_COOKIE_SECURE is not false on plain HTTP, or the URL you use is not in PFCENTRAL_TRUSTED_ORIGINS.
No setup link in the logsIt is printed only on the very first start. Run docker compose exec pf-central pf-central admin setup token for a new one.
Device stays Awaiting enrollmentThe firewall cannot reach port 2808, or the token expired. Generate a new token from the device page.
Enrolled but offlineThe firewall cannot reach port 24222. Check host firewall rules and the NATS_URL.

More in Troubleshooting.