-
Notifications
You must be signed in to change notification settings - Fork 0
Self Hosting
Arael Espinosa edited this page Apr 23, 2026
·
2 revisions
This guide covers deploying Piro on your own infrastructure using Docker Compose, plus the full environment variable reference.
- Docker 24+
- Docker Compose v2
- A PostgreSQL 17 database (included in the Compose file, or bring your own)
git clone https://github.com/Heva-Co/piro.git
cd pirocp .env.example .envEdit .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.comdocker 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.
Open http://localhost:3000/setup and create your owner account. After that, sign in at http://localhost:3000/auth/sign-in.
Go to Configuration → Workers → Register Worker, generate a token, and set it as WORKER_TOKEN in your .env, then restart:
docker compose up -d workerDeploy 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:latestOr download a self-contained binary from the Releases page — no runtime required.
docker compose pull
docker compose up -dMigrations run automatically on each startup.
| 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.
| Variable | Required | Default | Description |
|---|---|---|---|
Database__ConnectionString |
✅ | — | PostgreSQL connection string. Example: Host=db;Database=piro;Username=piro;Password=secret
|
| 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. |
| 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. |
| 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. |
| 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. |
| 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
|
-
JWT_SECRETis a long random string (≥ 32 chars), not the default -
POSTGRES_PASSWORDis 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_uploadsvolume is backed up (contains uploaded logo/favicon) -
postgres_datavolume is backed up regularly - Workers use dedicated tokens (one token per worker deployment)