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