Docker 撰写权限被拒绝,卷

时间:2021-02-02 05:56:58

标签: docker docker-compose

我有以下 docker-compose 文件:

version: "3.8"

services:
  api:
    image: myuser/myimage
    volumes:
      - static_volume:/app/static
      - /home/deployer/config_files/gunicorn.py:/app/gunicorn.py
      - /home/deployer/log_files:/app/log_files
    env_file:
      - /home/deployer/config_files/api.env
    expose:
      - 8000

  nginx:
    image: myuser/nginximage
    volumes:
      - static_volume:/app/static
      - /home/deployer/config_files/nginx.conf:/etc/nginx/conf.d/nginx.conf
    ports:
      - 80:80
    depends_on:
      - api

volumes:
  static_volume:

api 服务是使用以下 docker 文件构建的(已汇总以减小大小):

FROM python:3.9.1

WORKDIR /app

# Copy code etc into container
COPY ./api/ .
COPY entrypoint.sh .

# create static and log files directories
RUN mkdir static
RUN mkdir log_files

# create non root user, change ownership of all files, switch to this user
RUN adduser --system --group appuser
RUN chown -R appuser:appuser /app
USER appuser

CMD [ "/app/entrypoint.sh" ]

如果我从撰写文件中删除 /home/deployer/log_files:/app/log_files,一切正常。但是,我正在尝试将该日志文件目录用于 gunicorn 以用于日志文件。在 docker-compose up:

时包含该行会导致以下错误

Error: Error: '/app/log_files/gunicorn_error.log' isn't writable [PermissionError(13, 'Permission denied')]

在 linux 主机上,我使用名为 docker-compose up 的用户运行 deployer。根据 Dockerfile 在容器内,我创建了一个名为 appuser 的用户。我猜这与问题有关,但我不确定。

基本上我想要做的就是让容器内的日志文件可以在容器外访问,这样即使服务器重新启动它们也能持续存在。

1 个答案:

答案 0 :(得分:3)

/app/log_files 仍然归您容器内的 deployers 用户所有,appuser 没有写入权限。根据您的评论,/home/deployer/log_files 似乎归 deployer:deployers 所有,并拥有 drwxr-xr-x 权限。容器内 /app/log_files 的权限与绑定安装相同。

即使您的容器中不存在 deployers 用户,它仍由 deployers 用户的 UID 拥有(您可以通过从容器内部运行 ls 来检查这一点)。

您可以:

  • /home/deployer/log_files 添加全局可写权限,例如
    chmod 777 /home/deployer/log_files
    
    不过,这可能会带来安全风险,但其他解决方案稍微复杂一些,但效果更好。
  • 检索或设置 appuser 的 UID 并将 /home/deployer/log_files 的所有权设置为此用户。例如在 Dockerfile 中使用特定的 UID appuser 创建 1500
    RUN adduser -u 1500 --system --group appuser
    
    并从您的主机更改目录所有者到此 UID
    sudo chown 1500:1500 /home/deployer/log_files
    
    在容器运行时,appuser (UID 1500) 将能够写入此目录

更一般地说,您应该确保 /home/deployer/log_files 可由在容器内运行的用户写入,同时在需要时确保其访问安全。