Self-hosted Fider feedback board at feedback.nectenda.com #106
Labels
No labels
area:docs
area:identity
area:ops
area:plugin
area:server
channel:community
channel:direct
channel:owned
channel:press
channel:social
e2ee-constrained
gate:at-ga
gate:pre-ga
marketing
parity
relay:absent
relay:planned
relay:requested
relay:supported
risk:additive
risk:contract
risk:none
usability
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Nectenda/nectenda#106
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
Relay publishes a roadmap and release notes; Peerdraft publishes neither. A
public board where people post and vote on what gets built next is a signal the
product is alive and listening.
Self-hosting it is itself on-message. "Your feature requests do not go to a
SaaS vendor either" is a claim a hosted board cannot make, and GitHub Discussions
cannot make it either, because that route sends users to Microsoft.
Deferred — not being built now. The design below is done; this issue exists
so it is not re-derived. Featurebase's hosted equivalent puts SSO on its
Enterprise tier at $99/seat/month, which is more per month than the entire
infrastructure, so self-hosting remains the right answer whenever this is picked
up.
Why Fider, and not Featul
usefeatul/featulwas evaluated first. It is MIT, does feedback + roadmap +changelog in one, and would theme better (Tailwind 4, React 19). It was rejected
on evidence:
be ours to author, for a Bun/Turborepo monorepo of two Next.js 16 apps.
.env.examplerequires PostHog, Sentry, Upstash Redis, OpenRouter (anLLM key), Cloudflare R2, a GitHub App, passkeys, Stripe with hardcoded plan
price IDs, and a CMS. It is a SaaS codebase with the hosting wired in, not a
self-hostable tool.
whose pitch is that nobody is watching.
Fider: AGPL-3.0, 4,539 stars, active since 2017, Go binary plus Postgres,
official Docker images,
Dockerfileanddocker-compose.ymlin-repo. Note itsreleases page stops at 0.36.1 (July 2024) and looks abandoned — the commit
history does not: last commit 19 September 2026.
Design findings — do not re-derive these
Separate
fider-postgrescontainer, not a second database on GlitchTip's instanceSharing was the first instinct and it is wrong. Every ops mechanism here is keyed
on a service name:
deploy/console/actions.mjs:190takes a snapshot when aSTATEFULops service is upgraded, so a shared instance makes "upgradeglitchtip-postgres" an unannounced statement about Fider's storage too; andsnapshot.sh'spg()targets one container and one database from an env fileholding one credential pair. Cost of separating is near zero — same pinned
digest, so no extra layers, and the measured sibling is 32 MB.
Mount the parent (
/srv/ops/fider-postgres:/var/lib/postgresql), per thePG18
PGDATAcomment already in the compose file, and carry thelogging:block every service there has.
Pin the tagged release, not
:main:maindoes not breakdeploy/inventory.mjs— it blinds it silently, whichis worse.
tagLines('main')returns null, socompare()emits nolagflag andno
lineflag, and the row readsokwith a blank mark, on a tag that moves percommit. That is
louislam/uptime-kuma:1restated, against the file's own rulethat it "never reports a component as current on the strength of an absent
answer". Add a
POLICYentry raising the staleness thresholds, since upstreamtags infrequently while
mainships daily.(The underlying checker gap is filed separately. Checked 23 September 2026:
every pin on the fleet today is numeric, so it is latent rather than live — but
this pin is exactly what would trip it.)
Two earlier readings that were wrong, recorded so they are not repeated
deploy/test/console.test.tsdoes not enforce pinned digests. Nothingdoes.
renovate.json'spinDigests: trueproduces them. There is no test toreconcile and no allowlist to add.
verify-scrubber.shis not weakened by a Fider database. It would sitoutside
pg_dump -d "$PD"either way, so nothing currently asserted becomesweaker. The real scrubber gap is the sign-in shim, filed separately.
AGPL-3.0 — two separate rules
the program. So: no forked image, no baked-in patches, no compiled-in theme.
Configure through env and the admin UI only. That keeps the obligation
upstream's and the digest pin honest.
docs/positioning.mdforbids "open source" of anything. Neverdescribe the board's licence on nectenda.com at all — that is exactly where
the word creeps in. Say what the board does; say nothing about licences.
Skinning
Logo upload plus custom CSS that changes "the design of nearly everything"
(v0.13+). Gilding tokens, and self-host Literata/Karla via
@font-face— thesite removed the Google Fonts CDN deliberately, and reintroducing it on a
subdomain of a privacy product would undo that. This is skinning, not redesign;
the DOM stays Fider's.
SMTP
The existing ops credential is
alerts@nectenda.com, documented as "oneinternal-alerts credential". Fider sends customer-facing mail. Either give it
a
feedback@mailbox or reuse the credential with a distinct from-address andwrite down that the sharing is deliberate. Do not let it default. Note the
smtp+sslvssmtpstrap already documented inglitchtip.env.example.Remaining mechanics
Four-line Caddy vhost matching the existing shape (
encode zstd gzip, barereverse_proxy— nolb_try_*, that is the shard/identity pattern); DNS Arecord, DNS-only;
fider.env.examplecommitted andfider.envgitignoredexplicitly, since
.gitignorelists env files individually with no wildcard;provision-ops.shgains thewrite_filesentry at0600, themkdir, anextension of its placeholder-refusal loop, and the 32 KiB cloud-init guard that
provision-shard.shhas and it does not;UPGRADEABLE.opsandSTATEFULgainboth services; a Kuma monitor;
deploy/README.mdanddeploy/UPGRADES.mdupdated.
Capacity
Ops box is a cx23 at €5.49/month, 2 vCPU / 3.8 GB, measured 11 September 2026
at 440 MB of containers and ~1.0 GB of 3.8 GB used. Fider ~80 MB (single Go
binary, no worker), its Postgres ~35 MB → containers ~555 MB, ~2.7 GB free.
Headroom stays roughly fivefold. Incremental cost €0/month.
These are estimates and the baseline was an idle box. After it is up, run
docker stats --no-streamandfree -mand paste the real numbers intoprovision-ops.sh's comment block, where the last measurement lives.Privacy — the part that matters most
Fider holds email, display name, and every post, comment and vote —
attributed, indefinitely, on a public page. That is a new processing purpose
and a new disclosure.
docs/privacy.mdneeds a paragraph naming the board andstating plainly that posts are public, a row in the location table
(
Feedback board | Germany | our own servers) keeping the one-region claim true,and a retention line.
Verify what Fider actually does on account deletion before writing that line.
If it deletes the user and leaves posts standing, say that, rather than promising
a removal the software does not perform.
A limit to write down rather than discover
Fider reports to nothing. It has no DSN and must not be modified to gain one,
so its exceptions exist only in
docker compose logs fider, capped at 10m × 3.Put that in
UPGRADES.mdas a known limit rather than an incident-time surprise.Verification when this is picked up
caddy validateon the Caddyfile before pushing.node deploy/inventory.mjsshows the pin with a real digest and a markmatching intent. A blank mark with
IN LINE ?means the pin is wrong —that is the blinding failure, not a pass.
on it, reload, then confirm a non-zero row count in
fider-postgresdirectly.
Moved to the Vikunja board as NEC-82: https://projectron.nerchure.com/tasks/82