Skip to content

Deploying an EspoCRM App

Introduction

EspoCRM is a powerful, open-source Customer Relationship Management (CRM) platform designed to help businesses manage customer interactions, sales pipelines, marketing campaigns, and support services. Built with PHP and MySQL, EspoCRM offers a modern, intuitive interface with extensive customization capabilities to fit diverse business needs.

EspoCRM is designed to be:

  • Flexible and Customizable: Adapt the CRM to your business processes with custom entities, fields, and workflows
  • User-Friendly: Modern, responsive interface that works seamlessly across desktop and mobile devices
  • Feature-Rich: Comprehensive CRM features including lead management, opportunity tracking, contact management, and more
  • Extensible: Support for extensions and integrations to expand functionality
  • Secure: Built-in security features with role-based access control and data encryption
  • Open Source: Self-hosted solution giving you complete control over your data and infrastructure

Key features include:

  • Sales Management: Lead tracking, opportunity management, sales forecasting, and pipeline visualization
  • Contact Management: Comprehensive contact and account management with relationship tracking
  • Marketing Automation: Email campaigns, marketing lists, and campaign tracking
  • Customer Support: Case management, knowledge base, and support ticket system
  • Calendar & Activities: Integrated calendar, tasks, calls, and meetings management
  • Email Integration: Built-in email client with IMAP/SMTP support
  • Reporting & Analytics: Customizable reports and dashboards with visual analytics
  • Team Collaboration: Shared calendars, streams, and collaborative tools
  • Workflow Automation: Business process management with automated workflows
  • Mobile Access: Responsive design optimized for mobile devices

This comprehensive guide walks you through deploying EspoCRM on Klutch.sh using Docker, including detailed installation steps, database configuration, persistent storage setup, environment variables, and production-ready best practices.

Prerequisites

Before you begin deploying EspoCRM to Klutch.sh, ensure you have the following:

  • A Klutch.sh account
  • A GitHub account with a repository for your EspoCRM project
  • Docker installed locally for testing (optional but recommended)
  • Basic understanding of Docker, PHP applications, and CRM concepts
  • A MySQL or MariaDB database (can be provisioned separately on Klutch.sh)

Installation and Setup

Step 1: Create Your Project Directory

First, create a new directory for your EspoCRM deployment project:

Terminal window
mkdir espocrm-klutch
cd espocrm-klutch
git init

Step 2: Create the Dockerfile

Create a Dockerfile in your project root directory. This will define your EspoCRM container configuration:

# Use the official EspoCRM image
FROM espocrm/espocrm:latest
# Set the working directory
WORKDIR /var/www/html
# Set default environment variables
# These can be overridden in the Klutch.sh dashboard
ENV ESPOCRM_DATABASE_DRIVER=pdo_mysql
ENV ESPOCRM_DATABASE_HOST=db
ENV ESPOCRM_DATABASE_NAME=espocrm
ENV ESPOCRM_DATABASE_USER=espocrm
ENV ESPOCRM_DATABASE_PASSWORD=CHANGE_ME_SECURE_DB_PASSWORD
ENV ESPOCRM_ADMIN_USERNAME=admin
ENV ESPOCRM_ADMIN_PASSWORD=CHANGE_ME_SECURE_ADMIN_PASSWORD
ENV ESPOCRM_SITE_URL=http://localhost
# EspoCRM listens on port 80 by default
EXPOSE 80
# The entrypoint and command are defined in the base image

