docker-compose with multiple databases

Ava*_*che 17 database docker docker-compose

我试图弄清楚如何使用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"
Run Code Online (Sandbox Code Playgroud)

以上返回以下内容:

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
Run Code Online (Sandbox Code Playgroud)

基本上,我正在尝试将整个堆栈设置放在一个docker compose文件中,创建2个数据库并导入相应的sql转储.有人有什么建议吗?

Sca*_*dge 18

您正在尝试将两个数据库容器绑定到同一个端口 - 3306.这基本上是不可能的.您需要更改其中一个数据库的端口映射,例如mysql保留3306:3306,并且mysql2应该使用3307:3306.


mah*_*off 14

单个Docker容器中的多个数据库

本页其他位置的答案为每个数据库设置了专用容器,但是单个MySQL服务器可以托管多个数据库。是否应该是一个不同的问题,但是如果您想在一个容器中使用多个数据库,请参见以下示例

docker-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
Run Code Online (Sandbox Code Playgroud)

docker / provision / 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'@'%';
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?

之所以可行,是因为MySQL Docker项目具有一个入口点脚本,该脚本将贯穿文件/docker-entrypoint-initdb.d夹中的所有文件(如果存在)。这对于设置数据库以及初始化其架构和数据很有用。在docker-compose中,我们volumes用于将虚拟文件夹映射到主机系统上的文件夹。

  • 各位,我只是做了这个答案告诉我要做的事情,但我发现了一个问题,如果你使用 SQL 文件(01-databases.sql)创建 root 用户,你会得到一个错误,因为这个 root当您设置 MYSQL_ROOT_PASSWORD env 时,用户已经由 MySql docker 映像创建。您只需创建将在数据库应用程序连接选项中使用的应用程序用户。 (2认同)

Ava*_*che 13

正如对可能会对此进行调查的任何其他人的更新.

我解决了这个问题:

MYSQL_DATABASE: dbname 
Run Code Online (Sandbox Code Playgroud)

来自docker-compose.yml并将相关的create database语句直接添加到传递给docker-entrypoint-initdb.d的sql文件中.

在该阶段,sql命令在root下执行,因此您还需要添加一个语句,以向您要使用的数据库用户授予相关权限.

  • 你能粘贴完整的文件吗? (5认同)

Mun*_*oor 7

苦苦挣扎后,3天发现这篇文章 解决了这个问题救了我一命

文件结构

Project
??? docker-compose.yml (File)
??? init (Directory)
?   ??? 01.sql (File)
Run Code Online (Sandbox Code Playgroud)

然后将 init 目录指向 docker-compose.yml 文件中的卷内,如下所示

volumes: 
  - ./init:/docker-entrypoint-initdb.d
Run Code Online (Sandbox Code Playgroud)

01.sql

CREATE DATABASE IF NOT EXISTS `test`;
GRANT ALL ON `test`.* TO 'user'@'%';
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Ole*_*sky 6

在容器中运行多个服务

\n

从我的角度来看,上述答案都不完整。在原来的问题中,\n我看到尝试启动两个容器。运行两个数据库容器是好是坏?Docker 文档说

\n
\n

通常建议您通过每个容器使用一项服务来分隔关注区域。\n该服务可能会分叉为多个进程(例如,Apache Web 服务器启动多个工作进程)。\xe2\x80\x99 可以有多个进程,\n但为了充分利用 Docker,请避免一个容器负责整个应用程序的多个方面。\n您可以使用用户定义的网络和共享网络连接多个容器。卷。

\n
\n

将相同的规则应用于数据库似乎在逻辑上是正确的。因此,每个模式使用数据库容器没有任何问题。它提供了灵活性。

\n

下面我以更优雅的方式添加了网络和固定数据库初始化。通过扩展“mysql”容器,相同的 3306 端口将公开为外部端口,\n以提供从控制台或外部应用程序对 mysql 数据库的访问。\n该端口必须是唯一的。为了修复此错误,我还为 mysql2 容器添加了端口映射。这些端口提供从控制台或外部应用程序\n对数据库的访问。如果仅需要从应用容器访问数据库,则不需要这些映射。Docker 有自己的\n内部 DNS。这就是为什么可以通过使用容器名称作为域名来配置应用容器的数据库连接。因此,数据库连接字符串将为 dbuser@mysql:3306/dbname1 和 ndbuser@mysql2:3306/dbname2。

\n
version: '3'\nservices:\n\n httpd:\n    container_name: webserver\n    build: ./webserver/\n    ports:\n        - 80:80\n    links:\n        - mysql\n        - mysql2\n    volumes_from:\n        - app\n   \n mysql:\n    container_name: sqlserver\n    image: mysql:latest\n    ports:\n        - 3306:3306\n    volumes:\n        - ./dump.sql:/docker-entrypoint-initdb.d/dump.sql\n    environment:\n        MYSQL_ROOT_PASSWORD: root\n        MYSQL_DATABASE: dbname1\n        MYSQL_USER: dbuser\n        MYSQL_PASSWORD: dbpass\n    networks:\n      - app-network\n   \n mysql2:\n    extends: mysql\n    container_name: sqlserver2\n    ports:\n        - 3307:3306\n    volumes:\n        - ./dump2.sql:/docker-entrypoint-initdb.d/dump.sql\n    environment:\n        MYSQL_ROOT_PASSWORD: root\n        MYSQL_DATABASE: dbname2\n        MYSQL_USER: dbuser\n        MYSQL_PASSWORD: dbpass\n   networks:\n      - app2-network\n\n app:\n    container_name: webdata\n    image: php:latest\n    volumes:\n        - ../php:/var/www/html\n    command: "true"\n    networks:\n      - app-network\n      - app2-network\n\n#Docker Networks\nnetworks:\n  app-network:\n  app2-network:\n    driver: bridge\n#Volumes\nvolumes:\n  dbdata:\n    driver: local\n
Run Code Online (Sandbox Code Playgroud)\n


dav*_*ler 5

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"
Run Code Online (Sandbox Code Playgroud)

  • 您能否为“MYSQL_USER”、“MYSQL_ROOT_PASSWORD”、“MYSQL_PASSWORD”、“MYSQL_DATABASE”设置不同的值而不是“asdf”,以便您的 **Connect to mysql** 命令更加清晰。所有“asdf”值都有点令人困惑。谢谢 (5认同)

anu*_*anu 5

您可以在单个容器服务中拥有多个数据库:

docker-compose.yml

version: '3.7'
services:
  postgres-db:
    restart: always
    image: postgres:latest
    volumes:
      - db-volume:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    env_file:
      - ./db-prod.env
Run Code Online (Sandbox Code Playgroud)

db-prod.env

POSTGRES_USER=myusername
POSTGRES_PASSWORD=mypassword
POSTGRES_MULTIPLE_DATABASES=db1,db2
Run Code Online (Sandbox Code Playgroud)

资料来源: