· Reborn Foundation

Self-hosting Reborn Apps with Docker Compose

A step-by-step guide to running your own instance of Reborn Apps using Docker Compose.

self-hosting docker guide
Czytaj po polsku →

One of the core benefits of open-source software is the ability to run it yourself. Here’s how to self-host Reborn Apps using Docker Compose.

Prerequisites

  • Docker 25+ with Docker Compose
  • A server with at least 2 GB RAM
  • A domain name and TLS certificate (if you’re exposing the instance to the internet)

Two flows: dev vs production

The repository ships two Docker Compose flows - you need to consciously pick the right one.

FlowSource on host?ImageBoot timeUse case
Development (docker-compose.yml)Required (cloned repo)node:alpine + bind mount + pnpm install at bootSlow first start, HMR afterHacking on the code
Production (docker-compose.prod.yml.example)Not required at runtimePre-built from multi-stage Dockerfile<15 s, no pnpm installRunning your own instance

Important: the default docker-compose.yml is the dev flow. Pasting it into a panel like Portainer/Coolify without a cloned repo on the host will fail with ERR_PNPM_NO_PKG_MANIFEST - the bind mount points at an empty directory. For self-hosting, use the production flow below.

Quick start (production)

git clone https://github.com/fundacja-reborn/reapps.git
cd reapps

cp .env.example .env
cp docker-compose.prod.yml.example docker-compose.prod.yml

Generate secrets and fill in .env:

# Secret generator (one unique value per variable)
openssl rand -base64 48

Minimum values you need to set in .env:

PUBLIC_SITE_URL=https://your-domain.example.com   # or http://your-server-ip
DB_USER=postgres
DB_PASSWORD=<strong-random-password>
DB_NAME=reborn
JWT_SECRET=<openssl rand -base64 48>
REFRESH_TOKEN_SECRET=<openssl rand -base64 48>
SESSION_SECRET=<openssl rand -base64 48>
RECOVERY_KEY_SECRET=<openssl rand -base64 48>

Build and start:

docker compose -f docker-compose.yml -f docker-compose.prod.yml \
  --profile with-notes up -d --build --wait

After startup the containers listen on ports :4200 (re/task) and :4201 (re/notes) on the Docker host.

Reverse proxy and HTTPS

The apps don’t terminate TLS themselves - in production you need a reverse proxy in front that terminates HTTPS and preserves the /task and /notes path prefixes (those make SSO via shared origin work):

  • https://your-domain/task/http://127.0.0.1:4200/task/
  • https://your-domain/notes/http://127.0.0.1:4201/notes/

nginx, Caddy, Traefik, or Cloudflare Tunnel all work - nginx/dev.conf in the repo is a starting point (for production add listen 443 ssl;, certificate paths, HSTS).

The docker-compose.proxy.yml file in the repo is a development proxy on http://localhost:80 - useful for local SSO testing, but it does not replace a production reverse proxy with TLS.

Smoke-testing the production image locally

Before pointing a real domain at a fresh image, you can test the production flow on your own machine:

cp docker-compose.localprod.yml.example docker-compose.localprod.yml

docker compose -f docker-compose.yml -f docker-compose.localprod.yml \
  -f docker-compose.proxy.yml --profile with-notes -p reborn-localprod \
  up -d --build --wait
# → http://localhost/task and http://localhost/notes

This override uses http://localhost as the origin and the dev DB credentials, so it composes cleanly without further configuration.

Portainer, Coolify, Dokploy and other panels

Pasting raw YAML into a panel isn’t enough - the production flow needs the build context (the Dockerfile plus the source tree). Configure the stack so the panel clones the repo from https://github.com/fundacja-reborn/reapps.git instead of pasting YAML into the editor - that way the build has everything it needs. Then point it at two compose files:

  • docker-compose.yml
  • docker-compose.prod.yml.example (copied to docker-compose.prod.yml before deploy)

and pass values from .env through the panel’s environment-variable editor.

Why self-host?

For most users, our public instance is the easiest way to get started - it’s free, always up to date, and supported by the community. Self-hosting is an option for individuals and organizations with specific requirements:

  • Full control - your data stays on your hardware
  • Custom domain - use your own domain name
  • Regulatory compliance - meet internal data residency policies
  • Same encryption - E2E encryption works identically

💡 Whichever option you choose, consider supporting the project - your donation helps develop Reborn Apps for everyone.

Support

If you run into issues, check the self-hosting section in the README or open an issue on GitHub. The community is here to help.