Reputation: 807
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?
Upvotes: 1
Views: 859
Reputation: 1386
I suggest you follow the guide I posted on medium which uses the official Mybatis Migrations docker hub image
It gives you an 'out of the box' docker experience and allows you to target different environments (as mentioned in my post).
tl;dr
https://hub.docker.com/r/mybatis/migrations
for your base image.
.gitlab-ci.yml
from the post, you can add the action (eg. migrate up
) as your docker image entrypoint or command.--env
eg.
docker run \
--rm \
--env "MIGRATIONS_URL=jdbc:mysql://$(hostname):3306/mb_migration" \
-v $PWD:/migration \
-it mybatis/migrations status
Upvotes: 1
Reputation: 15861
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.
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.ServletContextListener
if you deploy a web application.
Here's how it may look like:
new UpOperation().operate(
new DataSourceConnectionProvider(dataSource),
new JavaMigrationLoader("mycompany.migration.script"), null, null);
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).
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 migrate
script that is part of the distribution archive.
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 --env
option for docker service create
or docker run
. The variable passed this way can be accessed as a regular environment variable in linux in your start.sh
.
Upvotes: 1