I'm trying to figure out how and when to run the mybatis schema migrations from a Docker container deployed inside a Docker Swarm. I mean: I need the most correct way to do that.
At the moment We build a Docker container from a Dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y \
openjdk-11-jre \
openjdk-11-jdk \
maven
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
COPY start.sh start.sh
RUN chmod +x start.sh
ENTRYPOINT ["/bin/sh","start.sh"]
then the start.sh script contains
mvn resources:resources migration:up -Dmigration.path="target/classes/migrations" -Dmigration.env=development -Papply_migrations
java -jar /app.jar
But in this way we have to build an image from Ubuntu, install Maven and lunch the migrations with the environment "hardcoded" into the start.sh file, so We need different files from different envs.
What do you think is the most correct method to run these scheme migrations during the build/deployment process?
Thanks in advance.
EDIT: I've found useful the solution to use the mybatis migration docker image found on DockerHub and posted by @h3adache but still to have an Issue trying to execute it on a DockerSwarm: the issue is related to the volume mounted between the host folder with mybatis migrations files and the container folder "/migration"
-v $PWD:/migration
My docker-compose.yml is
mybatis-migration:
image: mybatis/migrations
volumes:
- ./mybatis-migrations:/migration
command:
- up
It works fine locally against a dockerized MySQL but fails during the deploy with a GitLab pipeline.
The ./mybatis-migrations folder is, obviously, on my localhost when I checkout the code and It is in the build path of the GitLab repository when the GitLab runner builds everything but is not on the DockerSwarm host so it's unable to find that directory.
This is the error message:
invalid mount config for type "bind": bind source path does not exist
How can I fix this?
Let's look to the problem with maven first. I understand that you (quite rightfully) don't want to install maven (and probably JDK).
There are two ways to achieve what you need.
Runtime Schema Upgrade
You can run migration right from your application when it starts. It may be run from the main method or from the custom
javax.servlet.ServletContextListenerif you deploy a web application.Here's how it may look like:
Check the documentation with details how to configure this.
This would require to only include mybatis migration to the dependencies of your project (which you might already have).
Using mybatis migrations library directly
The other way is to run mybaits migration directly that is without maven. This can be done by installing the library inside docker as described in the documentation. Note that you only need the libraryr itself and JRE, so no JDK and maven is required.
Then you can run migration using
migratescript that is part of the distribution archive.Environment
In order to fix this you can pass that as a parameter to the docker container that runs
start.sh. One option is to use environment variable via--envoption fordocker service createordocker run. The variable passed this way can be accessed as a regular environment variable in linux in yourstart.sh.