Skip to main content
GuideFebruary 21, 202612 min read

How to Set Up Cloudflare with Odoo — Complete Guide (2026)

Cloudflare sits between your users and your Odoo server. It gives you free DDoS protection, a global CDN, automatic SSL, and caching for static assets. This guide walks through every configuration step from DNS records to cache rules, including Odoo-specific settings that prevent the most common problems.

Running Odoo in production without a reverse proxy or CDN means your server handles every request directly — static CSS files, product images, API calls, and brute-force login attempts all hit the same origin. Cloudflare fixes this with its free tier alone. No code changes to Odoo are needed. The entire setup takes about 15 minutes.

This guide assumes you have Odoo running on a server (any cloud provider works) with nginx as a reverse proxy in front of it. If you are using OEC.sh, nginx and SSL are already configured — you can skip straight to the Cloudflare dashboard settings.

Why Use Cloudflare with Odoo?

Cloudflare's free plan includes features that would cost hundreds of dollars per month from other providers. For Odoo deployments specifically:

  • DDoS protection — Cloudflare absorbs volumetric attacks before they reach your server. Their network handles 200+ Tbps of attack traffic. Free tier included.
  • Global CDN — 330+ data centers worldwide. Static assets (CSS, JS, images) are served from the nearest edge to your users, cutting load times by 40-70% for geographically distributed teams.
  • Automatic SSL — Free SSL certificates with automatic renewal. No more Let's Encrypt cron jobs failing silently.
  • Static asset caching — Odoo serves thousands of static files (/web/static/*). Caching these at the edge reduces origin server load by 40-60%.
  • Brotli compression — Compresses HTML, CSS, and JS responses automatically. Smaller payloads mean faster page loads.
  • HTTP/3 and QUIC — Modern protocol support that reduces connection setup time, especially on mobile networks.
  • Bot protection — Blocks known malicious bots. Reduces server load from scrapers and credential-stuffing attacks.

The free tier covers all of the above. Paid plans add WAF rules, advanced rate limiting, and image optimization — but most Odoo deployments run perfectly on the free tier.

DNS Configuration

First, add your domain to Cloudflare and point it to your Odoo server. After creating a Cloudflare account and adding your domain, update your nameservers at your registrar to the ones Cloudflare provides (usually something like ada.ns.cloudflare.com).

Then configure the following DNS records:

TypeNameContentProxyTTL
A@YOUR_SERVER_IPProxied (orange)Auto
AwwwYOUR_SERVER_IPProxied (orange)Auto
AAAA@YOUR_IPv6_ADDRESSProxied (orange)Auto

The orange cloud (Proxied) is critical. When the proxy is enabled, traffic flows through Cloudflare's network, which enables CDN caching, DDoS protection, and SSL termination. If you set it to DNS-only (gray cloud), Cloudflare only resolves DNS and provides none of its security or performance features.

If your server supports IPv6, add an AAAA record as well. Cloudflare serves both IPv4 and IPv6 to visitors regardless of your origin configuration, but having an AAAA record enables direct IPv6 connectivity to your origin server.

SSL/TLS Settings for Odoo

This is where most Odoo + Cloudflare setups go wrong. The SSL/TLS mode determines how Cloudflare connects to your origin server. Get it wrong and you end up with redirect loops or insecure connections.

Go to SSL/TLS > Overview in your Cloudflare dashboard and set the encryption mode:

Recommended
Full (strict)

Cloudflare connects to your origin over HTTPS and validates the certificate. Requires a valid SSL cert on your server (Let's Encrypt works). This is the correct setting for production Odoo.

Acceptable
Full

Cloudflare connects over HTTPS but does not validate the origin certificate. Use this only if you have a self-signed cert on your origin.

DO NOT USE
Flexible

Cloudflare connects to your origin over plain HTTP. This causes infinite redirect loops with Odoo because Odoo detects the insecure connection and redirects to HTTPS, which goes through Cloudflare again.

Additional SSL/TLS settings to configure:

  • Always Use HTTPS — Enable under SSL/TLS > Edge Certificates. Redirects all HTTP traffic to HTTPS.
  • Minimum TLS Version — Set to TLS 1.2 under SSL/TLS > Edge Certificates. TLS 1.0 and 1.1 are deprecated and insecure.
  • HSTS (HTTP Strict Transport Security) — Enable with max-age of at least 6 months (15768000 seconds). Include subdomains if applicable.
  • Automatic HTTPS Rewrites — Enable to fix mixed-content warnings when Odoo serves HTTP links inside HTTPS pages.

Caching Rules — What to Cache and What NOT to Cache

Caching is where Cloudflare delivers the biggest performance improvement for Odoo — but misconfiguring it will break sessions, leak data between users, or cause stale content. The rule is simple: cache static assets aggressively, bypass cache on everything dynamic.

Safe to Cache

  • /web/static/* — JS, CSS, fonts, module assets
  • /web/image/* — Product images, avatars
  • /web/content/* — File downloads (attachments)
  • /website/image/* — Website builder images

NEVER Cache

  • /web — Main app entry (session-dependent)
  • /web/session/* — Auth and session data
  • /web/dataset/* — JSON-RPC API calls
  • /longpolling/* — Real-time bus (Enterprise)
  • /websocket — WebSocket connection (Odoo 16+)
  • /web/action/* — User-specific action calls

Why this matters: Cloudflare does not cache HTML by default (only standard static file extensions like .js, .css, .png). But if you create a “Cache Everything” page rule, it will cache HTML responses — including Odoo's session-dependent pages. This means User A could see User B's dashboard. Always exclude dynamic paths explicitly.

Cache Rules Configuration

Cloudflare's Cache Rules (the newer replacement for Page Rules) give you precise control over what gets cached. Go to Caching > Cache Rules in your dashboard. You need two rules, in this order:

Rule 1: Bypass cache for dynamic paths (higher priority)

When: URI Path starts with "/web/session"
  OR URI Path starts with "/web/dataset"
  OR URI Path starts with "/web/action"
  OR URI Path starts with "/longpolling"
  OR URI Path equals "/websocket"
  OR URI Path equals "/web"

Then: Bypass cache

Rule 2: Cache static assets aggressively

When: URI Path starts with "/web/static"
  OR URI Path starts with "/web/image"
  OR URI Path starts with "/web/content"
  OR URI Path starts with "/website/image"

Then: Cache eligible
  Edge TTL: 1 month
  Browser TTL: 1 week

The long TTLs are safe because Odoo appends a unique hash to static asset URLs (e.g., /web/static/lib/bootstrap/css/bootstrap.css?unique=a3b2c1). When you update Odoo or install a module, the hash changes and the browser fetches the new version automatically.

If you are still using legacy Page Rules (3 free per domain), the equivalent setup is:

Page Rule 1: *yourdomain.com/web/session/*
  → Cache Level: Bypass

Page Rule 2: *yourdomain.com/web/static/*
  → Cache Level: Cache Everything
  → Edge Cache TTL: 1 month
  → Browser Cache TTL: 1 week

Page Rule 3: *yourdomain.com/longpolling/*
  → Cache Level: Bypass

Cloudflare Workers for Odoo (Optional)

Cloudflare Workers run JavaScript at the edge, letting you modify requests and responses before they reach your server. A few useful Workers for Odoo deployments:

Redirect www to non-www

This avoids duplicate content issues and canonicalizes your domain:

addEventListener("fetch", event => {
  const url = new URL(event.request.url);
  if (url.hostname.startsWith("www.")) {
    url.hostname = url.hostname.slice(4);
    event.respondWith(
      Response.redirect(url.toString(), 301)
    );
  } else {
    event.respondWith(fetch(event.request));
  }
});

Add security headers

Add headers that Odoo does not set by default:

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);
  const headers = new Headers(response.headers);

  headers.set("X-Content-Type-Options", "nosniff");
  headers.set("X-Frame-Options", "SAMEORIGIN");
  headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
  headers.set("Permissions-Policy",
    "camera=(), microphone=(), geolocation=()");

  return new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers,
  });
}

Block aggressive bots

Block bots that ignore robots.txt and hammer your Odoo JSON-RPC endpoints:

addEventListener("fetch", event => {
  const ua = event.request.headers.get("User-Agent") || "";
  const blocked = ["SemrushBot", "AhrefsBot", "MJ12bot",
                   "DotBot", "BLEXBot"];

  if (blocked.some(bot => ua.includes(bot))) {
    event.respondWith(
      new Response("Forbidden", { status: 403 })
    );
  } else {
    event.respondWith(fetch(event.request));
  }
});

Workers free tier: 100,000 requests/day. More than enough for most Odoo deployments.

DDoS Protection and Rate Limiting

Cloudflare's free DDoS protection is automatic — you don't need to configure anything. It mitigates L3/L4 volumetric attacks and most L7 HTTP floods out of the box. But Odoo has specific endpoints that benefit from additional protection.

Rate limiting for /web/login

The Odoo login page is the primary target for brute-force attacks. Configure rate limiting under Security > WAF > Rate limiting rules:

Rule: Odoo Login Rate Limit
When: URI Path equals "/web/login" AND Method equals "POST"
Rate: 5 requests per 1 minute per IP
Action: Block for 10 minutes
Response: Custom (429 Too Many Requests)

You can also rate-limit the JSON-RPC endpoint to prevent API abuse:

Rule: Odoo API Rate Limit
When: URI Path starts with "/web/dataset"
Rate: 60 requests per 1 minute per IP
Action: Challenge (CAPTCHA)

Under Attack Mode

If your Odoo instance is under active attack, enable Under Attack Mode from the Cloudflare dashboard overview page. This adds a 5-second JavaScript challenge before every request. It will slow down legitimate users slightly, so only use it during active attacks. You can also scope it to specific paths using a WAF custom rule instead of enabling it site-wide.

Troubleshooting Common Issues

These four issues cover about 90% of Cloudflare + Odoo support tickets:

522 Connection Timed Out

Cloudflare connected but your origin server did not respond within 100 seconds.

Common causes and fixes:

  • Firewall blocking Cloudflare IPs — Whitelist all Cloudflare IP ranges in your server firewall (iptables, ufw, or security group).
  • Nginx or Odoo not running — SSH into your server and check: systemctl status nginx odoo
  • Server overloaded — Check CPU and RAM usage. Odoo with too many workers can exhaust memory.
  • Wrong origin port — Cloudflare connects on ports 443 (HTTPS) or 80 (HTTP) by default. Make sure nginx listens on 443.
# Whitelist Cloudflare IPs in UFW
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
  sudo ufw allow from $ip to any port 443
done

for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
  sudo ufw allow from $ip to any port 443
done

Redirect Loops (ERR_TOO_MANY_REDIRECTS)

The browser shows “This page isn't working” and keeps redirecting.

Fix:

  • Set SSL/TLS mode to Full (strict), not Flexible.
  • Ensure your origin server has a valid SSL certificate and nginx is configured for HTTPS.
  • Check that Odoo's proxy_mode = True is set in odoo.conf.

WebSocket / Longpolling Not Working

Chat, notifications, or real-time updates stop working. The browser console shows WebSocket connection errors.

Fix:

  • Cloudflare supports WebSocket on all plans (including free). The issue is usually nginx configuration.
  • Your nginx config must proxy WebSocket headers. Here is the correct block:
# Nginx config for Odoo WebSocket/Longpolling
location /websocket {
    proxy_pass http://127.0.0.1:8072;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 86400;
}

# For Odoo < 16 (longpolling instead of websocket)
location /longpolling {
    proxy_pass http://127.0.0.1:8072;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Wrong IP Addresses in Odoo Logs

All requests show Cloudflare's IP instead of the visitor's real IP. Odoo's fail2ban-style login protection and geolocation features break.

Fix:

Cloudflare sends the visitor's real IP in the CF-Connecting-IP header. Configure nginx to trust this:

# Add to nginx http block or server block
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;

real_ip_header CF-Connecting-IP;

# Then in your server block, pass to Odoo:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Also ensure proxy_mode = True is set in your odoo.conf. Without this, Odoo ignores the X-Forwarded-For header entirely.

Complete Nginx Configuration for Odoo + Cloudflare

Here is a production-ready nginx configuration that works with Cloudflare and covers all the issues described above:

upstream odoo {
    server 127.0.0.1:8069;
}

upstream odoo-chat {
    server 127.0.0.1:8072;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # Cloudflare real IP restoration
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 131.0.72.0/22;
    real_ip_header CF-Connecting-IP;

    # Increase buffer size for Odoo
    proxy_buffers 16 64k;
    proxy_buffer_size 128k;
    proxy_read_timeout 720s;
    proxy_connect_timeout 720s;
    proxy_send_timeout 720s;
    client_max_body_size 200m;

    # Gzip (Cloudflare also compresses, but this
    # helps if you ever bypass Cloudflare)
    gzip on;
    gzip_types text/css text/plain text/xml
               application/json application/javascript;

    # Static files — let Cloudflare cache these
    location /web/static {
        proxy_pass http://odoo;
        proxy_cache_valid 200 60d;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # WebSocket (Odoo 16+)
    location /websocket {
        proxy_pass http://odoo-chat;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
    }

    # Longpolling (Odoo < 16)
    location /longpolling {
        proxy_pass http://odoo-chat;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # All other Odoo traffic
    location / {
        proxy_pass http://odoo;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;
}

OEC.sh + Cloudflare

If you are deploying Odoo through OEC.sh, most of the configuration above is handled automatically:

  • SSL certificates — Provisioned and renewed automatically via Let's Encrypt. No manual setup needed.
  • Nginx configuration — Pre-configured with correct proxy headers, WebSocket support, buffer sizes, and Cloudflare IP restoration.
  • DNS management — Point your domain to the server IP from the OEC.sh dashboard. If using Cloudflare, just set the A record to proxied.
  • Proxy mode — Odoo's proxy_mode is enabled by default in OEC.sh deployments, so X-Forwarded-For headers work correctly.
  • Firewall — The server firewall is pre-configured to allow traffic on ports 80 and 443. Add Cloudflare IP ranges if you want to restrict direct access.

With OEC.sh, adding Cloudflare to your Odoo deployment takes about 2 minutes. Add your domain to Cloudflare, create the A record pointing to your server IP (proxied), set SSL to Full (strict), and you are done. The remaining Cloudflare settings in this guide (caching rules, rate limiting, Workers) are optional optimizations you can add later.

Summary

Setting up Cloudflare with Odoo comes down to a handful of steps: DNS records with proxy enabled, SSL set to Full (strict), cache rules that only cache static paths, rate limiting on the login endpoint, and correct nginx headers for real IP forwarding and WebSocket support. Everything on this page works with Cloudflare's free tier.

The most common mistake is using Flexible SSL mode, which causes redirect loops. The second most common is caching dynamic paths, which leaks session data between users. Avoid those two and your Odoo deployment will be faster, more secure, and more resilient than running without Cloudflare.

For more server-side optimization, see our PostgreSQL tuning guide and cloud provider comparison. If you want to skip the manual configuration entirely, OEC.sh handles nginx, SSL, and server setup so you can focus on Cloudflare's edge features instead.

Frequently Asked Questions

Does Cloudflare work with Odoo Enterprise and Community?

Yes. Cloudflare works identically with both Odoo Community and Enterprise editions. The configuration steps for DNS, SSL, caching, and DDoS protection are the same regardless of which edition you run. The only difference is that Enterprise uses the longpolling service on a separate port (default 8072), which you need to proxy through nginx — but this does not change the Cloudflare setup.

Why does Odoo get redirect loops behind Cloudflare?

Redirect loops happen when Cloudflare’s SSL mode is set to ‘Flexible’ instead of ‘Full’ or ‘Full (strict)’. In Flexible mode, Cloudflare connects to your origin server over HTTP, but Odoo sees the insecure connection and tries to redirect to HTTPS, which goes back through Cloudflare, creating an infinite loop. The fix is to set SSL/TLS to ‘Full (strict)’ and ensure your origin server has a valid SSL certificate.

Should I cache Odoo pages with Cloudflare?

Only cache static assets — never cache dynamic Odoo pages. Static assets like /web/static/* and /web/image/* are safe to cache and can reduce server load by 40-60%. But paths like /web, /web/session, /web/dataset, /longpolling, and /websocket must always bypass the cache because they contain user-specific session data.

How do I fix Cloudflare 522 errors with Odoo?

A 522 error means Cloudflare cannot reach your origin server. Common causes: your server’s firewall is blocking Cloudflare IP ranges, nginx or Odoo is not running, the server is overloaded, or Cloudflare is connecting on the wrong port. Fix it by whitelisting Cloudflare IPs, checking that nginx and Odoo services are running, and verifying your origin server responds on port 443.

Does Cloudflare slow down Odoo?

No — Cloudflare typically speeds up Odoo. Static assets served from Cloudflare’s CDN load 2-5x faster for users far from your origin server. The proxy adds about 5-15ms of latency per request, but this is offset by caching, Brotli compression, and HTTP/3 support. For most deployments, enabling Cloudflare reduces average page load times by 15-30%.

Deploy Odoo with SSL and Nginx Pre-Configured

OEC.sh provisions your Odoo server with production-ready nginx, SSL certificates, and correct proxy headers out of the box. Just add Cloudflare and go. Free plan available.

Related Reading