Stack256 · 005

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/health runs a real query against your database — not just whether the process is alive. The container’s own Docker HEALTHCHECK uses 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.

  1. 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
  2. Set two values

    APP_SECRET (32+ random characters, from openssl rand -base64 36) and APP_URL. Everything else has a working default.

  3. Start it

    This pulls both images, starts PostgreSQL, applies migrations, and leaves the app and worker running.

    docker compose up -d
  4. 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.