docker中的httpd无法启动

时间:2016-11-04 15:26:35

标签: apache docker config volume

我正在尝试在docker中安装HTTPD,我写了一个像这样的dockerfile:

FROM centos

VOLUME /var/log/httpd
VOLUME /etc/httpd
VOLUME /var/www/html

# Update Yum Repostory
RUN yum clean all && \
    yum makecache fast && \
    yum -y update && \
    yum -y install httpd
RUN yum clean all
EXPOSE 80
CMD /usr/sbin/httpd -D BACKGROUND && tail -f /var/log/httpd/access_log

如果我在没有主机卷的情况下运行图像,它会起作用,但如果我使用参数:

则会失败
--volume /data/httpd/var/www/html:/var/www/html --volume /data/httpd/var/log:/var/log --volume /data/httpd/etc:/etc/httpd

错误信息是:

httpd: Could not open configuration file /etc/httpd/conf/httpd.conf: No such file or directory

我检查了空的挂载点:

# ll /data/httpd/etc/
total 0

但是如果我没有默认使用“音量”停靠者复制文件到临时文件夹:

# ll /var/lib/docker/volumes/04f083887e503c6138a65b300a1b40602d227bb2bbb58c69b700f6ac753d1c34/_data
total 4
drwxr-xr-x. 2 root root   35 Nov  3 03:16 conf
drwxr-xr-x. 2 root root   78 Nov  3 03:16 conf.d
drwxr-xr-x. 2 root root 4096 Nov  3 03:16 conf.modules.d
lrwxrwxrwx. 1 root root   19 Nov  3 03:16 logs -> ../../var/log/httpd
lrwxrwxrwx. 1 root root   29 Nov  3 03:16 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx. 1 root root   10 Nov  3 03:16 run -> /run/httpd

所以我很困惑,为什么码头工人拒绝将它们复制到指定位置?以及如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

这确实是一种记录在案的行为:

  

创建容器时初始化卷。如果容器的   基本映像包含指定安装点的数据,即现有数据   在卷初始化时将其复制到新卷中。 (注意这个   安装主机目录时不适用。)

即。当您挂载 / etc / httpd - volume / data / httpd / etc:/ etc / httpd 时,不会复制任何数据。

您还可以看到https://github.com/docker/docker/pull/9092更详细地讨论它为什么会这样运作(如果您感兴趣的话)。

通常的解决方法是将初始数据复制到ENTRYPOINT或CMD脚本中的卷文件夹(来自容器内), 万一它是空的。

请注意,您的初始数据集必须保留在卷文件夹之外(例如,作为/ opt中的.tar文件),以使其正常工作,因为卷文件夹将被安装在其上的主机文件夹遮蔽。

下面给出了一个示例Dockerfile和Script,它演示了行为:

示例Dockerfile

FROM debian:stable
RUN mkdir -p /opt/test/; touch /opt/test/initial-data-file
VOLUME /opt/test

示例脚本(尝试各种卷映射)

#Build image
>docker build -t volumetest .

Sending build context to Docker daemon  2.56 kB
Step 0 : FROM debian:stable
---> f7504c16316c
Step 1 : RUN mkdir -p /opt/test/; touch /opt/test/initial-data-file
---> Using cache
---> 1ea0475e1a18    
Step 2 : VOLUME /opt/test
---> Using cache
---> d8d32d849b82
Successfully built d8d32d849b82

#Implicit Volume mapping (as defined in Dockerfile)
>docker run --rm=true volumetest ls -l /opt/test
total 0
-rw-r--r-- 1 root root 0 Nov  4 18:26 initial-data-file

#Explicit Volume mapping
> docker run --rm=true --volume /opt/test volumetest ls -l /opt/test/
total 0
-rw-r--r-- 1 root root 0 Nov  4 18:26 initial-data-file

#Explicitly Mounted Volume
>mkdir test
>docker run --rm=true --volume "$(pwd)/test/:/opt/test" volumetest ls -l /opt/test
total 0

这是一个简单的入口点脚本,说明了可能的解决方法:

#!/bin/bash
VOLUME=/opt/test
DATA=/opt/data-volume.tar.gz

if [[ -n $(find "$VOLUME" -maxdepth 0 -empty) ]]
then
    echo Preseeding VOLUME $VOLUME with data from $DATA...
    tar -C "$VOLUME" -xvf "$DATA" 
fi

"$@"

将以下内容添加到Dockerfile

COPY data-volume.tar.gz entrypoint /opt/
ENTRYPOINT ["/opt/entrypoint"]

首先运行:

>docker run --rm=true --volume "$(pwd)/test/:/opt/test" volumetest ls -l /opt/test
Preseeding VOLUME /opt/test with data from /opt/data-volume.tar.gz...
preseeded-data
total 0
-rw-r--r-- 1 1001 users 0 Nov  4 18:43 preseeded-data

后续运行:

>docker run --rm=true --volume "$(pwd)/test/:/opt/test" volumetest ls -l /opt/test
ls -l /opt/test
total 0
-rw-r--r-- 1 1001 users 0 Nov  4 18:43 preseeded-data

请注意,卷文件夹将填充数据, 如果它之前完全是空的。