Skip to content

Hosting Other

Arael Espinosa edited this page Apr 23, 2026 · 1 revision

Other Deployment Options

Piro ships as self-contained binaries and Docker images, giving you flexibility in how you run it. Below are alternatives to the Docker Compose quickstart.


Self-Contained Binaries

Pre-built binaries are available on the Releases page for:

Platform API Worker
Linux x64
Linux arm64
macOS x64
macOS arm64 (Apple Silicon)
Windows x64

Binaries are self-contained — no .NET runtime required. Download, configure via environment variables, and run.

# Example: run the API on Linux
chmod +x piro-api-linux-x64
DATABASE__CONNECTIONSTRING="Host=localhost;Database=piro;Username=piro;Password=secret" \
AUTH__JWTSECRET="your-secret" \
./piro-api-linux-x64

Kubernetes

Piro can run on Kubernetes. There is no official Helm chart yet, but the Docker images work with standard Deployment + Service manifests.

Key considerations:

  • The API and Worker should be separate Deployments
  • The API needs a persistent volume for wwwroot/uploads (logo/favicon)
  • Workers connect outbound to the API over SignalR — no special networking is required beyond standard egress
  • Use a Kubernetes Secret for Auth__JwtSecret, Database__ConnectionString, and worker tokens
  • Do not scale the API to multiple replicas unless you configure sticky sessions on your ingress (SignalR requires the worker to maintain a connection to the same API pod)

systemd (Bare Metal / VM)

For a traditional Linux server deployment without Docker:

  1. Download the API and Worker binaries for your platform
  2. Create a system user: sudo useradd --system --no-create-home piro
  3. Place the binaries in /opt/piro/
  4. Create an environment file at /etc/piro/api.env:
    Database__ConnectionString=Host=localhost;Database=piro;Username=piro;Password=secret
    Auth__JwtSecret=your-long-secret
    ASPNETCORE_URLS=http://localhost:8080
  5. Create a systemd unit at /etc/systemd/system/piro-api.service:
    [Unit]
    Description=Piro API
    After=network.target postgresql.service
    
    [Service]
    User=piro
    WorkingDirectory=/opt/piro
    EnvironmentFile=/etc/piro/api.env
    ExecStart=/opt/piro/piro-api-linux-x64
    Restart=always
    RestartSec=5
    
    [Install]
    WantedBy=multi-user.target
  6. Enable and start: sudo systemctl enable --now piro-api
  7. Set up nginx or Caddy as a reverse proxy in front of port 8080

Repeat the same pattern for the Worker binary with its own unit file and env file.


Windows Server

The Windows x64 binary runs on Windows Server 2019+ or Windows 10+. You can register it as a Windows Service using sc.exe or NSSM:

# Using NSSM (Non-Sucking Service Manager)
nssm install PiroApi "C:\piro\piro-api-win-x64.exe"
nssm set PiroApi AppEnvironmentExtra "Database__ConnectionString=Host=localhost;..." "Auth__JwtSecret=..."
nssm start PiroApi

Cloud VMs (AWS, GCP, Azure)

Any VM that can run Docker or Linux binaries works. Recommended approach:

  1. Provision a VM (t3.small / e2-small / B1ms or larger)
  2. Install Docker and Docker Compose
  3. Follow the Docker deployment guide
  4. Use the cloud provider's managed PostgreSQL (RDS, Cloud SQL, Azure Database) instead of the bundled container for easier backups and scaling

Platforms That Are Not Supported

The following platforms are not compatible with Piro due to architectural constraints (see Hosting Overview):

  • AWS Lambda / ECS Fargate (task-per-request)
  • Vercel
  • Netlify Functions
  • Cloudflare Workers
  • Railway (ephemeral container restarts may break SignalR)
  • Render Free tier (spins down after inactivity)

Platforms with persistent containers (Railway Pro, Render paid plans, Fly.io) may work but are not officially tested.

Clone this wiki locally