Как выполнить скрипты после компоновки докеров?

Я пытаюсь сделать мой процесс dev более легким/поддерживаемым с помощью docker (-compose). Я не хочу использовать тома (если это возможно). Почему import.sh не запускается после запуска "docker-compose up -d"?

У меня есть следующие файлы:

docker-compose.yml
  mysql
  ---- import.sh
  ---- db.sql
  ---- Dockerfile

в docker-compose.yml есть:

version: '2'

services:
  database:
    image: mysql
    build:
      context: ./mysql/
      dockerfile: Dockerfile
    container_name: mysqltest
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 123456

в /mysql/Dockerfile есть:

ADD import.sh /tmp/import.sh
ADD db.sql /tmp/db.sql
RUN /tmp/import.sh

в /mysql/db.sql:

CREATE DATABASE test1;
CREATE DATABASE test2;
CREATE DATABASE test3;

Ответ 1

Вы можете использовать ENTRYPOINT или CMD в вашем Dockerfile, чтобы выполнить команду при запуске контейнера. Разница между ними заключается в том, что ENTRYPOINT выполняется каждый раз, когда запускается контейнер, а CMD может быть заменен параметром командной строки. Предполагая, что вы хотите выполнить команду X

docker run my-image Y

выполнит X, если ENTRYPOINT X был в Dockerfile, и Y, если CMD X был в Dockerfile.

Однако есть две оговорки:

  1. Команда будет выполняться каждый раз при запуске контейнера.
  2. После завершения команды контейнер закрывается.

Поэтому типичным решением является наличие скрипта docker-entrypoint. Он проверяет, запущен ли он в новом контейнере, инициируя его среду, и затем выполняет реальную программу контейнера. Взгляните на официальный MySQL Dockerfile и точку входа, чтобы получить представление.

Пример сценария точки входа может выглядеть следующим образом:

$ cat docker_entrypoint.sh                                                                                                                                          
if [ ! -f .initialized ]; then                                                                                                                                                                                    
    echo "Initializing container"                                                                                                                                                                                 
    # run initializing commands                                                                                                                                                                                   
    touch .initialized                                                                                                                                                                                            
fi                                                                                                                                                                                                                

exec "[email protected]"

Сначала проверяется, существует ли файл с именем .initialized. Если его нет, запускаются некоторые команды для инициализации среды контейнера. После чего touch .initialized создает .initialized как пустой файл. Следовательно, последующие запуски контейнера больше не будут выполнять команду инициализации. Во-вторых, запускается фактическое обслуживание. Выполнение этого с exec заменит процесс оболочки на процесс обслуживания. Следовательно, docker будет поддерживать работу контейнера до тех пор, пока служба не прекратит работу. "[email protected]" будет содержать "команду контейнера/изображения". Это устанавливается с помощью CMD X в Dockerfile и переопределяется по команде, как я уже указывал выше. Используя exec "[email protected]", вы сможете запускать различные программы в контейнере для проверки, например, bash и запустите службу по умолчанию, как указано в операторе Dockerfile CMD.

Ответ 2

Если вы просто хотите инициализировать свою БД в самый первый раз, вы можете использовать этот простой способ.

    volumes:
      - [the scripts dir]:/docker-entrypoint-initdb.d

Инициализация свежего экземпляра Когда контейнер запускается в первый раз, будет создана новая база данных с указанным именем и инициализирована с предоставленными переменными конфигурации. Кроме того, он будет выполнять файлы с расширениями .sh,.sql и .sql.gz, которые находятся в /docker-entrypoint-initdb.d. Файлы будут выполнены в алфавитном порядке. Вы можете легко заполнить ваши службы mysql, смонтировав дамп SQL в этот каталог и предоставив пользовательские изображения с предоставленными данными. Файлы SQL будут импортированы по умолчанию в базу данных, указанную в переменной MYSQL_DATABASE.

Док здесь: https://docs.docker.com/samples/library/mysql/