EspoCRM behind Traefik with Let's Encrypt

Traefik can publish a Docker EspoCRM over HTTPS with certificates issued by Let's Encrypt, provided ports, DNS and the container labels agree. This page covers how the pieces fit and what to confirm before you commit to it.

On this page

When EspoCRM behind Traefik with Let's Encrypt fits your host

Traefik can publish a Docker-based EspoCRM over HTTPS with Let's Encrypt certificates, but only when DNS, ports 80 and 443, and the container labels all agree on the same hostname. This setup fits a host that already runs several Docker applications and needs one edge proxy to terminate TLS and route each hostname to the right container. It also fits teams that prefer label-driven deployment, where the routing and certificate settings live beside the EspoCRM service in the Compose file. If your host runs only EspoCRM, or you want the least moving parts, the install script's bundled Nginx and MariaDB stack, or a plain Nginx or Apache host, is usually the simpler choice. Those options give you one web server to configure and one place to look when something breaks.

Whatever proxy you choose, the EspoCRM server requirements stay the same. The server configuration docs list PHP 8.3 to 8.5, MySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15, and EspoCRM's background jobs depend on cron or a scheduled task. Traefik does not run those jobs, does not replace the PHP runtime, and does not remove the need for a scheduler on the host or in a sidecar container. Confirm before you start that the image or base system you plan to use meets these versions, and that someone owns the scheduled job from day one. A proxy that serves the login page while background jobs silently stop is a common failure mode that looks healthy from the outside.

Before you write any labels, confirm three things with your network and DNS owners: the public hostname resolves to the host, inbound ports 80 and 443 reach Traefik, and no other service on the host already holds those ports. The ACME challenge that Let's Encrypt uses to issue a certificate depends on the first two, so a mismatch shows up as a certificate that never issues. Ask who controls the ACME account and certificate storage file, since that file holds the private keys and needs to be backed up and protected. Also confirm the Traefik and EspoCRM versions you intend to use against their current documentation, because label syntax and entrypoint defaults change between releases and this page does not pin them.

Traefik settings for EspoCRM and when each fits

This table compares the Traefik decisions that shape how EspoCRM is published, from the HTTP redirect to where TLS ends. Read each row for the condition that makes an option fit and the cost of choosing it. Confirm exact configuration keys against the Traefik documentation for the version you run.

DecisionOptionFits whenCost of choosing it
HTTP to HTTPS redirectRedirect on the web entrypoint to the websecure entrypointAll public access to the CRM should use HTTPS, which is the normal case for customer dataPlain HTTP clients get a redirect, so any non-browser integration must follow it or call HTTPS directly
ACME challenge typeHTTP-01 challenge on port 80Port 80 is reachable from the internet and the host name resolves publiclyPort 80 must stay open for renewals, which some hardened networks do not allow
ACME challenge typeTLS-ALPN-01 challenge on port 443Only port 443 can be exposed, for example behind a restrictive perimeterRequires the TLS challenge to pass through the same entrypoint that serves EspoCRM, so confirm the setup with your firewall team
ACME challenge typeDNS challenge through a DNS providerThe host is not reachable from the internet or you need wildcard certificatesNeeds provider API credentials stored as secrets and a supported Traefik provider, so confirm the provider is available in your version
Certificate storageacme.json file on a persistent volumeA single Traefik instance runs on the host, which is the typical single-host setupThe file holds private keys, so restrict its permissions and include it in backups with the same care as the database
Host rule and path prefixesDedicated host name for EspoCRM with no path prefixEspoCRM is the only app on the host name and the application expects the root pathEach app needs its own host name and DNS record, which adds naming and certificate work
Host rule and path prefixesPath prefix on a shared host nameSeveral apps must share one domain and you accept the extra routing rulesEspoCRM generates absolute links and assets, so a prefix often needs extra configuration. Test login, uploads and the WebSocket path
TLS terminationTerminate TLS at Traefik and forward plain HTTP to the EspoCRM containerTraefik is the single point for certificates and the internal network is trustedEspoCRM must be told it sits behind a proxy and that the original scheme is HTTPS, or links and secure cookies can break
TLS terminationPass TLS through to the containerThe application must hold its own certificate or the network policy demands end-to-end encryptionTraefik cannot read routing data inside the connection, and certificate renewal moves into the container, which adds operational work

How the ACME TLS challenge issues certificates for EspoCRM

