odoo 作为知名ERP程序,其开源性和可扩展性吸引了大量的用户。但是安装配置一直是老大难。在容器技术得到广泛引用的现在,odoo官方也出了docker版本,避免了安装配置上面的很多麻烦。详细介绍见:https://hub.docker.com/_/odoo

一般来说,大部分项目跟着官方的说明写配置都可以顺利运行,但是,docker官方给出的配置中,却偏偏有一个可能在生产环境中最需要用的docker-compose.yml文件无法正常启动odoo的docker。

这个配置文件是官方给出的docker compose examples的第三个

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_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:

测试环境:(1)centos 7.6, docker 版本 18.09; (2)ubuntu 18.04, docker版本18.09

根据官方给出的这个配置文件,配置好config文件(一般来说,默认配置即可,可以注释掉 - ./config:/etc/odoo选项),运行docker-compose up -d 后,打开chrome,输入http://IP:8069后,提示ERR_EMPTY_RESPONSE,如果是火狐,则提示链接被重置。

按经验,这种情况可能是selinux的锅,但是设置setenforce 0 后仍然无效,用 docker logs 命令查看输出,也没有任何错误错误的信息,仅仅有几行日志,貌似是卡在某处了。

于是一样一样排查,可以确定,官方给出的第一个docker-compose.yml配置可以正常运行,配置如下

version: '2'
services:
  web:
    image: odoo:12.0
    depends_on:
      - db
    ports:
      - "8069:8069"
  db:
    image: postgres:10
    environment:
      - POSTGRES_PASSWORD=odoo
      - POSTGRES_USER=odoo
      - POSTGRES_DB=postgres

那么就严格限制变量,一个一个查。首先查数据库,这个经常引发奇怪的问题。先把web部分按照可以运行的配置写,db部分按照官方第三个不能正常运行示例的内容,拼凑起一个docker-compose.yml

version: '2'
services:
  web:
    image: odoo:12.0
    depends_on:
      - db
    ports:
      - "8069:8069"
  db:
    image: postgres:10
    environment:
      - POSTGRES_PASSWORD=odoo
      - POSTGRES_USER=odoo
      - PGDATA=/var/lib/postgresql/data/pgdata
    volumes:
      - odoo-db-data:/var/lib/postgresql/data/pgdata
volumes:
  odoo-db-data:

写好后,重新运行docker-compose up -d,结果还是出错,不过这次提示比较统一,无论是chrome还是火狐,统一提示:Internal Server Error。

本来打算进入docker调试一下数据库,但是重新检查配置文件的时候,发现官方示例竟然漏掉了环境变量:- POSTGRES_DB=postgres, 加上去就好了。

也就是说,数据库部分的配置除了一个低级错误以外,没有什么大问题。

下面,集中精力排查web的问题。一般来说,挂载某个路径导致http挂掉最大可能是权限,大部分时候是selinux没有配置好。尽管大多数时候,selinux是背锅侠,但是这次貌似与之无关。难道,又是低级错误?

仔细审视dockerfile文件后,发现有这一行

# Set default user when running the container
USER odoo

基本可以确认,容器内的odoo用户有很大的“作案嫌疑”。以odoo用户的身份进入容器中,检查/var/lib/odoo的权限,发现是--x,只有执行,没有读写。而这个目录正是放web页面内容的地方,不能写自然http服务要卡住了。另外,在容器中,odoo的uid和gid都是101,挂载路径时,容器中目录和容器外目录的权限是一样的,但用户、组是通过id来联系的(内外可以不同名),只有挂载到容器内的目录uid和gid一样,容器内的“运行用户”才能获得正确的权限。

解决方案:

1、暴力办法,找到odoo-web-data目录,修改为777权限。一定要777权限,775也不可以,除非你的用户root用户有附加gid是101

2、检查系统内有没有uid=101的用户,或是gid=101的组,如果有,恭喜,转到解决方案1;如果没有,执行如下命令

(1) sudo groupadd -g 101 odoo

(2) sudo useradd -d /home/odoo -u 101 -g 101 -s /sbin/nologin odoo

(3) 找到odoo-web-data目录,执行

sudo chown -Rf odoo:odoo odoo-web-data

不过,建议执行解决方案之前,清理掉 odoo-web-data 和 odoo-db-data 里面的内容,如果不清理,有时候还会出现Internal Server Error或者是其他奇怪的内容。

下面把建议的docker-compose.yml贴出来

version: '3'
services:
  web:
    image: odoo:12.0
    depends_on:
      - db
    ports:
      - "8069:8069"
    volumes:
#挂载用:z参数,以防selinux权限出问题
      - ./odoo-web-data:/var/lib/odoo:z
#如果用默认配置,下面这行可以注释掉
#      - ./config:/etc/odoo
      - ./addons:/mnt/extra-addons
#如果使用顶级/全局volumes (top-level volumes) 下面这样写
#      - odoo-web-data:/var/lib/odoo:z
#如果采用top-level volumes,则相对路径的odoo-web-data一行需要注释掉
  db:
    image: postgres:10
    environment:
      - POSTGRES_PASSWORD=odoo
      - POSTGRES_USER=odoo
#一定要注意下面一行,官方文档漏掉了,如果没有这行会报错
      - POSTGRES_DB=postgres
      - PGDATA=/var/lib/postgresql/data/pgdata
    volumes:
      - ./odoo-db-data:/var/lib/postgresql/data/pgdata:z
#本配置用相对路径,如果要用top-level volumes,则下面相应内容取消注释
#volumes:
#  odoo-web-data:
#  odoo-db-data:

**注意用了这个配置文件后,还需要用解决方案里的办法。更改权限

02-12 19:50