cajund
cajund

Reputation: 141

Adding Flyway to a MySQL Docker Container

I'm building an derivative to this Docker container for mysql (using it as a starting point): https://github.com/docker-library/mysql

I've amended the Dockerfile to add in Flyway. Everything is set up to edit the config file to connect to the local DB instance, etc. The intent is to call this command from inside the https://github.com/docker-library/mysql/blob/master/5.7/docker-entrypoint.sh file (which runs as the ENTRYPOINT) around line 186:

flyway migrate

I get a connection refused when this is run from inside the shell script:

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

But, if I remove the command from the shell script, rebuild and log in to the container, and run the same command manually, it works with no problems.

I suspect that there may be some differences with how the script connects to the DB to do its thing (it has a built in SQL "runner"), but I can't seem to hunt it down. The container restarts the server during the process, which is what may be the difference here.

Since this container is intended for development, one alternative (a work-around, really) is to use the built in SQL "runner" for this container, using the filename format that Flyway expects, then use Flyway to manage the production DB's versions.

Thanks in advance for any help.

Upvotes: 5

Views: 8616

Answers (2)

supermonk
supermonk

Reputation: 385

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 # and paste below

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

save and close

docker-compose up -d

wait for 2 minutes

docker-compose run supermonk-flyway

Ref :

  1. https://github.com/supermonk/webapp/tree/branch-1/docker/docker-database
  2. Thanks to docker community and mysql community
  3. docker-compose logs -f

Upvotes: 1

Grzesiek
Grzesiek

Reputation: 715

I mean it's the good way to start from the ready image (for start).

  • You may start from image docker "mysql"

    FROM mysql
    

    If you start the finished image - when creating new version your docker then will only update the difference.

  • Next, step you may install java and net-tools

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

    ENV MYSQL_DATABASE=mydb
    ENV MYSQL_ROOT_PASSWORD=root
    
  • Add flyway

    ADD flyway /opt/flyway
    
  • Add migrations

    ADD sql /opt/flyway/sql
    
  • Add config flyway

    ADD config /opt/flyway/conf
    
  • Add script to start

    ADD start /root/start.sh
    
  • Check start mysql

    RUN netstat -ntlp
    
  • Check java version

    RUN java -version
    

Example file: /opt/flyway/conf/flyway.conf

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

Example file: start.sh

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

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

Flyway documentation

I mean that you in next step may use flyway as service:

For example:

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

etc ...

Upvotes: 1

Related Questions