2016-11-04 73 views
1

我想在泊坞窗安装HTTPD,我写了这样的dockerfile:的httpd在码头工人无法启动

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 

但是,如果我没有在文件默认情况下,泊坞窗copys用“量”到一个临时文件夹:

# 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 

所以我很困惑,为什么搬运工拒绝将其复制到指定的位置?以及如何解决这个问题?

回答

2

这确实是一个记录的行为:在创建容器时

卷被初始化。如果容器的 基本映像包含指定安装点上的数据,则在卷初始化时,现有数据 将被复制到新卷中。 (请注意,安装主机目录时,该 并不适用。)

即当你安装的/ etc/httpd的--volume /数据/的httpd的/ etc中:/ etc/httpd的,没有数据将被复制。

您也可以参考https://github.com/docker/docker/pull/9092了解更多关于它为什么以这种方式工作的原因(如果您有兴趣)。

对此的常用解决方法是将您的初始数据复制到ENTRYPOINT或CMD脚本中的卷文件夹(来自容器内),如果它为空,则为 。

请注意,您的初始数据集必须保存在卷文件夹之外(例如,作为/ opt中的.tar文件),因为此文件夹将被安装在其上的主文件夹遮盖。

下面给出的是一个样品Dockerfile和脚本,它可以说明问题:

样品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 

"[email protected]" 

添加以下到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 

注意,该卷文件夹将与填充数据, ,如果它是完全em pty之前。

+0

谢谢你,Zeppelin,但你是什么意思“安装主机目录”?我正在使用“volume”参数,我希望它能够做到文档所说的:“在卷初始化时将现有数据复制到新卷中”,但它不会发生。 – user3593261

+0

挂载一个卷意味着你通过在命令行上同时指定主机文件系统文件夹(即_/date/httpd/etc/_),作为容器内的卷(_/etc/httpd_)。 volume =/data/httpd/etc:/ etc/httpd。 (这是_mounted_卷的语法)。 这与使用--volume/etc/httpd简单声明卷不同(请注意,没有指定主机文件夹路径)。 – zeppelin

+0

谢谢你的解释,但如果我不给它一个挂载点,它就没有意义了。但是,我删除了本地路径(--volume =/etc/httpd),但它仍然失败,因为它创建了一个新的临时文件夹,也没有复制任何内容。 – user3593261