---
title: "Deploy Feedbacks | (Just Updated) Self-Hosted Website Feedback Capture with REST API & MCP, Owner Pre-Created"
description: "Feedbacks self-hosted feedback capture, REST API, MCP, Postgres"
category: "Other"
url: https://railway.com/deploy/feedbacks-or-just-updated-self-hosted-we
---

# Deploy Feedbacks | (Just Updated) Self-Hosted Website Feedback Capture with REST API & MCP, Owner Pre-Created

Feedbacks self-hosted feedback capture, REST API, MCP, Postgres

**[Deploy Feedbacks | (Just Updated) Self-Hosted Website Feedback Capture with REST API & MCP, Owner Pre-Created on Railway](https://railway.com/template/feedbacks-or-just-updated-self-hosted-we)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/feedbacks-or-just-updated-self-hosted-we/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** Other

## Template content

### postgres

- **Image:** postgres:18.6@sha256:74935e72241653ca55e0414067e6d8763aceb8a810eb51b452253ec3dcfc4336

### feedbacks

- **Image:** ghcr.io/bon5co/feedbacks-railway:0.3.3@sha256:517ee99ac51f290c483c611dd38dd59581a2a5563d610b187203868bc0da4e31
- **Health check:** /readyz
- **Public domain:** Yes

### minio

- **Image:** pgsty/silo:RELEASE.2026-09-16T00-00-00Z
- **Start command:** `/bin/sh -c 'MINIO_BROWSER=off exec silo server /data --address ":${PORT:-8080}"'`
- **Health check:** /minio/health/live
- **Public domain:** Yes

## Documentation

# Deploy and Host Feedbacks on Railway

**Built for an LLM agent to deploy and use.** The deploy form has no fields to fill: the owner account is created from generated credentials at first boot, the object-storage bucket is created for you, and the REST API and MCP server take an agent token that the owner mints with one call. Feedbacks is an open-source, self-hosted website feedback tool: a Chrome extension captures screenshots and annotations, and threads, replies, statuses and agent tokens are served over a REST API and a built-in MCP server, on PostgreSQL.

## About Hosting Feedbacks

This template runs three services: **feedbacks** (the web app, the REST API at `POST /api/OPERATION` (for example `/api/projects.list`) and the MCP endpoint at `/mcp`, behind one public domain), **postgres** (PostgreSQL 18 on a volume mounted at `/var/lib/postgresql`) and **minio** (an S3-compatible store, `pgsty/silo`, on a volume at `/data`).

**Why there is a storage service.** In production Feedbacks refuses local storage and starts only with a private S3 bucket on an HTTPS endpoint. The minio service gets a public Railway domain only because that gives the endpoint its HTTPS; it is not anonymous. Every request needs the generated `MINIO_ROOT_USER` and `MINIO_ROOT_PASSWORD`, and the console is switched off. The feedbacks service creates the `feedbacks` bucket on first boot. Point `S3_HOST`, `S3_ACCESS_KEY_ID` and `S3_SECRET_ACCESS_KEY` at AWS S3, R2 or any other HTTPS S3 endpoint to replace it.

**Created at boot.** A stock image has no owner and no way to make one except a CLI, and it needs a unique `ORGANIZATION_ID`. This template's image creates the owner from `ADMIN_EMAIL` and `ADMIN_PASSWORD`, derives a stable `ORGANIZATION_ID` from the database password, builds `DATABASE_URL`, `APP_ORIGIN` and `S3_ENDPOINT` from the variables, trusts two proxy hops so the real client address reaches the login throttle, and then starts the unmodified upstream server. Sign-up is invite-only.

**What persists.** Projects, feedback threads, replies, accounts and agent tokens live in the PostgreSQL volume; screenshots and attachments live in the minio volume.

**Using the web interface.** Open the public URL and sign in with the `ADMIN_EMAIL` and `ADMIN_PASSWORD` values from the feedbacks service variables. The Chrome extension pairs with the same URL.

### Agent contract

- Public URL: `https://RAILWAY_PUBLIC_DOMAIN` (the generated domain of the `feedbacks` service)
- Private URL: `http://feedbacks.railway.internal:8080`
- Credentials: the variables `ADMIN_EMAIL` and `ADMIN_PASSWORD` on the `feedbacks` service
- Auth: `POST /api/auth.login` (JSON `email`, `password`, header `Origin` equal to the public URL) sets a session cookie and returns `csrf`; with the cookie, the header `X-CSRF-Token` and the same `Origin`, `POST /api/tokens.create` returns an agent token shown once, which is then sent as `Authorization: Bearer TOKEN` on every `/api/OPERATION` and `/mcp` call. Without a valid credential the API answers `401`
- Health: `GET /readyz` returns 200 without credentials

```bash
#!/bin/sh
# needs: SITE_URL (public https URL of the feedbacks service), ADMIN_EMAIL and ADMIN_PASSWORD (its variables); also curl, sed
J='Content-Type: application/json'
O="Origin: $SITE_URL"
JAR=$(mktemp)
CSRF=$(curl -s -c "$JAR" -X POST "$SITE_URL/api/auth.login" -H "$J" -H "$O" -d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}" | sed -n 's/.*"csrf":"\([^"]*\)".*/\1/p')
web() { curl -s -b "$JAR" -X POST "$SITE_URL/api/$1" -H "$J" -H "$O" -H "X-CSRF-Token: $CSRF" -d "$2"; }
curl -s -o /dev/null -w "health: %{http_code}\n" "$SITE_URL/readyz"
curl -s -o /dev/null -w "read without key: %{http_code}\n" -X POST -H "$J" -d '{}' "$SITE_URL/api/projects.list"
curl -s -o /dev/null -w "write without key: %{http_code}\n" -X POST -H "$J" -d '{"name":"x","origins":["https://example.org"]}' "$SITE_URL/api/projects.create"
curl -s -o /dev/null -w "write wrong key: %{http_code}\n" -X POST -H "Authorization: Bearer wrong" -H "$J" -d '{"name":"x","origins":["https://example.org"]}' "$SITE_URL/api/projects.create"
PID=$(web projects.create '{"name":"Agent check","origins":["https://example.org"]}' | sed -n 's/.*"id":"\([^"]*\)".*/\1/p')
echo "project created: $PID"
TOKEN=$(web tokens.create "{\"name\":\"agent\",\"projectIds\":[\"$PID\"],\"scopes\":[\"projects.list\",\"projects.get\",\"threads.list\"]}" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "$J" -d '{}' "$SITE_URL/api/projects.list" | sed -n 's/.*"name":"\(Agent check\)".*/agent key read: \1/p'
rm -f "$JAR"
```

A fresh deploy prints `health: 200`, `read without key: 401`, `write without key: 401`, `write wrong key: 401`, a created project id and `agent key read: Agent check`.

## Why Deploy Feedbacks on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Feedbacks on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

- **Agent-ready** - no deployer fields, a contract block and one script that proves a sign-in, an agent token, an authenticated read and the refusal of a write without a key.
- **Boots from an empty form** - owner, bucket and organization id are created for you, which the stock image cannot do.
- **Data survives redeploys** - PostgreSQL and the object store each sit on a volume.
- **Pinned** - all three images are pinned by digest.
- **Your feedback stays yours** - no SaaS seat pricing, screenshots stay in your own bucket.

## Common Use Cases

- **Website and web-app feedback capture** - testers and customers send annotated screenshots tied to the page and element.
- **Agent-driven triage** - a coding agent lists threads, reads screenshots, replies and updates status over the REST API or MCP.
- **Bug reporting for QA and staging** - collect issues with context from a Chrome extension into one self-hosted inbox.
- **UserSnap or Marker.io alternative** - self-hosted visual feedback without per-seat pricing.

## Dependencies for Feedbacks Hosting

- PostgreSQL, deployed alongside as the `postgres` service, and an S3-compatible bucket, deployed alongside as the `minio` service. A custom domain is optional.

### Deployment Dependencies

- [Feedbacks repository](https://github.com/Softinator-TechLabs/feedbacks-oss)
- [Official Docker image](https://hub.docker.com/r/softinator/feedbacks)
- [MinIO-compatible store image](https://hub.docker.com/r/pgsty/silo)
- [Wrapper image source](https://github.com/bon5co/feedbacks-railway)


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/feedbacks-or-just-updated-self-hosted-we