The ACME TLS challenge is how Let's Encrypt confirms that whoever requests a certificate for the EspoCRM hostname actually controls it. Traefik's ACME resolver asks the certificate authority for a challenge, and the authority then connects back to the hostname on the public internet, usually on port 443, to check the answer Traefik presents. That check only succeeds if the public DNS record for the hostname already points at the host where Traefik listens and the port is reachable from outside your network. For this reason, create the DNS record before the first request reaches Traefik, and confirm from a machine outside your network that the name resolves to the right address and that port 443 answers.

Keep the certificate store, the acme.json file that Traefik writes, on a named volume or a bind-mounted host path so it survives container restarts and image updates. If the store is lost, Traefik requests new certificates on startup, and repeated requests can exhaust the issuance limits Let's Encrypt applies to each account and domain. Renewals depend on the same stored state. Before you go live, point the resolver at the Let's Encrypt staging certificate authority and test the full path, because staging certificates are untrusted by browsers but follow the same challenge flow and carry much looser limits. Confirm the current rate limits and the staging endpoint in Let's Encrypt's own documentation before you rely on either, since those values are the vendor's to set and change.

A challenge failure is easy to miss because Traefik keeps serving traffic. The browser shows a default or self-signed certificate for the EspoCRM hostname instead of a Let's Encrypt certificate, and the login page may still load over HTTPS. To diagnose it, read the Traefik container logs for ACME errors, which normally name the failed domain and the reason the challenge was refused, and inspect the stored certificate entry in acme.json for the hostname. Also check that the router's Host rule matches the hostname exactly. If the logs show a DNS or connection error, the fix sits outside Traefik, in the DNS record, the firewall or the port mapping.

Setting up Traefik and the EspoCRM container with labels

