DocsByRcDocsByRc
Odoo 19 企业级部署
Odoo 19 · ERP

Odoo 19 企业级部署

Ubuntu 26.04 上 Odoo 19 生产部署双路径:源码直装与 Docker,Nginx 反代、Cloudflare Tunnel 内网穿透、备份维护全覆盖。

适用Ubuntu 26.04
难度中等
阅读—

为满足企业级生产环境对数据主权与稳定性的核心要求,本指南同步了 2026 年最新稳定技术栈。教程涵盖了【路径 A:源码直装】与 【路径 B:Docker 容器化】双路径。

整体逻辑说明:
1. 你需要在【路径 A】和【路径 B】中任选其一将 Odoo 跑起来。对于新手,强烈推荐直接跳到第 6 步做【路径 B】。
2. 无论你选哪个路径,Odoo 最终都会在你服务器的 8069 端口运行。
3. 所以,第 7 步和第 8 步的网关配置对两种路径是完全通用的。
新手必读(如何使用 nano 编辑器):
本教程中会大量使用 nano 命令来创建和编辑文件。进入编辑界面后:
1. 粘贴代码:右键单击即可粘贴(或使用 Shift+Insert)。
2. 保存文件:按下键盘上的 Ctrl + O,然后按 Enter (回车键) 确认文件名。
3. 退出编辑:按下 Ctrl + X 即可回到命令行。

第一步是更新系统包,并建立严密的系统级用户隔离。

BASH
# 更新系统并同步上海时区
sudo apt update && sudo apt upgrade -y
sudo timedatectl set-timezone Asia/Shanghai

# 创建服务专用账号 odoo(保留 bash,第 4 步需 sudo su - 切换)
sudo useradd -m -d /opt/odoo -U -r -s /bin/bash odoo
如果你选择 Docker 部署(第6步),请跳过第 2、3、4、5 步,直接前往第 6 步!

采用 PostgreSQL 18,遵循最小权限原则,仅授予 odoo 用户创建数据库的权限。

BASH
# 安装数据库服务
sudo apt install postgresql-18 postgresql-client-18 -y

# 创建非超级用户角色 (-d: 允许建库, -R: 禁止建角色, -S: 非超级用户)
sudo su - postgres -c "createuser -d -R -S odoo"
BASH
# 安装必备构建依赖 (注意这是一整行长命令)
sudo apt install git python3-pip python3.14-dev python3-venv build-essential \
libssl-dev libffi-dev libxml2-dev libxslt1-dev zlib1g-dev libsasl2-dev \
libldap2-dev libpq-dev liblcms2-dev -y

# 下载并安装静态 PDF 组件包(注意:下面是 Ubuntu 24.04 noble 的包)
# Ubuntu 26.04 请去 releases 页面找对应你系统版本的 deb,把下面两行的文件名换掉
cd /tmp
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.noble_amd64.deb
sudo apt install ./wkhtmltox_0.12.6.1-3.noble_amd64.deb -y
VENV
# 切换到刚才创建的 odoo 账号
sudo su - odoo

# 下载 Odoo 19 源码
git clone https://www.github.com/odoo/odoo --depth 1 --branch 19.0 /opt/odoo/odoo-server

# 创建并激活 Python 虚拟环境
cd /opt/odoo
python3 -m venv odoo-venv
source odoo-venv/bin/activate

# 优先安装核心兼容补丁包
pip install --upgrade pip
pip install cython lxml lxml_html_clean

# 安装 Odoo 核心依赖
pip install -r odoo-server/requirements.txt

# 退出 odoo 用户,回到拥有 root 权限的账号
exit

1. 创建目录并移交权限

BASH
sudo mkdir -p /var/lib/odoo /var/log/odoo /etc/odoo
sudo chown odoo:odoo -R /var/lib/odoo /var/log/odoo /etc/odoo

2. 编写 Odoo 配置文件

执行以下命令打开编辑器:

BASH
sudo nano /etc/odoo/odoo.conf

将以下内容粘贴进去(修改密码),保存退出(Ctrl+O, 回车, Ctrl+X):

