将 Flyway 添加到 MySQL Docker 容器

Posted

技术标签:

【中文标题】将 Flyway 添加到 MySQL Docker 容器【英文标题】:Adding Flyway to a MySQL Docker Container 【发布时间】:2017-08-31 20:21:18 【问题描述】:

我正在为 mysql 构建这个 Docker 容器的衍生产品(使用它作为起点):https://github.com/docker-library/mysql

我已修改 Dockerfile 以添加到 Flyway。一切都设置为编辑配置文件以连接到本地数据库实例等。目的是在第 186 行附近的 https://github.com/docker-library/mysql/blob/master/5.7/docker-entrypoint.sh 文件(作为 ENTRYPOINT 运行)内部调用此命令:

flyway migrate

从 shell 脚本内部运行时,连接被拒绝:

Flyway 4.1.2 by Boxfuse

ERROR: 
Unable to obtain Jdbc connection from DataSource 
(jdbc:mysql://localhost:3306/db-name) for user 'root': Could not connect to address=(host=localhost)(port=3306)(type=master) : Connection refused
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL State  : 08
Error Code : -1
Message    : Could not connect to address=(host=localhost)(port=3306)(type=master) : Connection refused

但是,如果我从 shell 脚本中删除命令,重新构建并登录到容器,然后手动运行相同的命令,它就没有问题了。

我怀疑脚本连接到数据库以执行其操作的方式可能存在一些差异(它有一个内置的 SQL“运行器”),但我似乎无法找到它。容器在这个过程中会重新启动服务器,这可能是这里的不同之处。

由于此容器旨在用于开发,因此一种替代方法(实际上是一种解决方法)是使用此容器的内置 SQL“运行器”,使用 Flyway 期望的文件名格式,然后使用 Flyway 来管理生产DB 的版本。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

我的意思是这是从准备好的图像开始的好方法(开始)。

你可以从镜像 docker "mysql" 开始

FROM mysql

如果您启动完成的图像 - 在创建新版本时您的 docker 然后 只会更新差异。

接下来,你可以安装java和net-tools

RUN apt-get -y install apt-utils openjdk-8-jdk net-tools

配置mysql

ENV MYSQL_DATABASE=mydb
ENV MYSQL_ROOT_PASSWORD=root

添加航路

ADD flyway /opt/flyway

添加迁移

ADD sql /opt/flyway/sql

添加配置飞路

ADD config /opt/flyway/conf

添加脚本开始

ADD start /root/start.sh

检查启动mysql

RUN netstat -ntlp

检查java版本

RUN java -version

示例文件:/opt/flyway/conf/flyway.conf

flyway.driver=com.mysql.jdbc.Driver
flyway.url=jdbc:mysql://localhost:3306/mydb
flyway.user=root
flyway.password=root

示例文件:start.sh

#!/bin/bash
cd /opt/flyway
flyway migrate

# may change to start.sh to start product migration or development. 

Flyway documentation

我的意思是你下一步可能会使用flyway作为服务:

例如:

docker run -it -p 3307:3306 my_docker_flyway /root/start << migration_prod.sh

docker run -it -p 3308:3306 my_docker_flayway /root/start << migration_dev.sh

等等……

【讨论】:

我会试试这个并得到结果。谢谢。 因此,我得出结论,这最终是不可行或不可取的。原因如下:mysql 容器启动一个守护进程并保持容器运行。其次,Flyway 的架构是针对外部服务运行的。因此,我一直在尝试完成的是从已经运行服务的容器中运行 Flyway。这是架构冲突。所以,我认为解决方案(正如我在上面提出的)是在原始容器构建中包含 Flyway 文件以更新容器的开发版本,然后使用这些相同的文件来“外部”使用 Flyway 更新测试/产品数据库。 请私信给我。【参考方案2】:
services:
# Standard Mysql Box, we have to add tricky things else logging by workbench is hard
supermonk-mysql:
  image: mysql
  command:  --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  environment:
    - MYSQL_ROOT_PASSWORD=P@ssw0rd
    - MYSQL_ROOT_HOST=%
    - MYSQL_DATABASE=test
  ports:
    - "3306:3306"
  healthcheck:
    test: ["CMD-SHELL", "nc -z 127.0.0.1 3306 || exit 1"]
    interval: 1m30s
    timeout: 60s
    retries: 6

# Flyway is best for mysql schema migration history.
supermonk-flyway:
  container_name: supermonk-flyway
  image: boxfuse/flyway
  command: -url=jdbc:mysql://supermonk-mysql:3306/test?verifyServerCertificate=false&useSSL=true -schemas=test -user=root -password=P@ssw0rd migrate
  volumes:
   - "./sql:/flyway/sql"
  depends_on:
   - supermonk-mysql

mkdir ./sql vi ./sql/V1.1__Init.sql # 并粘贴到下面

CREATE TABLE IF NOT EXISTS test.USER (
id VARCHAR(64),
fname VARCHAR(256),
lname VARCHAR(256),
CONSTRAINT pk PRIMARY KEY (id));

保存并关闭

docker-compose up -d

等待 2 分钟

docker-compose run supermonk-flyway

参考:

    https://github.com/supermonk/webapp/tree/branch-1/docker/docker-database 感谢docker社区和mysql社区 docker-compose 日志 -f

【讨论】:

以上是关于将 Flyway 添加到 MySQL Docker 容器的主要内容,如果未能解决你的问题,请参考以下文章

无法将docker Spring-Boot应用程序与docker-compose中的mysql容器和flyway连接起来

使用 Docker 和 Jenkins 自动化 Flyway 迁移

将环境变量传递给 Docker 时,Flyway 迁移失败

在docker中运行flyway时连接被拒绝

Docker Flyway MySQL 8:客户端不支持服务器请求的身份验证协议。考虑升级 MariaDB 客户端

docker mysql initdb 脚本无法连接到数据库