This sequence takes a Docker EspoCRM host from DNS and open ports to a working HTTPS login page, with Traefik handling certificates and routing while the database and daemon stay off the public network. Each step ends with a check you can run before moving on.

  1. Confirm DNS and inbound ports 80 and 443

    Before any container starts, confirm that the hostname you plan to use for EspoCRM resolves to the public address of the host, and that inbound TCP ports 80 and 443 reach that host through your firewall, security group or load balancer. Port 80 is needed for the HTTP redirect and, with the default HTTP challenge, for Let's Encrypt validation. Check from outside your network with a DNS lookup of the hostname and a connection test to each port. The step is done when the name resolves to the expected address and both ports answer from outside. Confirm with your network team which firewall rules and any upstream load balancer apply, because a blocked port 80 is a common reason certificate issuance fails.

  2. Create the shared proxy network

    Create a dedicated Docker network that Traefik and every application it publishes will join. On the Docker host, run docker network create proxy once, then confirm it exists with docker network ls. Keep this network separate from the default Compose network that EspoCRM uses internally for its database and daemon. This separation is what keeps the database and background containers unreachable from the proxy-facing side. The step is done when the proxy network appears in the list and no database or daemon container is attached to it.

  3. Run Traefik with entrypoints and a persistent ACME store

    Start Traefik as its own Compose project on the proxy network. Define two entrypoints, one named web on port 80 and one named websecure on port 443, and enable the Docker provider with exposedByDefault set to false so only containers that carry explicit labels are published. Configure a certificate resolver that uses the ACME TLS challenge, and point its storage at a file such as acme.json on a volume that survives container restarts. Set the file mode to 600 before Traefik writes to it. Start the stack and check the Traefik logs for resolver errors. The step is done when Traefik runs, the dashboard or logs show both entrypoints listening, and the ACME file persists across a restart. Confirm the exact challenge type and option names against the Traefik version you install.

  4. Attach the EspoCRM application container to the proxy network

    In the EspoCRM Compose file, keep the database and daemon services on the internal default network only. Attach just the application service to both the internal network and the external proxy network, and mark the proxy network as external so Compose uses the one you created. Do not publish any container port to the host for the application, because Traefik reaches it over the Docker network. Run docker compose config to review the resolved file and confirm that the database and daemon services list no proxy network and no published ports. The step is done when the config output shows the application as the only service on both networks.

  5. Add labels for the host rule, websecure router and resolver

    Add Traefik labels to the EspoCRM application service. Set traefik.enable to true, and set a router rule with the hostname, for example a Host rule for the name you confirmed in the first step. Bind that router to the websecure entrypoint, enable TLS on it, and assign your certificate resolver name so Traefik requests a certificate for the host. Set the backend port label to the port the EspoCRM container listens on internally, which you should confirm from the image documentation rather than assume. Recreate the service with docker compose up -d and check the Traefik logs for the certificate request. The step is done when Traefik shows an active router for the host and the logs record a certificate obtained for it.

  6. Add the HTTP to HTTPS redirect router

    Add a second router to the same application service that matches the same host rule on the web entrypoint. Attach a redirect middleware that sends requests to the HTTPS scheme and keeps the path. Use a middleware name that does not collide with others on the same Traefik instance, because labels are shared across all containers the proxy reads. Once the stack is recreated, test the redirect from a machine outside the host with `curl -I The check passes when the response is a 301 or 302 status with a Location header beginning with https. The step is done when that redirect is returned and the HTTPS address follows.

  7. Verify the certificate and the EspoCRM login page

    Open the HTTPS address in a browser and inspect the certificate. The issuer should be the certificate authority Traefik used through ACME, and the expiry date should fall in the future. Confirm that the browser shows no mixed-content or trust warnings, then load the EspoCRM login page and sign in with an administrator account to confirm the application responds through the proxy. Record the issuer and expiry in your build notes, and check that the ACME file is backed up with the rest of the proxy volumes. The step is done when the login page loads over HTTPS with a valid certificate and the first sign-in succeeds. Confirm final behavior with your own security team, since trust settings differ by environment.

  8. Run several applications on the same host

    To publish another application on the same host, give it its own hostname, attach its application container to the proxy network, and add its own router and service labels. Traefik will route each hostname to the correct container and request a separate certificate for each name. Keep each application's database and background containers on its internal network only. Repeat the redirect and certificate checks for every new hostname. The step is done when each hostname returns its own login page over HTTPS and the first application still works after the second is added.

Running EspoCRM beside other apps on one host

When a host serves only EspoCRM, the setup stays small: one Traefik instance terminates TLS for one hostname and forwards traffic to the EspoCRM container. Traefik reads its configuration from labels on the EspoCRM service, so the Compose file carries the routing rule, the entrypoint and the certificate resolver in one place. The application container should not publish ports 80 or 443 to the host. Only Traefik does that.

  • One router: a single Host() rule matches the CRM hostname and sends traffic to the EspoCRM service port.
  • Entrypoints: define a web entrypoint on port 80 for the HTTP to HTTPS redirect and a websecure entrypoint on port 443 for application traffic.
  • ACME resolver: configure one certificate resolver for the TLS challenge, and confirm the hostname resolves to the host before the first request.
  • Labels only: keep the EspoCRM labels to the router, service and TLS settings so the Compose file stays readable during upgrades.
  • No conflicting proxy: confirm the EspoCRM install script's Nginx stack is not also running on this host, since it would compete for the same ports.

After the stack starts, check that the HTTP address redirects to HTTPS and that the certificate presented belongs to the CRM hostname.

Security and operational controls at the Traefik edge

Traefik sits in front of EspoCRM and decides who reaches the application, how traffic is encrypted and what gets logged. The cards below cover the edge controls that matter most, and each one ends in a check your team can run before go-live and repeat after changes.

Keep the dashboard and API private

Traefik's dashboard and API expose routing details and can change configuration, so they should not be published on a public hostname. Bind the dashboard to an internal router protected by an admin-only middleware, or disable it in production. To verify, request the dashboard hostname from outside your network and confirm it is refused or unreachable, and confirm that only the EspoCRM and certificate routes appear on the public entrypoint.

Limit the Docker socket mount

Traefik's Docker provider reads container labels through the Docker socket, and anyone with write access to that socket effectively controls the host. Mount the socket read-only where your Traefik version allows it, or place a socket proxy that exposes only the read calls Traefik needs. To verify, inspect the Traefik service definition and confirm the socket mount flags and that no other container mounts the socket.

Enforce HTTPS and security headers

Redirect every port 80 request to HTTPS with a permanent redirect, then apply a middleware that sets HSTS, a content security policy suited to EspoCRM's front end and frame restrictions on the EspoCRM router. Test the chain with a TLS scanner and a header check against the public hostname. Confirm that the HSTS lifetime is one you intend to keep, because browsers cache it.

Protect ACME storage and private keys

The ACME file that Traefik writes holds your account key and issued certificate private keys. Keep it on a volume readable only by the Traefik user, typically mode 600 on the JSON file, and exclude it from unencrypted backups or store backups encrypted. To verify, check the file mode and owner on the host, confirm the file is not world-readable inside the container, and run a restore test on a separate host.

Align EspoCRM policy with the edge

EspoCRM's own security settings must match what Traefik allows. Use IP allowlists for administrator access where your network supports them, require two-factor authentication, shorten auth token lifetime, disable password recovery for admin accounts and keep admins off daily work. Note that UI-driven upgrades are disabled by default as of version 10.0, so plan upgrades through your change process. Verify each setting in the administration panel and record the result.

Log access and watch certificate renewal

Keep Traefik access logs and error logs in a location your team reviews, and forward them to your log platform if you have one. Track certificate renewal events and alert on failed ACME challenges, since an expired certificate stops the public site. Test the alert by temporarily blocking port 443 in a staging environment. Confirm that log retention matches your internal policy and that EspoCRM's own application logs are collected alongside the edge logs.

Where Traefik conflicts with the EspoCRM install script stack

If the host was built with the EspoCRM installation script for Ubuntu, Debian or Linux Mint, it already runs a Docker stack with Nginx and MariaDB, and that stack may have set up Let's Encrypt certificates. That means the host probably already owns ports 80 and 443, so Traefik cannot bind to them until the existing stack is changed or removed. The script is not documented as supporting Traefik, so do not assume its generated files will accept a proxy change without edits. Before you touch anything, confirm which containers publish host ports and which ones only listen on the internal Docker network.

You have three realistic paths, and the choice should follow from what you need to keep. You can keep the script stack and accept Nginx as the public entry point, which avoids new risk but gives you no Traefik labels. You can move only the EspoCRM containers behind Traefik by hand, removing the Nginx port bindings and adding labels, which is viable if you are comfortable maintaining a hand-edited Compose file that the script does not know about. You can rebuild on a Compose file you write yourself, which is cleanest for a multi-app host but means migrating data. Ask your engineers to state which path they chose and why, and who will own the resulting files after handover.

Whichever path you take, check the command.sh backup and restore routine first, because it was written around the script's own containers and paths. Run a test backup and a test restore on a copy before the proxy change, then repeat both afterward to confirm that the database, files and configuration still line up with the new container names and network. Also test the upgrade routine in the same way, since a proxy change can break the assumptions an upgrade step makes. Record the results, so a failed change can be rolled back to the known working stack.

Limits to confirm before you publish EspoCRM through Traefik

Traefik, DNS, the network path and the hosting provider each decide whether a Let's Encrypt certificate issues and whether EspoCRM stays reachable. None of these can be settled from a configuration example alone, so confirm each one against vendor documentation or a test environment before you publish the host.

Traefik version and label syntax

The label keys on the EspoCRM container, such as entrypoint names, router rules and certificate resolver settings, depend on the Traefik release you run. Examples written for one major version can fail silently on another, leaving the router unmatched. Check the label syntax against the Traefik documentation for your exact version, then confirm the router appears in the dashboard or API before you test TLS.

DNS provider and ACME challenge

The ACME challenge type you choose must be supported by your DNS provider and reachable from the internet. The HTTP challenge needs port 80 open to Traefik, while a DNS challenge needs API access and credentials for your DNS zone. Confirm which challenge your provider and network allow, and where those credentials will be stored, before you enable the resolver.

ISP and cloud firewall rules

Residential ISPs, cloud security groups and upstream firewalls often block inbound port 80 or 443, which breaks the HTTP challenge and the HTTP to HTTPS redirect. Check that both ports reach the Traefik host from the public internet, not only from your internal network. A test from outside your network is the only reliable confirmation.

WebSocket and upload limits through the proxy

EspoCRM's WebSocket daemon and attachment uploads both pass through Traefik, so the proxy must forward upgrade requests and allow the body sizes and timeouts your users need. Traefik defaults may differ from the limits your PHP and EspoCRM settings expect. Confirm request size and timeout settings with the EspoCRM server configuration docs, then test a large attachment upload and a live notification.

Hosting provider rules for public TLS

Some hosting providers restrict inbound traffic, block public web services on certain plans or require approval before a host serves public certificates. Shared or managed hosting may also terminate TLS in front of your server, which changes where certificates live. Confirm with the provider that the host may serve public TLS on the ports you plan to use, and that no provider load balancer conflicts with Traefik.

What EspoCRM behind Traefik costs and needs from your team

What drives the effort of putting EspoCRM behind Traefik?

The effort depends mainly on how many applications already share the host, how much Docker and reverse proxy work exists today, and how much access you can grant for DNS and firewall changes. A host that only runs EspoCRM is simpler than one that already publishes several apps through Traefik, because labels, entrypoints and certificate storage have to be checked against what is running. Testing needs also matter: confirming HTTP to HTTPS redirects, certificate issuance, WebSocket traffic and the background job schedule takes longer than the router itself. Ask for these four inputs to be written down before a scoping call, since they decide the size of the work more than the EspoCRM configuration does.

Can one engineer set up EspoCRM behind Traefik alone?

A single engineer who knows Docker Compose, DNS and TLS can usually complete a single-host setup, provided they have root or Docker access, a domain they can manage, and time to test. The harder part is ownership after go-live: the person who configures Traefik must also understand certificate storage, renewal, and how the EspoCRM containers, database and daemon restart together. If that knowledge sits with one person who is unavailable during an incident, the setup is fragile. Many teams keep the build in-house and bring in a partner only for a review or for the parts they have not done before.

What does DeployOpen need from our team to start?

The work needs four things from your side. First, host access, either an SSH account with sudo or a Docker host you administer, plus confirmation of which other services already listen on ports 80 and 443. Second, DNS changes made by someone who controls the zone, since the hostname has to resolve to the host before the ACME TLS challenge can succeed. Third, a test window in which the instance can be restarted and users can be told about brief interruptions. Fourth, a named owner for certificates and the Traefik configuration who can approve changes and receive renewal alerts. These should be agreed in the written scope before work begins.

How long does a single-host EspoCRM setup behind Traefik take?

No duration is fixed for this topic, and any figure given without a scoping conversation would be a guess. The timeline is set by the inputs listed above: how many applications share the host, whether the Docker and reverse proxy layer is already standardized, how quickly DNS and firewall changes can be made, and how much testing your organization requires before go-live. Ask for the scope, the deliverables and the timeline in writing, and check that the plan includes a rollback step and a test window. A short written scope usually makes the schedule easier to confirm.

Is self-hosting EspoCRM free, and what do we actually pay for?

The EspoCRM open-source edition can be downloaded and self-hosted for free, and its code is licensed under AGPL-3.0. EspoCRM Cloud is a separate paid service, priced at 15 US dollars per user per month on the Basic plan with a minimum of 3 users, according to the EspoCRM pricing page. Self-hosting therefore shifts the cost to infrastructure and labor: the server or virtual machine, storage, backups, DNS, the engineer's time for the Traefik setup, and ongoing operations. Ask any partner to separate one-time setup fees from recurring support so you can compare the total with a cloud subscription over the same period.

What recurring work follows go-live behind Traefik?

Several tasks recur after go-live. Certificate renewal should be checked regularly, both that Let's Encrypt certificates are renewing and that the stored certificate data is backed up. Traefik and Docker images need updates that are tested against the EspoCRM stack before rollout. EspoCRM itself is upgraded on its own schedule, and major upgrades need planning around extensions, customizations and PHP versions. Background jobs and the WebSocket daemon should be monitored after each change. Ask who performs each task, how often, and whether the arrangement is a one-time engagement or an ongoing retainer, since DeployOpen offers ongoing support and upgrades as retainers.

What should we check on the EspoCRM and Traefik security side?

Beyond TLS, the reverse proxy layer is the place to control who can reach the CRM. Confirm that only the required entrypoints are published, that the Traefik dashboard is not exposed on the internet, and that the EspoCRM security settings match your policy, including two-factor authentication, password rules and limits on token lifetime. The EspoCRM security documentation also recommends restricting access by IP address where your network allows it. Ask the implementer to show which ports are open, how certificate private keys are protected on disk, and who can change labels or the ACME configuration.

How DeployOpen scopes and delivers EspoCRM behind a proxy

DeployOpen plans, implements, hardens, documents and supports self-hosted EspoCRM inside your own infrastructure, including the Traefik routing, certificate issuance and container labels described on this page. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.

How we scope

  • Written scope covers the hosts, domains, networks and Docker host that Traefik will front for EspoCRM.
  • We confirm how DNS records, public ports and the ACME challenge type will be handled in your environment.
  • Scope lists every other application on the shared host so routing rules and entrypoints are agreed up front.

How we build

  • We configure Traefik entrypoints, the HTTP to HTTPS redirect and the ACME resolver in your environment.
  • EspoCRM container labels, the websocket route and forwarded headers are built and tested against your domain.
  • We test certificate issuance, renewal behavior and failure handling in a staging environment before cutover.

How we hand over

  • Handover includes the Compose and Traefik configuration files, a routing map and a record of certificate storage locations.
  • Runbooks describe how to add a new application to the shared host without disrupting EspoCRM routing.
  • We document the verification steps your team can repeat after upgrades, host reboots or Traefik version changes.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after handover.
  • Retainer work can cover Traefik version upgrades, ACME renewal monitoring and changes to routing for new applications.
  • Ask any provider to confirm in writing who owns the certificate storage, backups and access to the Traefik dashboard.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.