Run Java application (Spring Boot + MySQL) by Docker compose - java

I'm trying to run an application on my local machine using Docker. I also want to run the application on a remote server. Without Docker in Intelij Idea everything works fine.
On the local machine I installed Docker. Created a Dockerfile and docker-compose.yml in the root folder of the project. Some errors I made in these files. I think, the communication as I understand it between database and my application is not working.
Maybe something wrong with MYSQL_ROOT_PASSWORD, because i really don't know what the password from MYSQL_ROOT_PASSWORD. I just know username and password. I run mysql by MySQLWorkbanch, i create here commection named "my_connection", there is user named "bestuser" and login "bestuser".
enter image description here
This is my structure of project
enter image description here
I tried combine ports, 8080:8080, 8081:8080, 3306:3306, 3307:3306.. But nothing.
MySQL image running well, but app image get alot of errors.
enter image description here
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/crm?useSSL=false
spring.datasource.username=bestuser
spring.datasource.password=bestuser
#spring.datasource.password=T#3;jbY7L#m6
spring.sql.init.mode=always
#spring.datasource.initialization-mode=always
#server.port=8080
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.jms.listener.acknowledge-mode=auto
info.name=CRM system. Accounting for sales, merchandise, payroll
info.description=CRM system. Accounting for sales, merchandise, payroll
info.author=Vitaliy Shvetsov
#spring.security.user.name=vitaliy
#spring.security.user.password=vitaliy
spring.view.prefix:/WEB-INF/
spring.view.suffix:.jsp
spring.view.view-names:views/*
#spring.thymeleaf.prefix=/webapp/WEB-INF/
#spring.thymeleaf.view-names:views/*
#management.endpoints.web.exposure.include=*
#spring.mvc.view.prefix: /WEB-INF/views/
#spring.mvc.view.suffix: .jsp
#spring.thymeleaf.suffix=.html
#spring.thymeleaf.prefix=classpath:/templates/
# ==============================================================
# = Keep the connection alive if idle for a long time (needed in production)
# ==============================================================
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# ==============================================================
# = Show or not log for each sql query
# ==============================================================
#spring.jpa.show-sql = true
# ==============================================================
# = Hibernate ddl auto (create, create-drop, update)
# ==============================================================
spring.jpa.hibernate.ddl-auto = update
# ==============================================================
# = The SQL dialect makes Hibernate generate better SQL for the chosen database
# ==============================================================
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.main.allow-circular-references=true
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: . # Use an image built from the specified dockerfile in the `springboot-app-server` directory.
dockerfile: Dockerfile
ports:
- "8081:8080" # Forward the exposed port 4000 on the container to port 4000 on the host machine
restart: always
depends_on:
- db # This service depends on mysql. Start that first.
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:mysql://localhost:3306/crm?useSSL=false
SPRING_DATASOURCE_USERNAME: bestuser
SPRING_DATASOURCE_PASSWORD: bestuser
# Database Service (Mysql)
db:
image: mysql:8.0
ports:
- "3307:3306"
restart: always
environment:
MYSQL_DATABASE: crm
MYSQL_USER: bestuser
MYSQL_PASSWORD: bestuser
MYSQL_ROOT_PASSWORD: bestuser
Dockerfile
# Use a Java base image
FROM openjdk:11
# Set the working directory
WORKDIR /
# Copy the application jar to the container
COPY target/crm-0.0.1-SNAPSHOT.war .
EXPOSE 8080
# Set the environment variables
ENV JAVA_OPTS=""
# Define the command to run the application
CMD ["java", "-jar", "crm-0.0.1-SNAPSHOT.war"]
Please help me figure out what I did wrong, thank you in advance!

Is the application referring to the right database ?
No. Check SPRING_DATASOURCE_URL in docker-compose file, localhost in the url points to your local db. Change it to db (service name you have given in the docker-compose file for mysql).

Related

unable to execute oracle data setup script from docker compose

I am trying to set up oracle data once my oracle container is up and running, below is my compose file:
version: '3'
services:
oracle:
image: absolutapps/oracle-12c-ee
container_name: oracle-docker
ports:
- 8080:8080
- 1521:1521
environment:
CASSANDRA_BROADCAST_ADDRESS: 127.0.0.1
ORACLE_ALLOW_REMOTE: "true"
volumes:
- ./scripts/oracle-init.sh:/oracle-init.sh
oracle-init.sh:
#!/usr/bin/env bash
echo "### SETUP EXECUTION! ###"
sqlplus -s "system/oracle#localhost:1521/orcl /scripts/init-oracle.sql"
echo "### SETUP EXECUTED! ###"
init-oracle.sql :
CREATE USER ot_consumer_tryout IDENTIFIED BY ot_consumer_tryout;
Can anyone help me what is wrong with above snippets. My docker container getting started but sql script does not execute ,here is the log from terminal:
oracle-docker | Running init scripts...
oracle-docker | Init scripts in /oracle.init.d/: Ignoring /oracle.init.d/*
oracle-docker |
oracle-docker | Done with scripts we are ready to go
Look at the volume you created
- ./scripts/oracle-init.sh:/oracle-init.sh
which means inside your container the file is in '/oracle-init.sh' but your
container might be expecting in a different location something with folder name oracle.init.d as per your container log.
oracle-init.sh is trying to run /scripts/init-oracle.sql , hope your image already has it otherwise you will have to mount it as well in compose file.

Java container cant connect to MYSQL container with docker-compose

I was given a multy-steps task and im stuck !!
im trying to connect my Java container to my MYSQL container,but im getting 503 ERROR
HTTP ERROR 503
Problem accessing /. Reason:
Service Unavailable
docker-compose file :
version: "3.3"
services:
lavagna:
build: .
ports:
- "8080:8080"
networks:
- back_net
depends_on:
- my_db
environment:
spring.datasource.url: "jdbc:mysql://my-db:3306/lavagna"
my_db:
image: mysql:5.7
ports:
- "3306:3306"
networks:
- back_net
volumes:
- $PWD/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: 123
MYSQL_USER: eyal
MYSQL_PASSWORD: 123
networks:
back_net:
driver: bridge
I got the JAVA src files,i just used maven localy to build it and use target for the Java Dockerfile
java app dockerfile :
FROM openjdk:8-jre-alpine
EXPOSE 8080
COPY ./target/. .
COPY ./entrypoint.sh .
ENV DB_DIALECT MYSQL
ENV DB_URL jdbc:mysql://localhost:3306/lavagna
ENV DB_USER "root"
ENV DB_PASS "123"
ENV SPRING_PROFILE dev
RUN apk update \
&& apk add ca-certificates \
&& update-ca-certificates && apk add openssl
RUN chmod 774 entrypoint.sh
ENTRYPOINT [ "./entrypoint.sh" ]
I think you need a combination of comments and answers given already. Your containers are on the same network, so it appears to boil down to configuration.
In your docker file update your DB_URL to:
ENV DB_URL jdbc:mysql://my_db:3306/lavagna
If you use localhost your container will loopback to itself, and never hit the network.
In your docker-compose yml file, you have a typo in the url, try updating to:
spring.datasource.url: "jdbc:mysql://my_db:3306/lavagna"
As an aside, using depends_on does not wait for the service to be ready. It simply dictates start order as the documentation states:
There are several things to be aware of when using depends_on:
depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready...

How to create multiple copies of a java application in Docker Compose file for ribbon load balancing?

How do you set up a docker-compose file for a spring application that has client-side load balancing with ribbon? Say I have in my application.properties file specify server.port=8000. I need to create 3 additional copies of the service that run on different ports than 8000 (exposing or not). How do you achieve this by not generate different images or use an orchestration tool?
This may solve your problem.
version: '3.5'
services:
myapp:
ports:
- "8000"
#port 8000 is mapped to a random portnumber
# deploy:
# mode: replicated
# replicas: 3
docker-compose up -d --scale myapp=3 myapp

Spring Boot + docker-compose + MySQL: Connection refused

I'm trying to set up a Spring Boot application that depends on a MySQL database called teste in docker-compose. After issuing docker-compose up, I'm getting:
Caused by: java.net.ConnectException: Connection refused (Connection refused)
I'm running on Linux Mint, my docker-compose version is 1.23.2, my Docker version is 18.09.0.
application.properties
# JPA PROPS
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.datasource.url=jdbc:mysql://db:3306/teste?useSSL=false&serverTimezone=UTC
spring.datasource.username=rafael
spring.datasource.password=password
spring.database.driverClassName =com.mysql.cj.jdbc.Driver
docker-compose.yml
version: '3.5'
services:
db:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=teste
- MYSQL_USER=rafael
- MYSQL_PASSWORD=password
ports:
- 3306:3306
web:
image: spring-mysql
depends_on:
- db
links:
- db
ports:
- 8080:8080
environment:
- DATABASE_HOST=db
- DATABASE_USER=rafael
- DATABASE_NAME=teste
- DATABASE_PORT=3306
and the Dockerfile
FROM openjdk:8
ADD target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Docker compose always starts and stops containers in dependency order, or sequential order in the file if not given. But docker-compose does not guarantee that it will wait till the dependency container is running. You can refer here for further details. So the problem here is that your database is not ready when your spring-mysql container tries to access the database. So, the recommended solution is you could use wait-for-it.sh or similar script to wrap your spring-mysql app starting ENTRYPOINT.
As example if you use wait-for-it.sh your ENTRYPOINT in your Dockerfile should change to following after copying above script to your project root:
ENTRYPOINT ["./wait-for-it.sh", "db:3306", "--", "java", "-jar", "app.jar"]
And two other important thing to consider here is:
Do not use links they are deprecated you should use user-defined network instead. All services in docker-compose file will be in single user-defined network if you don't explicitly define any network. So you just have to remove the links from compose file.
You don't need to publish the port for docker container if you only use it inside the user-defined network.
I was facing the same issue and in case you do not want to use any custom scripts, this can easily be resolved using health checks along with depends on. A sample using these is as follows:
services:
mysql-db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=vikas1234
- MYSQL_USER=vikas
ports:
- 3306:3306
restart: always
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
timeout: 20s
retries: 10
app:
image: shop-keeper
container_name: shop-keeper-app
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:8080
depends_on:
mysql-db:
condition: service_healthy
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db:3306/shopkeeper?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: vikas1234
Your config looks nice, I would just recommend:
Remove links: db. It has no value in user-defined bridge networking
Remove port exposing for db unless you want to connect from outside docker-compose - all ports are exposed automatically inside user-defined bridge network.
I think the problem is that database container takes more time to start than web. depends_on just controls the order, but does not guarantee you database readiness. If possible, set several connection attempts or put socket-wait procedure in your web container.

Host '172.23.0.9' is not allowed to connect to this MariaDB server

Hiho
Spring Settings
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url= jdbc:mysql://vetdb:3306/vetdb?useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.datasource.password=root
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.platform=mysql
spring.datasource.initialize=true
spring.jpa.show-sql=false
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jmx.default-domain=TierarztDatenController
endpoints.jmx.uniquie-names=true
Docker Compose
vetdb:
container_name: vetdb
hostname: vetdb
image: mariadb
restart: always
command: --default-authentication-plugin=mysql_native_password --innodb-flush-method=O_DSYNC --innodb-use-native-aio=0 --log_bin=ON
environment:
MYSQL_ROOT_PASSWORD: ${VET_DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${VET_DB_NAME}
MYSQL_PASSWORD: ${VET_DB_PASSWORD}
MYSQL_ROOT_HOST: '%'
volumes:
# - "${VET_DB_PATH}/mysql-conf:/etc/mysql/conf.d"
- "${VET_DB_PATH}:/var/lib/mysql"
- "${VET_DB_PATH}/mysql-log:/var/log/mysql"
.env
VET_DB_PATH=./dockervolumes/microservices/VET/db
VET_DB_NAME=vetdb
VET_DB_ROOT_PASSWORD=root
VET_DB_PASSWORD=root
Exception: `java.sql.SQLException: null, message from server: "Host '172.23.0.9' is not allowed to connect to this MariaDB server"`
i added MYSQL_ROOT_HOST: '%' to allow everyone to connect to the db but it didnt work
i tried to use a config-file.cnf containing bind-address = 0.0.0.0 but it didnt work
funny thing is everything worked well before i restarted the container today and i didnt change this service in 3 days
i tried see if name/password = root work
$ docker exec -it vetdb bash
root#vetdb:/# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
but root without password works (inside the container)
root#vetdb:/# mysql -u root
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 21
Server version: 10.3.9-MariaDB-1:10.3.9+maria~bionic-log mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
if i just remove spring.datasource.password=root
or set it to spring.datasource.password=
then it results in the same exception
what am i doing wrong?
i changed the environment variables to this
environment:
- "MYSQL_ROOT_PASSWORD=${VET_DB_ROOT_PASSWORD}"
- "MYSQL_DATABASE=${VET_DB_NAME}"
- "MYSQL_ROOT_HOST=%"
and deleted everything rerun it and it worked
docker-compose down
docker rm -f $(docker container ls -aq)
docker-compose rm -v
docker volume prune
docker system prune
rm dockerdockervolumes/ -rf
and it worked

Categories