docker-compose with multiple databases
我试图弄清楚如何使用docker-compose.yml和2个从sql dumps导入的数据库来实现docker。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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" |
上面返回以下内容:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
基本上,我试图在单个docker compose文件中获取整个堆栈设置,创建2个数据库并导入相应的sql转储。
有人有什么建议吗?
单个Docker容器中的多个数据库
此页面上其他位置的答案为每个数据库设置了专用容器,但是单个MySQL服务器能够托管多个数据库。是否应该是另一个问题,但是如果要在单个容器中使用多个数据库,请参见以下示例。
docker-compose.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
docker / provision / mysql / init / 01-databases.sql:
1 2 3 4 5 6 7 | # 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项目具有一个入口点脚本,该脚本将贯穿
您正在尝试将两个数据库容器都绑定到同一端口-
您需要更改其中一个数据库的端口映射,例如
只是对可能研究此问题的其他人的更新。
我通过以下方法解决了这个问题:
1 | MYSQL_DATABASE: dbname |
from docker-compose.yml,并将相关的create database语句直接添加到要传递到docker-entrypoint-initdb.d的sql文件中。
在那个阶段,sql命令是在root用户下执行的,因此,您还需要添加一条语句,以向要使用的数据库用户授予相关权限。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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" |
-
在
docker-compose up 之后 -
连接到mysql1
1mysql -h localhost -uasdf -P 3307 -pasdf asdf --protocol=tcp -D asdf -
连接到mysql2
1mysql -h localhost -uasdf -P 3308 -pasdf asdf --protocol=tcp -D asdf
经过奋斗,三天后才发现这篇文章
解决此问题挽救了我的生命
文件结构
1 2 3 4 | Project a"?a"€a"€ docker-compose.yml (File) a"?a"€a"€ init (Directory) a"? a"?a"€a"€ 01.sql (File) |
然后在docker-compose.yml文件中的卷中指向init目录,如下所示:
1 2 | volumes: - ./init:/docker-entrypoint-initdb.d |
01.sql
1 2 | CREATE DATABASE IF NOT EXISTS `test`; GRANT ALL ON `test`.* TO 'user'@'%'; |
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | version: '3.6' services: # MySQL db: image: mysql command: --default-authentication-plugin=mysql_native_password restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mydb MYSQL_USER: user MYSQL_PASSWORD: user volumes: - ./init:/docker-entrypoint-initdb.d adminer: image: adminer restart: always ports: - 8080:8080 |
对我来说,接下来要帮助:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | db: image: postgres container_name: mgt_db restart: always environment: POSTGRES_USER: postgres POSTGRES_DB: mgtdb POSTGRES_HOST_AUTH_METHOD: trust ports: - 5432:5432 db2: image: postgres container_name: pay_vault_db restart: always environment: POSTGRES_USER: postgres POSTGRES_DB: payvaultdb POSTGRES_HOST_AUTH_METHOD: trust ports: - 5433:5432 |
在容器中运行多个服务
从我的angular来看,以上所有答案均不完整。在原始问题中,
我看到了尝试启动两个容器的尝试。运行两个数据库容器是好是坏? Docker文档说
It is generally recommended that you separate areas of concern by using one service per container.
That service may fork into multiple processes (for example, Apache web server starts multiple worker processes). Ita€?s ok to have multiple processes,
but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application.
You can connect multiple containers using user-defined networks and shared volumes.
在逻辑上也将相同的规则应用于数据库似乎是正确的。因此,每个架构使用数据库容器都没有错。它提供了灵活性。
下面我在更多地方添加了网络和固定数据库初始化
优雅的方式。通过扩展\\'mysql \\'容器,相同的3306端口暴露为外部
提供从控制台或外部应用程序对mysql数据库的访问。
该端口必须是唯一的。要解决此错误,我添加了端口映射
mysql2容器也是如此。这些端口提供对数据库的访问
控制台或外部应用程序。如果需要从应用程序访问数据库
仅容器,不需要这些映射。 Docker有自己的
内部DNS。这就是为什么可以为应用程序容器建立数据库连接的原因
通过使用容器名称作为域名进行配置。因此,数据库
连接字符串将为dbuser @ mysql:3306 / dbname1和
dbuser @ mysql2:3306 / dbname2。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | version: '3' services: 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: - ./dump.sql:/docker-entrypoint-initdb.d/dump.sql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: dbname1 MYSQL_USER: dbuser MYSQL_PASSWORD: dbpass networks: - app-network mysql2: extends: mysql container_name: sqlserver2 ports: - 3307:3306 volumes: - ./dump2.sql:/docker-entrypoint-initdb.d/dump.sql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: dbname2 MYSQL_USER: dbuser MYSQL_PASSWORD: dbpass networks: - app2-network app: container_name: webdata image: php:latest volumes: - ../php:/var/www/html command:"true" networks: - app-network - app2-network #Docker Networks networks: app-network: app2-network: driver: bridge #Volumes volumes: dbdata: driver: local |