Self-Hosting ReviewInbox
ReviewInbox self-hosting uses Docker Compose with separate web, api, worker, and postgres services. Run it behind your own HTTPS reverse proxy on a VPS.
ReviewInbox is in early alpha. Pin a semver release and read release notes before upgrading.
Requirements
Section titled “Requirements”- A Linux VPS with Docker and Docker Compose.
- A domain name pointing to the VPS.
- An HTTPS reverse proxy such as Traefik, Caddy, or Nginx.
- A pinned ReviewInbox release version, for example
0.1.0.
Install
Section titled “Install”Create an application directory:
sudo mkdir -p /opt/reviewinboxsudo chown "$USER":"$USER" /opt/reviewinboxcd /opt/reviewinboxDownload the Compose and environment files:
curl -fsSLO https://raw.githubusercontent.com/reviewinbox/reviewinbox/main/docker-compose.self-hosted.ymlcurl -fsSLo .env.self-hosted https://raw.githubusercontent.com/reviewinbox/reviewinbox/main/.env.self-hosted.exampleGenerate secrets:
openssl rand -base64 32 # BETTER_AUTH_SECRETopenssl rand -base64 32 # APP_ENCRYPTION_KEYEdit .env.self-hosted:
nano .env.self-hostedchmod 600 .env.self-hostedSet these required values:
REVIEWINBOX_VERSION: the exact semver release to run.APP_PUBLIC_URL: your public HTTPS origin, for examplehttps://reviewinbox.example.com.BETTER_AUTH_URL: the same public HTTPS origin when using one domain.BETTER_AUTH_TRUSTED_ORIGINS: the same public HTTPS origin.BETTER_AUTH_SECRET: one generated base64 value.APP_ENCRYPTION_KEY: one generated base64 value. This encrypts Store Credentials.POSTGRES_PASSWORD: a strong database password.
Do not commit .env.self-hosted, attach it to support tickets, or include it in broad log bundles. It contains credentials for auth, Store Credential encryption, Postgres, SMTP, AI, and object storage.
Start the stack:
docker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml up -dCheck service status:
docker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml psdocker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml logs -f apiAI Drafting
Section titled “AI Drafting”AI drafting is optional. Without it, ReviewInbox still imports Reviews and supports manual Reply Draft editing, but it will not generate autogenerated Reply Drafts.
Enable AI-generated Reply Drafts with an OpenAI-compatible provider:
AI_PROVIDER=openai-compatibleAI_MODEL=gpt-4.1-miniAI_API_KEY=your-provider-keyAI_BASE_URL=Set AI_BASE_URL only when your provider requires a custom OpenAI-compatible endpoint.
Reverse Proxy Model
Section titled “Reverse Proxy Model”Use one public domain:
- Route
/api/*to127.0.0.1:3000. - Route all other requests to
127.0.0.1:8080.
This keeps Better Auth cookies and browser requests simple. The web container calls the API through relative /api paths by default.
reviewinbox.example.com { reverse_proxy /api/* 127.0.0.1:3000 reverse_proxy 127.0.0.1:8080}Caddy manages HTTPS automatically when the domain points to the VPS.
server { listen 80; server_name reviewinbox.example.com;
location /api/ { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}Use Certbot or your preferred ACME client to enable HTTPS.
Traefik
Section titled “Traefik”If Traefik runs on the same Docker host, attach ReviewInbox services to your Traefik network and add labels with a compose override:
services: api: networks: - default - traefik labels: traefik.enable: "true" traefik.http.routers.reviewinbox-api.rule: Host(`reviewinbox.example.com`) && PathPrefix(`/api`) traefik.http.routers.reviewinbox-api.entrypoints: websecure traefik.http.routers.reviewinbox-api.tls.certresolver: letsencrypt traefik.http.services.reviewinbox-api.loadbalancer.server.port: "3000"
web: networks: - default - traefik labels: traefik.enable: "true" traefik.http.routers.reviewinbox-web.rule: Host(`reviewinbox.example.com`) traefik.http.routers.reviewinbox-web.entrypoints: websecure traefik.http.routers.reviewinbox-web.tls.certresolver: letsencrypt traefik.http.services.reviewinbox-web.loadbalancer.server.port: "80"
networks: traefik: external: trueUpgrades
Section titled “Upgrades”Update the version pin in .env.self-hosted:
REVIEWINBOX_VERSION=0.1.1Pull and restart:
docker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml pulldocker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml up -dThe API service runs pending database migrations on startup in the self-hosted compose file. Keep this to one API instance unless migrations are moved to a dedicated deployment job.
Backups
Section titled “Backups”Back up Postgres and uploaded files regularly.
Create a database dump:
docker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml exec -T postgres pg_dump -U reviewinbox reviewinbox > reviewinbox.sqlList named volumes:
docker volume ls | grep reviewinboxBack up the postgres-data and uploads volumes with your VPS backup tooling.
Operations
Section titled “Operations”View logs:
docker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml logs -f api worker webRestart one service:
docker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml restart workerStop the stack:
docker compose --env-file .env.self-hosted -f docker-compose.self-hosted.yml down