You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo单数据库环境下实现动态子域名映射功能的咨询

Odoo单数据库动态用户子域名实现方案

前置要求

你需要提前完成泛域名解析与反向代理配置,这是功能生效的基础:

  • 域名DNS服务商处配置*.appdomain.com的泛解析记录,指向Odoo服务器公网IP
  • 申请泛域名SSL证书,用于所有子域名的HTTPS访问

步骤1:反向代理配置(以Nginx为例)

要保证所有子域名请求都正常转发到Odoo服务,且保留原始Host头、不触发跳转,配置示例如下:

server {
    listen 443 ssl http2;
    server_name *.appdomain.com appdomain.com;
    
    # SSL证书配置替换为你自己的证书路径
    ssl_certificate /path/to/your/fullchain.pem;
    ssl_certificate_key /path/to/your/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8069; # 替换为你的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;
    }
}

步骤2:Odoo自定义模块开发实现路由重写

Odoo原生没有子域名路由映射逻辑,需要自定义模块实现内部路径重写(不会触发3xx跳转,地址栏保持子域名):

  1. 新建自定义模块,命名为user_subdomain_route,模块依赖写base, web
  2. 在模块中创建Python文件继承ir.http类,重写请求分发逻辑,代码示例:
from odoo import models
from odoo.http import request
import re

class IrHttpSubdomain(models.AbstractModel):
    _inherit = 'ir.http'

    @classmethod
    def _dispatch(cls):
        host = request.httprequest.host.lower()
        main_domain = "appdomain.com" # 替换为你的实际主域名

        # 提取子域名
        subdomain_match = re.match(r"^([a-zA-Z0-9-]+)\." + re.escape(main_domain), host)
        if subdomain_match:
            subdomain = subdomain_match.group(1)
            # 跳过系统保留子域名,可根据需求增减
            reserved_subdomains = {"www", "admin", "api", "mail", "cdn"}
            if subdomain not in reserved_subdomains:
                # 校验子域名对应用户是否存在
                exist_user = request.env["res.users"].sudo().search([("login", "=", subdomain)], limit=1)
                if exist_user:
                    # 内部重写路径,无跳转,地址栏保持子域名
                    origin_path = request.httprequest.path
                    if origin_path == "/":
                        new_path = f"/users/{subdomain}"
                    else:
                        new_path = f"/users/{subdomain}{origin_path}"
                    request.httprequest.path = new_path
        return super()._dispatch()
  1. 新增控制器实现/users/<username>路径的业务逻辑,返回对应用户的专属页面内容
  2. 安装该自定义模块

步骤3:Odoo系统参数调整

  • 登录Odoo后台,进入「设置」-「技术」-「系统参数」
    • 新增参数web.base.url,值为https://appdomain.com
    • 新增参数web.base.url.freeze,值为True,避免Odoo自动修改基础URL
  • 启动Odoo时添加参数--db-filter=^你的数据库名称$,关闭多数据库筛选逻辑,避免子域名被识别为数据库名

可选优化

如果需要保证子域名页面内的链接、静态资源路径自动适配当前子域名,可以重写Odoo的url_for方法,避免页面链接跳转到主域。

  • 注意用户注册时要限制login字段只能使用字母、数字、短横线,避免出现非法子域名

内容的提问来源于stack exchange,提问作者IDev DooR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 09:45:05