Приветствую, вопрос следующий, пытаюсь связать 2 отдельных docker контейнера в docker-compose, но постоянно натыкаюсь на грабли то в одном то в другом.
Вкратце, сейчас логика развертывания в текущих отдельных контейнерах следующая:
1.1 docker run mysql:latest, dockerfile этого контейнера (в упрощнном виде):
--- FROM mysql:latest
--- RUN apt-get install wget
--- RUN wget <db_dump.sql>
1.2 docker exec mysql "mysql < <db_dump.sql>"
- docker run sinatra (connect mysql:3306)
Мигрирую на docker-compose и сразу же натыкаюсь на ворох проблем:
1) Как правильно организовать логику скачивания дампа базы wget’ом и закачивания её в mysql?
Мейнтейнеры образа предлагают шарить volume с дампами, которые будут залиты, мне этот подход не рабоатет тк мне надо слить образы wget’ом, который, кстати, на борту образа не присутсвует.
Пробовал в compose создавать build context со ссылкой на dockerfile по подобию оригинального докерфайла:
docker-compose.yml:
version: '3'
services:
db:
build: ./db
db/Dockerfile: (упрощённо):
-- FROM mysql:latest
-- RUN apt-get install wget
-- RUN wget <db_dump.sql>
-- RUN mysql < <db_dump.sql>
Этот подход не рабочий, так как логика запуска mysqld для этого image обёрнута wrapper’ом, который запускается ENTRYPOINT’ом по умолчанию. То есть строка «RUN mysql..» не отработает тк mysqld в этот момент будет не запущен.
Есть вариант обновить Entrypoint по умолчанию, добавив туда нужную логику сверху, но это КМК совсем грязный хак учитывая типовость задачи.
Гугление навело на stackoverflow где оптимальным решением было принято создание -1) просто mysql контейнера без дампа и -2) доп контейнера где отрабатывает wget и , собственно, mysql < <dump>
.
Может есть менее кривые способы?
2) Если всё таки завести 2-й контейнер,
упрощаю освной mysql до
version: '3'
services:
db:
image: mysql:latest
ports:
- "3306:3306"
tty: true
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
- доавляю новый контейнер в docker-compose (фрагмент):
mysql-seed:
build: ./db-seed
ports:
- "3307:3306"
tty: true
depends_on:
- db
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
где, в свою очередь ./db-seed/Dockerfile выглядит примерно так:
FROM mysql:latest
ARG MYSQL_ROOT_PASSWORD
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_DATABASE
RUN apt-get update && \
apt-get install -y --no-install-recommends \
wget unzip less vim \
mysql-client iputils-ping
RUN ping -c2 db
и вот тут интересное, когда этот контейнер собирается, он не видит хоста «db», то есть будь-то пинги, будь то логика залива дампа - на этом этапе не может отработать, так как хост 1-ого контейнера не виден.
Если же я закомментриую RUN ping db
, стартанну стек через docker-compose up , дождусь пока контейнеры поднимуться , залогинюсь на mysql-seed и вручную пингану db/запущу залив дампа - всё ок, всё отрабатывает. Хост виден.
Что я делаю не так? На этапе build контейнер не должен видеть другие контейнеры?
Если так, то как тогда наиболее канонично запилить такую логику?