Documentation Index
Fetch the complete documentation index at: https://docs.rxresu.me/llms.txt
Use this file to discover all available pages before exploring further.
@react-pdf/renderer. New deployments no longer require Browserless, Chromium, or any external print service as a dependency. The PRINTER_* and BROWSERLESS_* environment variables are no longer read and can be removed from your .env.Overview
Reactive Resume can be self-hosted using Docker in a matter of minutes, and this guide will walk you through the process. Here are some of the services you’ll need to get started:PostgreSQL
Email (optional)
Storage (optional)
/app/data.- Docker Hub:
amruthpillai/reactive-resume:latest - GitHub Container Registry:
ghcr.io/amruthpillai/reactive-resume:latest
Minimum requirements
Docker + Docker Compose
Compute
Storage
Quickstart using Docker Compose
Create a new folder (for examplereactive-resume/) with:
compose.yml.env- a persistent data directory for uploads (for example
./data)
Create compose.yml
PORT and serves both the API and the built web app.
The default image uses PORT=3000, so the example maps 3000:3000. If you change
PORT, update the container-side port mapping and health check to match.How startup works (database migrations)
Environment variables
Required
APP_URLDATABASE_URLAUTH_SECRET
Optional
- SMTP (
SMTP_*) - Social auth (
GOOGLE_*,GITHUB_*,LINKEDIN_*,OAUTH_*) - S3 storage (
S3_*) - AI providers and AI Agent workspace (
ENCRYPTION_SECRET,REDIS_URL) - Feature flags (
FLAG_*)
Server
Server
TZ: Sets the container timezone (affects logs and server-side timestamps). Recommended:Etc/UTC.APP_URL: Canonical/public URL for your instance (used for absolute URLs, redirects, and auth flows). If behind a reverse proxy, set this to your public HTTPS URL (for example,https://resume.example.com).PORT: Port the production Docker container listens on. Defaults to3000in the official image. If you change it, update your Compose port mapping and health check from3000to the new container port.SERVER_PORT: Used only for local development when the Vite web app and Hono server run as separate processes. It is ignored by the production Docker image.
Database (PostgreSQL)
Database (PostgreSQL)
DATABASE_URL: Postgres connection string in the formatpostgresql://USER:PASSWORD@HOST:PORT/DATABASE. - In Docker Compose, setHOSTto the Postgres service name (e.g.postgres), notlocalhost. - If your password contains special characters (@,#,:), URL-encode it. - For managed Postgres, add provider-specific params (for example?sslmode=require) when needed.
Authentication
Authentication
AUTH_SECRET: Secret used to secure authentication. Changing it invalidates existing sessions.Generate with:GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET (optional): Enables Google sign-in.GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET (optional): Enables GitHub sign-in.LINKEDIN_CLIENT_ID / LINKEDIN_CLIENT_SECRET (optional): Enables LinkedIn sign-in.BETTER_AUTH_API_KEY (optional): Enables Better Auth dashboard integrations.Custom OAuth provider (optional):OAUTH_PROVIDER_NAME: Display name in the UIOAUTH_CLIENT_ID/OAUTH_CLIENT_SECRET: Required for any custom OAuth providerOAUTH_SCOPES: Space-separated scopes (defaults toopenid profile email)
- Option A — OIDC Discovery (preferred): Set
OAUTH_DISCOVERY_URLto your provider’s.well-known/openid-configurationURL - Option B — Manual URLs: Set all three:
OAUTH_AUTHORIZATION_URL,OAUTH_TOKEN_URL, andOAUTH_USER_INFO_URL
Email (SMTP, optional)
Email (SMTP, optional)
- Email delivery is enabled only when all of
SMTP_HOST,SMTP_USER,SMTP_PASS, andSMTP_FROMare set. SMTP_HOST: SMTP host (if empty, email sending is disabled).SMTP_PORT: Defaults to587in the app.SMTP_USER/SMTP_PASS: SMTP credentials.SMTP_FROM: Default from address (for example,Reactive Resume <[email protected]>).SMTP_SECURE:"true"or"false"(string). Match your provider settings.
Storage (S3 or local)
Storage (S3 or local)
- Default (local): If all
S3_*values are empty, uploads are stored under/app/datain the official image. - Mount local uploads to persistent storage (for example
./data:/app/data) or uploads can be lost on container recreation. LOCAL_STORAGE_PATH(optional): Overrides the local data directory. Defaults to/app/datain the official Docker image and<workspace>/datain development. The container validates this path is writable at startup and refuses to start otherwise.- Rootless Docker:
/app/dataremains the container path. Prefer the named volume from the example Compose file, or make sure a bind-mounted host directory is writable by the container’snodeuser mapping. - S3/S3-compatible: Configure
S3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEY,S3_REGION,S3_ENDPOINT, andS3_BUCKET. - Agent attachments/private objects: The AI Agent workspace requires S3-compatible storage for private objects. Local storage rejects private objects.
S3_FORCE_PATH_STYLEcontrols bucket addressing (defaults to"false"):"true"for path-style URLs (https://endpoint/bucket) common with MinIO/SeaweedFS."false"for virtual-hosted-style URLs (https://bucket.endpoint) common with AWS S3 / Cloudflare R2.
AI features (optional)
AI features (optional)
ENCRYPTION_SECRET is configured. The AI Agent workspace also requires REDIS_URL. The rest of Reactive Resume can run without them.REDIS_URL: Redis connection string used by the AI Agent workspace.ENCRYPTION_SECRET: Secret used to encrypt saved AI provider credentials. Generate withopenssl rand -hex 32.- Live web research depends on the selected AI provider/model supporting native web search. The app does not run its own URL crawler.
REDIS_URL.Feature Flags
Feature Flags
FLAG_DISABLE_SIGNUPS: Disables new signups (web app and server). Useful for private instances.FLAG_DISABLE_EMAIL_AUTH: Disables email/password login entirely. Also disables email verification, forgot password, and reset password flows. Users can still sign up via social auth (Google/GitHub/LinkedIn/Custom OAuth), unless FLAG_DISABLE_SIGNUPS is also set to true. Useful when only SSO is required.FLAG_DISABLE_IMAGE_PROCESSING: Disables image processing. This is useful if you are using a machine with limited resources, like a Raspberry Pi.FLAG_ALLOW_UNSAFE_OAUTH_REDIRECT_URI: Allows dynamic OAuth client registration to use any parseable redirect URI, including custom schemes, private hosts, and non-loopbackhttp://URLs. Warning: enabling this on a public or multi-tenant deployment can enable phishing or token exfiltration. Only enable on trusted, self-hosted deployments.FLAG_ALLOW_UNSAFE_AI_BASE_URL: Allows AI providers to be configured with unsafe, private, or non-public base URLs, includinghttp://and private/loopback addresses (for example, a local Ollama instance athttp://192.168.1.10:11434). Public HTTPS provider URLs remain the safe default. Warning: enabling this on a multi-tenant deployment is an SSRF risk. Only enable on trusted, self-hosted deployments.
Updating your installation
To update your Reactive Resume installation to the latest available version, follow these steps:- Back up your database and uploads first (highly recommended before every update).
-
Pull the latest images for all services defined in your Docker Compose file.
-
Restart the containers to run the new images.
-
Check migration/startup logs after deploy.
-
(Optional) Remove old, unused Docker images to free up disk space.
Backups (recommended)
Regular backups are essential to protect your data. Reactive Resume stores data in two places: the PostgreSQL database and file uploads (either local storage or S3).Database backups
Your PostgreSQL database contains all user accounts, resumes, and application data. For self-hosted deployments, you can usepg_dump to create periodic backups of your database and store them in a secure location. Many hosting providers also offer automated backup solutions for managed PostgreSQL instances, which handle scheduling, retention, and restoration for you.
Upload backups
If you’re using local storage (the./data directory), include this directory in your regular backup routine. A simple approach is to use rsync or a similar tool to copy the directory to a remote server or cloud storage.
If you’re using S3-compatible storage, consider enabling versioning on your bucket to protect against accidental deletions. Most S3 providers also support lifecycle rules for automatic cleanup of old versions and cross-region replication for disaster recovery.
Health Checks
Reactive Resume exposes a health check endpoint at/api/health that verifies the application and its dependencies. It checks database and storage; if either is unhealthy, the endpoint returns HTTP 503.
How it works
The Docker Compose configuration includes a health check that periodically calls the/api/health endpoint:
docker compose ps or docker ps.
Reverse proxy integration
Most reverse proxies (such as Traefik, Caddy, or nginx with upstream health checks) can use Docker’s health status to make routing decisions:- Healthy containers receive traffic as normal
- Unhealthy containers are automatically removed from the load balancer pool
Manually checking health
You can manually verify the health of your Reactive Resume instance:Troubleshooting
The app container exits immediately
The app container exits immediately
- Common cause: database migrations failed (often a bad
DATABASE_URL). - What to do:
Check logs for migration errors and database connectivity details:
Can't sign in / redirects loop / cookies don't stick
Can't sign in / redirects loop / cookies don't stick
PDF export fails or downloads an empty file
PDF export fails or downloads an empty file
- Common cause: PDFs are now rendered in the browser via
@react-pdf/renderer, so failures usually come from a blocked download, an extreme browser memory limit, or a custom CSP that strips inline workers. - Checks: confirm the browser is up to date, the page hasn’t been opened in a restricted iframe, and that no extension is intercepting the download. There is no server-side printer to inspect.
/api/health returns 503 even though Postgres is up
/api/health returns 503 even though Postgres is up
- Common cause: storage health failed (not only database). - Fix: inspect the endpoint response payload and
check the
storagefield: http://127.0.0.1:3000/api/health
Uploads disappear after restart
Uploads disappear after restart
- Cause: local upload storage wasn’t mounted to a persistent volume. - Fix: add a volume mount like
./data:/app/dataand redeploy.
Emails aren't being delivered
Emails aren't being delivered
- Expected behavior: if SMTP isn’t fully configured, the app logs emails to the console. - Fix: set
SMTP_HOST,SMTP_USER,SMTP_PASS, andSMTP_FROM, then verifySMTP_PORTandSMTP_SECURE.
Dynamic OAuth redirect URI is rejected
Dynamic OAuth redirect URI is rejected
- Common cause: redirect URI is not the app origin or a local loopback callback. - Fix: use an app-origin or loopback redirect URI, or enable
FLAG_ALLOW_UNSAFE_OAUTH_REDIRECT_URIonly on a trusted self-hosted deployment that needs arbitrary redirect URIs.
S3 storage error: ENOTFOUND bucket.endpoint
S3 storage error: ENOTFOUND bucket.endpoint
- Common cause: The S3 client is using virtual-hosted-style addressing (prepending the bucket name to the endpoint), but your S3-compatible storage expects path-style addressing.
- Symptom: Error message like
getaddrinfo ENOTFOUND mybucket.s3-server.comwhen your endpoint iss3-server.com. - Fix: Set
S3_FORCE_PATH_STYLE="true"in your environment. This is required for most self-hosted S3-compatible services like MinIO, SeaweedFS, etc.