Domain, subdomain & SSL
Point a (sub)domain at the install, issue a free certificate through cPanel AutoSSL or Let's Encrypt, force HTTPS and update APP_URL safely.
HTTPS is not optional for this product: Meta OAuth requires an HTTPS redirect URI, WhatsApp webhooks are signature-checked, push and OTP flows live in browsers and mobile apps, and cPanel AutoSSL issues certificates for free. This page gets a fresh (sub)domain from DNS to a green padlock.
Who this is for
- Super-admin / hosting admin — wiring
crm.yourdomain.comto the install. - Support — diagnosing redirect loops, mixed-content warnings and "Meta says redirect URI invalid".
Prerequisites: the app is already uploaded and the installer completed (cPanel deployment walkthrough).
Step 1 — Create the subdomain (DNS)
If your domain's nameservers already point at this host (the usual case for cPanel):
- cPanel → Domains → Create A New Domain →
crm.yourdomain.com. - The DNS
Arecord is created automatically. Nothing else to do.
If the domain's DNS lives elsewhere (registrar, Cloudflare):
-
Create the subdomain in cPanel first (document root as in the walkthrough).
-
Then add a DNS record at the DNS provider:
Type Name Value Acrmyour server's IP address (If using Cloudflare, start with the proxy off (grey cloud) while you issue the certificate, then decide about proxying — see Reverse proxies below.)
Expected result: crm.yourdomain.com resolves to the server (a 403/placeholder is fine at this stage).
Step 2 — Issue the certificate
Two free paths, both inside cPanel:
Option A — AutoSSL (most cPanel hosts):
- cPanel → SSL/TLS Status.
- Tick the domain → Run AutoSSL.
- Wait 1–5 minutes; refresh until the domain shows a padlock.
Option B — Let's Encrypt plugin (hosts with the plugin installed):
- cPanel → Let's Encrypt SSL (or "SSL/TLS → Manage SSL Hosts").
- Choose the domain → Issue.
- Wait for issuance to complete.
Expected result: https://crm.yourdomain.com/ loads without a browser warning.
Certificate fails to issue? The common causes are: DNS not yet resolving to this server, a Cloudflare proxy in front (the HTTP-01 challenge can be blocked), or the document root not existing yet. Fix DNS first, then re-run AutoSSL.
Step 3 — Force HTTPS
Pick one:
cPanel toggle (easiest): cPanel → Domains → find the subdomain → toggle Force HTTPS Redirect on. (The exact label varies by panel version.)
.htaccess rule (works everywhere): add below the existing RewriteEngine On line in the site's .htaccess (for a standard layout that file is public/.htaccess):
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Behind Cloudflare? If Cloudflare terminates TLS (orange cloud), the X-Forwarded-Proto condition above prevents a redirect loop. Also set TRUSTED_PROXIES in .env to Cloudflare's IP ranges so Laravel sees real visitor IPs — otherwise the login lockout and audit log record Cloudflare's addresses. See Environment variables.
Step 4 — Update the application
Two values must reflect the final HTTPS URL, or generated links, OAuth redirects and webhook URLs will be wrong:
-
.env:APP_URL=https://crm.yourdomain.com # On HTTPS deployments, also uncomment the session hardening block: SESSION_SECURE_COOKIE=true SESSION_HTTP_ONLY=true SESSION_SAME_SITE=lax(If the install lives in a subfolder and the document root is not
public/,APP_URLmust include the subfolder:https://crm.yourdomain.com/crm.) -
Clear compiled config so the change takes effect:
cd ~/crm-app php artisan optimize:clearOn no-SSH hosts, the same happens automatically the next time the app detects stale caches, but a quick
config:clearthrough any terminal access is the reliable way.
Expected result: https://crm.yourdomain.com/api/v1/health returns {"status":"ok",...} and the browser shows a padlock with no mixed-content warnings.
Step 5 — Update your integrations
Any URL you already pasted into an external dashboard must be revisited if the domain changed:
| Where | What to update |
|---|---|
| Meta app dashboard | OAuth redirect URI — taken from Super Admin → Meta Developer settings, which is built from APP_URL |
| WhatsApp Cloud API | Callback URL — rebuilt from APP_URL on the WhatsApp connection page |
| Razorpay / Cashfree | Webhook URLs /api/webhooks/razorpay|cashfree |
| Uptime monitor | Point it at /api/v1/health |
Full list: Meta / WhatsApp / payment callbacks.
Common mistakes
- Leaving
APP_URL=http://…while browsing over HTTPS — e-mails and OAuth redirect URIs come outhttp://and break. - Forcing HTTPS while the certificate is still pending — visitors hit certificate errors.
- Setting
SESSION_SECURE_COOKIE=truebefore HTTPS works — nobody can log in (cookies never send over HTTP). - Changing the domain after WhatsApp was connected and forgetting the callback URL update.
- Using a trailing slash in
APP_URL— omit it.
Troubleshooting
| Symptom | Check |
|---|---|
Redirect loop (ERR_TOO_MANY_REDIRECTS) |
A proxy (Cloudflare) with your own HTTPS rule — use the X-Forwarded-Proto condition, set TRUSTED_PROXIES |
| Padlock but "Not secure" assets | Mixed content: some asset URL still http:// — fix APP_URL, clear caches |
| AutoSSL won't issue | DNS resolution, existing redirect at the domain root, or a proxy blocking challenges |
| Login works on HTTP, fails on HTTPS | SESSION_SECURE_COOKIE=true set before HTTPS was live, or APP_URL scheme mismatch |
| Mobile app can't reach the server | The app requires https://…/api/v1/mobile/ with the correct scheme and trailing slash |
Technical details
- Runtime URL:
config('app.url')←APP_URL; used to build Meta OAuth redirects (route('oauth.callback', ['source' => 'meta'])) and the WhatsApp callback URL (rtrim(config('app.url'),'/') . '/api/messaging/whatsapp/webhook/{tenant}/{token}'). - Session hardening keys:
SESSION_SECURE_COOKIE,SESSION_HTTP_ONLY,SESSION_SAME_SITE(documented as commented defaults in.env.example). - Proxy trust:
TRUSTED_PROXIESin.env;SA_IP_ALLOWLISTbehavior depends on real client IPs. - Security headers on responses:
public/.htaccess(X-Content-Type-Options,X-Frame-Optionswith the embeddable-widget exemption,Referrer-Policy).
Related guides
Was this page helpful?
Thanks — noted. ✦