Docker中安装Odoo并使三方模块代码分离

为什么要代码分离

如果代码包含在Docker镜像中,那么随着代码的迭代,镜像会越来越大,每次更新代码都需要重新构建容器,并且每隔一段时间就要更新基础镜像。

如何做

我们的第三方模块代码是放在/extra/addons目录中的,在启动容器的时候,挂在代码目录到Docker中,即可使odoo自动加载第三方模块。

遇到的问题

问题是第三方模块中经常会有额外应用的python库,这些库肯定是在创建镜像的时候无法预知的,因此也不可能在构建镜像中把所有的第三方依赖库装全。那么我们就需要有一种方法,在容器启动的时候自动安装我们添加的新依赖,从而避免因缺少依赖导致的容器启动失败。

我们可以在/extra/addons目录下放一个requirements.txt文件,将我们自己代码中使用的第三方库列出,然后在镜像的entrypoint.sh中写入如下代码:

1
pip install -r /extra/addons/requirements.txt

这样,容器在启动的时候就会自动使用pip安装依赖。对于一些使用了复杂的语句,甚至依赖c++的模块,可能会碰到系统层面的问题,这个时候更新镜像是避免不了了。

需要注意的是,requirments.txt 这行代码要加在odoo服务代码之前,否则不会运行:

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
set -e
pip install -r /mnt/extra-addons/requirements.txt
# set the postgres database host, port, user and password according to the environment
# and pass them as arguments to the odoo process if not present in the config file
: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}}
: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}}
: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}}
: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}}
DB_ARGS=()
function check_config() {
param="$1"
value="$2"
if ! grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then
DB_ARGS+=("--${param}")
DB_ARGS+=("${value}")
fi;
}
check_config "db_host" "$HOST"
check_config "db_port" "$PORT"
check_config "db_user" "$USER"
check_config "db_password" "$PASSWORD"
case "$1" in
-- | odoo)
shift
if [[ "$1" == "scaffold" ]] ; then
exec odoo "$@"
else
exec odoo "$@" "${DB_ARGS[@]}"
fi
;;
-*)
exec odoo "$@" "${DB_ARGS[@]}"
;;
*)
exec "$@"
esac
exit 1