Home > Software engineering >  How to share database schemas in DockerCompose file?
How to share database schemas in DockerCompose file?

Time:06-06

I`m learning Docker. I build my image from Dockerfile in the counter app. And I am using mysql as a database. DockerCompose file is using one db and two container from the same app image. Mysql db has two different schemas. My goal is to use separate app services with different ports(e.g. 9000 and 9001), and they have own schemas. When I call localhost:9000/index it shows first counter and when I call localhost:9000/index it shows second counter.

But problem is that both of them use first schema, and so result being same counter. How can I isolate schemas?

Compose-file ->

    version: '3.1'

services:

  mysql:
    image: mysql
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - mysql_data:/var/lib/mysql


  hello-docker:
    image: hello-docker:0.0.2
    restart: always
    environment:
      DB_CONNECTION_IP: mysql
      DB_SCHEMA_NAME: hello-counter
    ports:
        - "9000:9000"
    volumes:
        - mysql_data:/var/lib/mysql

  hello-docker2:
    image: hello-docker:0.0.2
    restart: always
    environment:
      DB_CONNECTION_IP: mysql
      DB_SCHEMA_NAME: hello_counter2
    ports:
      - "9001:9000"

volumes:
  mysql_data:

application.yaml ->

spring:
  datasource:
    url: &connectionUrl jdbc:mysql://${DB_CONNECTION_IP:localhost}:${DB_CONNECTION_PORT:3306}/${DB_SCHEMA_NAME}?allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate.ddl-auto: validate
    generate-ddl: true
    show-sql: true
    properties.hibernate.format_sql: true


server:
  port: 9000

CodePudding user response:

It is better having separate docker compose for each application and its database.

And if you want only one docker compose for both applications, you can define two separate services for mysql with different exposed schemas and ports and refer to each of them in your applications.

This would be same as your application that you have defined two services for it.

In addition here:

When I call localhost:9000/index it shows first counter and when I call localhost:9000/index it shows second counter.

You referred to same application, It seems you mean:

localhost:9000/index

and

localhost:9001/index

CodePudding user response:

The easiest way to accomplish this is to run a separate database per service. You can put these in a single Compose file if you'd like. (Or as @EskandarAbedini suggests in their answer you can run a separate Compose file per service, though this can get unwieldy if you have a significant stack based on largely the same code base.)

version: '3.8'
services:
  mysql1:
    image: mysql
    volumes:
      - mysql_data1:/var/lib/mysql
  hello-docker1:
    image: hello-docker:0.0.2
    environment:
      DB_CONNECTION_IP: mysql1
    ports:
        - "9000:9000"

  mysql2:
    image: mysql
    volumes:
      - mysql_data2:/var/lib/mysql
  hello-docker2:
    image: hello-docker:0.0.2
    environment:
      DB_CONNECTION_IP: mysql2
    ports:
        - "9001:9000"

volumes:
  mysql_data1:
  mysql_data2:

Note that both pairs of containers run the same images, but the MySQL containers have separated storage, and the application containers publish different host ports for the same container port. You'd have to separately run tasks like database migration for each container.

In principle nothing stops you from running multiple databases or schemata in a single MySQL container, provided you execute the correct SQL CREATE DATABASE call. You'd need a custom SQL init script to set this up; you couldn't do it with just environment-variable configuration.

  • Related