在Ubuntu 20.04 LTS上安装部署Odoo15并设置Nginx SSL反向代理
安装odoo的方法很多,最简单的是用deb包来安装,或者使用docker来部署,当然如果你想自己定义一些东西,可以考虑源码安装方式,下面我就是用的源码安装方式。
在正式安装之前先确保你的VPS能够访问Github,以及一个域名(设置Nginx SSL代理的时候需要)。
安装依赖
第一步是安装Git 、Pip 、Node.js 和开发构建Odoo所需的工具:
sudo apt update sudo apt install git python3-pip build-essential wget python3-dev python3-venv \ python3-wheel libfreetype6-dev libxml2-dev libzip-dev libldap2-dev libsasl2-dev \ python3-setuptools node- less libjpeg-dev zlib1g-dev libpq-dev \ libxslt1-dev libldap2-dev libtiff5-dev libjpeg8-dev libopenjp2-7-dev \ liblcms2-dev libwebp-dev libharfbuzz-dev libfribidi-dev libxcb1-dev |
创建系统用户
在 root 用户下运行 Odoo 会带来安全风险。我们将创建一个新的系统用户和组,主目录为/opt/odoo15来运行 Odoo 服务。为此,请运行以下命令:
sudo useradd -m -d /opt/odoo15 -U -r -s /bin/bash odoo15 |
您可以随意命名用户,只要您创建一个同名的 PostgreSQL 用户即可。
安装和配置 PostgreSQL
Odoo 使用 PostgreSQL 作为数据库后端。PostgreSQL 包含在标准的 Ubuntu 存储库中。安装很简单:
sudo apt install postgresql |
安装服务后,创建一个与之前创建的系统用户同名的 PostgreSQL 用户。在这个例子中,那就是odoo15:
sudo su - postgres -c "createuser -s odoo15" |
安装 wkhtmltopdf
wkhtmltopdf 是一组开源命令行工具,用于将 HTML 页面渲染为 PDF 和各种图像格式。要在 Odoo 中打印 PDF 报告,您需要安装该wkhtmltox软件包。
Ubuntu 存储库中包含的 wkhtmltopdf 版本不支持页眉和页脚。Odoo 的推荐版本是 version 0.12.5。我们将从 Github 下载并安装该软件包:
sudo wget https: //github .com /wkhtmltopdf/wkhtmltopdf/releases/download/0 .12.5 /wkhtmltox_0 .12.5-1.bionic_amd64.deb |
下载文件后,键入以下命令进行安装:
sudo apt install . /wkhtmltox_0 .12.5-1.bionic_amd64.deb |
安装和配置 Odoo 15
我们将在隔离的Python 虚拟环境中从源代码安装 Odoo 。
首先,更改为用户 “odoo15”:
sudo su - odoo15 |
从 GitHub 克隆 Odoo 15 源代码:
git clone https: //www .github.com /odoo/odoo --depth 1 --branch 15.0 /opt/odoo15/odoo |
为 Odoo 创建一个新的 Python 虚拟环境:
cd /opt/odoo15 python3 -m venv odoo-venv |
激活虚拟环境:
source odoo-venv /bin/activate |
Odoo 依赖项在 requirements.txt 文件中指定。使用 pip3 安装所有必需的 Python 模块:
pip3 install wheel pip3 install -r odoo /requirements .txt |
如果在安装过程中遇到任何编译错误,请确保安装了本Installing Prerequisites节中列出的所有必需依赖项。
完成后,键入以下命令停用环境:
deactivate |
我们将为 第三方插件创建一个新目录和一个单独的目录:
mkdir /opt/odoo15/odoo-custom-addons |
稍后我们会将这个目录添加到addons_path
参数中。该参数定义了 Odoo 搜索模块的目录列表。
切换回您的sudo用户:
exit |
创建一个配置文件,内容如下:
sudo vi /etc/odoo15 .conf |
1 2 3 4 5 6 7 8 | [options] ; This is the password that allows database operations: admin_passwd = my_admin_passwd db_host = False db_port = False db_user = odoo15 db_password = False addons_path = /opt/odoo15/odoo/addons,/opt/odoo15/odoo-custom-addons |
不要忘记将 更改my_admin_passwd为更安全的内容。
创建 Systemd 单元文件
单元文件是一种配置 ini 样式的文件,其中包含有关服务的信息。
打开您的文本编辑器 并创建一个以odoo15.service以下内容命名的文件:
sudo vi /etc/systemd/system/odoo15 .service |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [Unit] Description=Odoo15 Requires=postgresql.service After=network.target postgresql.service [Service] Type=simple SyslogIdentifier=odoo15 PermissionsStartOnly=true User=odoo15 Group=odoo15 ExecStart=/opt/odoo15/odoo-venv/bin/python3 /opt/odoo15/odoo/odoo-bin -c /etc/odoo15.conf StandardOutput=journal+console [Install] WantedBy=multi-user.target |
通知 systemd 存在新的单元文件:
sudo systemctl daemon-reload |
启动 Odoo 服务并通过运行以下命令使其在启动时启动:
sudo systemctl enable --now odoo15 |
验证服务是否已启动并正在运行:
sudo systemctl status odoo15 |
安装Nginx
sudo apt install nginx |
安装 Certbot
sudo apt install certbot |
生成强 Dh (Diffie-Hellman) 组
Diffie–Hellman 密钥交换 (DH) 是一种通过不安全的通信通道安全地交换加密密钥的方法。
通过键入以下命令生成一组新的 2048 位 DH 参数:
sudo openssl dhparam -out /etc/ssl/certs/dhparam .pem 2048 |
您也可以使用最长 4096 位的密钥长度,但生成可能需要 30 分钟以上,具体取决于系统熵。
获取 Let’s Encrypt SSL 证书
为了获得域的 SSL 证书,我们将使用 Webroot 插件,该插件通过创建一个临时文件来验证${webroot-path}/.well-known/acme-challenge目录中请求的域。Let’s Encrypt 服务器向临时文件发出 HTTP 请求,以验证请求的域是否解析为运行 certbot 的服务器。
为了更简单,我们将把所有的 HTTP 请求映射.well-known/acme-challenge到一个目录,/var/lib/letsencrypt.
以下命令将创建目录并使其可用于 Nginx 服务器:
sudo mkdir -p /var/lib/letsencrypt/ .well-known sudo chgrp www-data /var/lib/letsencrypt sudo chmod g+s /var/lib/letsencrypt |
为了避免重复代码,我们将创建两个片段并将它们包含在所有 Nginx 服务器块文件中。
打开您的文本编辑器 并创建第一个片段letsencrypt.conf:
sudo vi /etc/nginx/snippets/letsencrypt .conf |
1 2 3 4 5 6 | location ^~ /.well-known/acme-challenge/ { allow all; root /var/lib/letsencrypt/; default_type "text/plain"; try_files $uri =404; } |
接下来,创建第二个片段 ,ssl.conf其中包括Mozilla推荐的芯片 ,启用 OCSP 装订、HTTP 严格传输安全 (HSTS) 并强制执行少数以安全为中心的 HTTP 标头。
sudo vi /etc/nginx/snippets/ssl .conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers on; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 30s; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; |
创建letsencrypt.conf代码段后,打开域服务器阻止文件并包含如下所示的代码段:
sudo vi /etc/nginx/sites-available/example .com.conf |
1 2 3 4 5 6 | server { listen 80; server_name example.com www.example.com; include snippets/letsencrypt.conf; } |
要启用新的服务器块,请创建从文件到sites-enabled目录的符号链接:
sudo ln -s /etc/nginx/sites-available/example .com.conf /etc/nginx/sites-enabled/ |
重新启动 Nginx 服务 以使更改生效:
sudo systemctl restart nginx |
您现在可以使用 webroot 插件运行 Certbot 并通过发出以下命令获取 SSL 证书文件:
sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com |
如果成功获取 SSL 证书,certbot 将打印以下消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2020-10-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le |
为Odoo15配置 SSL 反向代理
sudo vi /etc/nginx/sites-enabled/example .com.conf |
以下配置设置 SSL 终止、HTTP 到 HTTPS 重定向 、WWW 到非 WWW 重定向、缓存静态文件并启用GZip 压缩。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # Odoo servers upstream odoo { server 127.0.0.1:8069; } upstream odoochat { server 127.0.0.1:8072; } # HTTP -> HTTPS server { listen 80; server_name www.example.com example.com; include snippets/letsencrypt.conf; return 301 https://example.com$request_uri; } # WWW -> NON WWW server { listen 443 ssl http2; server_name www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; include snippets/ssl.conf; include snippets/letsencrypt.conf; return 301 https://example.com$request_uri; } server { listen 443 ssl http2; server_name example.com; proxy_read_timeout 720s; proxy_connect_timeout 720s; proxy_send_timeout 720s; # Proxy headers 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; # SSL parameters ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; include snippets/ssl.conf; include snippets/letsencrypt.conf; # log files access_log /var/log/nginx/odoo.access.log; error_log /var/log/nginx/odoo.error.log; # Handle longpoll requests location /longpolling { proxy_pass http://odoochat; } # Handle / requests location / { proxy_redirect off; proxy_pass http://odoo; } # Cache static files location ~* /web/static/ { proxy_cache_valid 200 90m; proxy_buffering on; expires 864000; proxy_pass http://odoo; } # Gzip gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript; gzip on; } |
完成后,重新启动 Nginx 服务:
sudo systemctl restart nginx |
告诉 Odoo 启用多处理并使用代理和更改绑定接口
默认情况下,Odoo 在多线程模式下工作。对于生产部署,建议更改为多处理服务器,因为它可以提高稳定性并更好地利用系统资源。
要启用多处理,您需要编辑 Odoo 配置并设置非零数量的工作进程。worker 的数量是根据系统中 CPU 内核的数量和可用的 RAM 内存计算的。
根据官方的Odoo 文档 ,要计算工人数量和所需的RAM 内存 大小,您可以使用以下公式和假设:
工人数计算
理论最大worker数=(system_cpus * 2)+ 1
1 个工人可以服务 ~= 6 个并发用户
Cron 工作者也需要 CPU
RAM内存大小计算
我们会认为所有请求中有 20% 是重请求,80% 是轻请求。大量请求使用大约 1 GB 的 RAM,而较轻的请求使用大约 150 MB 的 RAM
需要的内存 = number_of_workers * ( (light_worker_ratio * light_worker_ram_estimation) + (heavy_worker_ratio * heavy_worker_ram_estimation) )
如果您不知道系统上有多少 CPU,请使用以下grep 命令:
grep -c ^processor /proc/cpuinfo |
假设您有一个具有 4 个 CPU 内核、8 GB RAM 内存和 30 个并发 Odoo 用户的系统。
30 users / 6 = 5 (5 是理论所需的工人数量)
(4 * 2) + 1 = 9 ( 9 是理论最大工人数)
根据上面的计算,您可以使用 5 个工人 + 1 个工人作为 cron 工人,总共 6 个工人。
根据worker数量计算RAM内存消耗:
RAM = 6 * ((0.8150) + (0.21024)) ~= 2 GB of RAM
计算表明,Odoo 安装将需要大约 2GB 的 RAM。
默认情况下,Odoo 服务器侦听8069所有接口上的端口。要禁用对 Odoo 实例的直接访问,您可以阻止8069所有公共接口的端口或强制 Odoo 仅侦听本地接口。
我们修改Odoo的设置文件为下面就行
sudo vi /etc/odoo15 .conf |
1 2 3 4 5 6 7 8 9 10 | proxy_mode = True xmlrpc_interface = 127.0.0.1 netrpc_interface = 127.0.0.1 limit_memory_hard = 2684354560 limit_memory_soft = 2147483648 limit_request = 8192 limit_time_cpu = 600 limit_time_real = 1200 max_cron_threads = 1 workers = 5 |
重启 Odoo 服务以使更改生效:
sudo systemctl restart odoo15 |
如果想以后方便迁移以及一台机器上运行多个Odoo实例可以看我写的另外一篇如何用docker部署odoo
配置有问题:
# Handle / requests
location / {
proxy_redirect off;
proxy_pass http://odoo;
}
这里的proxy_redirect off;是错误额的
这个也是官方教程里给的,我亲自部署过应该没问题,不过现在17了应该会有些不同。