全书完整目录请见:Odoo 12开发者指南(Cookbook)第三版
本章中,我们将讲解如下部分
- 安装Odoo来供生产使用
- 为生产环境调整配置文件
- 设置Odoo来作为系统服务
- 使用nginx和Let’s Encrypt配置反向代理及SSL
- 使用Docker来运行Odoo
- 通过docker-compose运行Odoo
- 管理网站的内容分发网络(CDN)
引言
在第一章 安装Odoo开发环境(从源码轻松安装Odoo一节),以及第二章 管理Odoo服务器实例(标准化你的实例目录布局一节)中,我们探讨了开发环境的设置。生产环境的要求与其会稍有不同。本章讲解Odoo部署的具体内容。
安装Odoo来供生产使用
在生产阶段安装Odoo与为开发安装Odoo并没有很大的区别。但有些可用的方法,这部分中将提供一个类似于开发环境的安装。
准备工作
我们预设你已有准备好了一个开发实例。这部分中我们假设:
- 你实例的这个项目以与第二章 管理Odoo服务器实例中标准化你的实例目录布局所建议的方式进行管理。我们将使用https://github.com/你的登录名/project.git。这个仓库应包含该实例在开发时所使用的配置文件,该实例的具体插件以及在该项目上下文你所创建的帮助脚本。
ℹ️注意:
如果你项目的配置文件包含安全信息,如密码,则不应将该项目推送到GitHub这样的公共服务上。而应使用内部Git仓库或私有GitHub项目。 - 部署服务器运行着Debian Stretch(但使用做过一些修改的衍生发行版应该也可以运行,如Ubuntu,更多信息请参见第一章 安装Odoo开发环境)。
- 你通过使用ssh或sudo拥有最终服务器的root权限。如果没有该权限,则应找到系统管理员来协助你对部署服务器做相关配置。
- 你知道最终的完全限定域名(FQDN)并可通过它来访问该服务器。
如何操作…
你需要执行如下步骤来为生产环境安装Odoo(译者注:GitHub 脚本):
- 以root权限安装并构建如下依赖:
123456789101112# apt-get update# apt-get install git python3.5 postgresql nano virtualenv \gcc python3.5-dev libxml2-dev libxslt1-dev \libevent-dev libsasl2-dev libldap2-dev libpq-dev \libpng-dev libjpeg-dev \xfonts-75dpi xfonts-base wget xz-utils# wget -O wkhtmltox.tar.xz \https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz# tar xvf wkhtmltox.tar.xz# mv wkhtmltox/lib/* /usr/local/lib/# mv wkhtmltox/bin/* /usr/local/bin/# mv wkhtmltox/share/man/man1 /usr/local/share/man/ - 以root用户创建一个名为odoo的用户:
1# adduser odoo - 配置PostgreSQL数据库:
12# sudo -u postgres createuser odoo# sudo -u postgres createdb -O odoo odoo_project - 以odoo用户克隆项目仓库:
12345# su odoo$ mkdir ~/odoo-prod$ cd ~/odoo-prod$ git clone https://github.com/yourlogin/project.git project$ mkdir -p project/src - 以odoo用户,克隆Odoo源代码:
12$ cd project/src$ git clone -b 12.0 --single-branch https://github.com/odoo/odoo.git odoo - 创建virtualenv并安装依赖:
123$ virtualenv -p python3 ~/env-odoo-12.0$ source ~/env-odoo-12.0/bin/activate$ pip3 install -r odoo/requirements.txt - 在project/src子目录中克隆所有第三方插件仓库:
1$ git clone -b 12.0 https://github.com/OCA/partner-contact.git - 创建~/odoo-prod/project/bin目录:
1$ mkdir ~/odoo-prod/project/bin - 创建一个脚本~/odoo-prod/project/bin/start-odoo来在生产环境轻松启动Odoo:
12345#! /bin/shPYTHON=~env-odoo-12.0/bin/python3ODOO=~odoo/odoo-prod/project/src/odoo/odoo-binCONF=~odoo/odoo-prod/project/production.conf${PYTHON} ${ODOO} -c ${CONF} "$@" - 让该脚本可执行:
1$ chmod +x ~/odoo-prod/project/bin/start-odoo - 以root用户卸载gcc:
1# apt-get remove gcc
运行原理…
大部分的内容和第一章 安装Odoo开发环境中所描述的是一样的,但也有一些关键的区别。
我们在使用一个独立的系统用户来作为Odoo的登录用户。这让我们可以控制谁对账户拥有权限,例如通过配置sudo或ssh认证密钥的方式。它还允许我们给用户授予尽量少的权限,以防实例受到威胁和攻击。
连接这一账户的数据库没有任何特权 – 甚至没有数据库创建的权限。我们只需在外部创建数据库一次。如果实例受到攻击,黑客将不能在服务器上创建其它数据库。
我们所创建的Odoo脚本将会在本章后面的设置Odoo来作为系统服务中使用到。它使用production.conf 配置文件,这在下一部分为生产环境调整配置文件中将进行讲解。
我们在操作的最后卸载了gcc,这样在黑客获取到权限时,他们将不能使用它来编译本地的可执行文件。
在这一部分的最后,你的服务尚未准备就绪,你需要参照本章中的为生产环境调整配置文件、设置Odoo来作为系统服务和配置反向代理及 SSL 的部分。
扩展内容…
以下为准备部署你的实例时需要考虑的几个更重要的点。
服务器选型
你应该使用什么样的服务器?基本上当今所有的物理服务器都足以处理包含20个并发用户的平均大小的Odoo实例。因为虚拟机通常分配了更少的资源,如果你计划使用虚拟机,你会需要稍稍更多的关注一下。以下是帮助你上手的几个重要的点。显然,需要对它们进行优化来匹配你对Odoo的使用。
一个小型Odoo实例至少需要1 GB的内存。对于内存分配要适当宽松点,最后为服务添加2-4 GB的swap内存也是不错的起点。最少给你的服务2 个/核CPU。如果你在同一台主机上运行PostgreSQL服务,至少为数据库分配4个/核 CPU 以及1 GB内存。额外的CPU/核数将由Odoo的worker使用,这会在下一部分为生产环境调整配置文件中讲解。
如果你保留Git历史记录的话(这部分我们推荐保留),实例的源代码将占用1-2GB的磁盘空间。文件存储(配置文件中的data_dir)会随着实例的使用不断增长,这一增长严重地依赖于你的实例用来做什么。一开始分配5GB,在磁盘爆满前你应该会有足够的时间来进行磁盘使用的监控。如果你在同一台主机上运行数据库,给包含数据库运行文件的分区分配足够的磁盘空间,50GB起。
你还将为主机上数据库和文件存储的备份预留空间。这很大程度取决于你的备份计划,200GB是一个不错的初始配置。
PostgreSQL调优
讨论PostgreSQL的调优不在本书的范畴内。你可能会需要阅读Packt出版社的PostgreSQL 10管理员指南或PostgreSQL 10.0高性能等书来获得这一个课题更深入的知识。
PostgreSQL的默认配置通常很保守,以防止数据库服务独占所有的系统资源。在生产服务器上,你可以无忧地提升postgresql.conf 文件中的一些参数来获取更好的性能。以下是你可以用于入手PostgreSQL 9.6 的一些设置:
1 2 3 4 5 6 7 8 9 10 |
max_connections = 80 shared_buffers = 256MB effective_cache_size = 768MB work_mem = 3276kB maintenance_work_mem = 64MB min_wal_size = 2GB max_wal_size = 4GB checkpoint_completion_target = 0.9 wal_buffers = 7864kB default_statistics_target = 100 |
在修改了这些设置之后你需要重启PostgreSQL(sudo /etc/init.d/postgresql restart)。
pgtune工具可以帮助你找到更多的合适的配置。在线版本地址为http://pgtune.leopard.in.ua/:
访问该网站并填写其中的表单:
- DB Version:使用你所安装的数据库版本(默认Debian Stretch为9.6,Ubuntu 18.04为10.5)
- OS Type: Linux。
- DB Type:选择Online transaction processing system,因为Odoo使用了大量的事务。
- Total Memory (RAM):填写你想为PostgreSQL分配的内存,如果你使用一台独立的服务机则接近它的所有内存(参见下一段中有关独立数据库服务器的内容了解更多详情)。
- Number of CPUs (core):这个参数的值为你想要为PostgreSQL分配的CPU数量/核数。
- Number of Connections:你的数据库服务可以接受的最大并发数。
- Data Storage:数据存储设备的类型。例如,SSD或HDD。
如果你的实例负载很重,可以通过将数据库服务和Odoo服务分离到两台不同的主机上来获得更佳的体验。不要使用同一台物理主机上的两个虚拟机,如果你已经碰到这种状况时使用高速网络连接的两台物理服务器。那样,你会需要确保数据库服务器主机上pg_hba.conf文件允许来自Odoo服务器的密码验证连接,并且postgresql.conf文件允许PostgreSQL服务在网卡上监听这两台服务器。
源码版本
在克隆Odoo和第三方依赖时,你会想要确保使用与开发环境中所使用的相同修订版本。有几种实现方式:
- 你可以在一个文件中手动记录本地修订的SHA1版本,在项目仓库中进行记录,并确保你在生产服务器上使用相同的修订版本。
- 你可以使用自己的GitHub仓库中对这些仓库复制的标签或分支。
- 你可以使用git submodule来绑定你项目仓库中的这些修订版本(访问https://git-scm.com/book/en/v2/Git-Tools-Submodules来获取这个很顺手的工具的文档)。
ℹ️为什么不使用Odoo所提供的Linux发行包?
如果这么做,你会上手很快,因为很多事情发行包都会替你处理好。但是,使用打包的资源会带来一些问题。最重要的是,你不能轻松地为Odoo源代码打补丁,通过源代码运行时则更为容易。没错,这不是你需要日常做的事,但能够使用标准开发工具来完成这一任务,而不是手动地在生产服务器上应用并跟踪补丁,会有巨大的帮助并节约宝贵的时间。
备份
这一部分不讲解备份。至少你应使用服务器上的cron任务来进行每天的备份。一个简单且基础的方案是以root用户运行crontab -e 来编辑 crontab文件并添加如下代码:
1 2 3 4 |
@daily su postgres -c pg_dumpall | gzip >\ /backups/postgresql-$(date +%u).dump.gz @daily tar czf /backups/odoo-filestore-$(date +%u).tgz \ /home/odoo/odoo-prod/project/filestore |
不要忘记创建这个/backups目录。备份文件不应存储在相同的硬盘上,理想情况下,这些文件应镜像到在不同物理空间的服务器上。定期检查这些备份,保留不能还原的备份文件是没有意义的。
推荐的方案是保留最近7天的每日备份,这表示如果问题出现的话你会丢失大约一天的运行数据。PostgreSQL有更高级的方案可允许基于时间点的故障恢复(PITR)。你可以在Packt出版社的PostgreSQL 9 Admin Cookbook一书了解到更多信息。类似地,有很多可用于文件备份Linux的工具,如duplicity(http://duplicity.nongnu.org/),会让管理更容易。
为生产环境调整配置文件
在第一章 安装Odoo开发环境中,我们了解了如何将实例配置保存到一个文件中。很多参数我们都使用了默认值,并且如果你照着第二章 管理Odoo服务器实例中标准化你的实例目录布局以及本章中安装Odoo来供生产使用小节来安装生产环境的话,你应该会在生产环境中有着相同的配置文件。这一节展示如何获取一个适合于正式环境的配置文件。
准备工作
我们假设你已经通过安装Odoo来供生产使用一节在生产服务器上安装了Odoo。假设你在与Odoo相同的服务器上运行PostgreSQL。
你可以安装pwgen小工具来生成随机密码。
我们这里按照在生产服务器上运行它们来描述这些步骤,但也可以在你的开发服务器上进行执行,因为新的配置文件被添加到了我们用于部署到生产环境的项目的Git仓库中。
如何操作…
要为生产环境调整配置文件,你需要按照如下步骤:
- 在开发环境的基础上新建一个生产环境的配置文件:
12$ cd ~/odoo-prod/project$ cp development.conf production.conf - 编辑生产环境配置production.conf 文件。
- 修改addons_path来匹配生产环境的根路径:
1addons_path = /home/odoo/odoo-prod/project/src/odoo/addons, /home/odoo/odoo-prod/project/src/odoo/odoo/addons, /home/odoo/odoo-prod/project/src/partner-contact - 修改数据路径:
1data_dir = /home/odoo/odoo-prod/project/filestore - 修改服务服务日志路径来匹配生产环境的根路径:
1logfile = /home/odoo/odoo-prod/project/logs/odoo.log - 配置日志轮询:
1logrotate = True - 配置日志处理器:
12log_level = warnlog_handler = :WARNING,werkzeug:CRITICAL,odoo.service.server:INFO - 调整数据库连接参数:
1234567db_host = Falsedb_maxconn = 64db_name = odoo-projectdb_password = Falsedb_port = Falsedb_template = template1db_user = False - 配置数据库过滤器并禁用数据库列出显示:
12dbfilter = odoo-project$list_db = False - 使用pwgen生成的随机密码来修改master密码
1admin_password = 使用一个随机密码 - 配置Odoo来以worker进程运行:
12345678workers = 4# limit_memory_hard: 4GBlimit_memory_hard = 4294967296# limit_memory_soft: 640MBlimit_memory_soft = 671088640limit_request = 8192limit_time_cpu = 120limit_time_real = 300 - 仅监听本地网卡:
1http_interface = 127.0.0.1 - 保存该文件并将其添加至Git仓库:
12$ git add production.conf$ git commit -m "add production configuration file"
运行原理…
这一节中的使用的大部分参数都在第一章 安装Odoo开发环境的在一个文件中存储实例配置中进行了讲解。
在第3, 4和5步中,我们修改了插件路径和日志文件。如果你用于开发的环境与生产环境有着相同的布局,这是要求做的,因为Odoo在配置文件中预期的是绝对路径。
第6步启动了日志轮询。这会引发Odoo配置日志模块来实现服务日志的按日存档,并且保存日志30天。对生产服务器这非常有用,可以避免日志最终消耗掉所有的可用磁盘空间。
第7步配置了日志级别。这里建议的配置非常保守,仅会记录WARNING级别以上的日志信息,除werkzeug (CRITICAL) 和odoo.service.server (INFO)外。有关日志过滤的更多信息,参见第八章 调试,那里你会发现生成服务日志帮助调试方法一节。可根据自身情况进行自由调整。
第8步配置数据库设置。如果你的PostgreSQL数据库服务在本地运行并且按照前面部分所讲解的进行设置这会生效。如果你在其它服务器上运行PostgreSQL,会需要将False值替换为你的数据库实例对应的连接配置。
第9步通过配置数据库过滤器来限制该实例的可用数据库。我们还禁用了列出数据库,这并不是严格必需的,因为我们在dbfilter中设置的正则表达式仅会匹配单个数据库。但这样做仍是一件好事,可以避免向任何人展示数据库列表,来避免有用户连接到错误的数据库上。
第10步为实例设置了一个足够复杂的master密码。master密码用于通过用户界面管理数据库,一些社区插件也使用它来作为导致数据损失的动作执行前进行安全验证。你极其需要设置这一足够复杂的值。我们推荐使用pwgen小工具来生成一个随机密码,但任意其它方法都有效。
第11步配置Odoo使用worker进程进行运行。在这种模式下,Odoo会创建一些worker进程(本例中为4个)来处理HTTP请求。这与默认配置相比有几个优势,其中请求由单独的线程进行处理,如下:
- 请求可更好地使用服务器的多个或多核 CPU 来并行进行处理(Python多线程由于Python解释器中的全局锁(GIL)的存在而受到限制)。
- 可以根据资源消耗终止其中的一个worker进程。下表中给出了可以配置的不同资源限制:
参数 推荐值 描述 limit_memory_hard 4294967296 这是一个worker进程可以分配的最大内存值。我们推荐使用4 GB,因为Odoo所启动的一些进程可以分配大量的内存。 limit_memory_soft 671088640 如果一个worker 进程最终的消耗超过这一限制(我们的设置为640 MB),在它结束处理当前请求后会被终止。 limit_request 8192 一个worker进程会在处理这么多请求之后被终止 limit_time_cpu 120 这是允许处理一个请求的最长 CPU 时间。 limit_time_real 300 这是允许处理一个请求的最长真实时间。
第12步配置内部Odoo网页服务仅监听本地接口。这表示该实例无法通过其它服务器访问。这让我们可以在相同服务器上配置反向代理来访问该服务,并强制加密连接。参见本章后面的配置反向代理及SSL一节。
小贴士:如果你不确定应为服务设置多少个worker进程,使用以下公式为你的系统计算一个worker进程数:
No. of workers = (No. of CPU * 2) + 1
这里,一个worker进程可以处理大约6个并发用户。
扩展内容…
在使用worker进程运行时,你可能会碰到如下针对该模式的具体问题:
- 如果你在使用worker进程运行时获得一些wkhtmltopdf未如预期运行的奇怪报错(例如,以状态码-11 或 -6过早的退出 ),那么很有可能你所设置的limit_memory_hard的值过低。试着做一些提升,因为默认值是出名的过低。
- 如果你在执行长操作时得到超时错误(包括CSV导入、导出以及插件模块安装),试着提升limit_time_cpu和limit_time_real参数,因为同样它们的默认值也相当低。如果你有反向代理 ,还应检查其超时限制(反向代理中的过低限制不会阻止事务的完成,但会在用户的浏览器中展示错误消息,这会导致他们尝试重新导入并为服务器带来不必要的负载)。
- 如果你的实例在打印报表时完全卡住,试着提升worker进程数。这可能是由wkhtmltopdf在打印时占用所有可用worker进程所导致的死锁。
小贴士:不论什么情况下,保持在配置到生产环境前进行设置的验证,并记住在启用worker进程时测试打印报表。
设置Odoo来作为系统服务
对于一个生产实例,在机器重启时保持Odoo服务的启动非常的重要。在当前的Linux系统中,这通过systemd的配置来实现。如果你的操作系统不使用systemd,则需要查看文档来获取这一结果。
准备工作
我们假定你按着前面部分进行安装和Odoo实例的配置,尤其是Odoo的部署源代码应为/home/odoo/odoo-prod/project/src/odoo/,以及实例的配置文件应为/home/odoo/odoo-prod/project/production.conf。该脚本还使用了安装Odoo来供生产使用一节第9步中所创建的start-odoo 脚本。
如何操作…
你需要执行如下步骤配置systemd来启动Odoo:
- 使用root权限(sudo su),创建一个名为/lib/systemd/system/odoo.service的文件并添加如下内容:
12345678910111213[Unit]Description=Odoo 12.0After=postgresql.service[Service]Type=simpleUser=odooGroup=odooWorkingDirectory=/home/odoo/odoo-prod/projectExecStart=/home/odoo/odoo-prod/project/bin/start-odoo[Install]WantedBy=multi-user.target - 使用root权限,注册该服务:
1# systemctl enable odoo.service - 使用root权限,启动服务:
1# service odoo start - 可运行如下命令来停止服务:
1# service odoo stop
运行原理…
systemd 使用一些配置文件或脚本来识别在服务启动时必须运行的程序。这一节中所提供的配置需要做一些微调来适配你自己实例的路径。
ℹ️别忘记重启服务并查看Odoo是否正常启动!
使用nginx和Let’s Encrypt配置反向代理及SSL
在你通过HTTP协议访问Odoo服务时,用户浏览器与Odoo服务之前的所有信息都暴露在网络中,因此使用HTTPS协议来对传输信息进行加密非常之有必要。Odoo无法原生地实现这点,有必要配置反向代理来为Odoo处理加密和解密。这节向您展示使用nginx(http://nginx.net)来进行实现。我们还将向你展示在你的组织没有自己签署 SSL 证书的方式时使用Let’s Encrypt(https:// letsencrypt.org)来管理证书和更新证书。
相关文章:
准备工作
你应该知道服务器的对外名称以及相应地配置DNS。这一节中,我们将使用 odoo.example.com来作为我们的服务器名。你将需要使用自己的域名替换它。
如果你使用 Let’s Encrypt来获取SSL证书的话确保外界可通过DNS名称访问到你服务器的80和443端口。
如何操作…
你需要按照如下步骤来通过NGINX使用HTTPS访问你的实例:
译者注:下例中安装 ssl 证书需在公网进行,因Let’s Encrypt会通过 DNS 验证域名的有效性,相关文件请见 GitHub 仓库
- 使用root权限,安装Let’s Encrypt客户端certbot:
123456# apt-get update# apt-get install software-properties-common -y# add-apt-repository universe# add-apt-repository ppa:certbot/certbot# apt-get update# apt-get install certbot python-certbot-nginx -y - 使用root权限,从Let’s Encrypt请求一个证书(不要忘记修改email和服务器地址):
12# certbot certonly --standalone -n --agree-tos\-m youremail@example.com -d odoo.example.com
译者注:安80端口被占用可能会报Problem binding to port 80: Could not bind to IPv4 or IPv6.,需关闭相应服务如:service nginx stop - 使用root权限,安装nginx:
1# apt-get install nginx -y - 在/etc/nginx/sites-available/odoo-ssl中创建一个配置文件并添加上游引用如下:
123456upstream odoo {server 127.0.0.1:8069;}upstream odoochat {server 127.0.0.1:8072;} - 在相同的文件中,添加rewrite规则来将http重写向到https网站:
12345server {listen 80;server_name odoo.example.com;rewrite ^(.*) https://$host$1 permanent;} - 在相同的文件中,添加如下nginx配置来通过https提供Odoo实例的服务:
123456789server {listen 443;server_name odoo.example.com;proxy_read_timeout 720s;proxy_connect_timeout 720s;proxy_send_timeout 720s;# 在这里放置第7到12步的配置} - 在server版块中添加SSL配置:
12345678# SSL Configurationssl on;ssl_certificate /etc/letsencrypt/live/odoo.example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/odoo.example.com/privkey.pem;ssl_session_timeout 30m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384";ssl_prefer_server_ciphers on; - 在server版块中添加日志文件配置:
123# Add log filesaccess_log /var/log/nginx/odoo.access.log;error_log /var/log/nginx/odoo.error.log; - 通过在server版块中添加如下配置来启用gzip:
123# enable gzipgzip on;gzip_types text/css text/scss text/plain text/xml application/xml application/json application/javascript; - 在server版块中添加代理header配置:
12345# Add Headersproxy_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; - 在server版块中添加反向代理配置:
123456789# Manage longpolling on 8072 portlocation /longpolling {proxy_pass http://odoochat;}# Redirect requests to odoo server on 8069location / {proxy_redirect off;proxy_pass http://odoo;} - 通过在server版块中添加如下配置来启用静态缓存:
1234567# Enable static cachelocation ~* /web/static/ {proxy_cache_valid 200 60m;proxy_buffering on;expires 864000;proxy_pass http://odoo;} - 使用root权限,添加/etc/nginx/sites-enabled/中配置文件的链接:
12# ln -s /etc/nginx/sites-available/odoo-ssl\/etc/nginx/sites-enabled/odoo-ssl - 使用root权限,删除/etc/nginx/sites-enabled/default:
1# rm /etc/nginx/sites-enabled/default - 使用Odoo用户,编辑实例的生产配置文件来启动proxy_mode:
1proxy_mode = True - 使用root权限,重启你的odoo实例和nginx:
12# service odoo restart# service nginx restart - 使用root权限,创建一个etc/cron.d/letsencrypt计划任务文件来确保证书会被更新,添加如下内容(译者注:crontab -e):
111 5 * * * certbot renew
运行原理…
在第1步和第2步中,我们安装了certbot并为odoo.example.com网站生成了SSL证书。certbot程序是一个命令行工具,简化了与letsencrypt.org交互来生成免费SSL证书的操作。完整文档参见https://certbot.eff.org/docs/。本节中,我们使用了子命令certbot certonly,它将向Let’s Encrypt请求一个-d 选项所传递域名的签名证书。使用-m选项指定你的email地址。–standalone选项要求certbot设置本地临时网页服务,Let’s Encrypt将尝试与其联系来检查你对请求证书的域名的控制权。因此在托管Odoo的服务器上运行该命令、DNS指向该服务器以及没有防火禁用80和443端口的访问都很重要。
ℹ️这一检查通过连接http://<yourdomain>:80/.well-known/acme来实现。certbot的–standalone模式创建一个临时web服务监听该端口并能响应请求,但这仅在没有其它进程监听80端口及外部防火墙允许对该端口的外部访问通过时生效。
我们使用nginx作为反向HTTP代理。进入的HTTP和HTTPS连接都由nginx处理,它将该请求的处理代理至Odoo服务。Odoo服务配置为仅监听本地回环接口(127.0.0.1)的8069端口来接收正常请求(http_port)、监听8072端口来接收长轮询请求(longpolling_port)。你可能会需要按照自己的配置来调整这些端口号:
在第4步中,我们添加了/etc/nginx/sites-available/odoo-ssl这一nginx配置文件。在这个文件中,我们添加了一个上游引用 。这是对本地服务器的引用 ,我们将在下一步中使用到它。
在第5步中,我们添加了服务器配置来使用HTTP协议管理80端口进入的连接。我们不想要通过HTTP提供网站服务,因为数据以纯文本进行传输,这表示可以嗅探出密码。因此,我们添加了一个URL并重写了一条规则来将所有URL永久重定向到使用HTTPS协议加密的443端口。
第6-13步要更为复杂些,添加了配置来使用HTTPS协议处理连接。以下是配置中不同版块的详情:
- 第6步中的配置版块配置服务器处理对odoo.example.com域名443端口上的请求。
- 第7步中的配置版块配置了SSL协议,加密密钥及证书。
- 第8步中的配置版块添加了日志文件的位置。在请求通过Nginx进行服务提供时,该文件会用于存储日志。
- 第9步中添加了gzip版块,用于压缩文件。这对减小页面大小发挥了重要的作用。
- 第10步中的配置版块添加了额外的header来对每次请求提供更多的信息。这些额外的header用于向Odoo服务提供更多的信息。
- 第11步中添加了location /版块,定义了进入的请求的默认处理,它们会被代码到监听8069端口的Odoo服务。
- 第11步中添加了location /longpolling版块,用于处理以/longpolling开头的URL的查询,它们被通过8072端口转发到Odoo。这些连接由总线(bus)插件模块使用来给网页客户端发送通知。
- 第12步中添加了location ~* /web/static/版块,使用了正则表达式来匹配Odoo各模块静态文件的URL。这些文件很少进行更新,因此我们让nginx对它们进行缓存来减轻Odoo服务器的负载。
在最后一步中,我们使用了certbot renew命令,它检查待更新证书,并自动更新这些证书。默认Let’s Encrypt证书的有效期是90天,还是很短的。借助于这一每天运行的工具,即将过期的证书将会自动被更新。
扩展内容…
这一部分集中于nginx配置。你可能会更熟悉其它工具,如Apache网页服务器和mod_proxy。这时,你自然也可以使用它们来实现相似的设置。
如果不愿意使用Let’s Encrypt,而偏好于使用其它证书机构(CA),你可以使用如下步骤:
- 安装openssl:
1$ sudo apt-get install openssl - 为你的服务器生成密钥:
12$ mkdir ~/sslkey$ openssl genrsa -out ~/sslkey/server.key 2048 - 生成签署请求:
12$ openssl req -new -key ~/sslkey/server.key\-out ~/sslkey/server.csr - 以上的命令会接着一系列的问题询问你的公司名和Odoo服务URL等。不要填错了,否则你的证书将不可用。
- 你将可以发送~/sslkey/server.csr文件到你所选择的证书机构(CA)。CA会向你发回一个名为server.crt的文件。
- 你将需要在/etc/nginx/ssl/ 目录中存储该文件以及第2步中所生成的server.key文件:
123456# mkdir -p /etc/nginx/ssl# chown www-data /etc/nginx/ssl# mv server.key server.crt /etc/nginx/ssl# chmod 710 /etc/nginx/ssl# chown root:www-data /etc/nginx/ssl/*# chmod 640 /etc/nginx/ssl/* - 那么,在本节中所提供的/etc/nginx/sitesavailable/odoo-443这一nginx配置文件中,重写ssl_certificate和ssl_certificate_key行如下:
12ssl_certificate /etc/nginx/ssl/server.crt;ssl_certificate_key /etc/nginx/ssl/server.key; - 最后,重启nginx。
译者注:还有很多其它选择,如使用阿里云可直接在后台生成一年免费证书,下载文件配置到 Nginx中即可
其它知识
- 有关nginx配置选项的更多信息,参见http://nginx.org/en/docs/。
- 有关Apache2作为反向代理配置的教程及个人证书机构的使用,参见http://antiun.github.io/odoo-reverse-proxy-howto/。
使用Docker来运行Odoo
Docker项目通过提供更高级别的工具来让Linux容器(LXC)更易于管理。这些容器可易于应用的发布以及依赖的管理。Docker周边有一整套生态系统,用于方便容器化应用的部署和管理。讨论这些细节在本节的范畴之外,有兴趣的读者可阅读Packt出版社的Learning Docker来获取更深入的讲解。
这一节中,我们将来了解如何使用官方Odoo Docker镜像来运行一个开发或生产服务。
准备工作
我们假定在你的开发机器及生产服务器上都安装了Docker。在Debian GNU/Linux上安装Docker社区版的指南参见https://docs.docker.com/install/linux/docker-ce/debian/(其它平台的安装指南在该页面上也可以找到)。而在Ubuntu服务器上你可以使用如下命令来进行安装:
1 |
$ sudo apt-get install docker.io -y |
如何操作…
按照如下步骤来通过官方Odoo镜像来运行Docker(译者注:以下操作使用的是 root 账号,非 root 用户可以添加 sudo来执行命令):
- 通过如下命令设置PostgreSQL服务docker实例:
1# docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres:10 - 通过如下命令运行PostgresSQL数据库:
1# docker start db - 通过如下命令设置Odoo docker实例:
1# docker run -p 8069:8069 --name odoo --link db:db -t odoo - 通过如下命令运行odoo实例:
1# docker start odoo
以上命令会在8069端口上启动Odoo服务。在你的本地机器上,你可以通过http://localhost:8069来访问该odoo实例。
如果你想要查看运行中的docker容器的状态,运行如下命令即可:
1 |
# docker ps |
docker ps命令会展示类似如下的输出:
1 2 3 4 |
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4c1b4e50f632 odoo "/entrypoint.sh odoo" 10 seconds ago Up 9 seconds 0.0.0.0:8069->8069/tcp, 8071/tcp odoo 58854bebe4cb postgres:10 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 5432/tcp db |
运行原理…
Docker允许你创建系统镜像并将它们分发到其它服务器上来运行。Docker镜像通过编写Dockerfile来创建,该文件描述如何在已存在的Dockerfile上添加层。Docker镜像托管在https://hub.docker.com上,在这一节中,我们使用了PostgreSQL和Odoo的官方镜像。
在运行Odoo实例容器之前,我们需要为PostgreSQL设置一个容器。在第1步中,我们运行了PostgreSQL 10的Docker镜像。该命令会搜索这一PostgreSQL Docker镜像。如果在你的系统中不存在,Docker会下载它。在命令中,我们传递了–name db选项。这里,db是该PostgreSQL容器的名称。在第2步中,我们启动了PostgreSQL的Docker容器。
在第3步中,我们运行了Odoo的Docker镜像。这在8069端口上运行了Odoo实例。如是你想要以不同的配置来运行该命令,可以使用不同的选项。以下是进一步地讨论如何使用自定义选项来运行Odoo实例的一些示例。
运行带有配置文件的Odoo镜像
你可以使用自己的配置文件来运行Odoo实例。这样做你会需要使用-v volume选项。以下是通过/path/to/config/odoo.conf配置文件运行Odoo容器的命令:
1 |
# docker run -v /path/to/config.conf:/etc/odoo -p 8069:8069 --name odoo --link db:db -t odoo |
如果你不想载入该配置文件,而是想直接使用配置选项,那么你可以通过在命令行中传递带有 — 的选项,类似这样:
1 |
# docker run -p 8069:8069 --name odoo --link db:db -t odoo --db-filter=test |
运行带有自定义插件的Odoo镜像
默认Odoo容器运行社区版插件。如果你想要使用你自己的插件模块来运行Odoo,你可以你下面这样在/mnt/extra-addons目录中挂载自己的插来进行实现:
1 |
$ docker run -v /path/to/my_addons:/mnt/extra-addons -p 8069:8069 --name odoo --link db:db -t odoo |
运行多Odoo实例
如果你想在单个服务器上运行多个Odoo实例,那么你可以通过修改容器名及暴露的端口来进行实现。查看如下的命令,通过以odoo1和odoo2的名称来运行两个odoo容器。这些Odoo实例将分别运行在8070和8071端口上:
1 2 |
# docker run -p 8070:8069 --name odoo2 --link db:db -t odoo # docker run -p 8071:8069 --name odoo3 --link db:db -t odoo |
扩展内容…
如果使用官方Odoo Docker镜像安装的服务无法满足你的要求,那么你可以通过Dockerfile创建你自己的Docker镜像。Odoo官方的Dockerfile地址为https://github.com/odoo/docker。你可以修改该Dockerfile,然后使用docker build 命令构建Docker镜像。
通过docker-compose运行Odoo
在上一节中,我使用两个Docker容器来运行Odoo实例,PostgreSQL和Odoo容器。这一节中,我们将来了解docker-compose,docker-compose是用于管理多容器Docker应用的工具。
准备工作
为使用docker-compose工具来设置Odoo,你将在系统中需要安装docker-compose。在终端中执行如下命令来在系统中安装docker-compose:
1 |
$ sudo apt-get install docker-compose -y |
如何操作…
根据如下命令来通过docker-compose运行Odoo实例:
- 新建docker-compose.yaml文件并添加如下内容:
1234567891011121314version: '2'services:web:image: odoo:12.0depends_on:- dbports:- "8069:8069"db:image: postgres:10environment:- POSTGRES_DB=postgres- POSTGRES_PASSWORD=odoo- POSTGRES_USER=odoo - 在终端中执行如下命令来运行Odoo实例(译者注:root 用户或 sudo):
1# docker-compose up -d
以上命令会在8069端口上启动Odoo服务。在你的本地机器上,你可以通过http://localhost: 8069访问Odoo实例。使用docker ps命令来查看运行中的容器。
运行原理…
docker-compose需要一个YAML文件来设置服务。在YAML文件中,你需要添加想要部署的服务的明细。在创建YAML文件之后,你可以使用单条命令启动所有服务。
在第1步中,我们为自己的服务创建了YAML文件。要运行Odoo实例,我们需要两个容器:一个给PostgreSQL数据库,一个给Odoo自身。在services: 版块中我们添加了两个服务。第一个名为web。该服务用于运行Odoo实例。在该服务中,你需要指定你想要容器化的镜像名称。因此,在web服务中,我们添加了odoo:12.0来作为镜像。
Odoo实例不能无数据库运行。因此,我们需要通过depends_on键来指定依赖。接着,我们指定了PostgreSQL的服务。为该服务指定了名称db。注意这是这是我们在web服务的依赖中添加的相同服务。
第二步中,我们使用了docker-compose命令来运行该Odoo实例。docker-compose命令将运行两个容器。你可以通过docker ps命令来查看细节。在运行了该命令之后,可通过https://localhost:8069来访问Odoo。
如果你想要使用自定义插件或你自己的配置,可以像如下这样在docker compose YAML文件中指定数据卷:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
version: '2' services: web: image: odoo:12.0 depends_on: - db ports: - "8069:8069" volumes: - odoo-web-data:/var/lib/odoo - ./config:/etc/odoo - ./addons:/mnt/extra-addons db: image: postgres:10 environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=odoo - POSTGRES_USER=odoo - PGDATA=/var/lib/postgresql/data/pgdata volumes: - odoo-db-data:/var/lib/postgresql/data/pgdata volumes: odoo-web-data: odoo-db-data: |
该YAML文件将通过自定义插件和自定义配置来运行Odoo实例。它还使用volumes来作为Odoo和PostgreSQL数据目录。
扩展内容…
我们在这一节中设置的Docker镜像仅仅是一个初始框架。你可能需要优先大量参数来方例实例的管理,修改Dockerfile来让你通过本地源代码运行Odoo,而不是在每次编辑一个模块时都要重建,这些都不在本书的讨论范畴之内。
Docker是一个巨大的世界,提供了大量的选项。你可能会想要在一个Docker镜像仓库上发布你的镜像,以及使用docker push和docker pull来发布和获取你项目的Docker镜像。你还可能会想要运行一个Docker管理平台,如Rancher,来在一个有负载均衡的服务器集群上运行你的镜像。同时,你还可以通过持续集成环境集成镜像的构建步骤发布你的开发快照来进行测试。
管理网站的内容分发网络(CDN)
内容分发网络(CDN)如今非常的流行。CDN通过在地理上非常近的服务器提供静态资源的服务来降低网站的加载时间。Odoo有一个内置的选项来为网站应用配置CDN。在下例中,我们将来了解如何在Odoo中设置CDN。
准备工作
我们假定你启动了Odoo实例并且已安装website应用。如果你不知道如何在Odoo中安装应用,请参见第二章 管理Odoo服务器实例中的安装并升级本地插件模块一节。
市面上有很多可用的CDN服务提供商,如MaxCDN、KeyCDN和CloudFlare。下例中,我们将使用KeyCDN来作为我们的CDN服务提供商。如果你使用的是其它的CDN服务提供商,会发现相同类型的配置选项,因为大部分CDN服务提供商以相似的概念运行,因此你可以使用任意基于拉取的CDN服务提供商。
如何操作…
为Odoo网站设置CDN,你需要完成两个配置:
- 配置CDN提供商
- 在Odoo上配置CDN
配置CDN提供商
请按照这些步骤来配置CDN提供商。这里我们将使用KeyCDN账户:
- 登录你的KeyCDN账户
- 点击Zones菜单并添加一个新区域:
- 设置如下选项来激活该CDN区域:
- Zone Name:任意标识区域的名称
- Zone Status: active
- Zone Type: Pull
- Origin URL:你的Odoo实例所运行的 URL
- 保存该pull区域并从该列表中拷贝Zone URL。我们在下面的几步中将在 Odoo 配置中使用这一 URL
在Odoo上配置CDN
使用管理员账户登录你的Odoo实例并按照如下步骤来在Odoo中配置CDN:
- 激活开发者模式,因为CDN配置仅在激活了开发者模式之后才会显示。参照第一章 安装Odoo开发环境中激活Odoo开发者工具一节。
- 打开website应用的Configuration菜单并搜索内容分发网络(CDN)选项:
- 在网站配置中设置如下选项并保存设置:
- CDN Base URL:设置由CDN供应商所提供的URL。在我们的例子中,我们将使用在上一小节第3步中拷贝的区域 URL
- CDN Filters:这是网站静态资源的URL正则表达式列表。这些规则用于标识将通过CDN提供服务的静态资源。Odoo会在该字段中填写默认值,但如果你使用其它的 URL 来提供静态资源,请手动在单独的行中添加这些 URL。
按照如下步骤来检查CDN的集成是否正常:
译者注:上图及配置截图使用的是MaxCDN,当前使用 KeyCDN 尝试多次未能成功注册,相关截图来自原书
你可能会获取到 Cross-Origin Resource(跨域资源)的报错,如下图所示:
要修复这些错误,你需要通过CDN激活CORS。在keyCDN中,你会在高级特性中看到CORS选项,如下图所示:
运行原理…
在你激活一个pull区域时,KeyCDN会自动从你的网站上抓取所有的静态资源。它会在全球不同的服务器上缓存这些资源。要在你的Odoo网站上使用这些缓存资源,你需要通过CDN提供商所给出的 URL 来加载静态资源。在第5步中,我们为Odoo网站配置了这一 URL,这样在这一步后,Odoo将以CDN URL来加载静态资源。
ℹ️为避免后台用户的问题,Odoo仅对公开用户通过CDN URL来加载静态资源。一旦你做了登录,Odoo会停止使用CDN URL并会从相同的域加载静态资源。
扩展内容…
CDN服务商,如Cloudflare,使用基于DNS的技术来提供网站内容的服务。如果你想要使用Cloudflare配置CDN,需要进行更多的配置。要使用Cloudflare,你需要通过与你的网站域名不同的域名/子域名来提供缓存网站的服务。例如,odoo.com使用odoocdn.com来提供CDN资源的服务。之后,你需要在Odoo的配置中设置该域名/子域名为CDN Base URL。
ℹ️警告
在通过不同 URL 为相同网站提供服务时需要格外小心,因为如果你提交该CDN域名给搜索引擎索引的话可能更改掉你的sitemap.xml文件。
2. 关于 Python 版本书中使用3.5可能出于历史原因,完全可以使用3.6,但暂不推荐使用3.7,否则要处理的问题会比较多