Docker 撰写权限被卷拒绝

dar*_*ool 6 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:
Run Code Online (Sandbox Code Playgroud)

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" ]
Run Code Online (Sandbox Code Playgroud)

如果我/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。我猜这与问题有关,但我不确定。

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

Pie*_* B. 12

/app/log_filesdeployers仍然由容器内的用户拥有,并且appuser无权写入它。根据您的评论,它似乎是经过许可/home/deployer/log_files拥有的。内部容器的权限与绑定安装相同。deployer:deployersdrwxr-xr-x/app/log_files

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

你可以:

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

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