2016-11-04 4 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 

Но если я не использую «объем» по Копирует докеров по умолчанию над файлами в папку Temp:

# 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

Это документально поведение действительно:

Объемы инициализируются при создании контейнера. Если базовое изображение контейнера содержит данные в указанной точке монтирования, то существующие данные копируются в новый том после инициализации тома. (Обратите внимание, что это не применяется при установке каталога хоста.)

т.е. при монтировании /и т.д./HTTPD объем --volume/данные/HTTPD/и т.д.:/и т.д./HTTPD, данные не будут скопированы.

Вы также можете увидеть https://github.com/docker/docker/pull/9092 для более подробного обсуждения того, почему он работает таким образом (в случае, если вы заинтересованы).

Обычным обходным путем для этого является копирование исходных данных в папку томов (изнутри контейнера) внутри сценария ENTRYPOINT или CMD, в случае, если он пуст.

Обратите внимание, что исходный набор данных должен храниться вне папки томов (например, в качестве .tar-файла в/opt), поскольку это будет работать, поскольку папка тома будет затенена папкой хоста, установленной над ней.

Ниже приведен пример 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 

Обратите внимание, что папка объем будет только заполняться данных, , если это было полностью pty раньше.

+0

Спасибо, Цеппелин, но что вы подразумеваете под «установкой каталога хоста»? Я использую параметр «volume», я надеюсь, что он сможет сделать то, что говорит документ: «существующие данные копируются в новый том при инициализации тома», но этого не происходит. – user3593261

+0

Установка тома означает, что вы создаете папку вашей файловой системы хоста (то есть _/date/httpd/etc/_), доступную в качестве тома (_/etc/httpd_) внутри вашего контейнера, указав оба в командной строке: volume =/data/httpd/etc:/etc/httpd. (который является синтаксисом для томов _mounted_). Это отличается от простого объявления тома с помощью --volume/etc/httpd (обратите внимание, что путь к каталогу не указан). – zeppelin

+0

Спасибо за ваше объяснение, но это не имеет смысла, если я не дам ему точку монтирования. Тем не менее, я удалил локальный путь (--volume =/etc/httpd), который все еще не удалось, так как он создал новую папку temp, и ничего не было скопировано. – user3593261