Self-hosted edition · free

Run Filterping on your own server

The self-hosted edition is free and has no limits: no license key, no property cap. You run the API and PostgreSQL with Docker Compose, and point the app at your server.

The source repository is not public yet. Its address will be published on this page. Until then, REPOSITORY_URL in the commands below stands for it.

What you run

You need Git and Docker with the Compose plugin (Docker Desktop includes it), on a machine that stays on. The API applies its own database migrations when it starts.

Quickstart on your own network

Get the source and create the environment file:

git clone REPOSITORY_URL filterping
cd filterping
cp .env.example .env

Edit .env and replace two values:

The ConnectionStrings__… lines in .env are for running the API outside Docker; Compose does not use them. Then build and start:

docker compose up -d --build
# postgres healthy, api running:
docker compose ps
curl http://localhost:5050/health/live
# {"status":"ok"}

The API listens on port 5050 of this machine. PostgreSQL is reachable only from the machine itself, at 127.0.0.1:55432.

Connect the app

In the Filterping app, open Account → Server address and enter http://<this machine's LAN address>:5050, for example http://192.168.1.20:5050. Then create a homeowner account; it lives only on your server.

This quickstart speaks plain HTTP, so keep it on a network you trust. For access from outside your home, or for cellular readers, set up HTTPS as below.

On a server with HTTPS

The repository's deploy/ folder holds the production stack: Caddy in front (the only published ports, 80 and 443), the API, and PostgreSQL on an internal network. docs/deploy.md is the full runbook, including server hardening, backups and rollback. In short:

  1. Point a DNS A record for your API host name (for example api.example.com) at the server, and wait until it resolves. Caddy requests the certificate on first start.
  2. Create the settings file and fill in API_DOMAIN, ACME_EMAIL, POSTGRES_PASSWORD and IDENTITY_SIGNING_KEY. Each value is explained in the file.
    cp deploy/.env.production.example deploy/.env.production
    chmod 600 deploy/.env.production
    openssl rand -hex 32        # POSTGRES_PASSWORD
    openssl rand -base64 48     # IDENTITY_SIGNING_KEY
  3. deploy/Caddyfile also serves the Filterping website. Delete its website part (the (web_headers) and (web_csp) snippets and the two {$WEB_DOMAIN} blocks), or Caddy keeps asking Let's Encrypt for a certificate for a domain you don't control.
  4. Check the configuration, then build and start:
    docker compose -f deploy/compose.prod.yaml \
      --env-file deploy/.env.production config --quiet
    docker compose -f deploy/compose.prod.yaml \
      --env-file deploy/.env.production up -d --build
    curl https://api.example.com/health/live
    # {"status":"ok"}

Then enter https://api.example.com as the server address in the app.

Updates and backups

To update the quickstart, pull the latest source and rebuild. The API migrates the database on start, and migrations only go forward, so take a backup first:

docker compose exec -T postgres \
  pg_dump -U hvac_nfc_tracker -Fc hvac_nfc_tracker > filterping-backup.dump
git pull
docker compose up -d --build

The user and database names above are the defaults from .env.example; use yours if you changed them. On the HTTPS stack, deploy/backup.sh makes a verified nightly dump, and docs/deploy.md describes updates, restores and rollback.

Readers

Fixed readers are paired from the app. During pairing, the app gives the reader the address of the server it is connected to, so pair readers after the app points at your server.

The cellular (LTE) reader trusts only Let's Encrypt's ISRG Root X1 certificate, so it needs a server with a Let's Encrypt certificate, such as the HTTPS stack above.

Questions

Write to contact@filterping.com. If you would rather not run a server, Filterping Cloud is priced per property.