Docker - 无法通过脚本删除容器内的文件
Posted
技术标签:
【中文标题】Docker - 无法通过脚本删除容器内的文件【英文标题】:Docker - Cannot delete files inside container via script 【发布时间】:2021-10-10 11:04:19 【问题描述】:在这个 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
我怎样才能防止这个错误?
【问题讨论】:
你确定你的入口点设置正确并且脚本正在执行吗? @Elia 是的,脚本正在执行。它正在创建数据库用户和表,它们都在那里。我在示例代码中省略了它。 我假设通过 dockerfile 复制文件是由 root 用户执行的,但 init.sh 是由 postgress 用户运行的,这就是你没有权限删除它的原因 【参考方案1】:如果你检查它的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 组中,您将无法删除文件,尽管您仍然拥有w
的/tmp
权限.这就是即使您将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
,将其权限更改为777
,然后将data.txt
复制到/tmp2
。
【讨论】:
以上是关于Docker - 无法通过脚本删除容器内的文件的主要内容,如果未能解决你的问题,请参考以下文章
docker容器内的mysql说“无法通过套接字'/var/run/mysqld/mysqld.sock'连接到本地MySQL服务器”