I am trying to dockerize a spring boot web app with mongodb backend.
I run mongo and map it to host with following command:
docker run -p27017:27017 --name my-mongodb-container -d mongo:latest
I have built a jar with spring boot code and am able to run it successfully. It inserts and prints some data.
Now I dockerize this jar with the following Dockerfile
FROM adoptopenjdk/openjdk11
EXPOSE 8080
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
I run the docker container as:
docker run -p 4444:8080 --name mydoctest --link my-mongodb-container doc40
The instance comes up, tries to connect to mongo an fails. But the app get loaded as I have another url that functions properly. However, it just returns hard coded data.
The error that i see in the console
2021-09-23 17:13:02.725 INFO 1 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {
hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2021-09-23 17:13:02.824 INFO 1 --- [localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread whi
le connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-4.2.3.jar!/:na]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:143) ~[mongodb-driver-cor
e-4.2.3.jar!/:na]
Any inputs are much appriciated
The problem begins with your connectionString to mongoDb and the architecture of containers
You are trying to connect to localhost:27017 from the java container. In the java container, Mongo is not running. Instead is running in another container. You have to change your connection string to point to my-mongodb-container:27017
I'll recommend using docker networks instead of --link since it is deprecated
https://docs.docker.com/network/links/
I'll give you a quick example
docker network create -d brigde app-network
docker run -p27017:27017 --name my-mongodb-container -d mongo:latest
docker network connect app-network my-mongodb-container
docker run -p 4444:8080 --name mydoctest doc40
docker network connect app-network mydoctest
(I have not tested it, let me know if there is any mistake)
Depends on the Mongo driver you are using to you have to set 2 different variables to change your connection string as stated in Spring Boot and how to configure connection details to MongoDB?
spring.data.mongodb.uri=mongodb://user:secret#mongo1.example.com:12345
spring.data.mongodb.host=127.0.0.1
So you can create the container respectively using
docker run -p 4444:8080 --name mydoctest -e SPRING_DATA_MONGODB_URI=mongodb://my-mongodb-container:27017 doc40
or
docker run -p 4444:8080 --name mydoctest -e SPRING_DATA_MONGODB_HOST=my-mongodb-container doc40
Finally got it to work.
The only change I did was to connect the instance to preferred n/w on startup.
docker run -p27017:27017 --name my-mongodb-container --network=app-network -d mongo:latest
docker run -p 4444:8080 --name mydoctest --network=app-network -e SPRING_DATA_MONGODB_URI=mongodb://my-mongodb-container:27017/test doc40
I was trying to run the container and then add it to a n/w.
What's the IP address of your Docker host machine?
Your app tries to connect to Mongo using localhost. Depending on what Docker installation you are using (taking the problem into account I assume Docker Toolbox), localhost won't work. You might try the IP address of Docker host instead of localhost. Most of the times, the IP is 192.168.99.100 but could be something else as well.
You can find the address by executing docker-machine ip using Docker command line.
Related
On Windows 10, with IntelliJ Idea I built a Spring Boot application (with the help of Bootify.io).
That application connects to a Postgres Database that resides in Docker (container-postgres-1) called Bootifytwo.
With the intention of playing and practicing with GraalVM, I downloaded a Docker image from Oracle.
From the corresponding GraalVM container (container-graalvm-1) I have been able to generate the target/bootifytwo executable.
But when I try to run it, it gives me a database connection error.
I put below all the steps that I executed, and after some images.
(Note the use of a network for intercommunication between the containers; as well as the use of volumes for each of the 2 containers).
Help with resolution would be appreciated.
Copy folder C:\CODIGO\IDEA_PROJECTS\bootifytwo to C:\Volumenes-Docker\vol-graalvm-1\bootifytwo
docker network create red-postgres-graalvm-1
docker run --name contenedor-postgres-1 -p 5433:5432 --network red-postgres-graalvm-1 -v "C:\Volumenes-Docker\vol-postgres-1:/var/lib/postgresql/data" -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=password -e POSTGRES_DB=bootifytwo -d postgres:13.9-alpine3.17
docker run --name contenedor-graalvm-1 -it --network=red-postgres-graalvm-1 -v "C:\Volumenes-Docker\vol-graalvm-1:/app" container-registry.oracle.com/graalvm/community:ol8-java17-22.3.0-b1 bash
gu install native-image
cd bootifytwo
. ./mvnw native:compile -Pnative
docker start contenedor-graalvm-1
docker exec -it contenedor-graalvm-1 bash
./target/bootifytwo
The postgresql db runs in an other docker than your application. So you can't connect with localhost.
Change your setup to connect to contenedor-postgres-1
I'm trying to dockerize MySQL and Spring Boot application however whenever I try to run my docker container and connect my docker image to the network the container automatically stops running.I'm new to docker so any help well is appreciated.
C:\Users\shawn>docker run --name mysqldb --network springboot -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=passion -e MYSQL_USER=root -e MYSQL_PASSWORD=password -d mysql:5.7
54d2a7c0ec819ec5e8e550ad61f55e8aabc7783ffad12d1ae04e79e7925d8064
C:\Users\shawn>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
I've tried using docker starting and using docker run with a specific port but still getting the same error.
I have spring boot project with one page - Hello word!
JAR app perfectly works in a docker container.
But in my host computer docker does not want run app. Page not available.
docker ps say:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4b34df7e3986 quality-serv "java -jar quality-s…" 21 hours ago Up 20 hours 0.0.0.0:8080->8080/tcp quality-service_con
But netstat (admin) does not find listeners on same port
App work only in the container, not in a personal computer.
I try many dif commands:
docker run -p 8080:8080 -d...
docker run --expose 9990 -p 9990:9990 -p 8080:8080 -it
docker run -d --net=host -P
docker run -it -d -p
They did not help.
Run yaml (docker-compose) with image description did not help too...
First make sure, when creating the container, the Dockerfile was exposing port 8080 EXPOSE 8080.
Then, if your application runs on port 8080, docker run -p 8080:8080 should be the command. Don't add -d by now, so you don't run detached mode and can see the logs.
I am new in docker and I try to connect to a mysql container from the local machine (host).
I pulled the latest version of mysql with:
docker pull mysql/mysql-server:latest
and started this (and the myadmin container with the following:
docker run --name mysql1 -e MYSQL_ROOT_PASSWORD=root -d mysql --default-authentication-plugin=mysql_native_password -P 3306 -h localhost
docker run --name myadmin -d --link mysql1:db -p 8081:80 phpmyadmin/phpmyadmin
I can access the phpmyadmin on my local browser (with localhost:8081) and I created a DB named 'userDB'.
Here you can see the docker check:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03126272c0e3 phpmyadmin/phpmyadmin "/run.sh supervisord…" 7 minutes ago Up 7 minutes 9000/tcp, 0.0.0.0:8081->80/tcp myadmin
c8d032921d7c mysql "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 3306/tcp, 33060/tcp mysql1
On my local JavaEE application (running on an GlassFish Webserver) I try to connect this mysql database with the following commands:
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/userDB", "root", "root");
return con;
} catch (Exception ex) {
System.out.println("Database.getConnection() Error -->"
+ ex.getMessage());
return null;
}
and got the following exception:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
What mistake do I do? How can i connect my Java application with the mysql docker container?
The first problem was that the port mapping must be one of the first parameters in the run statement of docker. This is the final run statement:
docker run -p 3306:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=root -d mysql --default-authentication-plugin=mysql_native_password -h 127.0.0.1
The next problem was to update the JDBC driver in maven (to the newest).
And last but not least: The useSSL param was set to false (not necessary on the local machine).
You need to setup Docker networking for that stuff to to work together. I don't review docker-compose here, you can do it on your own, but if using generic docker CLI, it will look like following:
First you create user-defined bridge network
docker network create foo
Then you start your containers attached to this net
docker run --network=foo --name mysql1 -e MYSQL_ROOT_PASSWORD=root -d mysql --default-authentication-plugin=mysql_native_password -P 3306 -h "0.0.0.0"
docker run --network=foo --name myadmin -p 8081:80 phpmyadmin/phpmyadmin
Notice: I changed localhost to 0.0.0.0 to allow remote connections and removed link argument - it is oboslete.
Now to connect between services you use their names and generic ports, like mysql1:3306 and myadmin:80.
To connect to services from host you use localhost and exposed ports: localhost:1234 and localhost:8081 appropriately.
I created a first couchbase server with the following command:
docker run -d --name db1 -p 8091-8094:8091-8094 -p 11210:11210 couchbase
The second server I created without the parameters for port because otherwise docker can't deploy the container:
docker run -d --name db2 couchbase
Now I can access the web console of the first container and create a cluster with the second container.
The problem is that I can't connect to the created cluster in Java because port 11210 is not published for the second container. I'm always getting a TimeoutException. How can I solve this?
You will have to expose the ports for the second container too, just as you did in first container (those "parameters" are port mappings).
Most likely, you were unable to run the second container with parameters because you tried mapping the same ports as you did in first container; aka, you tried this command:
docker run -d --name db2 -p 8091-8094:8091-8094 -p 11210:11210 couchbase
This wouldn't work because you cannot use ports that are already being used. So try mapping to different set of ports. For example:
docker run -d --name db2 -p 9091-9094:8091-8094 -p 11210:11210 couchbase
Notice how I am now using 9091-9094 instead of 8091-8094. The above command means: map ports 8091-8094 from the container to ports 9091-9094 in the host. Any requests sent to 9091-9094on host will be forwarded to 8091-8094 inside container automatically.
And then you can connect to your second container by specifying the new ports (9091-9094).
I suggest you to check the docker basics, especially the documentation for port mapping.
Finally I could solve the problem by setting up virtual machines for the servers with vagrants. This way it is no problem to have multiple Couchbase instances with the same ports.