Docker-compose с несколькими базами данных
Я пытаюсь понять, как реализовать докер, используя docker-compose.yml с двумя базами данных, импортированными из sql-дампов.
httpd:
container_name: webserver
build: ./webserver/
ports:
- 80:80
links:
- mysql
- mysql2
volumes_from:
- app
mysql:
container_name: sqlserver
image: mysql:latest
ports:
- 3306:3306
volumes:
- ./sqlserver:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: dbname1
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpass
mysql2:
extends: mysql
container_name: sqlserver2
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: dbname2
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpass
app:
container_name: webdata
image: php:latest
volumes:
- ../php:/var/www/html
command: "true"
Приведенное выше возвращает следующее:
Kronos:mybuild avanche$ ./run.sh
Creating sqlserver
Creating webdata
Creating sqlserver2
ERROR: for mysql2 driver failed programming external connectivity on endpoint sqlserver2 (6cae3dfe7997d3787a8d59a95c1b5164f7431041c1394128c14e5ae8efe647a8): Bind for 0.0.0.0:3306 failed: port is already allocated
Traceback (most recent call last):
File "<string>", line 3, in <module>
File "compose/cli/main.py", line 63, in main
AttributeError: 'ProjectError' object has no attribute 'msg'
docker-compose returned -1
В принципе, я пытаюсь настроить весь набор стека в одном файле-докере, создать 2 базы данных и импортировать соответствующие sql-дампы.
У кого-нибудь есть предложения?
Ответы
Ответ 1
Вы пытаетесь связать оба контейнера базы данных с одним и тем же портом - 3306
. Что принципиально невозможно.
Вам нужно изменить сопоставление портов для одной из баз данных, например mysql
хранит 3306:3306
, а mysql2
следует использовать 3307:3306
.
Ответ 2
Как обновление для всех, кто может это изучить.
Я решил это, удалив:
MYSQL_DATABASE: dbname
из docker-compose.yml и добавление соответствующих операторов создания базы данных непосредственно в файл sql, передаваемый в docker-entrypoint-initdb.d.
На этом этапе команды sql выполняются под root, поэтому вам также необходимо добавить оператор для предоставления соответствующих разрешений пользователю базы данных, которое вы хотите использовать.
Ответ 3
Несколько баз данных в одном контейнере Docker
Ответы в других разделах этой страницы настраивают выделенный контейнер для каждой базы данных, но один сервер MySQL способен разместить несколько баз данных. Нужно ли это - это другой вопрос, но если вам нужно несколько баз данных в одном контейнере, вот пример.
докер-compose.yml:
version: '3'
volumes:
db:
driver: local
services:
db:
image: mysql:5.7
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./docker/provision/mysql/init:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: local
Докер/положение /MySQL/INIT/01-databases.sql:
# create databases
CREATE DATABASE IF NOT EXISTS 'primary';
CREATE DATABASE IF NOT EXISTS 'secondary';
# create root user and grant rights
CREATE USER 'root'@'localhost' IDENTIFIED BY 'local';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
Как это работает?
Это работает, потому что проект MySQL Docker имеет сценарий точки входа, который будет запускаться через все файлы в папке /docker-entrypoint-initdb.d
, если он существует. Это полезно для настройки баз данных и инициализации их схемы и данных. В docker-compose мы используем volumes
для сопоставления этой виртуальной папки с папкой в хост-системе.
Ответ 4
version: '3'
services:
mysql1:
image: mysql:5.6.26
environment:
MYSQL_ROOT_PASSWORD: asdf
MYSQL_USER: asdf
MYSQL_HOST: localhost
MYSQL_PASSWORD: asdf
MYSQL_DATABASE: asdf
ports:
- "3307:3306"
mysql2:
image: mysql:5.6.26
environment:
MYSQL_ROOT_PASSWORD: asdf
MYSQL_USER: asdf
MYSQL_HOST: localhost
MYSQL_PASSWORD: asdf
MYSQL_DATABASE: asdf
ports:
- "3308:3306"