首页 > 解决方案 > 拥有非 root 用户时的文件所有者

问题描述

我正在使用 a 设置一个 Django 项目,Dockerfile并且我想知道在拥有非 root 用户时正确的所有权。

我的Dockerfile样子是这样的:

FROM python:3.7-slim

ENV DIR=/data
ENV USER=files

RUN groupadd --gid 1000 -r ${USER} \
  && useradd --uid 1000 --no-log-init -r -g ${USER} ${USER}

WORKDIR ${DIR}
COPY poetry.lock pyproject.toml ${DIR}/

RUN poetry install --no-interaction --no-ansi --no-root

ADD . ${DIR}

RUN chown -R ${USER}:${USER} ${DIR}
USER ${USER}

有两件事我不确定是否需要它们,但我在几篇文章中看到了它们。有人可以详细说明为什么/如果我想要它们。

  1. --gid 1000--uid 1000
  2. RUN chown -R ${USER}:${USER} ${DIR}

标签: dockerdockerfile

解决方案


你也不需要。在这个 Dockerfile 中还有许多其他的东西可以清理。

chown一个:您可能希望您的应用程序源代码由 root 拥有,并且是世界可读但不是世界可写的(通常模式 0644 或 0755)。这可以防止潜在的安全问题,即代码中的错误会意外覆盖应用程序的部分源代码或静态资产。

这里的悬而未决的问题是您是否需要在容器中保留持久数据。如果可以的话,尽量避免这种情况,将数据存储在外部数据库之类的地方;这将帮助您更新映像,并且在您需要运行容器的多个副本时会有所帮助。如果您需要,请将数据保存在与您的主应用程序目录分开的地方,并将chown该单个目录保存给非 root 用户。

非 root 用户可以有任何用户和组 ID。它并不特别需要匹配任何给定的主机用户,并且确实尝试使其匹配并不是最佳实践(我在 Mac 上,所以我的 uid 是 501;我需要重建 Docker 映像吗?)。

如果我要更新它,我也会避免这两个ENV变量;这些目录和用户名可能会在镜像中固定,您不需要经常引用它们,并且在运行时更改它们不会有效果。

这会将 Dockerfile 更改为:

FROM python:3.7-slim

# with a fixed username; without a fixed uid
RUN useradd --no-log-init -r files

# with a fixed path; then use . everywhere afterwards
WORKDIR /data

COPY poetry.lock pyproject.toml ./
RUN poetry install --no-interaction --no-ansi --no-root
# prefer COPY to ADD
COPY . ./
# no need to RUN chown; leave the files owned by root

# if you need a local data directory only
# RUN mkdir data && chown files data

# specify the runtime user and default CMD
USER files
CMD ["./main.py"]

如果您有一个可写的数据目录,并且您需要它是一个绑定挂载的主机目录,并且该目录归某个用户所有,那么您可以在运行容器时指定用户 ID。

docker run -u $(id -u):$(id -g) -v $PWD/data:/data/data myapp

推荐阅读