Peon
★ 103A self-hosted alternative to Vercel Heroku
About
Community Ratings
No ratings yetNew this week
Read recap →Features
- Git or Docker image deployments over SSH
- one-click service templates
- workspace/project tenancy
- role-based access
- background jobs for deployments and backups
- self-hosted PostgreSQL and queue support
- terminal WebSocket
- cron scheduling
- TLS
- logs
Details
- Last Updated
- Nov 5, 2026
- Created
- Jul 10, 2026
- Install Methods
- dockerdocker-composesource
- Requirements
- Node.js 20+pnpmPostgreSQLAWS SQS or local ElasticMQSES/S3 credentials for email and object storage featuresA Linux server reachable over SSH
- Default Port
- 3000Next.js development server web UI
- Authentication
- local
- API
- REST
- Backup & Export
- built-in-backupdatabase-dump
- Privacy & Independence
- Cloud: Optional
- User Model
- Multi-UserMulti-Tenant
- Deployment
Deployment: Docker Compose ✓6 Containers — moderate hosting footprintRuns as 6 containers
Run Peon yourself
Pick how much you want to manage.
netcupBest match
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
Hetzner
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
DigitalOcean
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
1 more way to host
Some links earn us a commission. netcup pays us one and is our preferred VPS host.
Is this your project? Sponsor a listing
Run Peon with Docker Compose
Compose file from the Peon project repository.
6 services · database: postgres · infra: postgres · 1 unclassified (elasticmq-native)
no resource limits declared
needs persistent storage (3 volumes)
docker-compose.yml · @ 150cdd4 · scanned Nov 3, 2026
# Optional self-host / production-like stack for Peon.
#
# Day-to-day local development usually runs the app on the host:
#
# docker compose --profile db up -d # Postgres
# docker compose --profile sqs up -d # ElasticMQ (local SQS)
# pnpm dev / pnpm worker / pnpm schedule / pnpm socket
#
# Or run the full containerized stack (app + worker + schedule + socket + SQS):
#
# docker compose --profile full up -d
#
# Point `.env` at ElasticMQ when using the local queue (see `.env.example`),
# or leave SQS_ENDPOINT empty to use real AWS SQS.
x-local-sqs-env: &local-sqs-env
SQS_ENDPOINT: http://elasticmq:9324
SQS_DEPLOYMENT_QUEUE_URL: http://elasticmq:9324/000000000000/peon-deployments
SQS_TASKS_QUEUE_URL: http://elasticmq:9324/000000000000/peon-tasks
AWS_ACCESS_KEY_ID: local
AWS_SECRET_ACCESS_KEY: local
services:
postgres:
image: postgres:16-alpine
container_name: peon-postgres
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: peon
ports:
- "5432:5432"
volumes:
- peon_pgdata:/var/lib/postgresql/data
- ./docker/postgres-init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 10
profiles: ["db"]
elasticmq:
image: softwaremill/elasticmq-native
container_name: peon-elasticmq
restart: unless-stopped
ports:
- "9324:9324"
volumes:
- ./docker/elasticmq.conf:/opt/elasticmq.conf:ro
profiles: ["sqs", "full"]
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: peon-app
restart: unless-stopped
command: ["pnpm", "start"]
env_file:
- .env
environment:
<<: *local-sqs-env
ports:
- "3000:3000"
depends_on:
- elasticmq
profiles: ["full"]
worker:
build:
context: .
dockerfile: docker/Dockerfile.worker
container_name: peon-worker
restart: unless-stopped
command: ["node", "--import", "tsx", "worker/index.ts"]
env_file:
- .env
environment:
<<: *local-sqs-env
depends_on:
- elasticmq
profiles: ["full"]
schedule:
build:
context: .
dockerfile: docker/Dockerfile.worker
container_name: peon-schedule
restart: unless-stopped
command: ["node", "--import", "tsx", "worker/schedule.ts"]
env_file:
- .env
environment:
<<: *local-sqs-env
depends_on:
- elasticmq
profiles: ["full"]
socket:
build:
context: .
dockerfile: docker/Dockerfile.worker
container_name: peon-socket
restart: unless-stopped
command: ["node", "--import", "tsx", "worker/socket.ts"]
env_file:
- .env
ports:
- "${TERMINAL_WS_PORT:-8081}:${TERMINAL_WS_PORT:-8081}"
profiles: ["full"]
volumes:
peon_pgdata:
This file may be out of date. Check the Peon documentation for current setup steps.
Tags
Track your self-hosted stack
Bookmark software to try, rate tools you've used, and keep your collection in one place.