Serve the CRM on your own domain with a real certificate — Cloudflare or certbot.
By default the installer serves the CRM over plain HTTP on port 80 — perfect for an IP address or a trial. To put it on your own domain with a padlock, you point the domain at your server and terminate HTTPS in front of the stack. The easiest way needs no terminal at all: you bind the domain right inside the CRM (Settings → Hosting — below). The manual server paths are there if you prefer them. You don't need all of these — pick one.
Three things need to be true first: the CRM is already installed and opens over HTTP at your server's IP; the server has a PUBLIC IP — a VPS or dedicated box, not a laptop behind a home router (that can't be reached from the internet without port-forwarding); and you control a domain in a registrar or in Cloudflare. Open the web ports in the server's firewall before you begin — port 80 for both paths, plus 443 for the certbot path:
sudo ufw allow 80/tcp sudo ufw allow 443/tcp
In your registrar or DNS panel, create an A record for the hostname you want (for example crm.yourbrand.com) pointing at your server's public IP, then wait for it to resolve — usually a few minutes.
A crm.yourbrand.com -> YOUR_SERVER_IP
Once the A record resolves, open the CRM as the owner and go to Settings → Hosting. Add your domain and press Save & apply. The CRM reconfigures its own web layer for you: it serves the panel on the server IP AND your domain, and cloaks every other host pointed at this box (your prelander domains) so the login never appears on them. No SSH, no nginx, no editing files — it takes a few seconds while the web layer reloads. (It uses the update-agent that ships with the standard install; if that isn't present the page tells you, and you can use a manual path below.)
Then set the encryption at Cloudflare's edge: the A record Proxied (orange cloud), SSL/TLS → Overview → Flexible, and SSL/TLS → Edge Certificates → Always Use HTTPS on. That's the padlock — visitors are sent to https and Cloudflare terminates it. Done.
You do NOT need this if you used Settings → Hosting above — it sets up the same thing for you. The two paths below do it by hand instead; pick one, you don't need both.
Add the domain to Cloudflare and set that A record to Proxied (orange cloud). Because the CRM serves plain HTTP on port 80, set SSL/TLS → Overview → encryption mode to Flexible — Full and Full (strict) expect real TLS on your origin, which the default install doesn't have (that's the certbot path below). Then turn on SSL/TLS → Edge Certificates → Always Use HTTPS so visitors are always sent to the padlocked https:// address. Cloudflare terminates HTTPS at its edge and forwards to your port 80 — no software or renewals on the box. Finally, set your public URL in .env so the browser and API agree, and re-up.
CORS_ORIGINS=https://crm.yourbrand.com docker compose up -d
Flexible encrypts the visitor↔Cloudflare leg (that's the padlock) but leaves the Cloudflare↔your-server leg unencrypted — fine to get going. Do NOT switch to Full or Full (strict) while your origin is plain HTTP: those modes need real TLS on your server on port 443 and will otherwise break the site (same failure as before). For end-to-end encryption, either follow the certbot path below, or — staying on Cloudflare — add a free Cloudflare Origin Certificate to your server, then move to Full (strict).
If you'd rather terminate TLS on your own box, run a small nginx in front of the CRM and let certbot manage a free Let's Encrypt certificate. Keep the A record DNS-only (grey cloud, not proxied) so certbot can validate the domain.
First move the CRM off port 80 so the host's nginx can own it — set WEB_PORT in .env and re-up:
WEB_PORT=8080 docker compose up -d
Install nginx and certbot, then add a reverse-proxy site for your domain. The two Upgrade headers keep the realtime feed working:
sudo apt update && sudo apt install -y nginx certbot python3-certbot-nginx
# /etc/nginx/sites-available/crm
server {
server_name crm.yourbrand.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Enable the site, then let certbot fetch the certificate and rewrite nginx to serve 443 with an automatic 80-to-443 redirect. It also installs a systemd timer that renews the certificate before it expires — nothing to do again.
sudo ln -s /etc/nginx/sites-available/crm /etc/nginx/sites-enabled/crm sudo certbot --nginx -d crm.yourbrand.com
Last, tell the app its public origin and re-up:
CORS_ORIGINS=https://crm.yourbrand.com docker compose up -d
This gets the same result as Settings → Hosting above — the panel on your domain, prelander domains cloaked — for when you'd rather run a script than click. If this box also serves your prelander/cloak domains, the admin panel must stay separate from them (a prelander domain should never show the login). The bundled helper does it on the server: it auto-detects your IP, serves the admin on your IP + admin domain, routes every other host to the cloak, moves the CRM to port 8080 and reloads nginx for you:
cd ~/d0pe-crm curl -fsSL https://d0pe.app/setup-domain.sh -o setup-domain.sh sudo ADMIN_DOMAIN="crm.yourbrand.com" bash setup-domain.sh
It writes /etc/nginx/sites-available/d0pe, which stays yours to edit — add more admin domains to the server_name, add custom routes — then sudo nginx -t && sudo systemctl reload nginx. Re-run the script any time to change domains. For a plain CRM-on-a-domain with no prelanders you don't need this; the Cloudflare path above is enough. Either way, finish with the Cloudflare/CORS step (A → your IP, Proxied, Flexible, Always Use HTTPS; CORS_ORIGINS=https://your-domain).
Either way your leads never leave your server — this only concerns the encryption layer in front of the CRM.
Give DNS a minute or two to resolve, then open https://crm.yourbrand.com in a browser: you should see the padlock and the CRM login. If it loads and you can sign in, you're done. From a terminal you can confirm the certificate answers:
curl -I https://crm.yourbrand.com