том docker-compose пуст даже после инициализации

Я пытаюсь создать образ для создания докеров для другого веб-сайта.

Все работает нормально, кроме моих томов.

Вот пример docker-compose.yml:

version: '2'

services:
  website:
    build: 
        context: ./dockerfiles/                                        
        args:                                                                      
            MYSQL_ROOT_PASSWORD: mysqlp@ssword 
    volumes:
        - ./logs:/var/log
        - ./html:/var/www
        - ./nginx:/etc/nginx
        - ./mysql-data:/var/lib/mysql
    ports:
        - "8082:80"
        - "3307:3306"

А вот и мой Dockerfile:

FROM php:5.6-fpm

ARG MYSQL_ROOT_PASSWORD

RUN export DEBIAN_FRONTEND=noninteractive; \
echo mysql-server mysql-server/root_password password $MYSQL_ROOT_PASSWORD | debconf-set-selections; \
echo mysql-server mysql-server/root_password_again  password $MYSQL_ROOT_PASSWORD | debconf-set-selections;

RUN apt-get update && apt-get install -y -q mysql-server php5-mysql nginx wget

EXPOSE 80 3306

VOLUME ["/var/www", "/etc/nginx", "/var/lib/mysql", "/var/log"]

Все работает хорошо, ожидайте, что все мои папки пусты в мои тома хоста. Я хочу видеть данные nginx conf и mysql в своих папках.

Что я делаю не так?

РЕДАКТИРОВАТЬ 1: На самом деле проблема в том, что я хочу, чтобы docker-compose создал том в моем каталоге докеров, если он не существует, и использовал этот том, если он существует, как это объясняется в https://stackoverflow.com/a/39181484. Но это не работает.


person Mayous    schedule 22.02.2017    source источник
comment
Я полагаю, что это относится к вашему случаю: Создайте том Docker с уже существующим данные в нем   -  person jrbeverly    schedule 22.02.2017
comment
Возможный дубликат Создать том Docker с уже существующими данными   -  person jrbeverly    schedule 22.02.2017
comment
На самом деле проблема в том, что я хочу, чтобы docker-compose создал том в моем каталоге докеров, если он не существует, и использовал этот том, если он существует, как это объясняется в stackoverflow.com/a/39181484. но, похоже, это не работает.   -  person Mayous    schedule 22.02.2017
comment
Каталог ./logs не создается? Я думал, что на данный момент это поведение docker-compose по умолчанию.   -  person jrbeverly    schedule 22.02.2017
comment
Да, он создан, но пуст. Разве он не должен содержать то, что уже находится в контейнерах /var/log?   -  person Mayous    schedule 22.02.2017
comment
Смонтированные тома не будут содержать содержимое /var/log. Как описано здесь, тома инициализируются при создании контейнера. Если базовый образ контейнера содержит данные в указанной точке подключения, эти существующие данные копируются в новый том при инициализации тома. (Обратите внимание, что это не применяется при монтировании каталога хоста.)   -  person jrbeverly    schedule 22.02.2017
comment
Итак, кажется, что я не могу получить доступ к /var/log/, если я хочу смонтировать каталог хоста в свой контейнер. Итак, как мне получить доступ к содержимому /var/log из контейнера? Если я удалю тома из docker-compose и включу тома в свой dockerfile, я увижу, что мой источник монтирования виден в /var/lib/docker/volumes/.../_data и содержит нужные мне файлы.   -  person Mayous    schedule 22.02.2017
comment
Давайте продолжим обсуждение в чате.   -  person Mayous    schedule 22.02.2017


Ответы (1)


Проблема в том, что вы ожидаете, что файлы из Контейнера будут смонтированы на вашем хосте.

Это не так, как это работает: это наоборот:

Docker монтирует вашу хост-папку в указанную вами папку-контейнер. Если вы зайдете внутрь контейнера, вы увидите, что там, где должны были быть файлы инициализации, ничего не будет (или что бы то ни было в папке (папках) вашего хоста), и вы можете записать файл в папку, и он будет появиться на вашем хосте.

Лучше всего получить файлы инициализации и изменить их для своего контейнера:

  • Создать контейнер без монтирования папок (там будут исходные данные контейнера)
  • Запустите контейнер (в контейнере будут файлы в нужном месте после установки nginx и т. д.) docker run <image>
  • Скопируйте файлы из контейнера с помощью docker cp <container>:<container_folder>/* <host_folder>
  • Теперь у вас есть «оригинальные» файлы из контейнера, инициализированные на вашем хосте.
  • Измените файлы, необходимые для контейнера.
  • Запустите контейнер, монтируя папки вашего хоста с новыми файлами в них.

Примечания: вы можете зайти внутрь контейнера с оболочкой (docker run -it <image> /bin/sh) и заархивировать все папки, чтобы убедиться, что у вас есть все, если есть вложенные папки, затем docker cp ... zip-файл

Кроме того, будьте осторожны с чувствительностью к регистру файловой системы: файлы Linux чувствительны к регистру. В Mac OS X их нет. Поэтому, если у вас есть Init.conf и init.conf в одной папке, они столкнутся, когда вы скопируете их на хост Mac OS X.

person MrE    schedule 22.02.2017
comment
Спасибо за Ваш ответ. Что я вижу, так это то, что если я монтирую том в контейнер, не указывая ничего в docker-compose, содержимое каждого тома отображается на хосте в /var/lib/docker/volumes/.../_data, только если том не существует раньше. Я понимаю, что если я укажу другой путь для моего тома на хост (как я сделал в docker-compose), поведение будет другим, даже если папка раньше не существовала? - person Mayous; 22.02.2017
comment
Вам не нужно возиться с /var/lib/docker/volumes... потому что это внутренний Docker. Docker будет создавать/удалять эти папки по мере необходимости, так что не полагайтесь на это. Docker использует многоуровневую файловую систему, поэтому повторно использует тома, если они определены несколько раз. Опять же, не полагайтесь на внутренние файлы Docker для выполнения вашей работы: смонтируйте папку хоста в том месте, где она находится в контейнере, и ожидайте, что в контейнере отобразится только то, что там находится. Если у вас есть файлы в папке контейнера, они будут там, если вы не смонтируете папку хоста. - person MrE; 22.02.2017
comment
если вам нужны оба набора файлов, то у вас должна быть ENTRYPOINT, которая запустит скрипт и решит, какой из них загрузить. Затем вы можете связать нужную папку / файл там, где это необходимо. - person MrE; 22.02.2017
comment
Это отличный ответ, он так много объясняет о том, как контейнеры монтируются на хосте. - person Sarke; 29.10.2017
comment
но почему docker mongo работает как ~/data/db:/data/db , контейнер /data/db не будет пустым - person leafiy; 29.09.2019
comment
Если вы смонтируете локальный (непустой) каталог, да, внутри контейнера он не будет пустым. Если вы сначала смонтируете его пустым, а затем инициализируете mongodb, mongo запишет свои файлы данных в эту папку, и они окажутся в локальной папке. - person MrE; 29.09.2019