Nginx + Docker 极简部署 Odoo16 支持 HTTPS

在生产环境使用 Odoo 官方 Docker 镜像部署 odoo16,使用 Nginx 作为反向代理,并支持 Https协议,记录遇到的问题,作为避坑指南,最后推荐一个免费的符合OpenAPI规范的接口模块。

环境

centos7docker V23nginxhttps 证书Odoo 模块

Docker 部署 Odoo16

安装 docker 及 docker compose (非 docker-compose 无下划线)

yum install -y yum-utils

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

启动 docker:sudo systemctl start docker测试 docker: docker run hello-world

坑:Odoo 16.0 附件默认存储到文件系统 (~/.local/share/Odoo 本次安装时是在该目录) ,但docker 中设置的 volume 默认为 /var/lib/odoo/,若升级或删除镜像会导致附件丢失, 日志报错:exceptions.CacheMiss,无法加载部分js。可以在odoo.conf 中设置为 data_dir = /var/lib/odoo。或设置 odoo 系统参数 ir_attachment.location 为 db-storage 将附件存储到数据库。 4. 目录结构

参考模板:https://github.com/khoibv/odoo-projects

├── addons -- 要安装的 odoo 模块

│ ├── muk_web_theme -- 主题模块

│ └── requirements.txt -- 额外安装的依赖 Python包

├── config

│ └── odoo.conf -- odoo 系统运行参数

├── .env -- docker 环境变量,设置容器名称、Odoo 版本

├── docker-compose.yml -- docker

├── odoo_pg_pass -- 数据库密码文件

└── restart.sh -- 脚本,pull 代码 重启容器等

拉取并创建 Odoo 镜像:docker compose up -d 启动了 Odoo 及 Postgresql 服务查看运行日志:docker logs -f --tail 2000 <容器名>进入镜像交互操作:docker exec -it <容器名> /bin/bahs

cd /mnt/extra-addons 实际进入的是 addons,将本地文件夹映射到 docker 容器在容器中安装新增依赖: pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 重启Odoo: docker compose restart web web 是docker-compose.yml中的配置docker-compose.yml 文件配置说明:(非完整配置)

services:

web:

image: "odoo:${VERSION}" #下载.env中配置的 Odoo 镜像版本

container_name: "${APP:-myodoo}-odoo-v${VERSION}" # 容器名

ports:

- "${VERSION}069:8069" # 将 odoo 默认 8069 端口映射到 docker 容器外部访问

- "${VERSION}072:8072" # websocket 实时聊天 端口

volumes:

- "odoo-web-data:/var/lib/odoo" # 创建 docker 数据卷,Odoo 生成的 web 数据,如附件等,需要与 Odoo 配置一致,删除容器数据不丢失

- "./v${VERSION}/config/odoo.conf:/etc/odoo/odoo.conf" # 本地文件映射到 docker

- "./v${VERSION}/addons:/mnt/extra-addons" # 本地 Odoo 模块映射到 Docker 中,可以被 Odoo 发现安装

db:

image: postgres:14 # 数据库镜像版本

environment:

- POSTGRES_DB=postgres

- POSTGRES_PASSWORD_FILE=/run/secrets/postgresql_password # 使用文件指定密码

- POSTGRES_USER=odoo # 数据库用户名

- PGDATA=/var/lib/postgresql/data/pgdata

volumes:

- odoo-db-data:/var/lib/postgresql/data/pgdata # 创建 docker 数据卷存放数据库的数据,升级容器防止数据丢失

secrets:

- postgresql_password

secrets:

postgresql_password:

file: odoo_pg_pass # 存放数据库密码字符串的本地文件

Odoo 运行参数

[options]

addons_path = /mnt/extra-addons

data_dir = /var/lib/odoo

admin_passwd = odoo

; http_port = 8069 -- 默认值

; longpolling_port = 8072 -- 默认值

; 代理模式,必须有反向代理服务

proxy_mode = True

dbfilter = <过滤数据库,支持正则>

db_user = <数据库用户名>

db_password = <数据库密码>

db_port = 5432

坑:LiveChat 实时聊天及通知不可用,查看日志 websocket 报错: websocket.py KeyError: 'socket'。 原因: 在多进程模式下,会启动一个监听 gevent port(默认8072) 的 LiveChat worker 进程,但客户端无法连接。 方案:需要使用反向代理把 /websocket 开头的请求重定向到gevent端口。 nginx 配置示例:

# Redirect websocket requests to odoo gevent port

location /websocket {

proxy_pass http://127.0.0.1:8072;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection $connection_upgrade;

proxy_set_header X-Forwarded-Host $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;

}

Nginx 配置说明(HTTPS)

首先在 /etc/odoo.conf 中开启代理模式:

proxy_mode = True

Nginx配置说明: (仅 server 部分,省略 http 等)

...

# http -> https 将 http 请求转为 https

server {

listen 80;

server_name odoo.mycompany.com;

rewrite ^(.*) https://$host$1 permanent;

}

server {

listen 443 ssl;

server_name www.mycompany.com;

# Add Headers for odoo proxy mode

proxy_set_header X-Forwarded-Host $host;

...

# SSL 证书,可从云厂商申请免费测试版,放到对应目录下

ssl_certificate /etc/ssl/nginx/server.crt;

ssl_certificate_key /etc/ssl/nginx/server.key;

...

# log 确认已存在 nginx 文件夹: `/var/log/nginx`

access_log /var/log/nginx/odoo.access.log;

error_log /var/log/nginx/odoo.error.log;

# 重定向 websocket 请求到 odoo gevent 端口

location /websocket {

proxy_pass http://127.0.0.1:8072;

...

}

# 重定向其他请求

location / {

proxy_redirect off;

proxy_pass http://127.0.0.1:8069; # 与 docker 设置一致

}

...

}

修改 Odoo 其他配置

坑:图片无法展示,浏览器报错:

Mixed Content: The page at 'https://' was loaded over HTTPS, but requested an insecure resource 'http://'. This request has been blocked; the content must be served over HTTPS.

通过 ssh 密钥对实现免密登录

可用于git 免密拉代码或登录远程服务器。核心在于客户机与远程服务机的配置,一台机器既可为服务端也可以为客户端。

客户端机器:使用指定的私钥访问服务器。

通过 ssh-add ~/.ssh/<私钥文件> 临时指定私钥写入配置文件 .ssh/config:

Host

HostName

PreferredAuthentications publickey

User

IdentityFile ~/.ssh/<私钥文件>

注意:不添加到 config 文件, 新打开终端, 可能报错:git Permission denied (publickey)

远程机器: 添加公钥到~/.ssh/authorized_keys: 存放可远程免密登录的用户公钥,每行一个 云主机:需要到控制台添加密钥对并绑定到服务器。

测试:ssh -i 私钥文件 username@ip 或 ssh

结果展示

参考

Nginx配置详解Odoo官网Https配置说明Odoo Docker 镜像Docker及config 配置模板Centos 安装 Docker

推荐模块

可生成生成符合OpenAPI规范的接口 自动记录接口调用日志 配置字段及权限 https://apps.odoo.com/apps/modules/16.0/openapi/

前端分页列表查询示例:

let params = {

kwargs: {

domain: [['is_published', '=', true]],

//可以查询关联表的字段, *2m 返回列表[{}], m2o返回对象

fields: ['id', 'name', 'tag_ids/name', 'published_date', 'view_count', 'author_id/name'],

limit: 10,

offset: 0,

}

}

const model = 'blog.post'

const url = `/${model}/call/search_read_nested`

const res = await CommonApi.queryList(url, params)

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: