Collect feedback under your own domain.
Shapio is an open-source feedback and feature-voting platform. Teams collect product feedback, let users vote on feature requests, track work on a public roadmap, and publish a changelog — all under their own domain, with nothing leaving your server.
What makes it different
Most of these follow from one decision: it is a real application you run on your own server, not a service someone else hosts.
-
Two-host, isolated sessions
The Workspace/Admin app and the Public Portal can run as independent applications with isolated sessions — signing into one never authenticates the other. Or run as one, on a single origin, with no extra configuration.
-
Zero email loss
Email is never sent inline. Every message is written to a durable outbox first, then enqueued — and a reaping cron re-queues anything stuck if the worker dies between the two steps. Your mail arrives, or you find out why.
-
Your secrets stay yours
SMTP credentials, OAuth tokens, and file-storage keys are encrypted at rest and never sent back to the browser after saving. Configuration can be set from the UI or as a fallback in
.env. -
Your storage, your way
Local disk in development; S3 or Cloudflare R2 in production, one setting. Your uploads never leave the storage you chose.
-
An audit trail that fires and forgets
Sign-ins, data exports, and account deletions are logged fire-and-forget — the trail is never allowed to slow the action it records, and never blocks on a downstream failure.
-
Health checks that mean something
GET /api/healthruns a real query against your database — not just whether the process is alive. The container’s own DockerHEALTHCHECKuses it, so a load balancer or uptime monitor sees the same truth your orchestrator does.
Installing it
You need Docker, and nothing else. No separate Node.js or PostgreSQL install — the images are prebuilt and PostgreSQL comes with them.
-
Get the two files
A compose file and an environment file. That is the whole setup.
curl -O https://raw.githubusercontent.com/stack256org/shapio/main/docker-compose.yml curl -o .env https://raw.githubusercontent.com/stack256org/shapio/main/.env.docker.example -
Set two values
APP_SECRET(32+ random characters, fromopenssl rand -base64 36) andAPP_URL. Everything else has a working default. -
Start it
This pulls both images, starts PostgreSQL, applies migrations, and leaves the app and worker running.
docker compose up -d -
Make your own login
A separate, deliberate step, so you see whether it worked rather than it failing quietly inside a background service.
pnpm make:admin you@example.com
You need two images. The app
(ghcr.io/stack256org/shapio) serves traffic, and the
worker (ghcr.io/stack256org/shapio-worker) sends
email and runs background jobs — nothing sends without it.
The compose file starts both for you.
What it needs
| Host | Anything that runs containers — Compose, Coolify, Dokploy, Portainer, Kubernetes, Swarm, ECS |
|---|---|
| Images |
ghcr.io/stack256org/shapio and
ghcr.io/stack256org/shapio-worker
|
| Architectures | amd64 and arm64, in every tag |
| Processes | The app, a worker (background jobs and email), and a one-off migrate step |
| Database | PostgreSQL 16+ — bundled, or point it at your own (Neon, Supabase, RDS) |
| File storage | Local disk, S3, or Cloudflare R2 — one setting |
| Health check |
GET /api/health, unauthenticated, reports
database reachability
|
| Licence | MIT |
Have a look at the code
Shapio is the fifth of 256. The README covers the full product specification, self-hosting, and everything else in detail.