springspring-bootdockerspring-properties

How to pass spring.datasource.data from docker as full path?


This is my docker-compose.yml file.

version: '3'
services:
  backend-service:
    build: ./backend-service
    volumes:
      - ./backend-service/database:/usr/lib/h2
    ports:
      - 8080:8080
    environment:
      - SPRING_DATASOURCE_URL=jdbc:h2:file:/usr/lib/h2/${DB}
      - SPRING_DATASOURCE_DRIVERCLASSNAME=org.h2.Driver
      - SPRING_DATASOURCE_USERNAME=SA
      - SPRING_DATASOURCE_PASSWORD=
      - SPRING_JPA_HIBERNATE_DDL-AUTO=update
      - SPRING_DATASOURCE_INITIALIZATION-MODE=always
      - SPRING_DATASOURCE_DATA=${DATA}
  frontend-service:
    build: ./frontend-service
    ports:
      - 3000:80
    depends_on:
      - backend-service

I want to pass a full system path to sql file like /usr/tmp/someSql.sql that should be executed when server is starting. I could use default data.sql but problem is that I will have multiple servers that will have different initial/update data so I don't want to put multiple files containing business data inside jar just to make it visible for spring boot and docker.

But even then if I put all the files inside resources folder and I have them in jar and use someData.sql as value it does not see that file during startup.

I also don't want to create endpoint for user to insert their own sql's for obvious reasons.

I already tried file:/usr/tmp/someSql.sql but I still get an error that file could not be found.


Solution

  • Okay a little late answer but I hope this will help someone in the future.

    TL:DR version: I needed to add volume for scripts folder so my docker-compose.yml was extended by this:

    volumes:
      ...
      - ./_init_scripts:/usr/init-data
    

    And then point to it using SPRING_DATASOURCE_DATA:

      - SPRING_DATASOURCE_DATA=file:/usr/init-data/${DATA}
    

    I am using .env file to store my configuration but it should work as long as scripts are present on docker enviroment and path is valid. eg.

      - SPRING_DATASOURCE_DATA=file:/usr/some/path/to/file/mySqlFile.sql
    

    This was **TL:DR version ** now full story if someone would like to analyse it a little better:

    I have 'docker project' folder structure like this:

    DockerProjectRoot
      \_ _databases
       |  \_ myDatabase.mv.db
       |
       |_ _enviroments
       |  \_ env.myenv
       |
       |_ _init_scripts
       |  \_ someData.sql
       |
       |_ backend-service
       |  |_ ...
       |  \_ Dockerfile
       |
       |_ frontend-service
       |  |_ ...
       |  \_ Dockerfile
       |
       |_ docker-compose.yml
    

    Directories:

    contents of env.myenv are:

    DB=myDatabase
    DATA=someData.sql
    

    And contents of docker-compose.yml

    version: '3'
    services:
      backend-service:
        build: ./backend-service
        volumes:
          - ./_databases:/usr/lib/h2
          - ./_init_scripts:/usr/init-data
        ports:
          - 8080:8080
        environment:
          - SPRING_DATASOURCE_URL=jdbc:h2:file:/usr/lib/h2/${DB}
          - SPRING_DATASOURCE_DRIVERCLASSNAME=org.h2.Driver
          - SPRING_DATASOURCE_USERNAME=SA
          - SPRING_DATASOURCE_PASSWORD=
          - SPRING_JPA_HIBERNATE_DDL-AUTO=update
          - SPRING_DATASOURCE_INITIALIZATION-MODE=always
          - SPRING_DATASOURCE_DATA=file:/usr/init-data/${DATA}
      frontend-service:
        build: ./frontend-service
        ports:
          - 3000:80
        depends_on:
          - backend-service
    

    So when running I was running docker-compose --env-file ._enviroments/.env.myenv up it would use enviromental variables: DB and DATA to point to database location and initial scritps. So my enviroment dynamic valuse would be:

    So in the end if I wanted to add new init-scripts I only need to add new .sql files to _init_scripts folder and update or create new .env file.