Deploying a FrappeHR App
Introduction
FrappeHR is a modern, open-source Human Resource Management System built on the Frappe Framework. It provides comprehensive HR functionalities including employee management, leave tracking, attendance, payroll, recruitment, and performance reviews. Deploying FrappeHR on Klutch.sh provides you with a scalable, secure infrastructure for managing your organization’s human resources, with support for persistent storage, automated deployments from GitHub, and seamless integration with databases.
This guide walks through deploying FrappeHR on Klutch.sh using a Dockerfile, configuring persistent volumes for data storage, setting up environment variables, and implementing best practices for production deployments.
Prerequisites
Before deploying FrappeHR on Klutch.sh, ensure you have:
- A Klutch.sh account (sign up here)
- A GitHub repository for your FrappeHR deployment
- Basic knowledge of Docker and HR management systems
- Understanding of MariaDB or MySQL database operations
- Familiarity with the Frappe Framework architecture
Understanding FrappeHR Architecture
FrappeHR is built on the Frappe Framework, which uses:
- Python (3.10+) for the backend application logic
- MariaDB/MySQL for database storage
- Redis for caching and background job queuing
- Node.js for building frontend assets
- Nginx as a reverse proxy (handled by Klutch.sh)
The application consists of multiple components that work together to provide a complete HR management solution. When deploying on Klutch.sh, we’ll containerize these components and configure them appropriately.
Deployment Steps
- A
Dockerfilefor building the FrappeHR application - Configuration files for environment-specific settings
- Any custom apps or modifications you want to include
- Store large assets (logs, uploads, backups) outside the Git repository using persistent volumes
- Keep sensitive configuration separate from the codebase
- Document any custom modifications or additional Frappe apps you’re including
- We use the official
frappe/erpnextbase image which includes all necessary dependencies - The FrappeHR app (HRMS) is installed using
bench get-app - Assets are built during the image creation for faster startup
- The application runs as the
frappeuser for security - Health checks ensure the application is running correctly
- Port 8000 is the default port for Frappe applications
- Create a separate MariaDB app on Klutch.sh
- Select TCP traffic type in the Klutch.sh dashboard
- Connect to the database on port 8000 (external) with the internal port set to 3306
- Attach persistent volumes for database storage at
/var/lib/mysql - Note the connection details for use in your FrappeHR app
- Create a new app for Redis
- Use the official Redis Docker image or create a simple Dockerfile:
- Select TCP traffic type
- Set the internal port to 6379
- Optionally attach a persistent volume to
/datafor Redis persistence - Go to your FrappeHR app in the Klutch.sh dashboard
- Navigate to the “Volumes” section
- Click “Add Volume”
- Enter the mount path (e.g.,
/home/frappe/frappe-bench/sites) - Specify the size in GB (e.g., 100)
- Click “Create” to attach the volume
- Never commit sensitive credentials to your repository
- Use Klutch.sh’s secret environment variables for passwords and API keys
- Rotate credentials regularly
- Use strong, unique passwords for database and admin accounts
- Select HTTP traffic type (FrappeHR is a web application)
- Set the internal port to 8000 (Frappe’s default port)
- Klutch.sh will automatically route external traffic to this port
- Push your repository with the Dockerfile and configuration files to GitHub
- In the Klutch.sh dashboard at klutch.sh/app, create a new project if you haven’t already
- Create a new app within your project
- Connect your GitHub repository
- Klutch.sh will automatically detect the Dockerfile and begin building
- Configure the environment variables, volumes, and port settings as described above
- Click “Create” to deploy
- Pull your code from GitHub
- Build the Docker image
- Deploy the container with your configurations
- Mount persistent volumes
- Start the FrappeHR application
- Access your FrappeHR instance at
https://example-app.klutch.sh - Log in using the admin credentials you set in environment variables
- Complete the initial setup wizard:
- Configure your company details
- Set up employee directory
- Configure leave types and policies
- Set up department and designation hierarchies
- Configure payroll settings
- Customize the system according to your organization’s requirements
- Create user accounts for your HR team
1. Prepare Your FrappeHR Repository
Create or fork a GitHub repository for your FrappeHR deployment. Your repository should include:
Important considerations:
Refer to the Klutch.sh Quick Start Guide for detailed instructions on repository setup and GitHub integration.
2. Create the Dockerfile
Klutch.sh automatically detects a Dockerfile if present in the root directory of your repository. Create a Dockerfile in your repository root with the following configuration:
FROM frappe/erpnext:v15
# Set working directoryWORKDIR /home/frappe/frappe-bench
# Install FrappeHRRUN bench get-app --branch version-15 https://github.com/frappe/hrms.git
# Install additional dependencies if neededRUN bench setup requirements
# Build assetsRUN bench build --app hrms
# Create sites directory if it doesn't existRUN mkdir -p /home/frappe/frappe-bench/sites
# Expose the default Frappe portEXPOSE 8000
# Set proper permissionsRUN chown -R frappe:frappe /home/frappe/frappe-bench
# Switch to frappe userUSER frappe
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:8000/api/method/ping || exit 1
# Start commandCMD ["bench", "start"]Dockerfile Explanation:
Alternative: Custom Build
If you need more control, you can build from a base Python image:
FROM python:3.10-slim
# Install system dependenciesRUN apt-get update && apt-get install -y \ git \ wget \ curl \ build-essential \ python3-dev \ libffi-dev \ libssl-dev \ libmysqlclient-dev \ mariadb-client \ redis-tools \ nodejs \ npm \ && rm -rf /var/lib/apt/lists/*
# Install benchRUN pip install frappe-bench
# Create frappe userRUN useradd -m -s /bin/bash frappe
# Switch to frappe userUSER frappeWORKDIR /home/frappe
# Initialize benchRUN bench init frappe-bench --frappe-branch version-15 --python python3.10
# Change to bench directoryWORKDIR /home/frappe/frappe-bench
# Get FrappeHRRUN bench get-app --branch version-15 https://github.com/frappe/hrms.git
# Expose portEXPOSE 8000
CMD ["bench", "start"]3. Configure Database Connection
FrappeHR requires a MariaDB or MySQL database. You can either:
Option A: Use an external managed database (recommended for production)
Set up a managed MariaDB/MySQL instance and configure connection via environment variables:
DB_HOST=your-database-host.example.comDB_PORT=3306DB_NAME=frappehr_productionDB_USER=frappehr_userDB_PASSWORD=your-secure-passwordOption B: Deploy MariaDB on Klutch.sh
4. Set Up Redis
FrappeHR uses Redis for caching and background jobs. Deploy Redis on Klutch.sh:
FROM redis:7-alpine
# Custom Redis configuration if neededCOPY redis.conf /usr/local/etc/redis/redis.conf
EXPOSE 6379
CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]5. Create a New Site
After deploying the FrappeHR container, you need to create a new site. This is typically done as part of the startup process. Create a startup script start.sh:
#!/bin/bashset -e
# Wait for database to be readyecho "Waiting for database..."while ! mysqladmin ping -h"${DB_HOST}" -P"${DB_PORT}" --silent; do sleep 2done
# Wait for Redis to be readyecho "Waiting for Redis..."while ! redis-cli -h "${REDIS_HOST}" -p "${REDIS_PORT}" ping; do sleep 2done
# Change to bench directorycd /home/frappe/frappe-bench
# Check if site exists, if not create itif [ ! -d "sites/${SITE_NAME}" ]; then echo "Creating new site: ${SITE_NAME}" bench new-site ${SITE_NAME} \ --admin-password "${ADMIN_PASSWORD}" \ --db-host "${DB_HOST}" \ --db-port "${DB_PORT}" \ --db-name "${DB_NAME}" \ --db-password "${DB_PASSWORD}" \ --no-mariadb-socket
# Install FrappeHR app bench --site ${SITE_NAME} install-app hrms
# Enable scheduler bench --site ${SITE_NAME} enable-schedulerfi
# Set site as current siteecho ${SITE_NAME} > sites/currentsite.txt
# Start benchexec bench startUpdate your Dockerfile to include this script:
# Add the startup scriptCOPY start.sh /home/frappe/start.shRUN chmod +x /home/frappe/start.sh
CMD ["/home/frappe/start.sh"]6. Configure Persistent Storage
FrappeHR requires persistent storage for several directories. In the Klutch.sh dashboard, attach persistent volumes with the following mount paths and recommended sizes:
| Mount Path | Purpose | Recommended Size |
|---|---|---|
/home/frappe/frappe-bench/sites | Site files, uploads, backups | 50GB - 200GB |
/home/frappe/frappe-bench/logs | Application logs | 10GB - 20GB |
Steps to attach volumes:
Note: You can only specify the mount path and size; volume names are managed automatically by Klutch.sh.
7. Configure Environment Variables
In the Klutch.sh dashboard, configure the following environment variables for your FrappeHR app. Mark sensitive values as secrets to prevent them from being logged.
Required Environment Variables:
# Site ConfigurationSITE_NAME=example-app.klutch.shADMIN_PASSWORD=your-secure-admin-password
# Database ConfigurationDB_HOST=your-mariadb-app.klutch.shDB_PORT=8000DB_NAME=frappehr_dbDB_USER=frappe_userDB_PASSWORD=your-database-password
# Redis ConfigurationREDIS_HOST=your-redis-app.klutch.shREDIS_PORT=8000REDIS_CACHE=redis://your-redis-app.klutch.sh:8000/1REDIS_QUEUE=redis://your-redis-app.klutch.sh:8000/2REDIS_SOCKETIO=redis://your-redis-app.klutch.sh:8000/3
# Application SettingsFRAPPE_SITE_NAME_HEADER=${SITE_NAME}DEVELOPER_MODE=0ALLOW_TESTS=0
# Mail Configuration (optional but recommended)MAIL_SERVER=smtp.gmail.comMAIL_PORT=587MAIL_USE_TLS=1MAIL_LOGIN=your-email@example.comMAIL_PASSWORD=your-email-passwordEnvironment Variables for Nixpacks Customization:
If you need to customize the build or start commands using Nixpacks, use these environment variables:
# Build-time environment variablesNIXPACKS_BUILD_CMD=bench build --app hrms
# Runtime environment variablesNIXPACKS_START_CMD=/home/frappe/start.shSecurity Best Practices:
8. Configure Internal Port
In the Klutch.sh dashboard:
9. Deploy the Application
Once everything is configured:
The deployment process will:
10. Initial Setup and Configuration
After your first deployment:
Getting Started with FrappeHR
Once deployed, here are some initial tasks to get started:
Create Your First Employee
- Navigate to HR > Employee from the sidebar
- Click New to create an employee record
- Fill in required fields:
- Employee Name
- Employee Number
- Date of Birth
- Date of Joining
- Department
- Designation
- Save the employee record
Configure Leave Types
- Go to HR > Leave Type
- Create common leave types:
- Annual Leave
- Sick Leave
- Casual Leave
- Maternity/Paternity Leave
- Configure leave allocation rules for each type
Set Up Attendance Tracking
- Navigate to HR > Attendance
- Configure attendance methods:
- Manual entry
- Biometric integration
- Mobile check-in
- Set up shift management if needed
Example API Usage
FrappeHR provides a REST API for integration with other systems:
import requests
# API endpointbase_url = "https://example-app.klutch.sh"api_key = "your-api-key"api_secret = "your-api-secret"
# Get list of employeesresponse = requests.get( f"{base_url}/api/resource/Employee", headers={ "Authorization": f"token {api_key}:{api_secret}" })
employees = response.json()print(f"Total employees: {len(employees['data'])}")
# Create a new leave applicationleave_data = { "employee": "EMP-001", "leave_type": "Annual Leave", "from_date": "2024-01-15", "to_date": "2024-01-19", "description": "Family vacation"}
response = requests.post( f"{base_url}/api/resource/Leave Application", json=leave_data, headers={ "Authorization": f"token {api_key}:{api_secret}" })
print(f"Leave application created: {response.json()}")Database Backups and Maintenance
Regular backups are crucial for data safety:
Automated Backups
Configure automated backups in FrappeHR:
- Go to Settings > System Settings
- Enable automatic backups
- Set backup frequency (daily recommended)
- Configure backup retention period
Manual Backup
Create a manual backup using the bench command:
# SSH into your container or run via execbench --site your-site-name backup
# Backup with filesbench --site your-site-name backup --with-filesBackups are stored in /home/frappe/frappe-bench/sites/your-site-name/private/backups/
Database Maintenance
Perform regular maintenance tasks:
# Optimize database tablesbench --site your-site-name mariadb -e "OPTIMIZE TABLE table_name"
# Clear cachebench --site your-site-name clear-cache
# Rebuild search indexbench --site your-site-name build-search-indexPerformance Optimization
Caching Configuration
Optimize Redis caching for better performance:
# In site_config.json (stored in persistent volume){ "redis_cache": "redis://your-redis-host:8000/1", "redis_queue": "redis://your-redis-host:8000/2", "redis_socketio": "redis://your-redis-host:8000/3", "cache_ttl": 86400}Background Jobs
Configure background workers for better performance:
# In your start.sh script, you can configure workersbench set-config -g worker_background_jobs 4bench set-config -g worker_short_jobs 2bench set-config -g worker_long_jobs 1Database Indexing
Ensure proper database indexes for frequently queried fields:
-- Add indexes for common queriesCREATE INDEX idx_employee_status ON `tabEmployee` (status);CREATE INDEX idx_attendance_date ON `tabAttendance` (attendance_date);CREATE INDEX idx_leave_from_date ON `tabLeave Application` (from_date);Monitoring and Logging
Application Logs
FrappeHR logs are stored in the persistent volume at /home/frappe/frappe-bench/logs/:
web.log- Web server logsworker.log- Background job logsschedule.log- Scheduled task logsredis_queue.log- Queue logs
Access logs using:
# View recent web logstail -f /home/frappe/frappe-bench/logs/web.log
# Search for errorsgrep ERROR /home/frappe/frappe-bench/logs/*.logMonitoring Key Metrics
Monitor these important metrics:
- Response Time: Average API response time
- Database Connections: Active database connections
- Redis Memory Usage: Cache memory utilization
- Background Job Queue: Pending jobs count
- Error Rate: Application error frequency
Use the Klutch.sh monitoring dashboard to track resource usage (CPU, memory, disk).
Health Checks
Implement health check endpoints:
# Custom health check endpoint@frappe.whitelist(allow_guest=True)def health_check(): # Check database connectivity frappe.db.sql("SELECT 1")
# Check Redis connectivity frappe.cache().get("health_check")
return {"status": "healthy"}Scaling Considerations
Horizontal Scaling
For high-traffic deployments:
-
Separate Web and Worker Processes:
- Deploy multiple web server instances
- Deploy dedicated worker instances for background jobs
- Use a load balancer (provided by Klutch.sh)
-
Database Read Replicas:
- Set up MariaDB read replicas for read-heavy operations
- Configure FrappeHR to use replicas for reporting queries
-
Redis Clustering:
- Use Redis Cluster for high availability
- Separate cache, queue, and socket.io Redis instances
Vertical Scaling
Increase resources for your Klutch.sh app:
- Upgrade CPU and memory allocation
- Increase persistent volume size as data grows
- Optimize database queries and indexes
Troubleshooting Common Issues
Site Not Accessible
Problem: Cannot access FrappeHR after deployment
Solutions:
-
Check application logs for errors:
Terminal window tail -f /home/frappe/frappe-bench/logs/web.log -
Verify environment variables are set correctly
-
Ensure database connection is working:
Terminal window bench --site your-site-name mariadb -e "SELECT 1" -
Check if the site exists:
Terminal window bench --site your-site-name migrate
Database Connection Errors
Problem: Cannot connect to database
Solutions:
- Verify database host and port in environment variables
- Check if database service is running
- Verify database credentials
- Ensure network connectivity between containers
Performance Issues
Problem: Slow response times
Solutions:
- Enable Redis caching properly
- Optimize database queries and add indexes
- Increase worker processes
- Monitor and increase resource allocation
- Clear cache:
bench --site your-site-name clear-cache
Background Jobs Not Running
Problem: Scheduled tasks not executing
Solutions:
-
Verify scheduler is enabled:
Terminal window bench --site your-site-name enable-scheduler -
Check worker logs:
Terminal window tail -f /home/frappe/frappe-bench/logs/worker.log -
Ensure Redis queue is configured correctly
-
Restart workers if needed
Security Best Practices
Application Security
-
Regular Updates: Keep FrappeHR and dependencies updated
Terminal window bench update --reset -
Strong Passwords: Enforce strong password policies
- Minimum length of 12 characters
- Mix of uppercase, lowercase, numbers, and symbols
- Regular password rotation
-
Two-Factor Authentication: Enable 2FA for all users
- Go to User Settings > Two Factor Authentication
- Require 2FA for administrator accounts
-
Role-Based Access Control: Implement least privilege principle
- Create custom roles based on job functions
- Regularly audit user permissions
- Remove inactive user accounts
Network Security
- HTTPS Only: Klutch.sh provides automatic HTTPS
- IP Whitelisting: Restrict access to admin panels
- API Security: Use API keys with limited permissions
- Rate Limiting: Prevent abuse of API endpoints
Data Security
- Encryption at Rest: Use encrypted persistent volumes
- Encryption in Transit: All connections use TLS
- Regular Backups: Automated daily backups
- Backup Testing: Regularly test backup restoration
- Data Retention: Implement data retention policies
Compliance Considerations
For organizations with compliance requirements:
- GDPR: Configure data privacy settings
- HIPAA: If handling health information, ensure proper security controls
- SOC 2: Implement audit logging and access controls
- Data Residency: Choose appropriate Klutch.sh regions
Advanced Configurations
Custom App Development
Extend FrappeHR with custom apps:
# Create a new custom appbench new-app custom_hr_app
# Install the app on your sitebench --site your-site-name install-app custom_hr_app
# Example custom doctypefrappe.ui.form.on('Employee', { refresh: function(frm) { // Add custom button frm.add_custom_button(__('Custom Action'), function() { // Your custom logic }); }});Integration with Third-Party Services
Integrate FrappeHR with external services:
Slack Integration:
import frappeimport requests
def send_slack_notification(message): webhook_url = frappe.conf.get("slack_webhook_url") requests.post(webhook_url, json={"text": message})
# Send notification on leave approval@frappe.whitelist()def on_leave_approved(doc, method): message = f"Leave approved for {doc.employee_name}" send_slack_notification(message)Email Notifications:
# Configure in site_config.json{ "mail_server": "smtp.gmail.com", "mail_port": 587, "use_tls": 1, "mail_login": "your-email@example.com", "mail_password": "your-password", "auto_email_id": "hr@yourcompany.com"}Multi-Tenant Configuration
Run multiple companies on a single instance:
# Create additional sitesbench new-site company2.example.com \ --admin-password password \ --install-app hrms
# Configure site routing in Klutch.sh# Use custom domains for each tenantMigration and Upgrades
Migrating from Another System
Import data from existing HR systems:
- Export data from your current system in CSV format
- Use FrappeHR’s data import tool:
- Go to Data Import Tool
- Select doctype (Employee, Leave Application, etc.)
- Upload CSV file
- Map fields
- Import data
Upgrading FrappeHR
Keep your installation up to date:
# Update to latest versioncd /home/frappe/frappe-benchbench update --reset
# Migrate databasebench --site your-site-name migrate
# Rebuild assetsbench build --app hrms
# Restart servicesbench restartFor major version upgrades:
- Review release notes and breaking changes
- Test upgrade in a staging environment
- Backup production data
- Perform upgrade during maintenance window
- Verify all functionality after upgrade
Production Best Practices
High Availability Setup
For mission-critical deployments:
- Multiple App Instances: Deploy 3+ FrappeHR instances
- Load Balancing: Distribute traffic across instances
- Database Replication: Set up master-slave replication
- Redis Sentinel: Use Redis Sentinel for automatic failover
- Monitoring: Implement comprehensive monitoring and alerting
Disaster Recovery Plan
Prepare for disaster scenarios:
- Regular Backups: Automated daily backups
- Off-site Storage: Store backups in separate region
- Recovery Testing: Quarterly disaster recovery drills
- Documentation: Maintain detailed recovery procedures
- RTO/RPO Targets: Define and meet recovery objectives
Performance Testing
Test system under load:
# Use Apache Bench for load testingab -n 1000 -c 10 https://example-app.klutch.sh/login
# Monitor during testwatch -n 1 'ps aux | grep bench'Cost Optimization
Optimize infrastructure costs:
- Right-size Resources: Monitor and adjust CPU/memory
- Storage Management: Clean up old logs and backups
- Database Optimization: Remove unused indexes
- Caching: Maximize Redis cache hit rate
- CDN: Use CDN for static assets
Resources and Further Reading
Official Documentation
Klutch.sh Resources
- Klutch.sh Quick Start Guide
- Klutch.sh Volumes Guide
- Klutch.sh Builds Guide
- Klutch.sh Deployments Guide
- Klutch.sh Monitoring Guide
Community Resources
Conclusion
Deploying FrappeHR on Klutch.sh provides a robust, scalable solution for managing your organization’s human resources. With automatic Dockerfile detection, persistent volumes for data storage, seamless GitHub integration, and flexible configuration options, you can focus on managing your workforce rather than infrastructure.
This guide has covered everything from initial setup to advanced configurations, security best practices, and production deployment strategies. Whether you’re running a small team or a large enterprise, FrappeHR on Klutch.sh can scale to meet your needs.
For additional assistance or advanced deployment scenarios, consult the official documentation or reach out to the Klutch.sh support team at klutch.sh/app.
Next Steps:
- Set up your development environment
- Deploy a test instance to familiarize yourself with the system
- Configure your organization’s specific HR policies
- Train your HR team on using FrappeHR
- Plan your production deployment strategy
- Implement monitoring and backup procedures