Docker Compose

Deploy the Netstamp controller and database with Docker Compose.

The repository’s standard Compose deployment is the recommended starting point for self-hosting. It runs three services:

ServicePurpose
postgresPostgreSQL 16 with TimescaleDB and a persistent named volume
migrateOne-shot database migration using the same Netstamp image version
netstampController, embedded web application, API, and Linux probe install assets

The stack publishes one controller port. It does not include a reverse proxy or TLS automation.

Download the release files

bash
mkdir -p /opt/netstamp
cd /opt/netstamp
curl -fsSLO https://github.com/yorukot/netstamp/releases/latest/download/compose.yaml
curl -fsSLO https://github.com/yorukot/netstamp/releases/latest/download/.env.example
cp .env.example .env
chmod 600 .env

Generate required secrets

Generate five independent values:

bash
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32

Put a different value on each line in .env:

dotenv
DATABASE_PASSWORD=<random value>
LOG_PSEUDONYM_KEY=<random value>
SYSTEM_SETTINGS_ENCRYPTION_KEY=<random value>
AUTH_SESSION_HASH_KEY=<random value>
AUTH_API_TOKEN_HASH_KEY=<random value>

Keep these values stable across restarts and upgrades. Changing a hash key invalidates the associated credentials. Changing the settings encryption key can make stored SMTP and external-provider credentials unreadable.

Start the stack

bash
docker compose pull
docker compose up -d
docker compose ps
docker compose logs migrate

The expected state is:

  • postgres is healthy.
  • migrate exited with status 0.
  • netstamp is running.
  • The published port answers both health endpoints.
bash
curl --fail http://127.0.0.1:3000/healthz
curl --fail http://127.0.0.1:3000/api/v1/healthz

Open http://127.0.0.1:3000 for a local installation. The first account created becomes a system administrator.

Pin image versions

The available image selectors are:

dotenv
NETSTAMP_IMAGE=yorukot/netstamp
NETSTAMP_VERSION=latest
TIMESCALEDB_IMAGE=timescale/timescaledb:2.20.3-pg16
NETSTAMP_PORT=3000

The Compose file attached to a GitHub release defaults to that release’s Netstamp tag. The repository copy uses latest for evaluation. For a controlled installation, pin NETSTAMP_VERSION and TIMESCALEDB_IMAGE to a tested release tag or digest.

The migration and application services always use the same Netstamp image version.

Persistent data

The database lives in the Compose volume logically named netstamp-postgres; Docker normally prefixes its actual name with the Compose project name. Removing containers does not remove the volume.

bash
docker volume ls --filter name=netstamp-postgres
docker compose exec postgres psql -U netstamp -d netstamp -c 'select now();'

Build a local image

To build the release image layout from a checkout:

bash
docker build -f deployments/Dockerfile -t netstamp:local .
NETSTAMP_IMAGE=netstamp NETSTAMP_VERSION=local docker compose up -d

The image includes the controller, migrations, web application, and amd64 and arm64 probe binaries.

Next, review Configuration and complete Reverse proxy and HTTPS before exposing Netstamp publicly.