Self-hosting
Fellesly runs as one API process with PostgreSQL behind a TLS reverse proxy. The web app and the marketing site are static files.
With Docker Compose
cp deploy/.env.example deploy/.env # fill in the values, see Configuration
docker compose -f deploy/docker-compose.yml --env-file deploy/.env up -d --buildThis starts Postgres 17 and the API on 127.0.0.1:3000. Put Caddy, nginx or Traefik in front for TLS, for example with Caddy:
api.example.no {
reverse_proxy 127.0.0.1:3000
}Set TRUST_PROXY=1 behind a proxy so rate limits and the admin audit log see client IPs.
One process
The API keeps its working set in memory and mirrors it to Postgres. Run exactly one API process per database.
Web app
EXPO_PUBLIC_API_URL=https://api.example.no pnpm build:webServe apps/app/dist from any static host, with a fallback to index.html. Set the API's APP_URL and CORS_ORIGIN to that address.
Marketing site and documentation
SITE_APP_URL=https://app.example.no pnpm --filter @fellesly/site build # apps/site/dist
pnpm --filter @fellesly/docs build # apps/docs/.vitepress/distThe docs build can also be served as a clean-URL nginx image:
docker build -f deploy/Dockerfile.docs -t fellesly-docs .
docker run --detach --name fellesly-docs --restart unless-stopped \
--publish 127.0.0.1:8082:80 fellesly-docsFor example, proxy docs.fellesly.no to 127.0.0.1:8082. The image serves VitePress pages at clean URLs and returns its generated 404 page for missing routes.
Coolify
Coolify can run the same images: the API from deploy/Dockerfile.api with a Postgres resource, and the web, marketing site and docs images as static sites. Configure the docs service with the docs.fellesly.no domain. Add the variables from Configuration to the API service.