Important Security Notes:

  • CRITICAL: Replace CHANGE_ME_SECURE_DB_PASSWORD with a strong, unique database password before deploying
  • CRITICAL: Replace CHANGE_ME_SECURE_ADMIN_PASSWORD with a strong, unique admin password before deploying
  • The ESPOCRM_SITE_URL should be set to your actual Klutch.sh app URL (e.g., https://example-app.klutch.sh)
  • Change the admin username from the default ‘admin’ for better security
  • Never commit real passwords to your repository - use environment variables in Klutch.sh instead
  • The official EspoCRM Docker image includes Apache and PHP pre-configured

Step 3: Create a .dockerignore File

Create a .dockerignore file to exclude unnecessary files from your Docker build:

.git
.github
.gitignore
README.md
.env
*.log
node_modules
data

Step 4: Create a README

Create a README.md file to document your deployment:

# EspoCRM Deployment
This repository contains the configuration for deploying EspoCRM on Klutch.sh.
## Setup
1. Configure environment variables in Klutch.sh dashboard
2. Set up MySQL database connection
3. Deploy the application
4. Complete the initial setup wizard
## Environment Variables
- `ESPOCRM_DATABASE_HOST`: MySQL database host
- `ESPOCRM_DATABASE_NAME`: Database name
- `ESPOCRM_DATABASE_USER`: Database user
- `ESPOCRM_DATABASE_PASSWORD`: Database password
- `ESPOCRM_ADMIN_USERNAME`: Initial admin username
- `ESPOCRM_ADMIN_PASSWORD`: Initial admin password
- `ESPOCRM_SITE_URL`: Your EspoCRM site URL

Step 5: Test Locally (Optional)

Before deploying to Klutch.sh, you can test your EspoCRM setup locally using Docker:

Terminal window
# Build the Docker image
docker build -t my-espocrm .
# Create a network for EspoCRM and MySQL
docker network create espocrm-network
# Run MySQL container
docker run -d \
--name espocrm-mysql \
--network espocrm-network \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=espocrm \
-e MYSQL_USER=espocrm \
-e MYSQL_PASSWORD=espocrm_password \
mysql:8.0
# Wait for MySQL to be ready (about 30 seconds)
sleep 30
# Run the EspoCRM container
docker run -d \
--name espocrm-app \
--network espocrm-network \
-p 8080:80 \
-e ESPOCRM_DATABASE_HOST=espocrm-mysql \
-e ESPOCRM_DATABASE_NAME=espocrm \
-e ESPOCRM_DATABASE_USER=espocrm \
-e ESPOCRM_DATABASE_PASSWORD=espocrm_password \
-e ESPOCRM_ADMIN_USERNAME=admin \
-e ESPOCRM_ADMIN_PASSWORD=admin \
-e ESPOCRM_SITE_URL=http://localhost:8080 \
my-espocrm
# Check if EspoCRM is running
# Wait a minute for the container to initialize, then visit http://localhost:8080
# View logs
docker logs espocrm-app
# Stop and remove the test containers when done
docker stop espocrm-app espocrm-mysql
docker rm espocrm-app espocrm-mysql
docker network rm espocrm-network

Step 6: Push to GitHub

Commit your Dockerfile and configuration to your GitHub repository:

Terminal window
git add Dockerfile .dockerignore README.md
git commit -m "Add EspoCRM Dockerfile configuration"
git remote add origin https://github.com/yourusername/espocrm-klutch.git
git push -u origin main

Setting Up the Database

EspoCRM requires a MySQL or MariaDB database to store all CRM data, including contacts, accounts, opportunities, and system configurations.

Database Setup Options

Option 1: Deploy MySQL on Klutch.sh

You can deploy a MySQL database on Klutch.sh. Follow the MySQL deployment guide to set up a MySQL instance.

Option 2: Use an External Database Service

You can use external database services such as:

Database Requirements

  • MySQL Version: 5.7 or higher (MySQL 8.0 recommended)
  • MariaDB Version: 10.2 or higher
  • Database Collation: utf8mb4_unicode_ci
  • Required Privileges: CREATE, DROP, SELECT, INSERT, UPDATE, DELETE, ALTER, INDEX

Create Database and User

If you’re managing your own MySQL instance, create a database and user for EspoCRM:

CREATE DATABASE espocrm CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'espocrm'@'your-klutch-app-ip' IDENTIFIED BY 'CHANGE_ME_SECURE_PASSWORD';
GRANT ALL PRIVILEGES ON espocrm.* TO 'espocrm'@'your-klutch-app-ip';
FLUSH PRIVILEGES;

Security Notes:

  • Replace CHANGE_ME_SECURE_PASSWORD with a strong, unique password
  • Replace 'your-klutch-app-ip' with the specific IP address or hostname of your Klutch.sh app for better security
  • If using '%' as the host (allows connections from any host), ensure your database is behind a firewall and only accessible to trusted networks

Deploying to Klutch.sh

Now that your EspoCRM project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh with persistent storage.

Deployment Steps

    1. Log in to Klutch.sh

      Navigate to klutch.sh/app and sign in to your account.

    2. Create a New Project

      Go to Create Project and give your project a meaningful name (e.g., “EspoCRM Production”).

    3. Create a New App

      Navigate to Create App and configure the following settings:

    4. Select Your Repository

      • Choose GitHub as your Git source
      • Select the repository containing your Dockerfile
      • Choose the branch you want to deploy (usually main or master)
    5. Configure Traffic Type

      • Traffic Type: Select HTTP (EspoCRM serves HTTP/HTTPS traffic)
      • Internal Port: Set to 80 (the port that EspoCRM listens on inside the container)
    6. Set Environment Variables

      Add the following essential environment variables for your EspoCRM configuration:

      Required Database Environment Variables:

      • ESPOCRM_DATABASE_DRIVER: Set to pdo_mysql
      • ESPOCRM_DATABASE_HOST: Your MySQL database hostname (e.g., mysql-service.klutch.sh or external database host)
      • ESPOCRM_DATABASE_PORT: Database port (default: 3306)
      • ESPOCRM_DATABASE_NAME: Database name (e.g., espocrm)
      • ESPOCRM_DATABASE_USER: Database username
      • ESPOCRM_DATABASE_PASSWORD: Database password (mark as secret)

      Required Site Configuration:

      • ESPOCRM_SITE_URL: Your Klutch.sh app URL (e.g., https://example-app.klutch.sh)
      • ESPOCRM_ADMIN_USERNAME: Initial admin username (change after first login)
      • ESPOCRM_ADMIN_PASSWORD: Initial admin password (change after first login, mark as secret)

      Optional but Recommended:

      • ESPOCRM_LANGUAGE: Default language (e.g., en_US)
      • ESPOCRM_TIMEZONE: Server timezone (e.g., America/New_York)
      • ESPOCRM_DATE_FORMAT: Date format (e.g., MM/DD/YYYY)
      • ESPOCRM_TIME_FORMAT: Time format (e.g., hh:mm A)
      • ESPOCRM_CURRENCY: Default currency (e.g., USD)

      Email Configuration (SMTP):

      • ESPOCRM_EMAIL_TRANSPORT: Set to smtp
      • ESPOCRM_EMAIL_FROM_NAME: Sender name for emails
      • ESPOCRM_EMAIL_FROM_ADDRESS: Sender email address
      • ESPOCRM_SMTP_HOST: SMTP server hostname
      • ESPOCRM_SMTP_PORT: SMTP port (typically 587 for TLS or 465 for SSL)
      • ESPOCRM_SMTP_SECURITY: Set to tls or ssl
      • ESPOCRM_SMTP_USERNAME: SMTP username
      • ESPOCRM_SMTP_PASSWORD: SMTP password (mark as secret)

      Security Note: Never commit sensitive credentials like database passwords or SMTP passwords to your repository. Always set them as environment variables in Klutch.sh and mark them as secrets.

    7. Attach Persistent Volumes

      EspoCRM requires persistent storage for custom modules, uploaded files, and configuration. Configure the following volumes:

      Volume 1 - Data Storage:

      • Mount Path: /var/www/html/data
      • Size: Choose based on expected file uploads and attachments (e.g., 10GB, 20GB, 50GB)

      Volume 2 - Custom Modules and Extensions:

      • Mount Path: /var/www/html/custom
      • Size: 5GB (for custom modules and extensions)

      Volume 3 - Configuration Files:

      • Mount Path: /var/www/html/config
      • Size: 1GB (for configuration files)

      Important: Persistent volumes are critical for EspoCRM. Without them, you’ll lose all custom configurations, uploaded files, and customizations when the container restarts.

    8. Configure Additional Settings

      • Region: Select the region closest to your users for optimal latency
      • Compute Resources:
        • Minimum: 1 CPU, 2GB RAM (for small teams up to 10 users)
        • Recommended: 2 CPU, 4GB RAM (for teams up to 50 users)
        • High Usage: 4+ CPU, 8GB+ RAM (for large teams and heavy usage)
      • Instances: Start with 1 instance (EspoCRM doesn’t natively support horizontal scaling)
    9. Deploy Your Application

      Click “Create” to start the deployment. Klutch.sh will:

      • Automatically detect your Dockerfile in the repository root
      • Build the Docker image with EspoCRM
      • Attach the persistent volumes to the specified mount paths
      • Start your EspoCRM container
      • Assign a URL for accessing your EspoCRM instance
    10. Access Your EspoCRM Instance

      Once deployment is complete, you’ll receive a URL like example-app.klutch.sh. Your EspoCRM instance will be accessible at:

      • Main Application: https://example-app.klutch.sh/

      Open the URL in your browser to complete the initial setup. Log in with the admin credentials you configured in the environment variables.


Getting Started with EspoCRM

After deploying EspoCRM, here’s how to get started with configuring and using your CRM system.

Initial Configuration

  1. Log In to Your EspoCRM Instance

    Open your EspoCRM instance at https://example-app.klutch.sh/ and log in with your admin credentials.

  2. Change Admin Password

    Immediately change your admin password from the default:

    • Click on your username in the top-right corner
    • Select “Preferences”
    • Navigate to the “Password” section
    • Set a strong, unique password
  3. Configure System Settings

    Navigate to Administration > Settings to configure:

    • Company information and logo
    • Email settings for sending emails
    • Currency and locale settings
    • Date and time formats
    • System timezone
  4. Set Up Email Integration

    Configure email accounts for your users:

    • Go to Administration > Email Accounts
    • Add IMAP/SMTP accounts for receiving and sending emails
    • Configure email templates for automated communications

Sample Code: EspoCRM API Integration

EspoCRM provides a powerful REST API for integrations. Here are examples of how to interact with your EspoCRM instance programmatically:

JavaScript/Node.js Example:

// EspoCRM API Client Example
const axios = require('axios');
class EspoCRMClient {
constructor(baseUrl, apiKey) {
this.baseUrl = baseUrl;
this.apiKey = apiKey;
this.client = axios.create({
baseURL: `${baseUrl}/api/v1`,
headers: {
'Content-Type': 'application/json',
'X-Api-Key': apiKey
}
});
}
// Create a new contact
async createContact(data) {
try {
const response = await this.client.post('/Contact', data);
console.log('Contact created:', response.data);
return response.data;
} catch (error) {
console.error('Error creating contact:', error.response?.data || error.message);
throw error;
}
}
// Get contact by ID
async getContact(contactId) {
try {
const response = await this.client.get(`/Contact/${contactId}`);
return response.data;
} catch (error) {
console.error('Error fetching contact:', error.response?.data || error.message);
throw error;
}
}
// Update a contact
async updateContact(contactId, data) {
try {
const response = await this.client.put(`/Contact/${contactId}`, data);
console.log('Contact updated:', response.data);
return response.data;
} catch (error) {
console.error('Error updating contact:', error.response?.data || error.message);
throw error;
}
}
// List contacts with filters
async listContacts(params = {}) {
try {
const response = await this.client.get('/Contact', { params });
return response.data;
} catch (error) {
console.error('Error listing contacts:', error.response?.data || error.message);
throw error;
}
}
// Create a new opportunity
async createOpportunity(data) {
try {
const response = await this.client.post('/Opportunity', data);
console.log('Opportunity created:', response.data);
return response.data;
} catch (error) {
console.error('Error creating opportunity:', error.response?.data || error.message);
throw error;
}
}
// Create a new lead
async createLead(data) {
try {
const response = await this.client.post('/Lead', data);
console.log('Lead created:', response.data);
return response.data;
} catch (error) {
console.error('Error creating lead:', error.response?.data || error.message);
throw error;
}
}
// Create a new account
async createAccount(data) {
try {
const response = await this.client.post('/Account', data);
console.log('Account created:', response.data);
return response.data;
} catch (error) {
console.error('Error creating account:', error.response?.data || error.message);
throw error;
}
}
}
// Usage example
// Note: Generate your API key in EspoCRM (see "Generating API Keys" section below)
const crm = new EspoCRMClient('https://example-app.klutch.sh', 'your-api-key');
// Create a contact
async function example() {
const newContact = await crm.createContact({
firstName: 'John',
lastName: 'Doe',
emailAddress: 'john.doe@example.com',
phoneNumber: '+1-555-0123',
accountId: 'account-id-here'
});
// List contacts
const contacts = await crm.listContacts({
maxSize: 20,
offset: 0,
orderBy: 'createdAt',
order: 'desc'
});
console.log('Contacts:', contacts);
// Create an opportunity
const opportunity = await crm.createOpportunity({
name: 'New Business Deal',
stage: 'Prospecting',
amount: 50000,
closeDate: '2024-12-31',
probability: 50,
accountId: 'account-id-here',
assignedUserId: 'user-id-here'
});
}
example();

Python Example:

import requests
import json
class EspoCRMClient:
def __init__(self, base_url, api_key):
self.base_url = base_url
self.api_key = api_key
self.headers = {
'Content-Type': 'application/json',
'X-Api-Key': api_key
}
def create_contact(self, data):
"""Create a new contact"""
url = f"{self.base_url}/api/v1/Contact"
response = requests.post(url, headers=self.headers, json=data)
response.raise_for_status()
return response.json()
def get_contact(self, contact_id):
"""Get contact by ID"""
url = f"{self.base_url}/api/v1/Contact/{contact_id}"
response = requests.get(url, headers=self.headers)
response.raise_for_status()
return response.json()
def update_contact(self, contact_id, data):
"""Update a contact"""
url = f"{self.base_url}/api/v1/Contact/{contact_id}"
response = requests.put(url, headers=self.headers, json=data)
response.raise_for_status()
return response.json()
def list_contacts(self, params=None):
"""List contacts with optional filters"""
url = f"{self.base_url}/api/v1/Contact"
response = requests.get(url, headers=self.headers, params=params)
response.raise_for_status()
return response.json()
def create_opportunity(self, data):
"""Create a new opportunity"""
url = f"{self.base_url}/api/v1/Opportunity"
response = requests.post(url, headers=self.headers, json=data)
response.raise_for_status()
return response.json()
def create_lead(self, data):
"""Create a new lead"""
url = f"{self.base_url}/api/v1/Lead"
response = requests.post(url, headers=self.headers, json=data)
response.raise_for_status()
return response.json()
def create_account(self, data):
"""Create a new account"""
url = f"{self.base_url}/api/v1/Account"
response = requests.post(url, headers=self.headers, json=data)
response.raise_for_status()
return response.json()
# Usage example
# Note: Generate your API key in EspoCRM (see "Generating API Keys" section below)
crm = EspoCRMClient('https://example-app.klutch.sh', 'your-api-key')
# Create a contact
new_contact = crm.create_contact({
'firstName': 'Jane',
'lastName': 'Smith',
'emailAddress': 'jane.smith@example.com',
'phoneNumber': '+1-555-0456',
'accountId': 'account-id-here'
})
print(f'Contact created: {new_contact}')
# List contacts
contacts = crm.list_contacts({
'maxSize': 20,
'offset': 0,
'orderBy': 'createdAt',
'order': 'desc'
})
print(f'Found {len(contacts.get("list", []))} contacts')
# Create an opportunity
opportunity = crm.create_opportunity({
'name': 'Enterprise Deal',
'stage': 'Qualification',
'amount': 100000,
'closeDate': '2024-12-31',
'probability': 75,
'accountId': 'account-id-here',
'assignedUserId': 'user-id-here'
})
print(f'Opportunity created: {opportunity}')

PHP Example:

<?php
class EspoCRMClient {
private $baseUrl;
private $apiKey;
public function __construct($baseUrl, $apiKey) {
$this->baseUrl = $baseUrl;
$this->apiKey = $apiKey;
}
private function request($method, $endpoint, $data = null) {
$url = $this->baseUrl . '/api/v1' . $endpoint;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-Api-Key: ' . $this->apiKey
]);
if ($data) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
throw new Exception("API request failed with status $httpCode: $response");
}
return json_decode($response, true);
}
public function createContact($data) {
return $this->request('POST', '/Contact', $data);
}
public function getContact($contactId) {
return $this->request('GET', "/Contact/$contactId");
}
public function updateContact($contactId, $data) {
return $this->request('PUT', "/Contact/$contactId", $data);
}
public function listContacts($params = []) {
$query = http_build_query($params);
return $this->request('GET', "/Contact?$query");
}
public function createOpportunity($data) {
return $this->request('POST', '/Opportunity', $data);
}
public function createLead($data) {
return $this->request('POST', '/Lead', $data);
}
public function createAccount($data) {
return $this->request('POST', '/Account', $data);
}
}
// Usage example
// Note: Generate your API key in EspoCRM (see "Generating API Keys" section below)
$crm = new EspoCRMClient('https://example-app.klutch.sh', 'your-api-key');
// Create a contact
$newContact = $crm->createContact([
'firstName' => 'Bob',
'lastName' => 'Johnson',
'emailAddress' => 'bob.johnson@example.com',
'phoneNumber' => '+1-555-0789',
'accountId' => 'account-id-here'
]);
echo "Contact created: " . print_r($newContact, true) . "\n";
// List contacts
$contacts = $crm->listContacts([
'maxSize' => 20,
'offset' => 0,
'orderBy' => 'createdAt',
'order' => 'desc'
]);
echo "Found " . count($contacts['list'] ?? []) . " contacts\n";
// Create an opportunity
$opportunity = $crm->createOpportunity([
'name' => 'Strategic Partnership',
'stage' => 'Proposal',
'amount' => 75000,
'closeDate' => '2024-12-31',
'probability' => 60,
'accountId' => 'account-id-here',
'assignedUserId' => 'user-id-here'
]);
echo "Opportunity created: " . print_r($opportunity, true) . "\n";
?>

