This guide walks you through deploying Reactive Resume — a free, open-source resume builder — on your own VPS. By the end, you’ll have a private, self-hosted instance accessible via your domain, with your data under your control. You’ll need a VPS (any Linux distribution works, Ubuntu 22.04/24.04 recommended), a domain name pointing to your server’s IP, and basic comfort with the command line.
What You’ll Need
- A VPS with at least 1 GB RAM and 10 GB storage (any provider).
- A domain name with an A record pointing to your VPS’s public IP.
- SSH access to the VPS (root or a user with sudo privileges).
- Optional but recommended: a Cloudflare account for free SSL and proxy.
Step-by-Step
- SSH into your VPS
Open a terminal and run:ssh user@your_server_ip. Update the system:sudo apt update && sudo apt upgrade -y. - Install Docker and Docker Compose
Reactive Resume is easiest to run with Docker. Install prerequisites:sudo apt install apt-transport-https ca-certificates curl software-properties-common -y. Add Docker’s official GPG key and repository, then install:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -andsudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable". Thensudo apt install docker-ce docker-compose-plugin -y. Enable Docker to start on boot:sudo systemctl enable docker. - Create a directory for Reactive Resume
Runmkdir -p ~/reactive-resume && cd ~/reactive-resume. - Create a docker-compose.yml file
Use a text editor (e.g.,nano docker-compose.yml) and paste the following:version: '3.8' services: reactive-resume: image: amruthpillai/reactive-resume:latest container_name: reactive-resume ports: - "3000:3000" environment: - NODE_ENV=production - PUBLIC_URL=https://yourdomain.com - DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres - JWT_SECRET=your_strong_secret_here depends_on: - db restart: unless-stopped db: image: postgres:16-alpine container_name: reactive-resume-db environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=postgres volumes: - pgdata:/var/lib/postgresql/data restart: unless-stopped volumes: pgdata:Replace
yourdomain.comwith your actual domain andyour_strong_secret_herewith a long random string (generate one withopenssl rand -hex 32). - Start the containers
Runsudo docker compose up -d. This pulls the images and starts both services. Check status withsudo docker compose ps— both should show “Up”. - Set up a reverse proxy (Nginx)
Install Nginx:sudo apt install nginx -y. Create a site config:sudo nano /etc/nginx/sites-available/reactive-resumeand paste:server { listen 80; server_name yourdomain.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }Enable the site:
sudo ln -s /etc/nginx/sites-available/reactive-resume /etc/nginx/sites-enabled/. Test config:sudo nginx -t, then reload:sudo systemctl reload nginx. - Enable HTTPS with Let’s Encrypt
Install Certbot:sudo apt install certbot python3-certbot-nginx -y. Runsudo certbot --nginx -d yourdomain.comand follow the prompts. This auto-configures SSL and renews it automatically. - Access your instance
Visithttps://yourdomain.com. You should see the Reactive Resume login page. The default admin credentials areadmin@admin.com/admin— change them immediately after first login (go to Profile → Settings → Change Password).
Common Mistakes
- Forgetting to change the default admin password — leaving it as admin/admin is a severe security risk.
- Using a weak JWT_SECRET — a short or guessable secret allows session forgery.
- Not opening port 3000 — if you skip the reverse proxy and try to access directly, ensure your firewall allows port 3000, but using Nginx on port 80/443 is safer.
- Pointing the domain to the wrong IP — make sure the A record points to your VPS’s IPv4 address, not IPv6 unless you’ve configured that.
- Running Docker commands without sudo — if your user isn’t in the docker group, you’ll get permission errors. Add yourself with
sudo usermod -aG docker $USERand log out/in.
Tips
- Back up the PostgreSQL data volume regularly. Use
docker run --rm -v reactive-resume_pgdata:/data -v $(pwd):/backup alpine tar czf /backup/pgdata.tar.gz -C /data .from the project directory. - Use a firewall like UFW:
sudo ufw allow OpenSSH,sudo ufw allow 'Nginx Full',sudo ufw enable. - Set up automatic updates for Docker images with a cron job, but test before applying.
- If you want to use a subdomain like
resume.example.com, just point that subdomain to your VPS and use it in the config. - Consider using a dedicated non-root user for Docker to reduce risk.
Troubleshooting
- Site doesn’t load — Check
sudo docker compose logs reactive-resumefor errors. Verify Nginx is running:sudo systemctl status nginx. Ensure your domain resolves:dig yourdomain.com. - Database connection error — Ensure the
DATABASE_URLmatches the Postgres credentials in the compose file. The host should bedb(the service name), notlocalhost. - Port 3000 already in use — Change the left side of the port mapping in compose (e.g.,
"3001:3000") and update Nginx’s proxy_pass tohttp://localhost:3001. - SSL certificate fails — Make sure port 80 is reachable from the internet. Temporarily disable UFW if needed, then re-enable after certbot.
- Can’t log in after changing password — Clear browser cookies and cache. If still stuck, reset the admin password via the database:
sudo docker exec -it reactive-resume-db psql -U postgres -d postgres -c "UPDATE users SET password = 'new_hash' WHERE email = 'admin@admin.com';"— but this requires generating a bcrypt hash, so it’s easier to reinstall or use the forgot-password flow if available.
Frequently Asked Questions
Is Reactive Resume free to self-host?
Yes, it’s open-source (MIT license) and completely free to self-host. You only pay for your VPS and domain.
Can I use SQLite instead of PostgreSQL?
Reactive Resume officially supports PostgreSQL. SQLite is not recommended because the app expects a relational database with specific features.
How do I update Reactive Resume?
In the project directory, run sudo docker compose pull then sudo docker compose up -d. This pulls the latest image and recreates the container.
Can I use a different reverse proxy like Caddy or Traefik?
Yes, any reverse proxy works. Caddy automatically handles SSL, so you could skip Certbot. Just make sure to proxy to port 3000.
What if I don’t have a domain name?
You can access via IP, but you’ll need to set PUBLIC_URL to http://your_server_ip and use HTTP (not HTTPS) unless you set up a self-signed cert. Many features like OAuth won’t work properly without a domain.
Is it safe to expose this to the internet?
With HTTPS, a strong admin password, and regular updates, it’s reasonably safe. However, consider adding basic authentication via Nginx or using a VPN if you’re the only user.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Delete Picture Kik? How to Remove Photos
- Resin vs FDM Printers for Miniatures: Detail, Durability, Cost
- Are Networked Implants Safe? What If One Fails?
- How to Stop WordPress Comment Spam: A Layered Guide
- What Happens to X Replies, DMs, and Followers After Deletion?
- Data Breaches That Shook the World