10

I have a project that runs when ./entrypoint.sh or docker-compose up is run from the root directory of project and generates the swagger API interface, but the calls return entry response no data.

If I run with MySQL on localhost without docker, works perfectly fine. How do I load the data?

entrypoint.sh

#!/bin/bash

docker network create turingmysql
docker container run -p  3306:3306 --name mysqldb --network turingmysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=tshirtshop -d mysql:5.7
docker-compose build
docker-compose up

DockerFile

FROM mysql:5.7

ADD ./database/tshirtshop.sql /docker-entrypoint-initdb.d
#### Stage 1: Build the application
FROM openjdk:8-jdk-alpine as build

# Set the current working directory inside the image
WORKDIR /app

# Copy maven executable to the image
COPY mvnw .
COPY .mvn .mvn

# Copy the pom.xml file
COPY pom.xml .

# Build all the dependencies in preparation to go offline. 
# This is a separate step so the dependencies will be cached unless 
# the pom.xml file has changed.
RUN ./mvnw dependency:go-offline -B

# Copy the project source
COPY src src


# Package the application
RUN ./mvnw package -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

#### Stage 2: A minimal docker image with command to run the app 
FROM openjdk:8-jre-alpine

ARG DEPENDENCY=/app/target/dependency

# Copy project dependencies from the build stage
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app

ENTRYPOINT ["java","-cp","app:app/lib/*","com.turing.ecommerce.TuringApplication"]

docker-compose.yml

version: '3.7'

# Define services
services:
  # App backend service
  app-server:
    # Configuration for building the docker image for the backend service
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
    restart: always
    depends_on: 
      - mysqldb # This service depends on mysql. Start that first.
    environment: # Pass environment variables to the service
      SPRING_DATASOURCE_URL: jdbc:mysql://mysqldb:3306/tshirtshop?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: root   
    networks: # Networks to join (Services on the same network can communicate with each other using their name)
      - turingmysql

      # Database Service (Mysql)
  mysqldb:
    image: mysql:5.7
    ports:
      - "3306:3306"
    restart: always

    environment:
      MYSQL_DATABASE: tshirtshop
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - db-data:/var/lib/mysql

    networks:
      - turingmysql  


# Volumes
volumes:
  db-data:

# Networks to be created to facilitate communication between containers
networks:
  turingmysql:
4
  • Well, is tshirtshop.sql inserting any values to the database? Is your application properly configured to query the database and not return empty results? Commented Sep 27, 2019 at 1:30
  • Yes, lots of create table and insert statements. Commented Sep 27, 2019 at 1:32
  • Have you inserted log statements into the API to verify things should be returned? Commented Sep 27, 2019 at 1:32
  • If I run without docker, the API calls return data. I have deployed on heroku where I created the database separately and deployed and it works but I am required to dockerize it. Commented Sep 27, 2019 at 1:37

3 Answers 3

3

Do you have two Dockerfiles? Looks like you built your own MySQL container?

Otherwise, these shouldn't be part of your Java multi-stage build

FROM mysql:5.7

ADD ./database/tshirtshop.sql /docker-entrypoint-initdb.d

Assuming that you did build a separate image for mysql, in the Docker-Compose, you're not using it, as you're still referring to image: mysql:5.7

Rather than building your own, you should mount the SQL script into it

For example

  mysqldb:
    image: mysql:5.7
    ...
    volumes:
      - db-data:/var/lib/mysql
      - ./database/tshirtshop.sql:/docker-entrypoint-initdb.d/0_init.sql

Then, forget the Java service for a minute and use MySQL workbench or the mysql CLI to verify that data is actually there. Once you do, then startup the API

Sign up to request clarification or add additional context in comments.

4 Comments

I have only one dockerfile. I have removed those two lines and tried to mount, no respite.
If you do docker-compose logs mysqldb, do you see it running the script?
docker-compose rm -sf mysqldb, then start it up again
Also, you should remove docker container run from your script since you are starting mysql in the docker-compose up command
2

If you copying sql scipt already to docker build then you do not need to mapped it again in the docker-compose, if you have docker-compose then you do not the bash script single command docker-compose up --build will do the job.

