A modern CV management system built on Payload CMS 3, designed for companies to create, manage, and export professional CVs.
- Multi-language support — German and English with localized content
- Flexible skill system — Organize skills in hierarchical groups with customizable proficiency levels
- PDF export — Generate professional PDFs with customizable branding and layout
- Multiple databases — MongoDB, PostgreSQL, or SQLite
- S3 storage — Optional cloud storage for media files
- OAuth integration — Single sign-on with your identity provider
- Multi-tenant — Manage CVs across multiple organizations
Ready-to-use configurations are provided in the docker-compose directory for MongoDB, PostgreSQL, and SQLite setups.
-
Copy the environment file:
curl -o .env https://raw.githubusercontent.com/tegonal/cv-manager/refs/heads/main/.env.example
-
Set required values in
.env:PAYLOAD_SECRET=your-strong-secret-here DATABASE_URI=postgres://user:pass@localhost:5432/cvmanager -
Start the application using one of the provided docker-compose configurations.
| Variable | Description |
|---|---|
PAYLOAD_SECRET |
Strong secret for encryption (required) |
DATABASE_URI |
Database connection string (see below) |
The adapter is auto-selected based on the URI scheme:
| Database | URI Format |
|---|---|
| PostgreSQL | postgres://user:pass@host:5432/db |
| MongoDB | mongodb://user:pass@host:27017/db |
| SQLite | file:///path/to/database.db |
For production deployments, configure S3-compatible storage:
S3_ENDPOINT=https://s3.example.com
S3_BUCKET=cv-manager-media
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
S3_REGION=us-east-1Without S3 configuration, files are stored locally in LOCAL_MEDIA_STORAGE_DIR (default: /data/media). Ensure this path is a mounted volume in Docker deployments.
Configure SMTP for password recovery emails:
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASS=your-smtp-password
SMTP_FROM_ADDRESS=[email protected]Without SMTP, password recovery tokens are printed to the application logs.
Enable single sign-on with your identity provider:
OAUTH_ENABLED=true
OAUTH_CLIENT_ID=your-client-id
OAUTH_CLIENT_SECRET=your-client-secret
OAUTH_TOKEN_ENDPOINT=https://auth.example.com/token
OAUTH_AUTHORIZE_ENDPOINT=https://auth.example.com/authorize
OAUTH_USERINFO_ENDPOINT=https://auth.example.com/userinfoConfigure PDF appearance through the admin panel without code changes:
| Setting | Options |
|---|---|
| Company Info | Name, address, city, website |
| Logo | Upload, width (mm), position (left/right), display (first page/all pages) |
| Typography | Font family (Rubik, Open Sans, Lato, Roboto, Merriweather, Playfair Display) |
| Colors | Primary color (borders, highlights), secondary color (skill indicators) |
| Skill Levels | Display as text, dots, or progress bars |
| Page Layout | Margins (top, bottom, left, right in mm), format (A4/Letter) |
For advanced customization, create your own PDF template:
-
Copy the example template:
cp src/payload/plugins/cv-pdf-generator/templates/custom-template/index.tsx.example \ src/payload/plugins/cv-pdf-generator/templates/custom-template/index.tsx
-
Customize the React components (uses react-pdf)
-
Rebuild:
yarn build
The default template at templates/default/index.tsx serves as a reference. Shared utilities in templates/lib/ provide date formatting, Lexical rich-text rendering, and Tailwind CSS helpers.
Set up these entities before creating CVs:
| Entity | Purpose |
|---|---|
| Organizations | Companies you create CVs for |
| Skill Groups | Categories like "Programming Languages", "Frameworks" |
| Skills | Individual skills within groups |
| Levels | Proficiency levels (e.g., Junior, Senior, Expert) |
| Languages | Spoken languages with proficiency |
| Projects | Shared project references |
Each CV contains:
| Section | Content |
|---|---|
| Profile | Personal info, contact details, links |
| Skills | Hierarchical skill groups with levels |
| Education | Degrees, certifications, training |
| Experience | Project history with descriptions |
Skills can be nested to match different career profiles:
Frontend Developer:
Frontend Technologies
├── React — Expert
├── Vue.js — Senior
└── Angular — Junior
Full Stack Developer:
Full Stack Development
├── Backend Frameworks — Expert
│ └── Spring, Node.js, Django
├── Databases — Senior
│ └── PostgreSQL, MongoDB
└── Frontend — Advanced
└── React, Vue.js
nvm use
yarn install
yarn run services:start # Start local Docker servicesyarn run dev:postgres # or dev:mongodb, dev:sqliteOr with custom .env:
cp .env.example .env
# Edit .env with your settings
yarn run devyarn run check # Lint, format, and type-checkAfter schema changes, generate migrations for all adapters:
yarn run migrate:create:all