apache 如何运行httpd:2.4-alpine docker映像而不是作为root用户

sqougxex  于 2022-11-16  发布在  Apache
关注(0)|答案(2)|浏览(255)

我尝试不以root用户身份运行httpd:2.4-alpinedocker image
预设行为:

> docker run -p 80:80 -d --rm --name httpd httpd:2.4-alpine
3c271ae8abfc3f54c0e63d62a2ce26fcbeeef29064da66f4b3f6bd00480ad4fb
> docker exec httpd --name httpd whoami
root

在查看该图像的Dockerfile定义后,可以看到创建了一个id为82www-data

...
RUN set -x \
    && adduser -u 82 -D -S -G www-data www-data
# 82 is the standard uid/gid for "www-data" in Alpine
...

让我们尝试使用此用户运行此映像,然后:

> docker stop httpd # cleaning previous instance
> docker run -p 80:80 --rm --name httpd -u www-data httpd:2.4-alpine

此操作失败,出现以下错误:
AH00558:httpd:无法使用172.17.0.3可靠地确定服务器的完全限定域名。全局设置“ServerName”指令以禁止显示以下消息AH 00558:httpd:无法使用172.17.0.3可靠地确定服务器的完全限定域名。请全局设置“ServerName”指令以禁止显示此消息[Tue Aug 30 15:57:25.958695 2022] [core:error] [pid 1:tid 140459379268424](13)权限被拒绝:AH 00099:无法创建/usr/local/apache 2/logs/httpd.pid。XXXXXX [2022年8月30日星期二15:57:25.959029] [核心:错误] [pid 1:tid 140459379268424] AH 00100:httpd:无法将pid记录到文件/usr/local/apache 2/logs/httpd.pid
我发现this answer似乎可以解决这个问题,但是因为我在一个Docker环境中,我不知道如何/是否可以应用这个解决方案。
有人知道我如何不以根目录运行此映像吗?

mrwjdhj3

mrwjdhj31#

虽然@javierlga的答案是正确的,但您不需要构建新映像来解决这个问题。我们需要做三件事:
1.以www-data用户身份运行Apache
1.授予www-data用户绑定到特权端口的能力,以及
1.处理需要将pid文件写入/usr/local/apache2/logs
我们可以使用-u的参数docker run来完成(1):

docker run -u www-data ...

我们可以使用--cap-add参数来求解(2):

docker run -u www-data --cap-add net_bind_service ...

我们可以在您在问题中发布的日志中看到问题:

Permission denied: AH00099: could not create /usr/local/apache2/logs/httpd.pid.XXXXXX

Apache正在尝试将文件写入/usr/local/apache2/logs,但www-data用户没有在此目录中创建文件的权限。
解决这个问题的方法有很多,最简单的方法是将pid文件移到/tmp,我们可以使用-C命令行选项将必要的配置指令传递给httpd

docker run ... docker.io/httpd:2.4.54-alpine \
  httpd-foreground -C 'PidFile /tmp/httpd.pid'

综合起来,我们得到:

docker run -u www-data \
  --cap-add net_bind_service -p 8080:80 \
  docker.io/httpd:2.4.54-alpine \
  httpd-foreground -C 'PidFile /tmp/httpd.pid'

或者在docker-compose.yaml文件中:

version: "3"

services:
  httpd:
    image: docker.io/httpd:2.4.54-alpine
    command: [httpd-foreground, -C, "PidFile /tmp/httpd.pid"]
    user: www-data
    ports:
      - "8080:80"
    cap_add:
      - net_bind_service

它运行无误,不需要维护我们自己的形象。

mccptt67

mccptt672#

这是因为默认情况下,用户www-data没有绑定特权端口的能力,事实上,任何其他常规端口都将遇到同样的问题。
如您所见,只有父进程以root用户身份运行,子进程以www-data用户身份运行。

/usr/local/apache2 # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 httpd -DFOREGROUND
    8 www-data  0:00 httpd -DFOREGROUND
    9 www-data  0:00 httpd -DFOREGROUND
   10 www-data  0:00 httpd -DFOREGROUND
   92 root      0:00 sh
   98 root      0:00 ps aux

通过将setcap 'cap_net_bind_service=+ep'设置为httpd二进制文件,您将能够以www-data用户身份运行它。
为了解决这个问题,你需要创建一个新的映像,这是一个Dockerfile示例:

FROM httpd:2.4-alpine

RUN apk add libcap && chown -hR www-data:www-data /usr/local/apache2/ && \
  setcap 'cap_net_bind_service=+ep' /usr/local/apache2/bin/httpd

USER www-data

创建新映像后,您将能够以非根用户身份运行该映像。
记录档:

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Tue Aug 30 16:51:43.660323 2022] [mpm_event:notice] [pid 1:tid 281473523657800] AH00489: Apache/2.4.54 (Unix) configured -- resuming normal operations
[Tue Aug 30 16:51:43.660358 2022] [core:notice] [pid 1:tid 281473523657800] AH00094: Command line: 'httpd -D FOREGROUND'

执行身份:

/usr/local/apache2 $ whoami
www-data

相关问题