Generating API Keys

To use the EspoCRM API:

  1. Log in to EspoCRM as an administrator
  2. Go to Administration > API Users
  3. Create a new API user or generate an API key for an existing user
  4. Copy the API key and use it in your integrations
  5. Set appropriate permissions for the API user

Common Use Cases

1. Managing Contacts and Accounts

// Create an account (company)
const account = await crm.createAccount({
name: 'Acme Corporation',
type: 'Customer',
industry: 'Technology',
website: 'https://acme.com',
billingAddress: {
street: '123 Main St',
city: 'New York',
state: 'NY',
postalCode: '10001',
country: 'USA'
}
});
// Create a contact linked to the account
const contact = await crm.createContact({
firstName: 'Alice',
lastName: 'Williams',
emailAddress: 'alice@acme.com',
title: 'VP of Sales',
accountId: account.id
});

2. Managing Sales Pipeline

// Create a lead
const lead = await crm.createLead({
firstName: 'Michael',
lastName: 'Brown',
status: 'New',
source: 'Web Site',
emailAddress: 'michael@example.com',
phoneNumber: '+1-555-1234',
description: 'Interested in our enterprise plan'
});
// Convert lead to opportunity
const opportunity = await crm.createOpportunity({
name: 'Enterprise Plan - Michael Brown',
accountName: 'Brown Industries',
stage: 'Prospecting',
amount: 25000,
closeDate: '2024-06-30',
probability: 25,
leadId: lead.id
});

3. Task and Activity Management

// Create a task
const response = await crm.client.post('/Task', {
name: 'Follow up with client',
status: 'Not Started',
priority: 'High',
dateStart: '2024-01-15 09:00:00',
dateEnd: '2024-01-15 10:00:00',
assignedUserId: 'user-id-here',
parentType: 'Opportunity',
parentId: 'opportunity-id-here'
});
// Create a meeting
const meeting = await crm.client.post('/Meeting', {
name: 'Sales Presentation',
status: 'Planned',
dateStart: '2024-01-20 14:00:00',
dateEnd: '2024-01-20 15:00:00',
assignedUserId: 'user-id-here',
attendees: ['contact-id-1', 'contact-id-2']
});

Production Best Practices

Security Recommendations

  • Strong Passwords: Use strong, unique passwords for admin accounts and database credentials. Change default passwords immediately after deployment.
  • Environment Variables: Store all sensitive credentials (database passwords, API keys, SMTP credentials) as environment variables in Klutch.sh, never in your code or Dockerfile.
  • HTTPS Only: Always use HTTPS for your EspoCRM instance. Klutch.sh provides SSL/TLS automatically.
  • Regular Updates: Keep your EspoCRM Docker image updated to the latest stable version for security patches and bug fixes.
  • API Security: Protect API keys and limit API user permissions to the minimum required for each integration.
  • Role-Based Access Control: Configure user roles and permissions properly to restrict access to sensitive data.
  • Two-Factor Authentication: Enable 2FA for admin accounts and critical user accounts.
  • Backup Encryption: Encrypt database backups that contain sensitive customer data.
  • File Upload Restrictions: Configure file upload restrictions to prevent malicious file uploads.

