All articles

Custom domain and HTTPS for Odoo: DNS, nginx, Let's Encrypt and proxy mode

Put Odoo on your own domain with HTTPS: DNS records, an nginx proxy with websockets, a Let's Encrypt certificate, proxy_mode, web.base.url and common mistakes.

By Muhammad Salman Ali Khan, Founder, Knova Digital Solutions · Published · 7 min read · Odoo configuration, Custom domain, Your own server, Odoo hosting

To run Odoo on your own domain with HTTPS, you need four things to agree: a DNS record pointing your domain at the server, a reverse proxy such as nginx that holds the certificate and forwards traffic (websockets included) to Odoo, a certificate, free from Let's Encrypt, and Odoo itself configured with proxy_mode = True and a web.base.url that uses your domain. When something breaks, it is almost always one of these four. This guide walks through each in order, lists the common mistakes, and shows how Knova Cloud does it for you.

Step 1: the DNS record

Create the record at whoever hosts your domain's DNS (your registrar, Cloudflare, Route 53 and so on):

AddressRecordPoints to
erp.example.com (a subdomain)CNAMEyour hosting's address for the server, or an A record to its IP
example.com (the bare domain)Athe server's IPv4 address
www.example.comCNAMEexample.com, or the same target as above

Four details cause most DNS trouble:

  • A bare domain can't have a CNAME. That's a DNS rule, not an Odoo one. Use an A record, or better, serve Odoo on www. or erp. and redirect the bare domain at your registrar.
  • Stray AAAA records. If the name also has an IPv6 record pointing somewhere else, some visitors and some certificate checks will go there.
  • Cloudflare's proxy. If the orange cloud is on, Cloudflare answers instead of your server, which interferes with certificate checks and websockets unless you configure it for that. When in doubt, set the record to "DNS only".
  • Propagation. Changes can take minutes to hours to be visible everywhere. Check with dig +short erp.example.com before blaming the server.

Step 2: the reverse proxy (nginx)

Odoo's deployment guide recommends running Odoo behind a proxy that terminates HTTPS and redirects plain HTTP to HTTPS. Two Odoo-specific points matter: with workers enabled, /websocket must go to Odoo's gevent port (8072 by default) with the upgrade headers, and Odoo must receive the real host, scheme and client IP in the X-Forwarded-Host, X-Forwarded-Proto and X-Forwarded-For headers. A minimal configuration, based on the sample in Odoo's documentation:

upstream odoo { server 127.0.0.1:8069; }
upstream odoochat { server 127.0.0.1:8072; }
map $http_upgrade $connection_upgrade { default upgrade; '' close; }

server {
    listen 80;
    server_name erp.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name erp.example.com;
    ssl_certificate     /etc/letsencrypt/live/erp.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/erp.example.com/privkey.pem;
    proxy_read_timeout 720s;
    client_max_body_size 100m;

    location /websocket {
        proxy_pass http://odoochat;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        proxy_pass http://odoo;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
    }
}

client_max_body_size is not in Odoo's sample; nginx's default of 1 MB is too small for most attachments and imports. Odoo's guide also suggests a Strict-Transport-Security header once HTTPS works reliably.

Step 3: the Let's Encrypt certificate

Let's Encrypt issues free certificates valid for 90 days and recommends renewing every 60. With certbot and its nginx plugin, one command gets the certificate and installs it:

sudo certbot --nginx -d erp.example.com

What it needs:

  • Port 80 open. The usual HTTP-01 challenge only works on port 80, so don't close it in the firewall even if you redirect everything to HTTPS.
  • DNS already pointing at this server. Otherwise Let's Encrypt checks someone else's machine and fails.
  • CAA records that allow Let's Encrypt, if your domain has any. A CAA record such as 0 issue "letsencrypt.org" permits it; a record listing only another authority blocks it.
  • A DNS-01 challenge for wildcards. A certificate covering every subdomain of example.com can't be issued over HTTP-01.

Most certbot installations renew automatically out of the box; sudo certbot renew --dry-run confirms yours does.

Step 4: tell Odoo where it lives

  • proxy_mode = True in the Odoo configuration file. Odoo's documentation says to enable it only behind a reverse proxy; with it, Odoo trusts those forwarded headers and knows the visitor came over HTTPS.
  • web.base.url. This system parameter is the address Odoo puts in emails, portal links, quotations and reports. Set it to https://erp.example.com (with the scheme, without a trailing slash) under Settings → Technical → System Parameters in developer mode.
  • web.base.url.freeze = True. Without it, Odoo resets web.base.url to whatever address an administrator last logged in from, such as the server's IP or an old domain.
  • The website's domain. If the Website app is installed, set the domain in Website → Configuration → Settings, which also tells search engines which address is the main one.
  • dbfilter, if the server hosts several databases, so each domain opens the right one.

Common mistakes

SymptomLikely cause
Redirect loop, or links in emails start with http://proxy_mode off, or X-Forwarded-Proto not passed
"Connection lost" banners, live chat or Discuss not updating/websocket not routed to the gevent port, or missing upgrade headers
Certificate name mismatch or "not private" warningDNS points elsewhere, or the certificate doesn't cover this name
Certificate request failsPort 80 closed, CAA blocks Let's Encrypt, or a proxied Cloudflare record
Emails link to the old addressweb.base.url not set or not frozen
Upload fails with "413 Request Entity Too Large"client_max_body_size too small

How Knova Cloud does it

On Knova Cloud, you add the domain in Settings → Custom domains (or in a branch's Settings tab) and pick the branch it serves. The platform shows the record to create: a CNAME to your project's address for a subdomain, or an A record to the server's IP for a bare domain, with a note that a bare domain breaks if the server's IP ever changes, so www. is the safer choice. With Cloudflare, it reminds you to use "DNS only".

Check tells you what it sees: no record yet, a record pointing at another server, or a stray AAAA record. The status then goes from Waiting for DNS to Waiting for certificate to Active. A Let's Encrypt certificate is requested as soon as the DNS points to the platform, usually within minutes, and renewed automatically; there's nothing to upload. Odoo always runs with proxy_mode on, websockets are routed for you, and the domain follows new builds of the branch without a rebuild. Staging and development branches can have their own domains too. Star a production domain to make it the primary one, and it becomes Odoo's web.base.url, frozen so a login from another address doesn't change it.

On your own server, when the platform installs Odoo for you, you give it the domain and an A record pointing at the server. The installer sets up nginx, the certificate with certbot and Odoo's proxy mode. If the DNS isn't ready yet, Odoo opens on the server's IP address first, and the platform keeps checking for a week and finishes the HTTPS setup once the record is visible. Prefer doing it by hand? Our Odoo 20 installation guide includes the nginx and certbot steps.

The custom domains documentation has the details. To see what a hosted project costs, with custom domains and certificates included, open the pricing page, or read how we work with businesses running Odoo.

Sources

Sources checked on 8 October 2026. Odoo is a trademark of Odoo S.A. Knova Cloud is an independent service, not affiliated with or endorsed by Odoo S.A.

About the author

Muhammad Salman Ali Khan, Founder, Knova Digital Solutions

Muhammad Salman Ali Khan is the founder of Knova Digital Solutions in Dubai. He builds and runs Odoo hosting and Odoo implementations for companies in the UAE and beyond, and writes these guides from that day-to-day work.

Try the workflow on your own repository

Pick the workers, storage and staging environments you need, and your first branch builds in minutes.

See pricing · Talk to us