Overview
This guide covers the deployment and configuration of EspoCRM using Docker Compose behind Traefik reverse proxy. EspoCRM serves as Mondo’s customer relationship management solution, accessible at crm.trymondo.com
.
Architecture
EspoCRM is deployed as a multi-container application with the following components:
- MariaDB: Database server storing EspoCRM data
- EspoCRM: Main application container
- EspoCRM Daemon: Background process container
- EspoCRM WebSocket: Real-time communications container
All services use the external traefik-net
network for routing through Traefik.
Prerequisites
- Docker Engine (24.0+)
- Docker Compose v2
- Traefik reverse proxy configured and running
- External
traefik-net
network
- DNS configured for
crm.trymondo.com
Deployment
Directory Structure
environments/prod/espocrm/
├── docker-compose.yml # Main configuration file
├── .env # Environment variables (not in repo)
Environment Variables
Create a .env
file with the following variables:
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_DATABASE=espocrm
MYSQL_USER=espocrm_user
MYSQL_PASSWORD=your_secure_password
ESPO_ADMIN_USERNAME=admin
ESPO_ADMIN_PASSWORD=your_secure_password
ESPO_SITE_URL=https://crm.trymondo.com
Never commit the .env
file to version control. Store passwords securely in
your password manager.
Docker Compose Configuration
The deployment uses a shared image reference and multiple service definitions:
x-espocrm-image: &espocrm-image
image: espocrm/espocrm:9.0.8
services:
mariadb:
image: mariadb:11.7.2
container_name: espocrm-db
restart: unless-stopped
init: true
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- mariadb-data:/var/lib/mysql
healthcheck:
test:
[
'CMD-SHELL',
'mariadb-admin ping -h 127.0.0.1 -u root -p$${MYSQL_ROOT_PASSWORD}',
]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
networks:
- espocrm-net
espocrm:
<<: *espocrm-image
container_name: espocrm
restart: unless-stopped
init: true
depends_on:
mariadb:
condition: service_healthy
environment:
ESPOCRM_DATABASE_DRIVER: mysql
ESPOCRM_DATABASE_HOST: mariadb
ESPOCRM_DATABASE_USER: ${MYSQL_USER}
ESPOCRM_DATABASE_PASSWORD: ${MYSQL_PASSWORD}
ESPOCRM_DATABASE_NAME: ${MYSQL_DATABASE}
ESPOCRM_ADMIN_USERNAME: ${ESPO_ADMIN_USERNAME}
ESPOCRM_ADMIN_PASSWORD: ${ESPO_ADMIN_PASSWORD}
ESPOCRM_SITE_URL: ${ESPO_SITE_URL}
volumes:
- html-data:/var/www/html
healthcheck:
test: ['CMD-SHELL', 'curl -sf http://localhost || exit 1']
interval: 10s
timeout: 5s
retries: 5
networks:
- traefik-net
- espocrm-net
labels:
- traefik.enable=true
- traefik.http.routers.espocrm.rule=Host(`crm.trymondo.com`)
- traefik.http.routers.espocrm.entrypoints=web,websecure
- traefik.http.routers.espocrm.tls=true
- traefik.http.routers.espocrm.tls.certresolver=production
- traefik.http.services.espocrm.loadbalancer.server.port=80
- traefik.http.routers.espocrm.middlewares=secureHeaders@file
espocrm-daemon:
<<: *espocrm-image
container_name: espocrm-daemon
restart: unless-stopped
init: true
entrypoint: docker-daemon.sh
depends_on:
- espocrm
volumes:
- html-data:/var/www/html
networks:
- espocrm-net
espocrm-websocket:
<<: *espocrm-image
container_name: espocrm-websocket
restart: unless-stopped
init: true
entrypoint: docker-websocket.sh
depends_on:
- espocrm
environment:
ESPOCRM_CONFIG_USE_WEB_SOCKET: 'true'
ESPOCRM_CONFIG_WEB_SOCKET_URL: 'wss://crm.trymondo.com/ws'
ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN: 'tcp://*:7777'
ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN: 'tcp://espocrm-websocket:7777'
volumes:
- html-data:/var/www/html
networks:
- traefik-net
- espocrm-net
labels:
- traefik.enable=true
- traefik.http.routers.espocrm-ws.rule=Host(`crm.trymondo.com`) && PathPrefix(`/ws`)
- traefik.http.routers.espocrm-ws.entrypoints=web,websecure
- traefik.http.routers.espocrm-ws.tls=true
- traefik.http.routers.espocrm-ws.tls.certresolver=production
- traefik.http.services.espocrm-ws.loadbalancer.server.port=80
volumes:
mariadb-data:
html-data:
networks:
traefik-net:
external: true
espocrm-net:
external: true
Deployment Commands
Deploy the stack with:
cd /opt/apps/espocrm
docker compose up -d
Verify all components are running:
Configuration Highlights
Traefik Integration
EspoCRM is configured with the following Traefik routing:
- Main application at
crm.trymondo.com
- WebSocket endpoint at
crm.trymondo.com/ws
- TLS certificate managed by Traefik’s
production
resolver
- Security headers applied through Traefik middleware
WebSocket Configuration
Real-time communication is enabled through ZeroMQ and WebSockets:
- WebSocket URL:
wss://crm.trymondo.com/ws
- Internal ZeroMQ communication between containers
- Separate Traefik router rule for WebSocket traffic
Volume Management
The deployment uses Docker named volumes:
mariadb-data
: Persistent storage for the database
html-data
: Shared volume for EspoCRM application data across all containers
Maintenance
Backup Strategy
EspoCRM data should be backed up regularly using Restic/Backrest:
# Backup database
docker compose exec mariadb mysqldump -u root -p${MYSQL_ROOT_PASSWORD} ${MYSQL_DATABASE} > backup_$(date +%Y%m%d).sql
# Include volumes in Backrest paths
# /var/lib/docker/volumes/espocrm_mariadb-data
# /var/lib/docker/volumes/espocrm_html-data
Updates
To update EspoCRM:
- Update the image version tag in
docker-compose.yml
- Pull the new image:
- Deploy the updated stack:
- Check logs for any migration issues:
Troubleshooting
Database Connection Issues
If EspoCRM can’t connect to the database:
- Check MariaDB container status:
docker compose ps mariadb
- Verify network connectivity:
docker compose exec espocrm ping mariadb
- Check database credentials:
docker compose exec mariadb mysql -u ${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SHOW DATABASES;"
WebSocket Issues
If real-time updates aren’t working:
- Check WebSocket container is running:
docker compose ps espocrm-websocket
- Verify WebSocket URL configuration matches the Traefik route.
- Test WebSocket connectivity from browser developer tools.
Traefik Routing Problems
If the site is unreachable:
- Check Traefik logs:
- Verify DNS resolution for
crm.trymondo.com
- Confirm Traefik network is correctly attached to all containers.
Resources
Next Steps
- Set up monitoring and alerting for EspoCRM services with Prometheus/Grafana
- Implement automated backups of volumes and database dumps
- Configure SMTP for email notifications
- Explore EspoCRM API integrations with other Mondo services