Performance Optimization

  • Resource Allocation: Monitor your application and adjust CPU/memory based on actual usage patterns and user count.
  • Database Optimization:
    • Create appropriate indexes on frequently queried fields
    • Regularly optimize database tables
    • Monitor slow queries and optimize them
  • Caching: EspoCRM includes built-in caching. Ensure adequate resources for cache operations.
  • File Storage: Use persistent volumes with adequate IOPS for file operations.
  • Email Processing: Configure scheduled jobs for email processing to avoid blocking the main application.
  • Job Queue: Monitor background jobs and ensure they process efficiently.
  • Browser Caching: Configure browser caching for static assets to reduce server load.

Backup and Recovery

  • Regular Backups: Implement a backup strategy for your persistent volumes, especially /var/www/html/data which contains uploaded files and configurations.
  • Database Backups: Schedule regular MySQL database backups:
    Terminal window
    mysqldump -h hostname -u username -p espocrm > espocrm_backup_$(date +%Y%m%d).sql
  • Configuration Backups: Keep backups of your environment variables and configuration settings.
  • Disaster Recovery Plan: Document your recovery procedures and test them regularly.
  • Version Control: Keep your Dockerfile and configuration in version control (Git) for easy rollback.
  • Backup Testing: Regularly test your backups by restoring them to a test environment.
  • Backup Retention: Define and implement a backup retention policy (daily, weekly, monthly).

