Deployment guide

Self-Host Reactive Resume on a VPS: Build and Share Your CVs

Deploy on a VPS Cloud →

Tutorial

Self-Host Reactive Resume on a VPS: Build and Share Your CVs

Self-hosting7 min read6 steps

Reactive Resume is an open-source (MIT) resume builder with over 42,000 GitHub stars. Since v5.1.0, it generates PDFs entirely in the browser — no server-side print service required. The result: two lightweight containers are enough for a full instance, and a 1 GB RAM VPS can host your resume tool without compromise.

Contents· Why self-host a resume builder1/9
  1. 01Why self-host a resume builder
  2. 02What you get with a self-hosted Reactive Resume
  3. 03Requirements
  4. 04Deploy Reactive Resume on your VPS
  5. 05The v5.1.0 shift: client-side PDF, no print server
  6. 06Keep your auth secret safe
  7. 07Use the REST API to automate your exports
  8. 08Backup and data portability
  9. 09Troubleshooting common errors

Why self-host a resume builder

SaaS resume tools monetise your career history, limit template access or charge for PDF downloads. Self-hosting Reactive Resume inverts the model: your resumes, photos and exports stay in a Docker volume on your VPS, exportable at any time via the UI or REST API, and shareable under your own domain. No template limits, no watermarks, no subscription dependency.

Self-hosting also gives you full control over the sensitive data a resume contains — personal contact details, employment history, skills. This data never transits through or is stored by a third party.

What you get with a self-hosted Reactive Resume

  • Browser-based drag-and-drop visual editor — no app to install, works on any device.
  • Professionally designed ATS-friendly templates — multiple layouts for different industries and experience levels.
  • Client-side PDF export since v5.1.0 — no Chrome, Puppeteer or Browserless server-side.
  • Public resume URL — share your profile on a readable, always-updated link.
  • Multiple resumes per account — maintain separate CVs for different roles or languages.
  • REST API — create and export resumes programmatically for HR tool integration.
  • Local storage — uploads (photos, portfolio images) written to a Docker volume, no S3 needed.
  • Optional OAuth authentication — connect a GitHub or Google account by adding the corresponding API keys to the configuration.

Requirements

A ServOrbit VPS with Ubuntu 24.04 and at least 1 GB RAM. The Node.js application idles around 300 MB and PostgreSQL 16 adds 100–200 MB — a 1 GB VPS handles a personal or small-team deployment comfortably.

Docker and Docker Compose are provisioned automatically by AWX at deploy time. A domain name is required: Reactive Resume anchors its authentication URL (APP_URL) at first start and cannot function behind a bare IP address.

If you plan to enable email-based account verification, an outgoing SMTP server is recommended. Without SMTP, the verification link is printed to Docker logs — practical for solo use, less suitable if you open access to other users.

Deploy Reactive Resume on your VPS

  1. Choose your domain before deploying

    Reactive Resume embeds APP_URL in authentication tokens and OAuth callbacks at first start — changing the domain afterwards breaks all sessions and requires deleting the PostgreSQL volume. Create your DNS A record (e.g. cv.yourdomain.com) and wait for propagation before deploying.

  2. One-click deploy from the ServOrbit Marketplace

    Open your ServOrbit control panel, go to Marketplace → Collaboration & Productivity → Reactive Resume, enter your domain and click Deploy. AWX installs Docker, generates a random auth secret, configures nginx with Let's Encrypt TLS and starts both containers (app + PostgreSQL) in under two minutes.

  3. Create your account and verify your email

    Navigate to https://cv.yourdomain.com and click Sign Up to create your account with email and password. Without SMTP configured, the verification link is printed to the Docker logs: docker compose logs reactive-resume | grep verify. Click the link to activate your account.

  4. Create your first resume

    Click the + button to create a new resume. Choose a template from the library, fill in your sections (Summary, Experience, Education, Skills) in the left panel and preview in real time on the right. Click Download to export a PDF — generation is fully client-side, no waiting for a print server.

  5. Share your resume publicly

    In the resume settings, toggle Public Resume ON. Reactive Resume generates a shareable URL — https://cv.yourdomain.com/r/your-name — that always serves the latest version of your document. Share this link in job applications instead of attaching a static PDF that you'd have to resend after every update.

  6. Configure OAuth authentication (optional)

    To allow sign-in via GitHub or Google, add the corresponding environment variables to your deployment configuration: GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET. Then restart the containers with docker compose restart. The social login buttons appear automatically on the sign-in page as soon as the variables are present.

The v5.1.0 shift: client-side PDF, no print server

Before v5.0, Reactive Resume depended on Browserless or a headless Chromium instance to generate PDFs server-side — adding 700 MB to 1 GB of RAM overhead and a dependency to maintain. Since v5.1.0, PDF generation is handled by @react-pdf/renderer, a JavaScript library running directly in the user's browser. The server only receives a document-save request — no Chrome, no Puppeteer, no print service required. This is what reduces the minimal stack to two lightweight containers.

Keep your auth secret safe

The ServOrbit deployment automatically generates a random value for SECRET_KEY. Never reuse a predictable value or share one between multiple instances. If you suspect a compromise, regenerate this key and restart the containers: all active sessions will be invalidated, forcing users to sign in again — this is the expected behaviour.

Use the REST API to automate your exports

Reactive Resume exposes a full REST API, accessible at /api/v3. You can create resumes, update them and trigger PDF exports programmatically — useful for integrating resume generation into an HR workflow or an automated application pipeline.

To authenticate, retrieve a JWT token via POST /api/v3/auth/login with your credentials. Then pass this token in the Authorization: Bearer <token> header of each request.

Example — list your resumes:

curl -s -H "Authorization: Bearer <your-token>" \
  https://cv.yourdomain.com/api/v3/resume | jq '.[].title'

Full API documentation is available in the official repository.

Backup and data portability

Two Docker volumes hold the entire instance: reactive_resume_db for the PostgreSQL database (accounts, resumes, settings) and reactive_resume_data for uploaded files (profile photos, portfolio images). Minimal backup:

docker run --rm \
  -v reactive_resume_db:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/db.tar.gz /data

For a direct SQL export: docker exec db pg_dump -U postgres postgres > backup.sql

Restore by mounting the volume on a fresh PostgreSQL container configured with the same public URL. Schedule these backups with a daily cron or use your VPS volume snapshot service for automatic coverage.

Troubleshooting common errors

Incorrect APP_URL after a domain change. Symptom: OAuth callbacks fail or the verification link points to the old domain. Fix: update APP_URL in the configuration, then delete the PostgreSQL volume (docker volume rm reactive_resume_db) and restart. All data will be lost — plan this step before creating production accounts.

App container restarting in a loop. Check the logs with docker compose logs reactive-resume. The most common error is a refused PostgreSQL connection (Connection refused to db:5432): the app container starts before PostgreSQL is ready. Wait 30 seconds and run docker compose up -d again.

PDF generated with incorrect layout. PDF rendering is handled client-side by @react-pdf/renderer and depends on your browser's rendering engine. If the output looks off, try a different browser (recent Chrome or Firefox). Old browsers or extensions that alter fonts can affect rendering.

secretOrPrivateKey must have a value error at startup. The SECRET_KEY variable is missing from the configuration. Add it with a random value of at least 32 characters: openssl rand -hex 32 generates a suitable value.

Public resume URL returning 404. Check that the resume is marked as public in its settings. If it is, check your nginx configuration: the location /r/ block must proxy to the Next.js frontend, not to the API.

Deploy Reactive Resume on your own server

Self-host Reactive Resume on a ServOrbit VPS — open source, no subscription, all your CV data on your own infrastructure.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab