Skip to main content

Install with Docker

Run pfSense Actions with the repository's Docker Compose file, which builds the image on your host and publishes the console and API on port 22603.

Why Use This Deployment?

  1. Publishes port 22603 on every IPv4 and IPv6 address of the Docker host, so devices on your network can open the console. The HTTPS reverse proxy guide covers a loopback binding that limits it to the Docker host.
  2. Needs no passwords or keys in files, because you create the administrator account in the browser with a one-time setup code from the container log.
  3. Keeps the controller database and its generated encryption key on a named data volume that survives rebuilds.
  4. Runs the service as a non-root user under s6-overlay, with a built-in health check.

Requirements

  • Docker with Compose — Docker Engine with the Compose plugin and BuildKit, on an amd64 or arm64 host.
  • Repository checkout — compose.yml builds the image from the root of the pfSense Actions repository.
  • Prepared pfSense — SSH turned on and an account ready, as described in Prepare pfSense.
  • HTTPS plan — A reverse proxy for any client that isn't on the Docker host, covered in HTTPS Reverse Proxy.

Change the Host Settings

compose.yml works without an environment file. To change the published port, the user the service runs as, or its time zone, copy the root sample file and edit it.

bash
cp .env.sample .env
.env
bash
PFSENSE_ACTIONS_PORT="22603"
PGID="1000"
PUID="1000"
TZ="UTC"

Every variable and its default is listed in the Configuration Reference.

Build and Start

Build the image and start the service from the repository root.

bash
docker compose up --build --detach

npm run deploy:container runs the same command. On the first start, pfSense Actions creates the controller database and an encryption key, which it saves as keys/installation.key in the data volume.

Find the Setup Code

While no administrator account exists, pfSense Actions prints a setup code in its log.

bash
docker compose logs app
text
WARN No administrator account exists yet. Open the console at /admin/ to create it.
WARN Setup code: ABCDE-FGHJK-LMNPQ (valid until 2026-01-01T12:30:00.000Z; restart the container for a new one)
  • The code works once and lasts 30 minutes, and docker compose restart app prints a new one.
  • Anyone who can read the container log can use the code, so it's worth creating the account right after the first start.

Create the Administrator Account

  1. Open http://<docker-host>:22603/admin/, where <docker-host> is the name or address of the machine that runs Docker. Use your PFSENSE_ACTIONS_PORT if you changed it, or your HTTPS address once the proxy is in place.
  2. Enter the One-time code from the log. Letter case, spaces, and dashes don't matter.
  3. Choose a Username and a Password of at least 12 characters, repeat the password in Confirm password, and select Create account. The bar under the field rates it from Weak to Strong, and any password of 12 or more characters is accepted.

The console signs you in right away, and the setup screen doesn't appear again.

Connect pfSense

  1. On Overview, select Set up the connection.
  2. Enter the firewall's IP address, the SSH port, and the SSH username.
  3. Choose Private key or Password under Sign in with, and paste the credential.
  4. Select Test and save.

pfSense Actions saves the connection only after it signs in with it, as described in pfSense Connection.

Create a Token

Create a personal access token with the pfsense:read scope as described in Access Tokens, and copy it while the console shows it.

Verify a Request

Send one connectivity check from the Docker host, keeping the token out of the process list.

bash
read -r -s PFSENSE_ACTIONS_TOKEN

printf 'header = "Authorization: Bearer %s"\n' "$PFSENSE_ACTIONS_TOKEN" \
  | curl --config - --silent --show-error \
      --write-out '\nHTTP %{http_code}\n' \
      http://127.0.0.1:22603/api/v1/connectivity

unset PFSENSE_ACTIONS_TOKEN

HTTP 200 with {"connected":true} means pfSense Actions signed in to the firewall and ran uname -mrs. HTTP 502 means the SSH sign-in or the command failed, which Troubleshooting covers.

Get Alerts

To hear when pfSense stops answering or sign-in is locked, add a notification destination on the console's Notifications page, as described in Notifications.

What the Data Volume Holds

The data volume pfsense_actions_data is mounted at /data and holds two things.

Raw tokens, raw recovery codes, and plaintext passwords or private keys aren't stored anywhere.

warning

The volume holds both the database and the key that decrypts it, so anyone with a copy of the volume can read the stored pfSense credential and notification secrets. Keep volume backups as safe as the firewall credential itself, as described in Backup and Recovery.

info

The image is built on node:24.22.0-trixie-slim, pinned by digest, with s6-overlay 3.2.3.2 downloaded from GitHub and checked against its SHA-256 checksums. Builds for any platform other than amd64 or arm64 stop with an error.