Monitoring and Logging

Monitor your EspoCRM instance for:

  • Application Performance: Response times, page load times, and API latency
  • Error Rates: Application errors, failed login attempts, and API errors
  • Resource Usage: CPU, memory, disk I/O, and network usage patterns
  • Database Performance: Query performance, connection pool usage, and slow queries
  • User Activity: Active users, session counts, and usage patterns
  • Email Delivery: Email sending success rates and bounce rates
  • Background Jobs: Job queue status and processing times
  • Security Events: Failed login attempts, suspicious activity, and access patterns

Scaling Considerations

  • Vertical Scaling: Increase CPU and memory for your Klutch.sh instance as your team grows
  • Volume Expansion: Monitor storage usage and expand volumes before reaching capacity
  • Database Optimization: Regularly review and optimize database queries and indexes
  • Archiving Strategy: Implement data archiving for old records to maintain performance
  • User Training: Train users on best practices to optimize system usage
  • Workflow Optimization: Regularly review and optimize business processes and workflows

Troubleshooting

Cannot Access EspoCRM

  • Verify your app is deployed and running in the Klutch.sh dashboard
  • Check that the internal port is set to 80
  • Ensure HTTP traffic type is selected (not TCP)
  • Review deployment logs for any startup errors
  • Verify environment variables are correctly set, especially ESPOCRM_SITE_URL

