问题
我的docker-compose堆栈由'postgresql','redis'和'Python api服务器'以及其他一些像opentracing等组成,但是问题区域仅限于上述内容。
我的撰写文件中的入口点是一个Shell脚本,该脚本通过读取环境变量以及其他应做的事情来动态创建一些文件和文件夹。现在,这些文件的创建就像一个超级按钮一样,但是这些动态生成的文件的文件和文件夹权限变得很有趣。在macOS上,这些动态生成的文件和文件夹由运行docker-compose up
的非root用户拥有。但是,在运行Ubuntu 19.01的Linux计算机上,尽管Dockerfile明确对整个项目的文件夹执行了root
并将活动用户设置为chown non-root-user:non-root-group
postgres容器将自身安装到给定路径上,但是该目录的所有者不再是创建它的人,而是一些奇怪的systemd-coredump
,这是因为Postgres Dockerfile上的userID和group映射到了该用户名在我的linux服务器上?如果是,建议如何避免这种情况?
由于运行docker-compose up
的非root用户无法在主机上保留文件和文件夹权限,因此Im遇到permission denied
问题。尽管chmod 777
可以解决这个问题,但我相信chmod 777从未真正解决任何问题。
重申所有这些仅在Linux计算机上是一个问题。在运行Docker-For-Mac的Macos上,既存的和动态生成的文件/文件夹都将非root用户登录后的用户保留为其所有者,并在容器内,Dockerfile中的指定USER仍为所有先前存在的所有者(那些通过COPY
)和新生成的动态文件/文件夹进行传输。
示例
文件和文件夹所有权更改的示例:
drwxrwxr-x 13 sparkle_deployment_2 sparkle_deployment_2 4096 Nov 21 01:00 PROTON/
drwx------ 19 systemd-coredump docker 4096 Nov 21 01:00 proton_db/
应该从上方将proton_db
安装到Postgres。此文件夹最初是由用户-sparkle_deployment_2
创建的。 docker-compose up
之后,所有者和组分别更改为system-coredump
和docker
。
这是我的一部分:docker-compose.yaml
version: "3.4"
services:
pg:
container_name: proton_postgres
restart: always
image: postgres
environment:
- POSTGRES_USER=${PG_USERNAME}
- POSTGRES_PASSWORD=${PG_PASSWORD}
- POSTGRES_DB=${PG_TARGET_DB}
volumes:
- ${PROTON_POSTGRES_VOLUME_MOUNT}:/var/lib/postgresql/data
ports:
- ${PG_TARGET_PORT}:${PG_TARGET_PORT}
redis:
container_name: proton_redis
restart: always
image: redis
volumes:
- ${PROTON_REDIS_VOLUME_MOUNT}:/data
ports:
- ${REDIS_TARGET_PORT}:${REDIS_TARGET_PORT}
proton:
container_name: proton
restart: always
image: proton_stretch
ports:
- ${PROTON_TARGET_PORT}:${PROTON_TARGET_PORT}
expose:
- ${PROTON_TARGET_PORT}
volumes:
- .:/PROTON
- ${PROTON_SQLITE_VOLUME_MOUNT}:/PROTON/proton-db
depends_on:
- pg
- redis
entrypoint: ["./proton.sh"]
这是我的API服务器的Dockerfile:
FROM python:3.7.3-stretch
RUN apt-get update
RUN apt-get install bash
RUN apt-get install -y gcc g++ unixodbc-dev
RUN groupadd -g proton_user_group
RUN useradd -G proton_user_group default_proton_user
RUN mkdir -p /PROTON
WORKDIR /PROTON
COPY . /PROTON
RUN python3 -m pip install -r requirements.txt --no-cache-dir
RUN chown -R default_proton_user:proton_user_group /PROTON
USER default_proton_user
EXPOSE 3000/tcp
如您所见,我正在执行chown
,以明确地将目录归非root用户所有。尽管如此,当动态生成文件/文件夹时,它们会以root
作为所有者。而且,这只会在linux上发生。
赢
就像在MacOS中一样,我希望Linux机器上的非root主机保留所有先前存在的动态生成的文件/文件夹的所有权,因此不会导致任何“权限被拒绝”的问题。
在Linux机器上加上相同的非root主机,以保留对Postgres容器卷安装位置的所有权。
答案 0 :(得分:1)
由于要在docker-compose中绑定安装python容器,因此Dockerfile文件和现有权限无关。在运行时,它将pwd
挂载到/ PROTON,因此/ PROTON处映像中的所有内容都被隐藏,并且容器仅在主机上看到pwd
。
容器中的用户是与主机匹配的简单UID和GID号。例如,在主机上使用id
命令来获取您的UID和GID。对我来说,它们是1000和1000。您只需要确保容器中运行的用户和组具有相同的UID / GID。
RUN groupadd --gid 1000 proton \
&& useradd --uid 1000 --gid proton --create-home proton
现在主机用户和容器用户的UID / GID相同,您会注意到在pwd
中创建的文件与每个用户的用户名匹配。主机上的Linux将查找UID 1000并查看其主机用户(对我来说是bret
),如果您执行docker-compose exec proton ls -al /PROTON
,则应注意它将在容器中查找用户1000并查看{ {1}}。 用户名只是ID的友好名称,因此只需确保它们在主机用户和容器使用之间匹配,就可以了。
不相关的提示
proton
change the user that compose starts your container with,但是如果它是您与USER一起放入Dockerfile中的文件,那么在这种情况下就不需要了。user: username
或COPY --chown=1000:1000 . /PROTON