[英]Why is postgres container ignoring /docker-entrypoint-initdb.d/* in Gitlab CI
Gitlab CI keeps ignoring the sql-files in /docker-entrypoint-initdb.d/*
in this project . Gitlab CI 在这个项目中一直忽略
/docker-entrypoint-initdb.d/*
中的 sql 文件。
here is docker-compose.yml
:这是
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
here is .gitlab-ci.yml
:这是
.gitlab-ci.yml
:
stages:
- deploy
deploy:
stage: deploy
image: debian:stable-slim
script:
- bash ./deploy.sh
The deployment script basically uses rsync to deploy the content of the repository to to the server via SSH:部署脚本基本上使用 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/"
and then ssh's into the server to stop and restart the container:然后 ssh 进入服务器以停止并重新启动容器:
ssh "gitlab-ci@$DEPLOY_SERVER" "cd test && docker-compose down && docker-compose up --build --detach"
This all goes well , but when the container starts up, it is supposed to run all the files that are in /docker-entrypoint-initdb.d/*
as we can see here .这一切都很顺利,但是当容器启动时,它应该运行
/docker-entrypoint-initdb.d/*
所有文件,正如我们在这里看到的那样。
But instead, when doing docker logs -f lbsn-testdb
on the server, I can see it stating但是相反,当在服务器上执行
docker logs -f lbsn-testdb
时,我可以看到它说明
/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
and I have no clue, why that happens.我不知道为什么会这样。 When running this container locally or even when I ssh to that server, clone the repo and bring up the containers manually, it all goes well and parses the sql-files.
在本地运行此容器时,甚至当我通过 ssh 连接到该服务器、克隆存储库并手动启动容器时,一切顺利并解析 sql 文件。 Just not when the Gitlab CI does it.
只是当 Gitlab CI 做到这一点时就不会了。
Any ideas on why that is?关于为什么会这样的任何想法?
This has been easier than I expected, and fatally nothing to do with Gitlab CI but with file permissions.这比我预期的要容易,而且与 Gitlab CI 无关,但与文件权限无关。
I passed --chmod=Du+rwx,Dgo-rwx,u+rw,go-rw
to rsync
which looked really secure because only the user can do stuff.我将
--chmod=Du+rwx,Dgo-rwx,u+rw,go-rw
传递给rsync
,这看起来非常安全,因为只有用户才能做事。 I confess that I propably copypasted it from somewhere on the internet.我承认我可能是从互联网上的某个地方复制粘贴的。 But then the files are mounted to the Docker container, and in there they have those permissions as well:
但是这些文件被挂载到 Docker 容器中,并且在那里它们也具有这些权限:
-rw------- 1 1005 1004 314 May 8 15:48 100-create-database.sql
On the host my gitlab-ci user owns those files, they are obviously also owned by some user with ID 1005 in the container as well, and no permissions are given to other users than this one.在主机上,我的 gitlab-ci 用户拥有这些文件,它们显然也归容器中某个 ID 为 1005 的用户所有,除此之外,其他用户没有任何权限。
Inside the container the user who does things is postgres
though, but it can't read those files.在容器内,执行操作的用户是
postgres
,但它无法读取这些文件。 Instead of complaining about that, it just ignores them.它没有抱怨,而是无视它们。 That might be something to create an issue about…
这可能会引起关于……的问题。
Now that I pass --chmod=D755,F644
it looks like that: 现在我通过了
--chmod=D755,F644
它看起来像这样:
-rw-r--r-- 1 1005 1004 314 May 8 15:48 100-create-database.sql
and the docker logs say和码头日志说
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/100-create-database.sql
Too easy to think of in the first place :-/一开始就太容易想到了:-/
If you already run the postgres service before, the init files will be ignored when you restart it so try to use --build
to build the image again如果您之前已经运行过 postgres 服务,当您重新启动它时,init 文件将被忽略,因此请尝试使用
--build
再次构建映像
docker-compose up --build -d
and before you run again :在你再次运行之前:
Check the existing volumes with检查现有的卷
docker volume ls
Then remove the one that you are using for you pg service with然后删除您正在使用的 pg 服务
docker volume rm {volume_name}
-> Make sure that the volume is not used by a container, if so then remove the container as well -> 确保该卷未被容器使用,如果是,则也删除该容器
I found this topic discovering a similar problem with PostgreSQL installation using the docker-compose tool.我发现这个主题发现了使用 docker-compose 工具安装 PostgreSQL 的类似问题。
The solution is basically the same.解决方法基本相同。 For the provided configuration:
对于提供的配置:
version: '3.6'
services:
testdb:
image: postgres:11
container_name: lbsn-testdb
restart: always
ports:
- "65432:5432"
volumes:
- ./testdb/init:/docker-entrypoint-initdb.d
Your deployment script should set 0755 permissions to your postgres container volume, like chmod -R 0755 ./testdb
in this case.您的部署脚本应该为您的 postgres 容器卷设置 0755 权限,例如
chmod -R 0755 ./testdb
在这种情况下。 It is important to make all subdirectories visible, so chmod -R
option is required.使所有子目录可见很重要,因此需要
chmod -R
选项。
Official Postgres image is running under internal postgres user with the UID 70. Your application user in the host is most likely has different UID like 1000 or something similar.官方 Postgres 图像在 UID 70 的内部 postgres 用户下运行。主机中的应用程序用户很可能具有不同的 UID,如 1000 或类似的东西。 That is the reason for postgres init script to miss installation steps due to permissions error.
这就是 postgres init 脚本由于权限错误而错过安装步骤的原因。 This issue appears several years, but still exist in the latest PostgreSQL version (currently is 12.1)
这个问题出现好几年了,但在最新的PostgreSQL版本(目前是12.1)中仍然存在
Please be aware of security vulnerability when having readable for all init files in the system.对系统中的所有 init 文件都可读时,请注意安全漏洞。 It is good to use shell environment variables to pass secrets into the init scrip.
最好使用 shell 环境变量将机密传递到 init 脚本中。
Here is a docker-compose example:这是一个 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
Corresponding script create-users.sh
for creating users may looks like:用于创建用户的相应脚本
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.