Database Connection Errors

  • Verify database credentials are correct in environment variables
  • Ensure database host is accessible from your Klutch.sh app
  • Check that the database exists and user has proper permissions
  • Verify database port (default 3306) is correct
  • Review MySQL/MariaDB logs for connection issues
  • Test database connectivity using MySQL client

Data Not Persisting

  • Verify persistent volumes are correctly attached at the specified mount paths
  • Check volume mount paths: /var/www/html/data, /var/www/html/custom, /var/www/html/config
  • Ensure volumes have sufficient space allocated
  • Review logs for permission or write errors
  • Check that the application has write permissions to mounted directories

Email Sending Issues

  • Verify SMTP environment variables are correctly set
  • Test SMTP credentials with your email provider
  • Check spam folders for sent emails
  • Review EspoCRM logs for email sending errors (Administration > Jobs)
  • Consider using a dedicated email service like SendGrid, Mailgun, or Amazon SES
  • Verify SMTP port is not blocked by firewall
  • Check email templates are properly configured

Performance Issues

  • Monitor resource usage in the Klutch.sh dashboard
  • Check database query performance in MySQL slow query log
  • Review and optimize frequently used queries
  • Consider increasing compute resources (CPU/RAM)
  • Ensure proper indexing on database tables
  • Review and optimize custom workflows and formulas
  • Check background job processing efficiency
  • Monitor disk I/O performance

Custom Modules Not Working

  • Verify persistent volume is attached to /var/www/html/custom
  • Check file permissions in the custom directory
  • Review EspoCRM logs for module loading errors
  • Ensure module files are correctly uploaded
  • Clear cache after installing custom modules (Administration > Clear Cache)
  • Verify module compatibility with your EspoCRM version

Session or Login Issues

  • Check that ESPOCRM_SITE_URL matches your actual URL
  • Verify cookie settings in EspoCRM configuration
  • Clear browser cache and cookies
  • Check session storage in the database
  • Review authentication logs for errors
  • Ensure system time is synchronized

Additional Resources


Conclusion

Deploying EspoCRM to Klutch.sh provides a powerful, flexible CRM platform for managing customer relationships, sales pipelines, and business processes. With Docker-based deployment, persistent storage, and comprehensive configuration options, you can build a production-ready CRM system that scales with your business. By following this guide, you’ve set up a secure, high-performance EspoCRM instance ready to manage contacts, opportunities, and customer interactions with a complete suite of CRM features and powerful API integration capabilities.