Skip to content

Self Hosting

Arael Espinosa edited this page Apr 23, 2026 · 2 revisions

Self-Hosting Guide

This guide covers deploying Piro on your own infrastructure using Docker Compose, plus the full environment variable reference.


Prerequisites

  • Docker 24+
  • Docker Compose v2
  • A PostgreSQL 17 database (included in the Compose file, or bring your own)

Quick Start

1. Clone the repository

git clone https://github.com/Heva-Co/piro.git
cd piro

2. Configure environment

cp .env.example .env

Edit .env and set at minimum:

POSTGRES_PASSWORD=your_secure_password
JWT_SECRET=replace_with_a_long_random_string_at_least_32_chars
WORKER_TOKEN=generate_after_first_login
ORIGIN=https://status.example.com

3. Start the stack

docker compose up -d
Service Port Description
frontend 3000 Admin panel & public status page
api 8080 Piro REST API
worker Default monitoring worker
db 5432 PostgreSQL

The API applies database migrations automatically on startup.

4. Complete setup

Open http://localhost:3000/setup and create your owner account. After that, sign in at http://localhost:3000/auth/sign-in.

5. Register your worker token

Go to Configuration → Workers → Register Worker, generate a token, and set it as WORKER_TOKEN in your .env, then restart:

docker compose up -d worker

6. Add remote workers (optional)

Deploy additional workers from any region to get multi-region check coverage:

docker run -d --restart unless-stopped \
  -e PIRO_API_URL=https://your-api.example.com \
  -e PIRO_WORKER_TOKEN=<token> \
  -e PIRO_WORKER_REGION=eu-west \
  ghcr.io/heva-co/piro-worker:latest

Or download a self-contained binary from the Releases page — no runtime required.

Updating

docker compose pull
docker compose up -d

Migrations run automatically on each startup.


Docker Images

Image Tags
ghcr.io/heva-co/piro-api latest, v0.1.0, …
ghcr.io/heva-co/piro-worker latest, v0.1.0, …

Both images support linux/amd64 and linux/arm64.


Environment Variable Reference

Piro API

Database

Variable Required Default Description
Database__ConnectionString PostgreSQL connection string. Example: Host=db;Database=piro;Username=piro;Password=secret

Authentication

Variable Required Default Description
Auth__JwtSecret Secret used to sign JWT tokens. Must be at least 32 characters.
Auth__AccessTokenExpiryMinutes 60 Access token lifetime in minutes.
Auth__RefreshTokenExpiryDays 30 Refresh token lifetime in days.

Email (alert triggers)

Variable Required Default Description
Email__Host SMTP host.
Email__Port 587 SMTP port.
Email__UseSsl false Use SSL/TLS.
Email__Username SMTP username.
Email__Password SMTP password.
Email__From Sender address for alert emails.

Observability (optional)

Variable Required Default Description
Sentry__Dsn Sentry DSN for error tracking.
Telemetry__PostHogApiKey PostHog API key for anonymous usage analytics.
Telemetry__Enabled true Set to false to disable telemetry entirely.

Piro Worker

Variable Required Default Description
PIRO_API_URL Base URL of the Piro API. Example: http://api:8080
PIRO_WORKER_TOKEN Worker token from Configuration → Workers → Register Worker.
PIRO_WORKER_REGION default Region label attached to all check results from this worker.

Frontend

Variable Required Default Description
PIRO_API_URL Internal URL of the API (used for SSR requests). Example: http://api:8080
ORIGIN Public URL of the frontend. Used for CORS and redirects. Example: https://status.example.com

Production Checklist

  • JWT_SECRET is a long random string (≥ 32 chars), not the default
  • POSTGRES_PASSWORD is changed from the default
  • Frontend is behind a TLS-terminating reverse proxy (nginx, Caddy, Traefik)
  • API is not exposed directly on port 8080 — proxy it or use a firewall rule
  • api_uploads volume is backed up (contains uploaded logo/favicon)
  • postgres_data volume is backed up regularly
  • Workers use dedicated tokens (one token per worker deployment)

Clone this wiki locally