Skip to content
selfhostitPublic

About

No description, website, or topics provided.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

should-we logo

should-we

Pick one option together.

Buy me a coffee

should-we on a phone: start a decision, share the link, say what matters, rate the options, see one ranking

Rank options (homes, cars, holiday spots, anything) when several people need to agree. Everyone says how much each point matters to them and rates every option. should-we weights each person's ratings by their own priorities and combines everyone into one ranking.

  • No accounts. Start a decision, share its link. Whoever has the link picks a name and takes part.
  • Phone first. Installable as an app ("Add to Home Screen"), saves as you tap, refreshes every few seconds.
  • Self-hosted. One small Docker image with no settings, run the same way as Splitwiz.

Version 2 is a rebuild. The Python version is release v1.0.0; see CHANGELOG.md.

Quickstart

On any machine with Docker (a NAS, a mini PC, your laptop):

mkdir -p should-we/pb_data && cd should-we
curl -O https://raw.githubusercontent.com/selfhostit/should-we/main/docker-compose.yml
docker compose up -d

If port 8091 is taken ("port is already allocated"), put a free port in a .env file next to docker-compose.yml, for example SHOULD_WE_PORT=8095, and your time zone too (TZ=Europe/Athens; the default is Europe/Brussels).

Open http://127.0.0.1:8091, type what you're deciding and what matters, then tap Share and send the link. Everyone picks a name, taps how much each point matters, and rates the options. Results shows the ranking.

To let friends join from their phones anywhere, put it behind HTTPS (see On a Synology NAS).

How it works

  1. Start a decision: what you're deciding, what matters (price, location, …) and your name. Or pick an example.
  2. Share the link. People who open it see who invited them and what they'll be asked to do, then pick a name.
  3. Say what matters: Don't care, A little, Important or Must-have, per point.
  4. Add and rate options, 0 (bad) to 5 (great) on each point.
  5. Results: each person's score for an option is their ratings averaged by their priorities; the option's score is the average over everyone who rated it. Big disagreements are marked "opinions split".

Anyone in the decision can edit the list of what matters later. For a choice that comes back (job hunting, holidays), use Start a new decision like this one at the bottom of a decision: it copies the points and your priorities. Everything is saved in pb_data on your server.

Run it on a home server

The Quickstart commands are all it takes. Put it behind your reverse proxy with HTTPS (Caddy, nginx, DSM, …) to share links outside your home. Data lives in pb_data/ next to the compose file.

On a Synology NAS

  1. Container Manager: install it from Package Center if it is missing.
  2. Folder: in File Station, create docker/should-we/pb_data.
  3. Project: Container Manager > Project > Create, name should-we, path /volume1/docker/should-we, and paste docker-compose.yml. Start it.
  4. Certificate: Control Panel > Security > Certificate > Add > Let's Encrypt, for should-we.<your-name>.synology.me (your Synology DDNS name with should-we. in front). If you already have a certificate for <your-name>.synology.me with "Include wildcard" ticked, it covers this too. No router changes are needed when port 443 already reaches the NAS (for example for Splitwiz).
  5. Reverse proxy: Control Panel > Login Portal > Advanced > Reverse Proxy > Create. Source: HTTPS, should-we.<your-name>.synology.me, port 443. Destination: HTTP, localhost, port 8091. Then assign the certificate to it under Certificate > Settings.
  6. Open https://should-we.<your-name>.synology.me and start a decision.

Updating

Pull the new image and recreate the container (Container Manager: Image > Update, then Project > Action > Build; anywhere else: docker compose pull && docker compose up -d). Or build on your computer and push straight to the NAS:

scripts/deploy-to-nas.sh you@your-nas-address

Images: :2 follows the newest 2.x release, :2.1.0 is that exact release and :edge follows main. Every image has a signed attestation of the workflow and commit that built it; check one with the GitHub CLI: gh attestation verify oci://ghcr.io/selfhostit/should-we:2 --repo selfhostit/should-we.

Backups

Copy the pb_data folder (on a Synology: add /volume1/docker/should-we to a Hyper Backup task). Optional: create an admin with docker exec -it should-we /app/should-we superuser upsert you@example.com 'password' --dir=/app/pb_data to browse the data at /_/ and schedule PocketBase's own backups.

Run it locally

# backend (needs Go 1.27+)
cd backend
go run . serve            # http://127.0.0.1:8090

# web app with hot reload (needs Node 22+), in another terminal
cd web
npm install
npm run dev               # proxies /api to :8090

Tests: cd backend && go test ./... and cd web && npm test && npm run check.

Releasing

Bump version in web/package.json, add a CHANGELOG entry, merge, then publish a GitHub release tagged vX.Y.Z. CI publishes the matching image tags (and moves :2 and :latest), and attests them.

How it is built

Part Choice
Backend PocketBase used as a Go framework (backend/), SQLite database
Rules and scoring backend/decide, unit tested
API backend/app/routes.go: a decision's id is its share link; your browser keeps a token proving which person you are
Web app Svelte 5 + Vite + Tailwind (web/), installable PWA
Packaging One Docker image (Dockerfile), published to ghcr.io/selfhostit/should-we by GitHub Actions

Security and maintenance

  • Not on the internet: the container listens on 127.0.0.1 only; reach it through Tailscale or your own reverse proxy with HTTPS.
  • Locked-down container: it drops every Linux capability and can't gain new ones.
  • Sign-ins and new decisions are rate limited, and the web app sends a Content Security Policy (backend/app/headers.go).
  • Versioned releases with a changelog; the compose file follows the 2 major version, which only moves on a release, so an update never jumps to a breaking one or to unreleased work. Every image has a signed attestation of the commit that built it.
  • Tested on every change in CI, with Actions pinned to commit hashes and every push scanned for committed secrets (gitleaks).
  • No analytics or tracking. The data stays in pb_data on your machine.

Found a security problem? Please write to kalfasyan@pm.me rather than opening an issue (security policy). Security and privacy covers every selfhostit app: what protects an install, what you are trusting and what is not done yet.

Support

If should-we helps you decide, you can buy me a coffee ☕

License

MIT

About

No description, website, or topics provided.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages