【问题标题】:How to run Apache as non-root user?如何以非 root 用户身份运行容器?
【发布时间】:2020-12-19 20:02:42
【问题描述】:

我正在从以下 Dockerfile 和以下命令 docker build --rm -f "Dockerfile" -t non_root_image_plz_work . 构建映像:

DockerFile

FROM node:14.7.0-buster-slim AS apache_for_selenium

# Create non-root group and user
RUN addgroup --system shared-folder \
&& adduser --system --home /var/cache/shared-folder --group shared-folder --uid 1001

# Make Port accessable 
EXPOSE 80/tcp

# Set Node env.Name
ENV NODE_ENV=dev 

RUN apt-get -qq update && apt-get -qq install -y --no-install-recommends nano git openssl bash musl curl apache2 apache2-utils systemd && \
    systemctl enable apache2 && npm config set registry http://localhost:5000/repository/repo && \
    npm i -g pm2 serve && mkdir /usr/share/shared-folder

RUN ln -sf /dev/stdout /var/log/apache2/access.log && \
    ln -sf /dev/stderr /var/log/apache2/error.log    

WORKDIR /usr/share/shared-folder 

COPY . /usr/share/shared-folder/

RUN npm install && npm cache clean --force && npm cache verify && \
    rm /var/www/html/index.html && \
    ln -s /usr/share/shared-folder/mochawesome-report /var/www/html/mochawesome-report && \
    chown www-data -R /var/www/html/mochawesome-report && chgrp www-data -R /var/www/html/mochawesome-report 

VOLUME /usr/share/shared-folder/mochawesome-report

USER 1001

CMD [ "sh", "-c", "service apache2 start ; pm2-runtime process.yml --no-daemon" ]

当我尝试使用docker run non_root_image_plz_work 运行映像时,我收到以下错误:

运行docker run 命令后出错: 启动 Apache httpd Web 服务器:apache2 失败! apache2 配置测试失败。 ... (警告)。 配置测试的输出是: mkdir: 无法创建目录 '/var/run/apache2': 权限被拒绝 chown:更改“/var/lock/apache2.3FGoa8Y71E”的所有权:不允许操作

这似乎是一个权限问题,好像我没有以非 root 用户身份正确运行容器。关于如何让容器以非 root 用户身份正常运行的任何建议?

注意:我在 Dockerfile 中使用了一个虚拟注册表,因为我不想显示实际的注册表,谢谢

【问题讨论】:

    标签: apache docker dockerfile containers root


    【解决方案1】:

    这里的问题:apache 是特殊用户。它只能由 root 用户启动。 您不能由其他用户启动 apache。这就是为什么您获得许可拒绝的原因。 看到我看到了你的dockerfile。您创建的用户是普通用户。

    尝试使用名称 apache-start 制作如下脚本:

        #!/bin/sh
    set -e
    # Apache gets grumpy about PID files pre-existing
    rm -f /usr/local/apache2/logs/httpd.pid
    exec httpd -DFOREGROUND "$@"
    

    你的 docker 文件应该是这样的

    FROM node:14.7.0-buster-slim AS apache_for_selenium
    # Create non-root group and user
    RUN addgroup --system shared-folder \
    && adduser --system --home /var/cache/shared-folder --group shared-folder --uid 1001
    # Make Port accessable 
    EXPOSE 80/tcp
    # Set Node env.Name
    ENV NODE_ENV=dev 
    RUN apt-get -qq update && apt-get -qq install -y --no-install-recommends nano git openssl bash musl curl apache2 apache2-utils systemd && \
        systemctl enable apache2 && npm config set registry http://localhost:5000/repository/repo && \
        npm i -g pm2 serve && mkdir /usr/share/shared-folder
    RUN ln -sf /dev/stdout /var/log/apache2/access.log && \
        ln -sf /dev/stderr /var/log/apache2/error.log    
    WORKDIR /usr/share/shared-folder 
    COPY . /usr/share/shared-folder/
    RUN npm install && npm cache clean --force && npm cache verify && \
        rm /var/www/html/index.html && \
        ln -s /usr/share/shared-folder/mochawesome-report /var/www/html/mochawesome-report && \
        chown www-data -R /var/www/html/mochawesome-report && chgrp www-data -R /var/www/html/mochawesome-report 
    VOLUME /usr/share/shared-folder/mochawesome-report
    COPY apache-start /usr/local/bin/
    CMD ["apache-start"]
    USER 1001
    

    【讨论】:

      【解决方案2】:

      在 Docker 中,所有文件夹都归 root 所有。在不知道您的目录结构的情况下,我猜您的问题是,您的用户 1001(或以1001 的权限运行的安装程序)试图访问(可能)拥有的目录root.

      你可以试试:

      1. 更改文件夹的权限。

        这可以让您知道访问了哪些文件夹并希望防止进一步的权限问题。

        chmod -R 777 /path/to/folder
        
      2. 给你的用户适当的权限。

        这是一个非常快速的演练。如果它没有解决您的问题,请发表评论,我会尝试更新它以获得更具体的答案。

        一个小例子(取自here)。 您可以使用无密码访问设置您的非 root 用户 foo

        RUN \
            groupadd -g 1001 foo && useradd -u 1001 -g foo -G sudo -m -s /bin/bash 1001 
        && \
            sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
            sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
            sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && \
            echo "foo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers;  su - foo -c id
        

        提示:您可能需要安装sudo

        apt-get install sudo
        

        现在,尝试使用sudo 运行入口点(或您的逗号)。


      编辑: 我已经更新了答案以匹配您的 Docker 文件。看看它。用户 nonroot 被分配 uuid 1001 并添加到 /etc/sudoers。此外,您的命令现在使用 sudo 运行,这应该可以防止权限问题。

      FROM node:14.7.0-buster-slim AS apache_for_selenium
      
      # Create non-root group and user
      RUN addgroup --system shared-folder \
          && adduser --system --home /var/cache/shared-folder --ingroup shared-folder --uid 1001 nonroot
      
      # Make Port accessable 
      EXPOSE 80/tcp
      
      # Set Node env.Name
      ENV NODE_ENV=dev 
      
      RUN apt-get -qq update && apt-get -qq install -y --no-install-recommends \
          sudo nano git openssl bash musl curl apache2 apache2-utils systemd \
          && systemctl enable apache2 
          #\
          # && #npm config set registry http://localhost:5000/repository/repo && \
          #npm i -g pm2 serve && mkdir /usr/share/shared-folder
      
      RUN ln -sf /dev/stdout /var/log/apache2/access.log && \
          ln -sf /dev/stderr /var/log/apache2/error.log    
      
      WORKDIR /usr/share/shared-folder 
      
      COPY . /usr/share/shared-folder/
      
      RUN npm install && npm cache clean --force && npm cache verify && \
          rm /var/www/html/index.html && \
          ln -s /usr/share/shared-folder/mochawesome-report /var/www/html/mochawesome-report && \
          chown www-data -R /var/www/html/mochawesome-report && chgrp www-data -R /var/www/html/mochawesome-report 
      
      VOLUME /usr/share/shared-folder/mochawesome-report
      
      RUN \
          sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
          sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
          sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && \
          echo "nonroot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
      
      USER nonroot
      CMD [ "sudo sh", "-c", "service apache2 start ; pm2-runtime process.yml --no-daemon" ]
      

      【讨论】:

      • 当我尝试从上面建议的更改运行容器时出现此错误:错误:在 Function.Module._resolveFilename (internal /modules/cjs/loader.js:1085:15) 在 Function.Module._load (internal/modules/cjs/loader.js:928:27) 在 Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js :60:12) 在 internal/main/run_main_module.js:17:47 { code: 'MODULE_NOT_FOUND', requireStack: [] }
      • 你是否通过 apt-get 安装了 sudo?
      • 为什么不使用入口点脚本代替 docker 奇怪的拆分命令呢? -> ENTRYPINT [ '/entrypoint.sh' ]
      • 是的,我做了,我将它添加到第二个 RUN 命令的末尾。另外,是否有理由注释掉包含 # && #npm config set registry localhost:5000/repository/repo && \ #npm i -g pm2 serve && mkdir /usr/share/shared-folder 的行?我已将其设置为私人仓库,我只是将“本地主机”用作占位符
      • 我对@9​​87654335@不是很熟悉,但我认为这不是权限问题。我能想到的唯一可能性是尝试CMD [ "sudo", "sh", "-c", "service apache2 start ; pm2-runtime process.yml --no-daemon" ],但这只是一个猜测。您可以按照我的建议尝试在入口点脚本中运行整个命令吗?
      猜你喜欢
      • 2018-06-18
      • 2020-11-16
      • 2018-07-02
      • 2013-07-02
      • 2017-02-06
      • 2020-11-02
      • 2017-07-08
      • 2017-06-22
      • 1970-01-01
      相关资源
      最近更新 更多