今天來個簡單的章節,而且之後還會修改到 entrypoint.sh
,也趁機更熟悉它。
問題是這樣的,還記得我們在 config 資料夾:odoo 部署中的敏感檔案管理 中,將環境變數從 docker-compose.yml
移到了 prod
和 dev
各自的 .env
中。但是,由於 PostgreSQL 的環境變數名稱與 odoo 所使用的環境變數名稱不同,導致我必須為資料庫使用者和密碼設定兩次,檔案變成如下所示:
- POSTGRES_DB=postgres # 設定資料庫名稱為 postgres
- POSTGRES_USER=odoo_user # 設定 PostgreSQL 使用者
- POSTGRES_PASSWORD=JXPF9aDZeZWlrDpf # 設定資料庫密碼
- HOST=postgresql # 設定 odoo 連接的資料庫主機名稱
- USER=odoo_user # 設定 odoo 連接資料庫的使用者名稱
- PASSWORD=JXPF9aDZeZWlrDpf # 設定 odoo 連接資料庫的密碼
雖然是小問題,但我總覺得有點齷齪(ak-tsak),可能會讓不熟悉的人疑惑為什麼要設定兩次;而且 odoo 映像檔的環境變數名稱只寫 HOST
、USER
、PASSWORD
,也讓人有些摸不著頭緒。
我們再重新仔細看看這段 entrypoint.sh
:
# 設定 PostgreSQL 資料庫的主機、埠口、用戶和密碼,從環境變數中讀取
: ${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
value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" | cut -d " " -f3 | sed 's/["\n\r]//g')
fi
DB_ARGS+=("--${param}") # 將參數名稱加入連線參數陣列
DB_ARGS+=("${value}") # 將參數值加入連線參數陣列
}
# 接著,將四個參數名稱和值分別傳入函式中:
check_config "db_host" "$HOST"
check_config "db_port" "$PORT"
check_config "db_user" "$USER"
check_config "db_password" "$PASSWORD"
現在我們以 password
為例,讓我們詳細解釋一下它是如何取得值的:
環境變數讀取與覆蓋:
: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}}
PASSWORD
是否已經設定,若有,則使用其值。DB_ENV_POSTGRES_PASSWORD
是否存在,若有,則使用其值。POSTGRES_PASSWORD
,若有,則使用其值。'odoo'
。最終從 odoo.conf 讀取與覆蓋並將參數添加到 DB_ARGS
中:
check_config
中,param
為 "db_password"
,value
為上面取得的 PASSWORD
值。$ODOO_RC
中是否已有 db_password
,若有,則以設定檔的值覆蓋 value
。"--db_password"
和對應的 value
加入 DB_ARGS
陣列。因此,最終 DB_ARGS
中會新增 --db_password
和對應的密碼值。
為了簡化設定,我們可以將讀取的環境變數名稱改為與 PostgreSQL 的環境變數名稱相同,變成:
: ${DB_HOST:=${POSTGRES_HOST:='db'}} # 設定 DB_HOST,預設為 'db'
: ${DB_PORT:=${POSTGRES_PORT:=5432}}
: ${DB_USER:=${POSTGRES_USER:='odoo'}}
: ${DB_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}
: ${DB_NAME:=${POSTGRES_DB:='odoo'}}
DB_ARGS=()
# 如果設定檔中有相應的參數,則使用設定檔中的值,否則使用環境變數的值
function check_config() {
param="$1"
value="$2"
if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then
value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" | cut -d " " -f3 | sed 's/["\n\r]//g')
fi
DB_ARGS+=("--${param}")
DB_ARGS+=("${value}")
}
check_config "db_host" "$DB_HOST"
check_config "db_port" "$DB_PORT"
check_config "db_user" "$DB_USER"
check_config "db_password" "$DB_PASSWORD"
check_config "database" "$DB_NAME"
順便把 database
也加進去,這樣在開發模組時,執行 -u
時就不必再手動加上 -d
了。(除非佈署計畫是在同一個 odoo 實例上使用多個資料庫,那麼這部分可能需要注意修改)
最後,我們來看看修改後的 .env
檔案:
POSTGRES_HOST=postgresql # 設定資料庫主機名稱
POSTGRES_PORT=5432 # 設定資料庫埠號
POSTGRES_DB=odoo # 設定資料庫名稱
POSTGRES_USER=odoo_user # 設定資料庫使用者名稱
POSTGRES_PASSWORD=JXPF9aDZeZWlrDpf # 設定資料庫密碼
如此修改後,我們就可以在 .env
中只放一次資料庫連線資訊,名稱變得更加直觀,而且不用擔心 odoo 和 PostgreSQL 兩邊對不上了。