Deploying Ever Gauzy
Introduction
Ever Gauzy is a comprehensive, open-source business management platform designed for collaborative, on-demand, and sharing economies. Combining enterprise resource planning (ERP), customer relationship management (CRM), human resource management (HRM), applicant tracking (ATS), and project management (PM) capabilities, Ever Gauzy provides organizations with a unified platform for managing every aspect of their operations.
Built with TypeScript, Node.js, NestJS, and Angular, Ever Gauzy offers a modern, scalable architecture that can grow with your business. Whether you’re managing employees, tracking time and activities, handling invoices and expenses, or coordinating projects and tasks, Ever Gauzy delivers the tools you need in a single, integrated platform.
Core Capabilities:
Human Resources Management: Manage your workforce with comprehensive employee profiles, onboarding workflows, contract management, and performance tracking. Monitor employee activities, track attendance, manage time off requests, and evaluate performance metrics to build a productive, engaged team.
Time Management and Tracking: Track work hours with precision using built-in timers, activity monitoring, and automated timesheets. Monitor employee productivity with screenshots and activity levels. Generate detailed time reports for payroll processing, project billing, and compliance requirements.
Project and Task Management: Organize work with projects, tasks, milestones, and sprints. Assign tasks to team members, track progress, set deadlines, and monitor project health. Integrate time tracking directly with tasks for accurate project costing and resource allocation.
Customer Relationship Management: Manage customer relationships throughout the entire lifecycle. Track leads, contacts, deals, and proposals. Monitor sales pipelines, schedule appointments, and maintain detailed communication histories. Build stronger customer relationships and close more deals.
Financial Management: Handle invoicing, expenses, estimates, and payments in one place. Generate professional invoices with customizable templates. Track expenses by project, employee, or category. Manage vendor relationships and monitor financial health with comprehensive reporting and analytics.
Applicant Tracking System: Streamline hiring with candidate management, interview scheduling, and evaluation workflows. Post job openings, track applications, schedule interviews, and collaborate with hiring teams. Make better hiring decisions with structured evaluation criteria and candidate comparisons.
Goals and KPIs: Set organizational and individual goals aligned with business objectives. Track key performance indicators, monitor progress toward targets, and measure success across teams and departments. Drive accountability and continuous improvement with transparent goal tracking.
Organization Management: Support multiple organizations, departments, teams, and roles within a single deployment. Manage organizational hierarchies, define team structures, and coordinate across business units. Perfect for agencies, multi-location businesses, and enterprise organizations.
Integration Ecosystem: Connect with external tools like Upwork, HubStaff, and other productivity platforms. Leverage REST APIs for custom integrations. Automate workflows with webhooks and external triggers.
Customization and Extensibility: Adapt the platform to your specific needs with custom fields, workflows, and business logic. Configure permissions and access controls. Brand the platform with your organization’s identity. Extend functionality through the open-source codebase.
Deploying Ever Gauzy on Klutch.sh provides automatic Docker detection, persistent storage for business-critical data, seamless scaling as your organization grows, automated SSL certificates for secure access, and managed infrastructure so you can focus on running your business.
This comprehensive guide covers every step of deploying Ever Gauzy on Klutch.sh, from initial repository setup to production optimization. You’ll learn how to configure databases, manage persistent storage, set up environment variables, optimize performance, and implement production-ready security practices.
Prerequisites
Before deploying Ever Gauzy to Klutch.sh, ensure you have:
- A Klutch.sh account with dashboard access
- A GitHub account for repository hosting
- A PostgreSQL database deployed on Klutch.sh or external provider (16.x recommended)
- Optional: Redis instance for caching and sessions (recommended for production)
- Docker installed locally for testing (optional)
- Basic understanding of business management systems and ERP/CRM concepts
- Familiarity with Node.js and TypeScript (for customizations)
- At least 4GB RAM and 20GB storage for production deployment
Understanding Ever Gauzy Architecture
Technology Stack
Ever Gauzy is built on a modern, enterprise-grade technology stack:
Backend:
- Node.js 18+: JavaScript runtime for server-side execution
- NestJS: Progressive Node.js framework for scalable server applications
- TypeScript: Type-safe development for maintainability
- TypeORM/MikroORM: Multi-database ORM support
- GraphQL + REST: Flexible API options for integrations
Frontend:
- Angular: Powerful framework for building dynamic web applications
- RxJS: Reactive programming for real-time updates
- Ngx-admin: Feature-rich admin dashboard template
- Nebular: UI components optimized for business applications
Database Options:
- PostgreSQL: Recommended for production (primary support)
- MySQL/MariaDB: Alternative relational database option
- SQLite: Development and testing (not recommended for production)
Infrastructure Dependencies:
- Redis: Caching, session management, and job queues (recommended)
- MinIO/S3: Object storage for file uploads and documents (optional)
- OpenSearch: Full-text search capabilities (optional)
- Cube.js: Analytics and reporting engine (optional)
Core Components
API Server: NestJS-based API handling all business logic, data operations, and external integrations
Web Application: Angular-based user interface for administrators, managers, and employees
Database Layer: PostgreSQL storing all business data with ACID compliance
Cache Layer: Redis for fast data access, session storage, and background job queues
File Storage: Local filesystem or S3-compatible object storage for uploads, documents, and media
Background Workers: Asynchronous job processing for emails, reports, and data synchronization
Authentication: JWT-based authentication with role-based access control
Time Tracker: Electron-based desktop application for employee time tracking and activity monitoring
Installation and Setup
Step 1: Create Your Project Directory
First, create a new directory for your Ever Gauzy deployment:
mkdir ever-gauzy-klutchcd ever-gauzy-klutchgit initYour project structure will look like:
ever-gauzy-klutch/├── Dockerfile├── .env.example├── .dockerignore├── .gitignore├── docker-entrypoint.sh├── config/│ └── (configuration files)├── uploads/│ └── (file uploads - persistent)└── README.mdStep 2: Create the Dockerfile
Create a production-ready Dockerfile for Ever Gauzy:
# Multi-stage build for optimized production imageFROM node:18-alpine AS builder
# Install build dependenciesRUN apk add --no-cache \ python3 \ make \ g++ \ git \ curl \ bash
# Set working directoryWORKDIR /app
# Clone Ever Gauzy repositoryRUN git clone --depth 1 --branch master https://github.com/ever-co/ever-gauzy.git .
# Install dependencies with YarnRUN yarn install --frozen-lockfile --network-timeout 1000000
# Build the applicationRUN yarn build:prod
# Production stageFROM node:18-alpine
# Install runtime dependenciesRUN apk add --no-cache \ curl \ bash \ postgresql-client \ ca-certificates \ dumb-init
# Create app user for securityRUN addgroup -g 1000 gauzy && \ adduser -u 1000 -G gauzy -s /bin/bash -D gauzy
# Set working directoryWORKDIR /app
# Copy built application from builder stageCOPY --from=builder --chown=gauzy:gauzy /app/dist /app/distCOPY --from=builder --chown=gauzy:gauzy /app/node_modules /app/node_modulesCOPY --from=builder --chown=gauzy:gauzy /app/package.json /app/package.jsonCOPY --from=builder --chown=gauzy:gauzy /app/.env.sample /app/.env.sample
# Create directories for persistent dataRUN mkdir -p /app/uploads /app/logs /app/public && \ chown -R gauzy:gauzy /app/uploads /app/logs /app/public
# Switch to non-root userUSER gauzy
# Expose application ports# 3000 - API server# 4200 - Web applicationEXPOSE 3000 4200
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:3000/api/health || exit 1
# Use dumb-init for proper signal handlingENTRYPOINT ["/usr/bin/dumb-init", "--"]
# Start the applicationCMD ["node", "dist/apps/api/main.js"]Key Features:
- Multi-stage build reduces final image size
- Non-root user for enhanced security
- Health checks for container orchestration
- Persistent volume directories pre-created
- Production build optimization
Step 3: Create Environment Configuration
Create a comprehensive .env.example file:
# Application ConfigurationAPP_NAME="Ever Gauzy"APP_LOGO="https://example-app.klutch.sh/assets/images/logo.png"APP_SIGNATURE="Ever Gauzy Platform"APP_LINK="https://example-app.klutch.sh"NODE_ENV=production
# Server ConfigurationAPI_HOST=0.0.0.0API_PORT=3000API_BASE_URL=https://example-app.klutch.sh/apiCLIENT_BASE_URL=https://example-app.klutch.sh
# Platform URLsPLATFORM_WEBSITE_URL=https://gauzy.coPLATFORM_WEBSITE_DOWNLOAD_URL=https://gauzy.co/downloads
# Database Configuration (PostgreSQL recommended)DB_ORM=typeormDB_TYPE=postgresDB_HOST=postgres.internal.example-app.klutch.shDB_PORT=5432DB_NAME=gauzyDB_USER=gauzy_userDB_PASS=secure_database_password_hereDB_LOGGING=errorDB_POOL_SIZE=40DB_CONNECTION_TIMEOUT=30000DB_SSL_MODE=false
# Redis Configuration (recommended for production)REDIS_ENABLED=trueREDIS_HOST=redis.internal.example-app.klutch.shREDIS_PORT=6379REDIS_PASSWORD=secure_redis_password_hereREDIS_TLS=falseREDIS_URL=redis://:secure_redis_password_here@redis.internal.example-app.klutch.sh:6379
# Session ConfigurationEXPRESS_SESSION_SECRET=secure_session_secret_minimum_32_characters
# JWT ConfigurationJWT_SECRET=secure_jwt_secret_minimum_32_charactersJWT_TOKEN_EXPIRATION_TIME=86400JWT_REFRESH_TOKEN_SECRET=secure_refresh_token_secret_32_charsJWT_REFRESH_TOKEN_EXPIRATION_TIME=2592000
# Email VerificationJWT_VERIFICATION_TOKEN_SECRET=secure_verification_secret_32_charsJWT_VERIFICATION_TOKEN_EXPIRATION_TIME=86400
# Magic Link AuthenticationMAGIC_CODE_EXPIRATION_TIME=600
# Rate LimitingTHROTTLE_ENABLED=trueTHROTTLE_TTL=60000THROTTLE_LIMIT=300
# File Upload ConfigurationFILE_STORAGE_PROVIDER=local# For local storageUPLOAD_PATH=/app/uploadsMAX_FILE_SIZE=10485760
# Email Configuration (SMTP)MAIL_FROM_ADDRESS=noreply@yourdomain.comMAIL_FROM_NAME="Ever Gauzy"MAIL_HOST=smtp.gmail.comMAIL_PORT=587MAIL_USERNAME=your-email@gmail.comMAIL_PASSWORD=your-app-passwordMAIL_SECURE=false
# SMS Configuration (optional - Twilio)TWILIO_ACCOUNT_SID=TWILIO_AUTH_TOKEN=TWILIO_FROM_NUMBER=
# Integration Configuration (optional)# Upwork IntegrationUPWORK_CLIENT_ID=UPWORK_CLIENT_SECRET=UPWORK_CALLBACK_URL=https://example-app.klutch.sh/api/integrations/upwork/callback
# HubStaff IntegrationHUBSTAFF_CLIENT_ID=HUBSTAFF_CLIENT_SECRET=HUBSTAFF_CALLBACK_URL=https://example-app.klutch.sh/api/integrations/hubstaff/callback
# GitHub IntegrationGAUZY_GITHUB_CLIENT_ID=GAUZY_GITHUB_CLIENT_SECRET=GAUZY_GITHUB_WEBHOOK_URL=https://example-app.klutch.sh/api/integrations/github/webhookGAUZY_GITHUB_WEBHOOK_SECRET=
# OAuth Configuration (optional)GOOGLE_CLIENT_ID=GOOGLE_CLIENT_SECRET=GOOGLE_CALLBACK_URL=https://example-app.klutch.sh/api/auth/google/callback
FACEBOOK_CLIENT_ID=FACEBOOK_CLIENT_SECRET=FACEBOOK_CALLBACK_URL=https://example-app.klutch.sh/api/auth/facebook/callback
# Logging ConfigurationLOG_LEVEL=infoSENTRY_DSN=
# Feature FlagsALLOW_SUPER_ADMIN_ROLE=trueDEMO=falseStep 4: Create Docker Ignore File
Create a .dockerignore file to optimize build times:
# Git files.git.gitignore.gitattributes
# Environment files.env.env.local.env.*.local
# Node modules (will be installed during build)node_modules*/*/node_modules
# Build artifactsdistbuild.nextout
# IDE files.vscode.idea*.swp*.swo*~
# OS files.DS_StoreThumbs.db
# Documentation*.mddocs
# Test files**/*.spec.ts**/*.test.tscoverage.nyc_output
# Logslogs*.lognpm-debug.log*yarn-debug.log*yarn-error.log*
# Temporary filestmptemp*.tmpStep 5: Create Initialization Script (Optional)
Create a docker-entrypoint.sh script for automated database migrations:
#!/bin/bashset -e
echo "Starting Ever Gauzy..."
# Wait for database to be readyecho "Waiting for database connection..."until PGPASSWORD=$DB_PASS psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -c '\q' 2>/dev/null; do echo "PostgreSQL is unavailable - sleeping" sleep 2done
echo "PostgreSQL is up - proceeding with startup"
# Run database migrations (if needed)if [ "$RUN_MIGRATIONS" = "true" ]; then echo "Running database migrations..." node dist/apps/api/main.js migratefi
# Seed initial data (only for first deployment)if [ "$SEED_DATA" = "true" ]; then echo "Seeding database with initial data..." node dist/apps/api/main.js seedfi
# Start the applicationecho "Starting Ever Gauzy API server..."exec node dist/apps/api/main.jsMake it executable:
chmod +x docker-entrypoint.shStep 6: Test Locally (Optional)
Test your Docker setup locally before deploying:
# Build the Docker imagedocker build -t ever-gauzy-klutch .
# Run with environment variablesdocker run -d \ --name gauzy-test \ -p 3000:3000 \ -p 4200:4200 \ -e NODE_ENV=production \ -e DB_TYPE=postgres \ -e DB_HOST=your-db-host \ -e DB_PORT=5432 \ -e DB_NAME=gauzy \ -e DB_USER=gauzy_user \ -e DB_PASS=your-password \ -e JWT_SECRET=test-secret-32-characters-min \ -v gauzy-uploads:/app/uploads \ ever-gauzy-klutch
# Check logsdocker logs -f gauzy-test
# Access the application at http://localhost:3000# Stop and remove when donedocker stop gauzy-testdocker rm gauzy-testStep 7: Push to GitHub
Commit and push your configuration to GitHub:
git add Dockerfile .env.example .dockerignore docker-entrypoint.shgit commit -m "Initial Ever Gauzy deployment configuration"git remote add origin https://github.com/yourusername/ever-gauzy-klutch.gitgit push -u origin mainDeploying to Klutch.sh
Now deploy Ever Gauzy on Klutch.sh with persistent storage and database integration:
-
Set Up PostgreSQL Database
Before deploying Ever Gauzy, you need a PostgreSQL database. Follow our PostgreSQL deployment guide to set up a database on Klutch.sh, or use an external managed PostgreSQL service.
Note your database connection details:
- Host:
your-postgres-app.klutch.sh(if using TCP traffic on Klutch.sh) - Port:
8000(external port for TCP traffic on Klutch.sh) - Database name:
gauzy - Username:
gauzy_user - Password: (secure password you set)
- Host:
-
Optional: Set Up Redis Cache
For production deployments, deploy Redis for caching and session management. Follow our Redis deployment guide.
Redis connection details:
- Host:
your-redis-app.klutch.sh - Port:
8000 - Password: (secure password you set)
- Host:
-
Log in to Klutch.sh
Navigate to klutch.sh/app and sign in to your account.
-
Create a New Project
Click “New Project” and give it a descriptive name like “Ever Gauzy Platform”.
-
Create a New App
Within your project:
- Click “New App”
- Select “GitHub” as your git source
- Choose your Ever Gauzy repository
- Select the main or master branch
- Klutch.sh will automatically detect the Dockerfile
-
Configure Network Settings
Set up networking for HTTP traffic:
- Traffic Type: Select HTTP
- Internal Port: Enter
3000(API server port) - Ever Gauzy serves the web application and API on the same port in this configuration
-
Configure Environment Variables
Add all required environment variables in the Klutch.sh dashboard. At minimum, configure:
Database Configuration:
DB_TYPE=postgresDB_HOST=your-postgres-app.klutch.shDB_PORT=8000DB_NAME=gauzyDB_USER=gauzy_userDB_PASS=your-secure-database-passwordApplication URLs:
API_BASE_URL=https://example-app.klutch.sh/apiCLIENT_BASE_URL=https://example-app.klutch.shNODE_ENV=productionSecurity Secrets (generate secure random strings):
JWT_SECRET=minimum-32-character-secure-random-stringJWT_REFRESH_TOKEN_SECRET=minimum-32-character-secure-random-stringJWT_VERIFICATION_TOKEN_SECRET=minimum-32-character-secure-random-stringEXPRESS_SESSION_SECRET=minimum-32-character-secure-random-stringRedis Configuration (if using):
REDIS_ENABLED=trueREDIS_HOST=your-redis-app.klutch.shREDIS_PORT=8000REDIS_PASSWORD=your-redis-passwordReplace
example-app.klutch.shwith your actual Klutch.sh domain. -
Attach Persistent Volumes
Ever Gauzy requires persistent storage for uploaded files and documents:
Volume 1 - File Uploads:
- Mount Path:
/app/uploads - Size: 10GB-50GB (depending on expected usage)
- Stores user uploads, documents, avatars, and media files
Volume 2 - Application Logs:
- Mount Path:
/app/logs - Size: 5GB-10GB
- Stores application logs for debugging and monitoring
Persistent volumes ensure your data survives deployments and container restarts.
- Mount Path:
-
Configure Resources
Set appropriate compute resources:
- CPU: 2-4 vCPUs minimum (4+ for production)
- Memory: 4GB minimum (8GB+ recommended for production)
- Instances: Start with 1, scale horizontally as needed
-
Deploy Your Application
Click “Deploy” to start the deployment process. Klutch.sh will:
- Build your Docker image from the Dockerfile
- Configure networking and persistent storage
- Set up environment variables
- Deploy the container
- Assign a domain like
example-app.klutch.sh
Initial deployment may take 10-15 minutes as Ever Gauzy builds and initializes the database.
-
Initialize Database
On first deployment, Ever Gauzy will automatically:
- Run database migrations to create tables and schemas
- Seed initial data (admin user, organizations, roles)
Monitor the deployment logs to ensure initialization completes successfully.
-
Access Ever Gauzy
Once deployed, access Ever Gauzy at your Klutch.sh domain:
- URL:
https://example-app.klutch.sh - Default Admin Email:
admin@ever.co - Default Admin Password:
admin
Important: Change the admin password immediately after first login!
- URL:
Initial Configuration
First Login and Setup
After deploying Ever Gauzy, complete the initial configuration:
-
Change Admin Credentials
Navigate to Settings → Profile and update:
- Admin email address
- Strong password (minimum 12 characters)
- Profile information
-
Configure Your Organization
Set up your organization details:
- Navigate to Settings → Organizations
- Update organization name, logo, and branding
- Configure contact information and address
- Set default currency and timezone
- Configure working hours and holidays
-
Set Up Employees
Add your team members:
- Navigate to Employees → Add Employee
- Enter employee details (name, email, role)
- Set employment type (full-time, contractor, etc.)
- Configure pay rates and billing rates
- Invite employees via email
-
Configure Teams and Departments
Organize your workforce:
- Create departments (Engineering, Sales, Marketing, etc.)
- Set up teams within departments
- Assign team managers and members
- Define team goals and KPIs
-
Set Up Projects
Create projects for work tracking:
- Navigate to Projects → Add Project
- Define project details, budget, and timeline
- Assign team members to projects
- Configure task lists and milestones
- Set up project billing and cost tracking
-
Configure Roles and Permissions
Define access controls:
- Navigate to Settings → Roles & Permissions
- Create custom roles for different user types
- Set granular permissions for each role
- Assign roles to employees
Email Configuration
Configure SMTP for sending notifications and invitations:
Add these environment variables in Klutch.sh:
MAIL_FROM_ADDRESS=noreply@yourdomain.comMAIL_FROM_NAME="Ever Gauzy"MAIL_HOST=smtp.gmail.comMAIL_PORT=587MAIL_USERNAME=your-email@gmail.comMAIL_PASSWORD=your-app-passwordMAIL_SECURE=falseFor Gmail:
- Enable 2-factor authentication
- Generate an app-specific password
- Use the app password in
MAIL_PASSWORD
Custom Domain Setup
Configure a custom domain for your Ever Gauzy instance:
-
In Klutch.sh dashboard, navigate to your app settings
-
Go to Domains → Add Custom Domain
-
Enter your domain:
gauzy.yourdomain.com -
Add the CNAME record to your DNS:
- Name:
gauzy - Value:
example-app.klutch.sh - TTL: 3600
- Name:
-
Update environment variables:
API_BASE_URL=https://gauzy.yourdomain.com/apiCLIENT_BASE_URL=https://gauzy.yourdomain.com -
Redeploy to apply changes
Klutch.sh automatically provisions SSL certificates via Let’s Encrypt.
Using Ever Gauzy
Time Tracking
Manual Time Entry:
- Navigate to Timesheet
- Click Add Time Log
- Select date, project, and task
- Enter start/end time or duration
- Add description and submit
Timer-Based Tracking:
- Click the timer icon in the navigation
- Select project and task
- Click Start Timer
- Work on your task
- Click Stop when finished
- Review and submit time log
Desktop Time Tracker (optional):
- Download the Ever Gauzy Desktop Timer app
- Configure connection to your Klutch.sh instance
- Enable activity monitoring and screenshots
- Track time automatically while working
Project Management
Create Projects:
1. Navigate to Projects → Add Project2. Enter project details: - Name and description - Client/customer - Start and end dates - Budget and currency3. Assign team members4. Set up task lists5. Configure billing settingsManage Tasks:
- Create tasks with titles, descriptions, priorities
- Assign tasks to team members
- Set due dates and estimates
- Track progress and completion
- Link tasks to time tracking
Invoicing and Billing
Generate Invoices:
- Navigate to Invoicing → Add Invoice
- Select client and project
- Add invoice items:
- Billable time logs
- Expenses
- Fixed-price items
- Review totals and tax calculations
- Send invoice to client via email
Track Expenses:
- Record expenses by project or category
- Upload receipt images
- Mark expenses as billable
- Include in client invoices
- Generate expense reports
Employee Management
Onboarding Workflow:
- Create employee profile
- Send invitation email
- Employee completes profile
- Assign to departments and teams
- Set up goals and KPIs
- Configure permissions and access
Performance Tracking:
- Set individual and team goals
- Define KPIs and metrics
- Track progress toward targets
- Conduct performance reviews
- Generate performance reports
Production Best Practices
Security Hardening
Secure Secrets Management:
- Use strong, unique passwords (minimum 32 characters for JWT secrets)
- Rotate JWT secrets periodically
- Store secrets securely (never commit to repository)
- Use different secrets for development and production
- Enable Redis password protection
- Configure database SSL connections
Access Control:
- Implement role-based access control (RBAC)
- Follow principle of least privilege
- Regularly audit user permissions
- Disable default admin account after creating new admin
- Enforce strong password policies
- Enable two-factor authentication for admin accounts
Network Security:
- Use HTTPS only (automatic on Klutch.sh)
- Configure CORS properly
- Implement rate limiting (already configured)
- Monitor for suspicious activity
- Regularly review access logs
Performance Optimization
Database Optimization:
-- Create indexes for frequently queried columnsCREATE INDEX idx_employee_user_id ON employee(user_id);CREATE INDEX idx_timesheet_employee_id ON timesheet(employee_id);CREATE INDEX idx_task_project_id ON task(project_id);
-- Analyze query performanceEXPLAIN ANALYZE SELECT * FROM timesheet WHERE employee_id = '...';
-- Monitor slow queriesSELECT query, mean_exec_time, callsFROM pg_stat_statementsORDER BY mean_exec_time DESCLIMIT 10;Redis Caching: Enable Redis for significant performance improvements:
- Session management (reduces database load)
- Query result caching
- Background job queues
- Real-time features
Application Tuning: Configure optimal settings in environment variables:
DB_POOL_SIZE=40THROTTLE_LIMIT=300MAX_FILE_SIZE=10485760Backup Strategy
Database Backups:
# Automated backup script#!/bin/bashDATE=$(date +%Y%m%d_%H%M%S)BACKUP_DIR="/backups"
# Create backup directorymkdir -p $BACKUP_DIR
# Backup PostgreSQL databasePGPASSWORD=$DB_PASS pg_dump \ -h $DB_HOST \ -p $DB_PORT \ -U $DB_USER \ -d $DB_NAME \ -F c \ -f $BACKUP_DIR/gauzy_backup_$DATE.dump
# Compress backupgzip $BACKUP_DIR/gauzy_backup_$DATE.dump
# Upload to S3 or cloud storage (optional)aws s3 cp $BACKUP_DIR/gauzy_backup_$DATE.dump.gz \ s3://your-bucket/gauzy-backups/
# Keep only last 30 days of backupsfind $BACKUP_DIR -name "gauzy_backup_*.dump.gz" -mtime +30 -delete
echo "Backup completed: gauzy_backup_$DATE.dump.gz"File Storage Backups:
- Persistent volumes on Klutch.sh are automatically backed up
- Consider additional backups to S3-compatible storage
- Test backup restoration procedures regularly
Restore Procedure:
# Restore from PostgreSQL dumpPGPASSWORD=$DB_PASS pg_restore \ -h $DB_HOST \ -p $DB_PORT \ -U $DB_USER \ -d $DB_NAME \ -c \ gauzy_backup_20240101_120000.dumpMonitoring and Logging
Application Monitoring:
- Monitor API response times
- Track error rates and exceptions
- Set up alerts for critical issues
- Monitor database connection pool usage
- Track memory and CPU utilization
Health Checks: Ever Gauzy includes a health endpoint:
# Check API healthcurl https://example-app.klutch.sh/api/health
# Expected response{ "status": "ok", "info": { "database": { "status": "up" }, "redis": { "status": "up" } }}Log Management:
- Configure appropriate log levels for production
- Centralize logs for analysis
- Set up log rotation to manage disk space
- Monitor logs for errors and warnings
Sentry Integration (optional):
SENTRY_DSN=https://your-sentry-dsn@sentry.io/project-idSENTRY_HTTP_TRACING_ENABLED=trueSENTRY_POSTGRES_TRACKING_ENABLED=falseScaling Strategies
Horizontal Scaling:
- Increase instance count in Klutch.sh dashboard
- Configure load balancing (automatic on Klutch.sh)
- Ensure Redis is enabled for session sharing
- Use external PostgreSQL for centralized data
Vertical Scaling:
- Increase CPU allocation for compute-intensive operations
- Add memory for handling more concurrent users
- Scale database resources separately
Database Scaling:
- Implement read replicas for reporting queries
- Consider connection pooling (PgBouncer)
- Optimize queries and add indexes
- Partition large tables by date or organization
Troubleshooting
Application Won’t Start
Symptom: Container restarts repeatedly or fails to start
Solutions:
-
Check deployment logs in Klutch.sh dashboard
-
Verify database connection:
Terminal window # Test database connectivityPGPASSWORD=$DB_PASS psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "SELECT version();" -
Ensure all required environment variables are set
-
Verify JWT secrets are at least 32 characters
-
Check database credentials are correct
-
Ensure database is accessible from your app
Cannot Login
Symptom: Admin credentials not working
Solutions:
-
Verify database was seeded with initial data
-
Reset admin password via database:
-- Connect to databaseUPDATE "user"SET password = '$2a$10$example_hashed_password'WHERE email = 'admin@ever.co'; -
Check JWT_SECRET is configured correctly
-
Verify Redis connection if session issues persist
-
Clear browser cache and cookies
Time Tracking Not Working
Symptom: Timer doesn’t start or time logs not saved
Solutions:
- Check employee is assigned to project
- Verify project has active status
- Ensure employee has time tracking permissions
- Check database connectivity
- Review application logs for errors
- Verify task exists and is active
File Uploads Failing
Symptom: Cannot upload documents or images
Solutions:
-
Verify persistent volume is attached at
/app/uploads -
Check volume has sufficient space
-
Ensure
MAX_FILE_SIZEenvironment variable is set appropriately -
Verify file type is allowed
-
Check disk space on persistent volume:
Terminal window df -h /app/uploads -
Review permissions on upload directory
Database Connection Errors
Symptom: “Connection refused” or “Connection timeout” errors
Solutions:
-
Verify PostgreSQL is running and accessible
-
Check database host and port configuration
-
Verify network connectivity:
Terminal window nc -zv $DB_HOST $DB_PORT -
Check PostgreSQL allows connections from application
-
Verify credentials are correct
-
Review PostgreSQL logs for connection issues
-
Ensure database connection pool size is appropriate
Performance Issues
Symptom: Slow response times or timeout errors
Solutions:
- Enable Redis caching for improved performance
- Optimize database queries and add indexes
- Increase database connection pool size
- Scale application resources (CPU/memory)
- Monitor slow query logs
- Implement query result caching
- Consider read replicas for reporting queries
- Optimize file upload sizes
Integration Issues
Symptom: OAuth or external integrations not working
Solutions:
- Verify callback URLs match exactly (including https)
- Check OAuth client IDs and secrets are correct
- Ensure callback URLs are whitelisted in external service
- Verify external service credentials
- Check firewall rules allow outbound connections
- Review integration logs for specific errors
Sample Code
REST API Integration
Node.js Example (using Axios):
const axios = require('axios');
// Configurationconst API_BASE_URL = 'https://example-app.klutch.sh/api';const API_TOKEN = 'your-jwt-token-here';
// Create API clientconst gauzyAPI = axios.create({ baseURL: API_BASE_URL, headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json' }});
// Get all employeesasync function getEmployees() { try { const response = await gauzyAPI.get('/employee'); console.log('Employees:', response.data); return response.data; } catch (error) { console.error('Error fetching employees:', error.response?.data || error.message); throw error; }}
// Create a time logasync function createTimeLog(data) { try { const response = await gauzyAPI.post('/timesheet/time-log', { employeeId: data.employeeId, projectId: data.projectId, taskId: data.taskId, logType: 'TRACKED', startedAt: data.startedAt, stoppedAt: data.stoppedAt, description: data.description }); console.log('Time log created:', response.data); return response.data; } catch (error) { console.error('Error creating time log:', error.response?.data || error.message); throw error; }}
// Get projectsasync function getProjects(organizationId) { try { const response = await gauzyAPI.get('/organization-projects', { params: { organizationId } }); console.log('Projects:', response.data); return response.data; } catch (error) { console.error('Error fetching projects:', error.response?.data || error.message); throw error; }}
// Create an invoiceasync function createInvoice(data) { try { const response = await gauzyAPI.post('/invoices', { invoiceDate: data.invoiceDate, invoiceNumber: data.invoiceNumber, dueDate: data.dueDate, organizationContactId: data.clientId, organizationId: data.organizationId, invoiceItems: data.items, totalValue: data.totalValue, currency: data.currency }); console.log('Invoice created:', response.data); return response.data; } catch (error) { console.error('Error creating invoice:', error.response?.data || error.message); throw error; }}
// Usage example(async () => { try { // Get all employees const employees = await getEmployees();
// Create a time log if (employees.items && employees.items.length > 0) { const timeLog = await createTimeLog({ employeeId: employees.items[0].id, projectId: 'project-uuid-here', startedAt: new Date('2024-01-15T09:00:00Z'), stoppedAt: new Date('2024-01-15T17:00:00Z'), description: 'Working on feature development' }); } } catch (error) { console.error('API Error:', error); }})();Python Example (using Requests):
import requestsfrom datetime import datetime, timedeltafrom typing import Dict, List, Optional
class GauzyAPI: def __init__(self, base_url: str, token: str): self.base_url = base_url.rstrip('/') self.session = requests.Session() self.session.headers.update({ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' })
def get_employees(self) -> List[Dict]: """Fetch all employees""" response = self.session.get(f'{self.base_url}/employee') response.raise_for_status() return response.json()
def create_time_log(self, employee_id: str, project_id: str, started_at: datetime, stopped_at: datetime, description: str = '', task_id: Optional[str] = None) -> Dict: """Create a new time log entry""" data = { 'employeeId': employee_id, 'projectId': project_id, 'logType': 'TRACKED', 'startedAt': started_at.isoformat(), 'stoppedAt': stopped_at.isoformat(), 'description': description }
if task_id: data['taskId'] = task_id
response = self.session.post(f'{self.base_url}/timesheet/time-log', json=data) response.raise_for_status() return response.json()
def get_projects(self, organization_id: str) -> List[Dict]: """Get all projects for an organization""" params = {'organizationId': organization_id} response = self.session.get(f'{self.base_url}/organization-projects', params=params) response.raise_for_status() return response.json()
def create_invoice(self, organization_id: str, client_id: str, invoice_date: datetime, due_date: datetime, items: List[Dict], currency: str = 'USD') -> Dict: """Create a new invoice""" total_value = sum(item['price'] * item['quantity'] for item in items)
data = { 'invoiceDate': invoice_date.isoformat(), 'dueDate': due_date.isoformat(), 'organizationContactId': client_id, 'organizationId': organization_id, 'invoiceItems': items, 'totalValue': total_value, 'currency': currency }
response = self.session.post(f'{self.base_url}/invoices', json=data) response.raise_for_status() return response.json()
def get_time_logs(self, employee_id: str, start_date: datetime, end_date: datetime) -> List[Dict]: """Get time logs for an employee within date range""" params = { 'employeeId': employee_id, 'startDate': start_date.isoformat(), 'endDate': end_date.isoformat() } response = self.session.get(f'{self.base_url}/timesheet/time-log', params=params) response.raise_for_status() return response.json()
# Usage exampleif __name__ == '__main__': # Initialize API client api = GauzyAPI( base_url='https://example-app.klutch.sh/api', token='your-jwt-token-here' )
try: # Get employees employees = api.get_employees() print(f"Found {len(employees['items'])} employees")
# Create time log if employees['items']: employee_id = employees['items'][0]['id']
time_log = api.create_time_log( employee_id=employee_id, project_id='project-uuid-here', started_at=datetime.now() - timedelta(hours=8), stopped_at=datetime.now(), description='Development work on new features' ) print(f"Time log created: {time_log['id']}")
# Get projects projects = api.get_projects(organization_id='org-uuid-here') print(f"Found {len(projects)} projects")
except requests.exceptions.HTTPError as e: print(f"API Error: {e.response.status_code} - {e.response.text}") except Exception as e: print(f"Error: {str(e)}")Go Example:
package main
import ( "bytes" "encoding/json" "fmt" "io" "net/http" "time")
const ( APIBaseURL = "https://example-app.klutch.sh/api" APIToken = "your-jwt-token-here")
type GauzyClient struct { BaseURL string HTTPClient *http.Client Token string}
type Employee struct { ID string `json:"id"` FirstName string `json:"firstName"` LastName string `json:"lastName"` Email string `json:"email"` Organization string `json:"organizationId"`}
type TimeLog struct { ID string `json:"id,omitempty"` EmployeeID string `json:"employeeId"` ProjectID string `json:"projectId"` TaskID string `json:"taskId,omitempty"` LogType string `json:"logType"` StartedAt time.Time `json:"startedAt"` StoppedAt time.Time `json:"stoppedAt"` Description string `json:"description"`}
func NewGauzyClient(baseURL, token string) *GauzyClient { return &GauzyClient{ BaseURL: baseURL, Token: token, HTTPClient: &http.Client{ Timeout: time.Second * 30, }, }}
func (c *GauzyClient) doRequest(method, path string, body interface{}) ([]byte, error) { var reqBody io.Reader if body != nil { jsonData, err := json.Marshal(body) if err != nil { return nil, fmt.Errorf("marshal request body: %w", err) } reqBody = bytes.NewBuffer(jsonData) }
req, err := http.NewRequest(method, c.BaseURL+path, reqBody) if err != nil { return nil, fmt.Errorf("create request: %w", err) }
req.Header.Set("Authorization", "Bearer "+c.Token) req.Header.Set("Content-Type", "application/json")
resp, err := c.HTTPClient.Do(req) if err != nil { return nil, fmt.Errorf("execute request: %w", err) } defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("read response: %w", err) }
if resp.StatusCode >= 400 { return nil, fmt.Errorf("API error %d: %s", resp.StatusCode, string(respBody)) }
return respBody, nil}
func (c *GauzyClient) GetEmployees() ([]Employee, error) { respBody, err := c.doRequest("GET", "/employee", nil) if err != nil { return nil, err }
var result struct { Items []Employee `json:"items"` } if err := json.Unmarshal(respBody, &result); err != nil { return nil, fmt.Errorf("unmarshal response: %w", err) }
return result.Items, nil}
func (c *GauzyClient) CreateTimeLog(timeLog TimeLog) (*TimeLog, error) { timeLog.LogType = "TRACKED"
respBody, err := c.doRequest("POST", "/timesheet/time-log", timeLog) if err != nil { return nil, err }
var result TimeLog if err := json.Unmarshal(respBody, &result); err != nil { return nil, fmt.Errorf("unmarshal response: %w", err) }
return &result, nil}
func main() { client := NewGauzyClient(APIBaseURL, APIToken)
// Get employees employees, err := client.GetEmployees() if err != nil { fmt.Printf("Error fetching employees: %v\n", err) return } fmt.Printf("Found %d employees\n", len(employees))
// Create time log if len(employees) > 0 { timeLog := TimeLog{ EmployeeID: employees[0].ID, ProjectID: "project-uuid-here", StartedAt: time.Now().Add(-8 * time.Hour), StoppedAt: time.Now(), Description: "Working on API integration", }
created, err := client.CreateTimeLog(timeLog) if err != nil { fmt.Printf("Error creating time log: %v\n", err) return } fmt.Printf("Time log created: %s\n", created.ID) }}Additional Resources
- Ever Gauzy Official Website
- Ever Gauzy Documentation
- Ever Gauzy GitHub Repository
- Ever Gauzy Wiki
- Ever Gauzy Live Demo
- Desktop Timer Application
- Slack Community
- Discord Community
- PostgreSQL Deployment Guide
- Redis Deployment Guide
Conclusion
Deploying Ever Gauzy on Klutch.sh provides your organization with a powerful, self-hosted business management platform that puts you in complete control of your data and workflows. With comprehensive ERP, CRM, HRM, and project management capabilities, Ever Gauzy enables teams of all sizes to streamline operations, track time and productivity, manage customer relationships, and grow their business efficiently.
By leveraging Klutch.sh’s managed infrastructure, you get automatic Docker deployments, persistent storage for business-critical data, seamless scaling as your organization grows, and enterprise-grade reliability without the operational complexity. Focus on running your business while Klutch.sh handles the infrastructure.
Start managing your entire business operation from a single, unified platform. Deploy Ever Gauzy on Klutch.sh today and transform how your organization works.