Docker - 无法通过脚本删除容器内的文件
Docker - Cannot delete files inside container via script
在这个 Postgres Docker 图像上,我正在复制几个文件来配置容器。
(1) init.sh - 复制到 Docker 入口点
(2) data.txt - 包含敏感信息
在 init.sh 的末尾,我想删除 data.txt,但文件永远不会被删除。
docker-compose.yml
version: '3.6'
services:
postgres_test:
container_name: postgres_13_3
image: postgres_13_3
restart: unless-stopped
build:
context: ./postgres
dockerfile: postgres_13_test.dk
environment:
POSTGRES_PASSWORD: 'test'
postgres_13_test.dk
FROM postgres:13.3-alpine3.14
# copy files over
COPY ./data.txt /tmp/data.txt
RUN chmod 777 /tmp/data.txt
COPY ./init.sh /docker-entrypoint-initdb.d/init.sh
init.sh
# ... do other things first
# then in the end, delete file
rm -rf /tmp/data.txt # <-- file never gets deleted
我错过了什么?
更新
现在用 --no-cache 重建容器 fesh,现在它显示此错误消息
postgres_13_3 | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sh
postgres_13_3 | rm: can't remove '/tmp/data.txt': Operation not permitted
我怎样才能避免这个错误?
如果你检查它的docker-entrypoint.sh,你会发现脚本/docker-entrypoint-initdb.d/*
只在第一次设置数据库时执行一次,这就是为什么你后来看到你的init.sh
未执行。
设置新容器后,脚本有机会执行,但您会看到权限问题,这是因为 init.sh
将以 postgres
用户执行,不是 root
用户,参见 this:
if [ "$(id -u)" = '0' ]; then
# then restart script as postgres user
exec su-exec postgres "$BASH_SOURCE" "$@"
fi
另外,如果查看/tmp
的权限,可以看到它的权限是:
ls -alh /tmp
total 8K
drwxrwxrwt 1 root root 4.0K Aug 7 15:16 .
drwxr-xr-x 1 root root 4.0K Aug 7 15:25 ..
-rwxrwxrwx 1 root root 0 Aug 7 15:01 data.txt
在这里,t
是 sticky bit
这意味着如果用户 postgres
和 root
不在同一个 linux 组中,您将无法删除文件,尽管您仍然拥有 /tmp
的 w
权限。这就是您无法删除 data.txt
的原因,即使您将 777
的权限更改为 data.txt
。
因此,对您而言,解决方案是将 data.txt
的所有权更改为 postgres
具有 chown
的内容,如下所示:
Dockerfile:
FROM postgres:13.3-alpine3.14
COPY ./data.txt /tmp/data.txt
RUN chmod 777 /tmp/data.txt
RUN chown postgres:postgres /tmp/data.txt
COPY ./init.sh /docker-entrypoint-initdb.d/init.sh
或,不要将data.txt
复制到/tmp
,只需设置一个新文件夹,如/tmp2
,将其权限更改为[=26] =],然后将 data.txt
复制到 /tmp2
。
在这个 Postgres Docker 图像上,我正在复制几个文件来配置容器。
(1) init.sh - 复制到 Docker 入口点 (2) data.txt - 包含敏感信息
在 init.sh 的末尾,我想删除 data.txt,但文件永远不会被删除。
docker-compose.yml
version: '3.6'
services:
postgres_test:
container_name: postgres_13_3
image: postgres_13_3
restart: unless-stopped
build:
context: ./postgres
dockerfile: postgres_13_test.dk
environment:
POSTGRES_PASSWORD: 'test'
postgres_13_test.dk
FROM postgres:13.3-alpine3.14
# copy files over
COPY ./data.txt /tmp/data.txt
RUN chmod 777 /tmp/data.txt
COPY ./init.sh /docker-entrypoint-initdb.d/init.sh
init.sh
# ... do other things first
# then in the end, delete file
rm -rf /tmp/data.txt # <-- file never gets deleted
我错过了什么?
更新
现在用 --no-cache 重建容器 fesh,现在它显示此错误消息
postgres_13_3 | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sh
postgres_13_3 | rm: can't remove '/tmp/data.txt': Operation not permitted
我怎样才能避免这个错误?
如果你检查它的docker-entrypoint.sh,你会发现脚本
/docker-entrypoint-initdb.d/*
只在第一次设置数据库时执行一次,这就是为什么你后来看到你的init.sh
未执行。设置新容器后,脚本有机会执行,但您会看到权限问题,这是因为
init.sh
将以postgres
用户执行,不是root
用户,参见 this:if [ "$(id -u)" = '0' ]; then # then restart script as postgres user exec su-exec postgres "$BASH_SOURCE" "$@" fi
另外,如果查看
/tmp
的权限,可以看到它的权限是:ls -alh /tmp total 8K drwxrwxrwt 1 root root 4.0K Aug 7 15:16 . drwxr-xr-x 1 root root 4.0K Aug 7 15:25 .. -rwxrwxrwx 1 root root 0 Aug 7 15:01 data.txt
在这里,
t
是sticky bit
这意味着如果用户postgres
和root
不在同一个 linux 组中,您将无法删除文件,尽管您仍然拥有/tmp
的w
权限。这就是您无法删除data.txt
的原因,即使您将777
的权限更改为data.txt
。
因此,对您而言,解决方案是将 data.txt
的所有权更改为 postgres
具有 chown
的内容,如下所示:
Dockerfile:
FROM postgres:13.3-alpine3.14
COPY ./data.txt /tmp/data.txt
RUN chmod 777 /tmp/data.txt
RUN chown postgres:postgres /tmp/data.txt
COPY ./init.sh /docker-entrypoint-initdb.d/init.sh
或,不要将data.txt
复制到/tmp
,只需设置一个新文件夹,如/tmp2
,将其权限更改为[=26] =],然后将 data.txt
复制到 /tmp2
。