我正在试图弄清楚如何使用docker-compose.yml和从sql转储导入的2个数据库来实现docker。
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
基本上,我正在尝试将整个堆栈设置放在一个docker compose文件中,创建2个数据库并导入相应的sql转储。 有人有什么建议吗?
答案 0 :(得分:12)
您尝试将两个数据库容器绑定到同一个端口 - 3306
。这基本上是不可能的。
您需要更改其中一个数据库的端口映射,例如mysql
保留3306:3306
,mysql2
应使用3307:3306
。
答案 1 :(得分:12)
正如对可能会对此进行调查的任何其他人的更新。
我通过删除:
解决了这个问题MYSQL_DATABASE: dbname
从 docker-compose.yml 并将相关的create database语句直接添加到传递给 docker-entrypoint-initdb.d 的sql文件中。
在该阶段,sql命令在root下执行,因此您还需要添加一个语句,以向您要使用的数据库用户授予相关权限。
答案 2 :(得分:10)
本页其他位置的答案为每个数据库设置了专用容器,但是单个MySQL服务器能够托管多个数据库。是否应该KEY_RESIZE
,但是如果要在单个容器中使用多个数据库,请is a different question。
docker-compose.yml:
C++
docker / provision / mysql / init / 01-databases.sql:
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
之所以可行,是因为here's an example有一个MySQL Docker project,它将在# 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 ON *.* TO 'root'@'%';
文件夹(如果存在)中的所有文件中运行。这对于设置数据库以及初始化其架构和数据很有用。在docker-compose中,我们使用/docker-entrypoint-initdb.d
将该虚拟文件夹映射到主机系统上的文件夹。
答案 3 :(得分: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"
docker-compose up
连接到mysql1
mysql -h localhost -uasdf -P 3307 -pasdf asdf --protocol=tcp -D asdf
连接到mysql2
mysql -h localhost -uasdf -P 3308 -pasdf asdf --protocol=tcp -D asdf
答案 4 :(得分:2)
对我来说,接下来要帮助:
PageFactory
答案 5 :(得分:2)
经过奋斗,三天后发现了这个Article 解决这个问题挽救了我的生命
文件结构
Project
├── docker-compose.yml (File)
├── init (Directory)
│ ├── 01.sql (File)
然后在docker-compose.yml文件中的卷中指向init目录,如下所示:
volumes:
- ./init:/docker-entrypoint-initdb.d
01.sql
CREATE DATABASE IF NOT EXISTS `test`;
GRANT ALL ON `test`.* TO 'user'@'%';
docker-compose.yml
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
答案 6 :(得分:2)
在一个容器中运行多个服务
从我的角度来看,以上答案都不完整。在原始问题中, 我看到尝试启动两个容器。运行两个数据库容器是好是坏? Docker 文档说
<块引用>通常建议您通过为每个容器使用一项服务来分隔关注区域。 该服务可能会分叉到多个进程中(例如,Apache Web 服务器启动多个工作进程)。可以有多个进程, 但要从 Docker 中获得最大收益,请避免一个容器负责整个应用程序的多个方面。 您可以使用用户定义的网络和共享卷连接多个容器。
将相同的规则也应用于数据库在逻辑上似乎是正确的。因此,每个模式使用数据库容器并没有错。它提供了灵活性。
下面我添加了更多的网络和固定数据库初始化 优雅的方式。通过扩展“mysql”容器,相同的 3306 端口被暴露为外部 提供从控制台或外部应用程序访问 mysql 数据库的权限。 该端口必须是唯一的。为了解决这个错误,我添加了端口映射 mysql2 容器也是如此。这些端口提供对数据库的访问 控制台或外部应用程序。如果需要从应用程序访问数据库 仅容器,不需要这些映射。 Docker 有自己的 内部 DNS。这就是为什么应用程序容器的数据库连接可以是 使用容器名称作为域名进行配置。所以,数据库 连接字符串将是 dbuser@mysql:3306/dbname1 和 dbuser@mysql2:3306/dbname2。
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
答案 7 :(得分:0)
当您研究 mysql 映像的 /usr/local/bin/docker-entrypoint.sh
时,您会注意到在映射的 *.sh
中处理 docker-entrypoint-initdb.d
文件的不同模式(查找 HERE
< /strong> 标记):
case "$f" in
*.sh)
if [ -x "$f" ]; then
"$f"
else
. "$f" # HERE!!
fi
;;
*.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;; # HERE!!
# ...
esac
有了这个,你可以创建一个没有可执行位的 000-databases.sh
,包含以下内容:
echo "
CREATE DATABASE IF NOT EXISTS \`other-database\`;
GRANT ALL PRIVILEGES ON \`other-database\`.* TO '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD';
" | docker_process_sql
此处的关键实用程序是 docker_process_sql
,它处理 SQL 脚本。 MYSQL_*
变量来自您的 docker-compose.yml
环境配置。