[英]ignoring /docker-entrypoint-initdb.d error for Postgres database in a configuration that previously worked
[英]Why is postgres container ignoring /docker-entrypoint-initdb.d/* in Gitlab CI
Gitlab CI 在這個項目中一直忽略/docker-entrypoint-initdb.d/*
中的 sql 文件。
這是docker-compose.yml
:
version: '3.6'
services:
testdb:
image: postgres:11
container_name: lbsn-testdb
restart: always
ports:
- "65432:5432"
volumes:
- ./testdb/init:/docker-entrypoint-initdb.d
這是.gitlab-ci.yml
:
stages:
- deploy
deploy:
stage: deploy
image: debian:stable-slim
script:
- bash ./deploy.sh
部署腳本基本上使用 rsync 通過 SSH 將存儲庫的內容部署到服務器:
rsync -rav --chmod=Du+rwx,Dgo-rwx,u+rw,go-rw -e "ssh -l gitlab-ci" --exclude=".git" --delete ./ "gitlab-ci@$DEPLOY_SERVER:test/"
然后 ssh 進入服務器以停止並重新啟動容器:
ssh "gitlab-ci@$DEPLOY_SERVER" "cd test && docker-compose down && docker-compose up --build --detach"
這一切都很順利,但是當容器啟動時,它應該運行/docker-entrypoint-initdb.d/*
所有文件,正如我們在這里看到的那樣。
但是相反,當在服務器上執行docker logs -f lbsn-testdb
時,我可以看到它說明
/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
我不知道為什么會這樣。 在本地運行此容器時,甚至當我通過 ssh 連接到該服務器、克隆存儲庫並手動啟動容器時,一切順利並解析 sql 文件。 只是當 Gitlab CI 做到這一點時就不會了。
關於為什么會這樣的任何想法?
這比我預期的要容易,而且與 Gitlab CI 無關,但與文件權限無關。
我將--chmod=Du+rwx,Dgo-rwx,u+rw,go-rw
傳遞給rsync
,這看起來非常安全,因為只有用戶才能做事。 我承認我可能是從互聯網上的某個地方復制粘貼的。 但是這些文件被掛載到 Docker 容器中,並且在那里它們也具有這些權限:
-rw------- 1 1005 1004 314 May 8 15:48 100-create-database.sql
在主機上,我的 gitlab-ci 用戶擁有這些文件,它們顯然也歸容器中某個 ID 為 1005 的用戶所有,除此之外,其他用戶沒有任何權限。
在容器內,執行操作的用戶是postgres
,但它無法讀取這些文件。 它沒有抱怨,而是無視它們。 這可能會引起關於……的問題。
現在我通過了--chmod=D755,F644
它看起來像這樣:
-rw-r--r-- 1 1005 1004 314 May 8 15:48 100-create-database.sql
和碼頭日志說
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/100-create-database.sql
一開始就太容易想到了:-/
如果您之前已經運行過 postgres 服務,當您重新啟動它時,init 文件將被忽略,因此請嘗試使用--build
再次構建映像
docker-compose up --build -d
在你再次運行之前:
檢查現有的卷
docker volume ls
然后刪除您正在使用的 pg 服務
docker volume rm {volume_name}
-> 確保該卷未被容器使用,如果是,則也刪除該容器
我發現這個主題發現了使用 docker-compose 工具安裝 PostgreSQL 的類似問題。
解決方法基本相同。 對於提供的配置:
version: '3.6'
services:
testdb:
image: postgres:11
container_name: lbsn-testdb
restart: always
ports:
- "65432:5432"
volumes:
- ./testdb/init:/docker-entrypoint-initdb.d
您的部署腳本應該為您的 postgres 容器卷設置 0755 權限,例如chmod -R 0755 ./testdb
在這種情況下。 使所有子目錄可見很重要,因此需要chmod -R
選項。
官方 Postgres 圖像在 UID 70 的內部 postgres 用戶下運行。主機中的應用程序用戶很可能具有不同的 UID,如 1000 或類似的東西。 這就是 postgres init 腳本由於權限錯誤而錯過安裝步驟的原因。 這個問題出現好幾年了,但在最新的PostgreSQL版本(目前是12.1)中仍然存在
對系統中的所有 init 文件都可讀時,請注意安全漏洞。 最好使用 shell 環境變量將機密傳遞到 init 腳本中。
這是一個 docker-compose 示例:
postgres:
image: postgres:12.1-alpine
container_name: app-postgres
environment:
- POSTGRES_USER
- POSTGRES_PASSWORD
- APP_POSTGRES_DB
- APP_POSTGRES_SCHEMA
- APP_POSTGRES_USER
- APP_POSTGRES_PASSWORD
ports:
- '5432:5432'
volumes:
- $HOME/app/conf/postgres:/docker-entrypoint-initdb.d
- $HOME/data/postgres:/var/lib/postgresql/data
用於創建用戶的相應腳本create-users.sh
可能如下所示:
#!/bin/bash
set -o nounset
set -o errexit
set -o pipefail
POSTGRES_USER="${POSTGRES_USER:-postgres}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD}"
APP_POSTGRES_DB="${APP_POSTGRES_DB:-app}"
APP_POSTGRES_SCHEMA="${APP_POSTGRES_SCHEMA:-app}"
APP_POSTGRES_USER="${APP_POSTGRES_USER:-appuser}"
APP_POSTGRES_PASSWORD="${APP_POSTGRES_PASSWORD:-app}"
DATABASE="${APP_POSTGRES_DB}"
# Create single database.
psql --variable ON_ERROR_STOP=1 --username "${POSTGRES_USER}" --command "CREATE DATABASE ${DATABASE}"
# Create app user.
psql --variable ON_ERROR_STOP=1 --username "${POSTGRES_USER}" --command "CREATE USER ${APP_POSTGRES_USER} SUPERUSER PASSWORD '${APP_POSTGRES_PASSWORD}'"
psql --variable ON_ERROR_STOP=1 --username "${POSTGRES_USER}" --command "GRANT ALL PRIVILEGES ON DATABASE ${DATABASE} TO ${APP_POSTGRES_USER}"
psql --variable ON_ERROR_STOP=1 --username "${POSTGRES_USER}" --dbname "${DATABASE}" --command "CREATE SCHEMA ${APP_POSTGRES_SCHEMA} AUTHORIZATION ${APP_POSTGRES_USER}"
psql --variable ON_ERROR_STOP=1 --username "${POSTGRES_USER}" --command "ALTER USER ${APP_POSTGRES_USER} SET search_path = ${APP_POSTGRES_SCHEMA},public"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.