簡體   English   中英

為什么 postgres 容器在 Gitlab CI 中忽略 /docker-entrypoint-initdb.d/*

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM