Добавление файлов в стандартные образы с помощью docker-compose

Я не уверен, ускользнет ли от меня что-то очевидное или это просто невозможно, но я пытаюсь собрать весь стек приложения с изображениями из Docker Hub.

Одним из них является mysql, который поддерживает добавление пользовательских файлов конфигурации через тома и запуск .sql-файлов из смонтированного каталога.

Но у меня эти файлы есть на машине, на которой я запускаю docker-compose, а не на хосте. Нет ли способа указать файлы с локального компьютера для копирования в контейнер, прежде чем он запустит точку входа / cmd? Неужели мне действительно нужно создавать локальные образы всего только для этого случая?


person Andreas Wederbrand    schedule 08.09.2016    source источник
comment
Я предоставил два способа копирования ваших данных с вашего локального компьютера на хост (локальный или удаленный). См. Здесь stackoverflow.com/a/39348811/1556338 В общем, вы хотите, чтобы ваши данные не попадали в изображение. Это делает ваше изображение пригодным для повторного использования в различных средах (dev / testing / prod, clientA, clientB и т. Д.).   -  person Bernard    schedule 08.09.2016
comment
Да, docker cp будет работать, но не как часть docker-compose, это отдельный шаг. Было бы лучше не заключать docker-compose в сценарий оболочки только для этого.   -  person Andreas Wederbrand    schedule 08.09.2016
comment
К сожалению, составление докеров ограничено. По мере того, как ваше использование становится более конкретным, вы не сможете избежать использования сценариев оболочки для некоторых вещей. Compose даже не работает с новым режимом Swarm.   -  person Bernard    schedule 08.09.2016
comment
Обычно для решения этой проблемы я создаю образы Docker для настройки. У меня есть эти файлы в CVS с Dockerfile, и я создаю образ Docker с версией (из Scratch). Позже я запускаю композицию с томами из, указывающими на этот контейнер файлов.   -  person Jorge Marey    schedule 08.09.2016


Ответы (5)


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

Пример конфигурации nginx в официальном образе:

version: "3.7"

services:
  nginx:
    image: nginx:alpine
    ports:
      - 80:80
    environment:
      NGINX_CONFIG: |
        server {
          server_name "~^www\.(.*)$$" ;
          return 301 $$scheme://$$1$$request_uri ;
        }
        server {
          server_name example.com
          ...
        }
    command:
      /bin/sh -c "echo \"$$NGINX_CONFIG\" > /etc/nginx/conf.d/redir.conf; nginx -g \"daemon off;\""

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

https://docs.docker.com/compose/compose-file/#env_file https://docs.docker.com/compose/compose-file/#variable-substitution

Чтобы получить исходную команду точки входа контейнера:

docker container inspect [container] | jq --raw-output .[0].Config.Cmd

Чтобы выяснить, какой файл нужно изменить, это обычно работает:

docker exec --interactive --tty [container] sh
person Bobík    schedule 18.04.2019
comment
Я одобряю этот ответ, поскольку он работает как минимум для небольших файлов. Хороший трюк. Мне придется переопределить точку входа по умолчанию для этого изображения, но это нормально. - person Andreas Wederbrand; 22.04.2019

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

Этот вариант достигается за счет использования docker-compose для создания вашего образа, и эта сборка отправит любые файлы из каталога сборки в удаленный механизм докеров. Ваш docker-compose.yml будет выглядеть так:

version: '2'

services:
  my-db-app:
    build: db/.
    image: custom-db

И db / Dockerfile будет выглядеть так:

FROM mysql:latest
COPY ./sql /sql

Точка входа / cmd останется без изменений. Вам нужно будет запустить docker-compose up --build, если изображение уже существует и вам нужно изменить файлы sql.


Вариант Б: используйте том для хранения данных. Это невозможно сделать непосредственно внутри docker-compose. Однако это предпочтительный способ включения файлов вне изображения в контейнер. Вы можете заполнить том по сети с помощью интерфейса командной строки докера и перенаправления ввода вместе с такой командой, как tar, для упаковки и распаковки тех файлов, которые отправляются через stdin:

tar -cC sql . | docker run --rm -it -v sql-files:/sql \
  busybox /bin/sh -c "tar -xC /sql"

Запустите это через скрипт, а затем пусть тот же скрипт отправит контейнер db, чтобы перезагрузить эту конфигурацию.


Вариант C: используйте какую-либо файловую систему, подключенную к сети. Если вы можете настроить NFS на хосте, на котором запущен интерфейс командной строки докера, вы можете подключиться к этим общим ресурсам NFS с удаленного узла докера, используя один из следующих вариантов:

# create a reusable volume
$ docker volume create --driver local \
    --opt type=nfs \
    --opt o=addr=192.168.1.1,rw \
    --opt device=:/path/to/dir \
    foo

# or from the docker run command
$ docker run -it --rm \
  --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,volume-opt=o=addr=192.168.1.1,volume-opt=device=:/host/path \
  foo

# or to create a service
$ docker service create \
  --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,volume-opt=o=addr=192.168.1.1,volume-opt=device=:/host/path \
  foo

Вариант D: в режиме роя вы можете включать файлы в качестве конфигураций в свой образ. Это позволяет отправлять файлы конфигурации, которые обычно необходимо отправить на любой узел в рое, по запросу на узел, на котором работает ваша служба. Для его определения используется docker-compose.yml файл, но режим swarm не использует сам docker-compose, поэтому он может не соответствовать вашим конкретным требованиям. Вы можете запустить кластер в режиме роя с одним узлом, поэтому эта опция доступна, даже если у вас только один узел. Эта опция требует, чтобы каждый из ваших файлов sql добавлялся как отдельная конфигурация. docker-compose.yml будет выглядеть так:

version: '3.4'

configs:
  sql_file_1:
    file: ./file_1.sql

services
  my-db-app:
    image: my-db-app:latest
    configs:
      - source: sql_file_1
        target: /sql/file_1.sql
        mode: 444

Тогда вместо docker-compose up вы запустите docker stack deploy -c docker-compose.yml my-db-stack.

person BMitch    schedule 08.09.2016

Вот как я это делаю с объемами:

services:
  my-db-app:
    command: /shell_scripts/go.sh
    volumes:
      - ./shell_scripts:/shell_scripts 
person Adam Spence    schedule 29.12.2016
comment
Это не работает, если shell_scripts находится на другом хосте от удаленного сервера докеров. - person BMitch; 01.01.2017
comment
Также у меня работало просто использование volumes: - ./:/config/path/in/container для монтирования файлов из корневого каталога проекта в контейнер. - person socona; 05.04.2019

я думаю, вам нужно было сделать в файле создания:

volumes:
 - src/file:dest/path
person Cristian Monti    schedule 12.04.2018

В качестве более позднего обновления этого вопроса: например, с роем докеров, размещенным на Amazon, вы можете определить том, который может использоваться службами и доступен на всех узлах роя (используя cloudstor, который, в свою очередь, имеет AWS EFS, лежащий в основе сохраняемости).

version: '3.3'
services:
  my-db-app:
    command: /shell_scripts/go.sh
    volumes:
      shell_scripts:/shell_scripts 
volumes:
    shell_scripts:
      driver: "cloudstor:aws"
person Eoan    schedule 30.09.2017