|
| 1 | +--- |
| 2 | +title: "Expose and Secure Your Self-Hosted Odoo Instance" |
| 3 | +description: "Use Odoo (an open-source ERP and business management suite) with ngroke when you want to securely expose Odoo’s services to the internet without complex network setups." |
| 4 | +sidebar_label: "Expose Odoo ERP Remotely" |
| 5 | +--- |
| 6 | + |
| 7 | +# Expose and Secure Your Self-Hosted Odoo with ngrok |
| 8 | + |
| 9 | +Odoo is great to self-host for development, demos, or integrations. When you need to share your instance over HTTPS or accept webhooks without deploying to the public internet, **ngrok** gives you a stable URL and powerful **Traffic Policy** controls to lock down access. |
| 10 | + |
| 11 | +This guide follows the style of our n8n example and adds Odoo-specific steps, including using a **static domain** and applying a **Traffic Policy**. |
| 12 | + |
| 13 | +--- |
| 14 | + |
| 15 | +## Prerequisites |
| 16 | + |
| 17 | +- An ngrok account and the ngrok agent installed |
| 18 | + ```bash |
| 19 | + # one-time setup |
| 20 | + ngrok config add-authtoken <YOUR_NGROK_AUTHTOKEN> |
| 21 | + |
| 22 | +Odoo running locally (default: http://localhost:8069) |
| 23 | + |
| 24 | +(Recommended) Admin access in Odoo to change System Parameters |
| 25 | + |
| 26 | + |
| 27 | +1) Reserve a static domain |
| 28 | + |
| 29 | +A static domain ensures your URL doesn’t change across restarts (important for Odoo links, redirects, and webhooks). |
| 30 | + |
| 31 | +In the ngrok dashboard, go to Domains → New +. |
| 32 | + |
| 33 | +Reserve a domain like your-odoo.ngrok.app. |
| 34 | + |
| 35 | +Save it as an environment variable: |
| 36 | + |
| 37 | +export NGROK_DOMAIN=your-odoo.ngrok.app |
| 38 | + |
| 39 | + |
| 40 | +Why a static domain? Odoo stores and uses absolute links. A stable host prevents broken links in emails, reports, and third-party callbacks. |
| 41 | + |
| 42 | + |
| 43 | +2) Start the ngrok endpoint for Odoo |
| 44 | + |
| 45 | +Expose Odoo on port 8069 at your static domain: |
| 46 | + |
| 47 | +ngrok http --domain=$NGROK_DOMAIN 8069 |
| 48 | + |
| 49 | +Open https://$NGROK_DOMAIN to see the Odoo login page (/web/login). |
| 50 | + |
| 51 | +3) (Recommended) Configure Odoo for a proxy & stable URLs |
| 52 | + |
| 53 | +Make sure Odoo generates correct HTTPS links and doesn’t rewrite your base URL. |
| 54 | + |
| 55 | +Enable proxy mode |
| 56 | + |
| 57 | +If ngrok (or any reverse proxy) terminates TLS, enable Odoo’s proxy mode: |
| 58 | +# odoo.conf |
| 59 | +[options] |
| 60 | +proxy_mode = True |
| 61 | + |
| 62 | +Restart Odoo after changing the config. |
| 63 | + |
| 64 | +Freeze the base URL |
| 65 | + |
| 66 | +Odoo updates web.base.url based on the host used at login. To keep it stable: |
| 67 | + |
| 68 | +In Odoo, go to Settings → Technical → System Parameters (enable developer mode if needed). |
| 69 | + |
| 70 | +Create or update: |
| 71 | + |
| 72 | +web.base.url → https://$NGROK_DOMAIN |
| 73 | + |
| 74 | +web.base.url.freeze → True |
| 75 | + |
| 76 | +This prevents unexpected rewrites if someone visits via a different hostname. |
| 77 | + |
| 78 | +4) Apply a Traffic Policy (secure your admin) |
| 79 | + |
| 80 | +Protect sensitive paths like /web and /web/login using Traffic Policy. Create a policy file (e.g., odoo-policy.yaml) and run the agent with --traffic-policy-file. |
| 81 | + |
| 82 | +Option A: Restrict admin to your IP |
| 83 | + |
| 84 | +# odoo-policy.yaml |
| 85 | +on_http_request: |
| 86 | + - if: request.path.startsWith("/web") |
| 87 | + actions: |
| 88 | + - type: restrict-ips |
| 89 | + config: |
| 90 | + # Replace with your public IP/CIDR, e.g. "203.0.113.7/32" |
| 91 | + allow: ["$YOUR_IP_CIDR"] |
| 92 | + |
| 93 | +Run: |
| 94 | +ngrok http --domain=$NGROK_DOMAIN 8069 \ |
| 95 | + --traffic-policy-file odoo-policy.yaml |
| 96 | + |
| 97 | +Only the allowed IPs can reach /web*; other requests are blocked before they hit Odoo. |
| 98 | + |
| 99 | +Option B: Require Basic Auth on admin |
| 100 | +# odoo-policy.yaml |
| 101 | +on_http_request: |
| 102 | + - if: request.path.startsWith("/web") |
| 103 | + actions: |
| 104 | + - type: basic-auth |
| 105 | + config: |
| 106 | + realm: "Odoo Admin" |
| 107 | + credentials: |
| 108 | + - "admin:changeMeNow123" |
| 109 | + |
| 110 | +Run with the same --traffic-policy-file flag. Visitors to /web* must pass HTTP Basic Auth before Odoo’s own login. |
| 111 | + |
| 112 | +Tip: You can combine rules. For example, Basic Auth for /web* and unrestricted access for public website paths. |
| 113 | + |
| 114 | +5) Test your endpoint |
| 115 | + |
| 116 | +From a terminal: |
| 117 | + |
| 118 | +curl -I https://$NGROK_DOMAIN |
| 119 | + |
| 120 | + |
| 121 | +Expected: HTTP/2 200 and Odoo’s login route (/web/login) when loaded in a browser. |
| 122 | + |
| 123 | +Troubleshooting |
| 124 | + |
| 125 | +Blank or mixed-content pages: Ensure proxy_mode = True and you’re visiting https://$NGROK_DOMAIN. |
| 126 | + |
| 127 | +Redirect loops or wrong links: Verify web.base.url is exactly https://$NGROK_DOMAIN and web.base.url.freeze = True. |
| 128 | + |
| 129 | +403 when applying policy: Confirm your IP/CIDR is correct or disable the policy while debugging. |
| 130 | + |
| 131 | +Port issues: Odoo defaults to 8069; double-check the port if customized. |
| 132 | + |
| 133 | +What’s next? |
| 134 | + |
| 135 | +Layer additional policies (OAuth/OIDC, rate limits, IP allow/deny lists) as needed. |
| 136 | + |
| 137 | +Use the ngrok dashboard’s Traffic Inspector to watch live requests and responses while testing. |
| 138 | + |
| 139 | +Reserve a custom domain you own and enable HTTPS via ngrok for a branded URL. |
0 commit comments