Flyway Container, MySQL and SSL/mTLS


Flyway is a handy utility to manage database schema migrations. Very similar to the schema migration mechanism in Ruby on Rails or Django, but Flyway is a standalone tool. So it’s best suited for some project which doesn’t have database schema management yet.

I needed to use Flyway for a project I worked with, the only catch is that the MySQL database requires SSL encrypted connection. I had a read on the official SSL support page and understood how it works with SSL. I ran the schema migrations in a CI pipeline which means running Flyway in a Docker container makes perfect sense. However there’s no out-of-box SSL support from Flyway’s office Docker document.

Then I decided to give it a try.

I tried to automate things as much as possible and came out with a solution which I thought most straight-forward: supply 3 SSL certs to the container(ENVs for path-to-file and volume mount for read access) and it should just work. Here’s a copy of the entrypoint script I did for the Flyway container

#!/bin/bash
set -euo pipefail

# ref. https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-using-ssl.html
# This script check ENVs and generate the java truststore if needed
if [[ -v CA_CERT_FILE ]] && [[ -v CLIENT_CERT_FILE ]] && [[ -v CLIENT_KEY_FILE ]]; then
    # the password is only used inside the container
    export STORE_PASS=playground
    export JAVA_ARGS="-Djavax.net.ssl.trustStore=/flyway/flyway-truststore -Djavax.net.ssl.trustStorePassword=${STORE_PASS} -Djavax.net.ssl.keyStore=/flyway/flyway-keystore -Djavax.net.ssl.keyStorePassword=${STORE_PASS}"

    echo "Generating a Java keystore..."
    # $CA_CERT_FILE, $CLIENT_KEY_FILE and $CLIENT_CERT_FILE are the paths to SSL certs for mysql client
    # for example
    # CA_CERT_FILE=/work/${CERTS}/ca.pem
    # CLIENT_KEY_FILE=/work/${CERTS}/client-key.pem
    # CLIENT_CERT_FILE=/work/${CERTS}/client-cert.pem

    # trust store for server authentication
    keytool -keystore flyway-truststore -storepass:env STORE_PASS -noprompt -trustcacerts -importcert -alias mysqlclient -file $CA_CERT_FILE

    # key store for client authentication
    openssl pkcs12 -export -in ${CLIENT_CERT_FILE} -inkey ${CLIENT_KEY_FILE} -out client.p12 -name mysql-client -passout pass:${STORE_PASS}
    keytool -importkeystore -deststorepass ${STORE_PASS} -destkeystore flyway-keystore -srckeystore client.p12 -srcstoretype PKCS12 -srcstorepass ${STORE_PASS} -alias mysql-client
fi
flyway $@

This is already tested in my project and you’re welcome to use pull it from DockerHub:

docker pull raynix/flyway:8.5.5

I’ve submitted this back to Flyway as a pull request. Hope it can be accepted.

Ref. MySQL Connector/J SSL Support

🙂

,