CONFIG
[options]
admin_passwd = YOUR_STRONG_MASTER_PASSWORD
db_user = odoo
data_dir = /var/lib/odoo
log_dir = /var/log/odoo
addons_path = /opt/odoo/odoo-server/addons
proxy_mode = True
workers = 4
workers 不能为 0:多进程 worker 数量,建议按 (CPU 核数 × 2) + 1 设置(2 核填 5,4 核填 9)。workers=0 时 Odoo 只跑单进程,8072 长连接端口无服务,第 7 步的 /websocket 会直接 502。
危险:必须执行下面这行命令锁定文件权限,防止系统内其他用户偷看你的数据库密码:
sudo chmod 600 /etc/odoo/odoo.conf

3. 创建后台启动服务 (Systemd)

执行以下命令打开编辑器:

BASH
sudo nano /etc/systemd/system/odoo.service

将以下内容粘贴进去,保存退出(Ctrl+O, 回车, Ctrl+X):

SERVICE
[Unit]
Description=Odoo19 Enterprise ERP
Requires=postgresql.service
After=network.target postgresql.service

[Service]
Type=simple
SyslogIdentifier=odoo
PermissionsStartOnly=true
User=odoo
Group=odoo
ExecStart=/opt/odoo/odoo-venv/bin/python3 /opt/odoo/odoo-server/odoo-bin -c /etc/odoo/odoo.conf
StandardOutput=journal+console
StandardError=journal+console
Restart=always

[Install]
WantedBy=multi-user.target

最后,加载刚才写好的服务并设置开机自启:

BASH
sudo systemctl daemon-reload
sudo systemctl enable --now odoo

使用 Docker 部署,并采用“绑定挂载 (Bind Mounts)”方案。此方案将所有数据映射在宿主机目录,极大地简化了日后的物理备份与跨服迁移。

1. 安装 Docker 环境(如果已安装请跳过)

纯净的 Ubuntu 默认可能没有装 Docker,需要先执行以下命令一键安装:

BASH
# 使用官方脚本一键安装 Docker 引擎和 Compose 插件
curl -fsSL https://get.docker.com | sudo sh

# 将当前用户加入 docker 组,以后敲 docker 就不需要加 sudo 了
sudo usermod -aG docker $USER
注意:执行完上面第二条命令后,必须断开服务器连接并重新 SSH 登录,否则会提示权限不足!

2. 建立生产目录结构

我们将所有数据统一放在 /opt/odoo-stack 目录下,方便日后直接打包这一个文件夹带走所有数据。

BASH
# 创建所需的一系列空文件夹
sudo mkdir -p /opt/odoo-stack/{config,addons,data,db-data}
# 获取文件夹的拥有权,并进入该目录
sudo chown -R $USER:$USER /opt/odoo-stack && cd /opt/odoo-stack

3. 创建配置文件 config/odoo.conf

确保你现在处于 /opt/odoo-stack 目录下,执行以下命令打开编辑器:

BASH
nano config/odoo.conf

填入以下内容,保存退出(Ctrl+O, 回车, Ctrl+X):

CONFIG
[options]
admin_passwd = YOUR_MASTER_PASSWORD
db_host = db
db_user = odoo
db_password = DB_PASSWORD
db_port = 5432
proxy_mode = True
workers = 4
addons_path = /mnt/extra-addons

4. 编写 Docker 核心编排文件

执行以下命令打开编辑器:

BASH
nano compose.yaml

填入以下内容,保存退出(注意上下级的空格缩进不能乱。并且针对 PostgreSQL 18,必须挂载到 `/var/lib/postgresql` 这一级以兼容新架构):

YAML
services:
  odoo:
    image: odoo:19.0
    container_name: odoo_prod
    depends_on:
      - db
    ports:
      - "8069:8069"
      - "8072:8072"  # websocket 长轮询端口,Nginx /websocket 反代到这里
    volumes:
      - ./data:/var/lib/odoo
      - ./config:/etc/odoo
      - ./addons:/mnt/extra-addons
    environment:
      - HOST=db
      - USER=odoo
      - PASSWORD=DB_PASSWORD
    restart: always

  db:
    image: postgres:18-alpine
    container_name: odoo_db
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_PASSWORD=DB_PASSWORD
      - POSTGRES_USER=odoo
    volumes:
      - ./db-data:/var/lib/postgresql
    restart: always
三处 DB_PASSWORD 必须是同一个密码!上面 odoo.conf 里的 db_password、compose.yaml 里 odoo 服务的 PASSWORD、db 服务的 POSTGRES_PASSWORD——三处填一样的值,否则 Odoo 连不上数据库,容器会反复重启。

5. 修正 UID 权限与一键启动(解决 Permission Denied)

