Reactive Resume¶
Reactive Resume is a one-of-a-kind resume builder that keeps your privacy in mind.
Installation¶
Default Port: 3000
Config¶
homelab/docker/reactive-resume/.env
CONTAINER_NAME=reactive-resume
# -- Postgress --
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
# -- Minio --
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
# -- Auth --
ACCESS_TOKEN_SECRET=access_token_secret
REFRESH_TOKEN_SECRET=refresh_token_secret
# -- Storage (Minio) --
STORAGE_ACCESS_KEY=minioadmin
STORAGE_SECRET_KEY=minioadmin
# -- Chrome --
CHROME_TOKEN=chrome_token
# -- age backup --
AGE_PUBLIC_KEYS=age123456
homelab/docker/reactive-resume/compose.yaml
---
services:
# Database (Postgres)
postgres:
image: postgres:16-alpine
restart: unless-stopped
env_file:
- .env
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: postgres
POSTGRES_USER: "${POSTGRES_USER}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_PASSWORD} -d postgres"]
interval: 10s
timeout: 5s
retries: 5
# Storage (for image uploads)
minio:
image: minio/minio:RELEASE.2025-05-24T17-08-30Z
restart: unless-stopped
command: server /data
ports:
- "9000:9000"
volumes:
- minio_data:/data
environment:
MINIO_ROOT_USER: "${MINIO_ROOT_USER}"
MINIO_ROOT_PASSWORD: "${MINIO_ROOT_PASSWORD}"
# Chrome Browser (for printing and previews)
chrome:
image: ghcr.io/browserless/chromium:v2.18.0 # Upgrading to newer versions causes issues
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
TIMEOUT: 10000
CONCURRENT: 10
TOKEN: "${CHROME_TOKEN}"
EXIT_ON_HEALTH_FAILURE: true
PRE_REQUEST_HEALTH_CHECK: true
# https://offen.github.io/docker-volume-backup/
backup_postgres: &backup_service
image: offen/docker-volume-backup:v2.43.3
environment: &backup_environment
BACKUP_FILENAME: backup-%Y-%m-%dT%H-%M-%S.tar.gz
BACKUP_LATEST_SYMLINK: backup-postgres-latest.tar.gz
BACKUP_PRUNING_PREFIX: backup-postgres-
BACKUP_RETENTION_DAYS: '14'
AGE_PUBLIC_KEYS: "${AGE_PUBLIC_KEYS}"
BACKUP_STOP_DURING_BACKUP_LABEL: service-postgres
volumes:
- postgres_data:/backup/my-app-backup:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
# - ${HOME}/backups:/archive
- /mnt/storage/backup/reactive-resume:/archive
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
backup_minio:
<<: *backup_service
environment:
<<: *backup_environment
BACKUP_FILENAME: backup2-%Y-%m-%dT%H-%M-%S.tar.gz
BACKUP_LATEST_SYMLINK: backup-minio-latest.tar.gz
BACKUP_PRUNING_PREFIX: backup-minio-
BACKUP_STOP_DURING_BACKUP_LABEL: service-minio
volumes:
- minio_data:/backup/my-app-backup:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
# - ${HOME}/backups:/archive
- /mnt/storage/backup/reactive-resume:/archive
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
reactive-resume:
image: ghcr.io/amruthpillai/reactive-resume:v4.4.5
restart: unless-stopped
ports:
- "3000:3000"
depends_on:
- postgres
- minio
- chrome
env_file:
- .env
environment:
# -- Environment Variables --
PORT: 3000
NODE_ENV: production
# -- URLs --
PUBLIC_URL: http://192.168.2.147:3000
STORAGE_URL: http://192.168.2.147:9000/default
# -- Printer (Chrome) --
CHROME_TOKEN: "${CHROME_TOKEN}"
CHROME_URL: ws://chrome:3000
# -- Database (Postgres) --
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/postgres
# -- Auth --
ACCESS_TOKEN_SECRET: ${ACCESS_TOKEN_SECRET}
REFRESH_TOKEN_SECRET: ${REFRESH_TOKEN_SECRET}
# -- Emails --
MAIL_FROM: noreply@localhost
# SMTP_URL: smtp://user:pass@smtp:587 # Optional
# -- Storage (Minio) --
STORAGE_ENDPOINT: minio
STORAGE_PORT: 9000
STORAGE_REGION: us-west-1 # Optional
STORAGE_BUCKET: default
STORAGE_ACCESS_KEY: "${STORAGE_ACCESS_KEY}"
STORAGE_SECRET_KEY: "${STORAGE_SECRET_KEY}"
STORAGE_USE_SSL: false
STORAGE_SKIP_BUCKET_CHECK: false
# -- Crowdin (Optional) --
# CROWDIN_PROJECT_ID:
# CROWDIN_PERSONAL_TOKEN:
# -- Email (Optional) --
# DISABLE_SIGNUPS: "false"
# DISABLE_EMAIL_AUTH: "false"
# -- GitHub (Optional) --
# GITHUB_CLIENT_ID: github_client_id
# GITHUB_CLIENT_SECRET: github_client_secret
# GITHUB_CALLBACK_URL: http://localhost:3000/api/auth/github/callback
# -- Google (Optional) --
# GOOGLE_CLIENT_ID: google_client_id
# GOOGLE_CLIENT_SECRET: google_client_secret
# GOOGLE_CALLBACK_URL: http://localhost:3000/api/auth/google/callback
# -- OpenID (Optional) --
# VITE_OPENID_NAME: OpenID
# OPENID_AUTHORIZATION_URL:
# OPENID_CALLBACK_URL: http://localhost:3000/api/auth/openid/callback
# OPENID_CLIENT_ID:
# OPENID_CLIENT_SECRET:
# OPENID_ISSUER:
# OPENID_SCOPE: openid profile email
# OPENID_TOKEN_URL:
# OPENID_USER_INFO_URL:
volumes:
minio_data:
postgres_data:
Traefik¶
homelab/pve/traefik/conf.d/reactive-resume.yaml
---
http:
#region routers
routers:
reactive-resume:
entryPoints:
- "websecure"
rule: "Host(`resume.l.nicholaswilde.io`)"
middlewares:
- default-headers@file
- https-redirectscheme@file
tls: {}
service: reactive-resume
#endregion
#region services
services:
reactive-resume:
loadBalancer:
servers:
- url: "http://192.168.2.147:3000"
passHostHeader: true
#endregion
middlewares:
https-redirectscheme:
redirectScheme:
scheme: https
permanent: true
default-headers:
headers:
frameDeny: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https
default-whitelist:
ipAllowList:
sourceRange:
- "10.0.0.0/8"
- "192.168.0.0/16"
- "172.16.0.0/12"
secured:
chain:
middlewares:
- default-whitelist
- default-headers
Task List¶
task: Available tasks for this project:
* backup: Backup volume data
* decrypt: Decrypt .env using SOPS
* encrypt: Encrypt .env using SOPS
* export: Export the task list
* init: Init .env file
* pull: Pull docker images
* restart: Restart Docker containers
* status: Docker container status
* stop: Stop Docker containers
* up: Run Docker compose in the foreground.
* up-d: Run Docker compose in the background.
* update: Update running containers
* upgrade: Upgrade Docker containers
* watch: Watch Docker container logs