> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trymondo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Espocrm

## 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
```

<Warning>
  Never commit the `.env` file to version control. Store passwords securely in
  your password manager.
</Warning>

### Docker Compose Configuration

The deployment uses a shared image reference and multiple service definitions:

```yaml theme={null}
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:

```bash theme={null}
cd /opt/apps/espocrm
docker compose up -d
```

Verify all components are running:

```bash theme={null}
docker compose ps
```

## 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:

```bash theme={null}
# 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:

1. Update the image version tag in `docker-compose.yml`
2. Pull the new image:
   ```bash theme={null}
   docker compose pull
   ```
3. Deploy the updated stack:
   ```bash theme={null}
   docker compose up -d
   ```
4. Check logs for any migration issues:
   ```bash theme={null}
   docker compose logs -f
   ```

## Troubleshooting

### Database Connection Issues

If EspoCRM can't connect to the database:

1. Check MariaDB container status:
   ```bash theme={null}
   docker compose ps mariadb
   ```
2. Verify network connectivity:
   ```bash theme={null}
   docker compose exec espocrm ping mariadb
   ```
3. Check database credentials:
   ```bash theme={null}
   docker compose exec mariadb mysql -u ${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SHOW DATABASES;"
   ```

### WebSocket Issues

If real-time updates aren't working:

1. Check WebSocket container is running:
   ```bash theme={null}
   docker compose ps espocrm-websocket
   ```
2. Verify WebSocket URL configuration matches the Traefik route.
3. Test WebSocket connectivity from browser developer tools.

### Traefik Routing Problems

If the site is unreachable:

1. Check Traefik logs:
   ```bash theme={null}
   docker logs traefik
   ```
2. Verify DNS resolution for `crm.trymondo.com`
3. Confirm Traefik network is correctly attached to all containers.

## Resources

* [Official EspoCRM Docker Documentation](https://docs.espocrm.com/administration/docker/)
* [MariaDB Documentation](https://mariadb.com/kb/en/documentation/)
* [Traefik v2 Documentation](https://doc.traefik.io/traefik/v2.0/)

## 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