So modify your docker-compose as per your Dockerfile.

Dockerfile

FROM mysql

ADD init.sql /docker-entrypoint-initdb.d

docker-compose

version: '3.7'

services:
  # App backend service
  app-server:
    # Configuration for building the docker image for the backend service
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
    restart: always
    depends_on: 
      - mysqldb # This service depends on mysql. Start that first.
    environment: # Pass environment variables to the service
      SPRING_DATASOURCE_URL: jdbc:mysql://mysqldb:3306/tshirtshop?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: root   
    networks: # Networks to join (Services on the same network can communicate with each other using container name)
      - uringmysql

      # Database Service (Mysql)

  mysql:
    build: .
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: appdata
      MYSQL_USER: test
      MYSQL_PASSWORD: root123
    volumes:
      - db-data:/var/lib/mysql
    tty: true
# Volumes
volumes:
  db-data:

# Networks to be created to facilitate communication between containers
networks:
  turingmysql:

Now just run

docker-compose up --build

this will build and up the container and you will not need to mapped the host init script, as it already in Docker image.

The directory structure will look like

enter image description here

Now you application will able to access DB using jdbc:mysql://mysqldb:3306/tshirtshop? this endpoint as both are in same network and can refer eacher other using name.

Comments

2

Thank you cricket_007 and Adii for the responses. They put me in the right direction. I want to document my experience and how the issue was resolved. New to dockerization so I was learning by practice. For anyone new to dockerization and having same issues in Spring Boot, MySQL and docker, this would surely help

First, my entrypoint.sh changed below. The docker-compose down is for restarts.

     #!/bin/bash

docker-compose down -v
docker-compose up --build

Second, I had to use an existing mysql image instead of building one.

version: '3.7'

# Define services
services:
  # App backend service
  app-server:
    # Configuration for building the docker image for the backend service
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
    restart: always
    depends_on: 
      - mysql # This service depends on mysql. Start that first.
    environment: # Pass environment variables to the service
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/tshirtshop?useSSL=false&allowPublicKeyRetrieval=true&useLegacyDatetimeCode=false&serverTimezone=UTC
      SPRING_DATASOURCE_USERNAME: turing
      SPRING_DATASOURCE_PASSWORD: pass  
    networks: # Networks to join (Services on the same network can communicate with each other using their name)
      - turingmysql

      # Database Service (Mysql)
  mysql:
    image: mysql/mysql-server
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: tshirtshop
      MYSQL_USER: turing
      MYSQL_PASSWORD: pass


    volumes:
      - db-data:/var/lib/mysql
      - ./database:/docker-entrypoint-initdb.d
    tty: true
    networks: # Networks to join (Services on the same network can communicate with each other using their name)
      - turingmysql

# Volumes
volumes:
  db-data:

 # Networks to be created to facilitate communication between containers
networks:
  turingmysql:
    driver: bridge

Needed to specify that the network is a bridge. My sql file was mounted from a folder relative to docker-compose.yml. Also had to add allowPublicKeyRetrieval=true to my jdbc url. Created a user to access the database tshirtshop.

And here is the Dockerfile.

#### Stage 1: Build the application
FROM openjdk:8-jdk-alpine as build

# Set the current working directory inside the image
WORKDIR /app

# Copy maven executable to the image
COPY mvnw .
COPY .mvn .mvn

# Copy the pom.xml file
COPY pom.xml .

# Build all the dependencies in preparation to go offline. 
# This is a separate step so the dependencies will be cached unless 
# the pom.xml file has changed.
RUN ./mvnw dependency:go-offline -B

# Copy the project source
COPY src src


# Package the application
RUN ./mvnw package -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

#### Stage 2: A minimal docker image with command to run the app 
FROM openjdk:8-jre-alpine

ARG DEPENDENCY=/app/target/dependency

# Copy project dependencies from the build stage
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app

ENTRYPOINT ["java","-cp","app:app/lib/*","com.turing.ecommerce.TuringApplication"]

to run, from root directory of project ./entrypoint.sh on mac and the rest is history.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.