Home > Back-end >  Elegent way to get dockerized API to connect with dockerized Mysql Database and create schema automa
Elegent way to get dockerized API to connect with dockerized Mysql Database and create schema automa

Time:08-24

Problem: 2 services, both running in separate docker containers

  • Mysql DB (container name: mysqldb, network: my-custom-network)
  • Api service that supports retrieving and writing data to Mysql service

Now I create a custom docker network my-custom-network with driver: bridge and connect both services to it.

Intention: Also I set spring.jpa.hibernate.ddl-auto=update so that when the api service is started and it connects with the DB first time it automatically creates the table. But this doesn't happen.

What happens is this:

  • Using the mysql image I start the DB container, setting all required passwords and users as environment variables. So this is container is up successfully.
  • Now when I try to build the image for my API server using the docker file, then while building it tries to connect with the database and it says HostNotFoundException: mysqldb not known. This is probably because mysql container is running on my custom network but while building the image docker doesn't know which network to use (I am not sure of this. So it fails.

Workaround that I did

  • set spring.jpa.hibernate.ddl-auto to none so that while building the api image, docker does not try to contact the mysql service.
  • Then image is successfully build. I run the api container on same my-custom-network and the container is up successfully.
  • Now when I try to write data to DB, an exception occurs saying dbname.tablename doesn't exists. Which means tables are not automatically creating when making first connection to the database as spring.jpa.hibernate.ddl-auto is set to none.

What I want

I want some way that tables etc are created automatically and the docker image also builds successfully. But I don't know how to do it and hence this question.

CodePudding user response:

Building an image and running a container are 2 very different things.

At build time (when you build an image based on a Dockerfile for example) there is no network setup to be done because there is nothing running. Only Docker building an image. So when you build your java image, only create the jar and that's it.

For running the containers I suggest using docker-compose. It makes your life a lot easier. Your java container should use something like a wait-for.sh script to wait for the database to become available. There are tons of examples on internet for such scripts. If you can't find such a script then for now just manually start the database container and wait for it to finish starting and then start the other container.

The main point is: the java application creates the data model at runtime (when the container starts) and not at build time (when the image is created).

CodePudding user response:

My guess is that you have a test failing at build time because of the property. If that is correct, you can just add a properties with spring.jpa.hibernate.ddl-auto=none in src/test/resources.

Alternative is to add a properties file in the container beside the jar with spring.jpa.hibernate.ddl-auto=update after building it with none. It should be read at runtime and override the one in the jar.

  • Related