必做:由于我们使用了绑定挂载,宿主机的文件夹权限默认不属于 Docker 内部账号。必须通过 chown 将产权移交给容器内部的 UID (Odoo为101,Postgres为999),否则系统将瞬间崩溃。
BASH
# 将挂载出来的文件夹产权,强制赋予容器内部的对应 UID
sudo chown -R 101:101 /opt/odoo-stack/data /opt/odoo-stack/addons /opt/odoo-stack/config
sudo chown -R 999:999 /opt/odoo-stack/db-data
# 给 Odoo 临时缓存更宽泛的读写权限
sudo chmod -R 775 /opt/odoo-stack/data

# 后台下载镜像并启动
docker compose up -d 

# 查看实时的运行日志,按 Ctrl+C 退出查看
docker compose logs -f
当日志中出现 database system is ready to accept connections,并且不再有 PermissionError 时,说明启动成功。Odoo 现在运行在本地服务器的 8069 端口。
提示:无论你使用路径 A 还是 B,Odoo 现在都在本地 8069 端口运行。下面我们需要用 Nginx 将其反代,以便支持大文件上传和安全访问。

执行以下命令安装 Nginx 并打开配置文件:

BASH
sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/odoo

粘贴以下内容(将域名修改为你自己的),保存并退出:

NGINX
server {
    listen 80;
    server_name erp.yourdomain.com;
    client_max_body_size 128M; # 允许上传最大128M的文件(如企业资料压缩包)

    location / {
        proxy_pass http://127.0.0.1:8069;
        proxy_read_timeout 900s; # 防止初始化数据库太慢导致页面报错
        proxy_connect_timeout 900s;
        proxy_set_header X-Forwarded-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;
    }

    # Odoo的长连接功能(用于即时聊天等)
    location /websocket {
        proxy_pass http://127.0.0.1:8072;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

激活 Nginx 配置:创建软链接并重启服务让配置生效。

BASH
# 将配置文件链接到 enabled 目录
sudo ln -s /etc/nginx/sites-available/odoo /etc/nginx/sites-enabled/
# 删掉 Nginx 默认站点,避免 80 端口被它占用
sudo rm -f /etc/nginx/sites-enabled/default
# 测试配置语法是否正确
sudo nginx -t
# 重启 Nginx 生效
sudo systemctl restart nginx

如果你的服务器没有公网 IP,通过 Cloudflare 内网穿透可以直接把本地 Nginx 暴露到外网。

1. 登录并进入 **Zero Trust Dashboard** 控制台,左侧导航栏找到 Networks > Tunnels。

2. 点击 Create a tunnel,类型选择 Cloudflared,起个名字比如 Odoo-Prod。

3. 页面会显示一串安装命令,复制里面 --token 后面的长串密钥,稍后用到。

4. 在 Ubuntu 端(见选项卡 2)执行完安装后,回到网页点击 Public Hostname,设置如下:

  • Subdomain (子域名): erp
  • Domain (主域名): 在下拉菜单选择你托管在 CF 的域名
  • Service Type (服务类型): HTTP
  • URL (转发地址): localhost:80 (这里填 80 端口,表示把外网流量交给刚才配置的本地 Nginx 处理)

在你的 Ubuntu 服务器中输入以下命令安装穿透客户端:

BASH
# 下载最新 cloudflared
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb

# 绑定令牌并作为系统服务运行 (把 YOUR_TUNNEL_TOKEN 换成网页上给的密钥)
sudo cloudflared service install YOUR_TUNNEL_TOKEN
安装成功后,回到 Cloudflare 网页端,看到 Status 变成 Healthy(绿色) 即可通过外网域名访问!

日常运维时可能需要用到的命令,请保存备用。

CMD
# (针对直装版) 完整物理备份:导出数据库SQL及打包附件文件夹
# 注意:把"你的库名"换成你在 Odoo 网页首次访问时创建的数据库名(第 2 步只建了角色,没建库)
sudo su - postgres -c "pg_dump 你的库名 > odoo_backup_$(date +%F).sql"
tar -czvf odoo_files_backup.tar.gz /var/lib/odoo

# (针对 Docker 绑定挂载版) 极简物理备份:连同所有数据和配置一锅端
sudo tar -czvf odoo_stack_full_backup.tar.gz /opt/odoo-stack

# 实时查看 Odoo 报错日志
cd /opt/odoo-stack && docker compose logs -f odoo