I'm attempting to create a Docker container using quay.io/keycloak/keycloak:20.0.1 image the that will connect to a Postgres Database listening on IPv6. Working with a downloaded zip of Keycloak, the application is able to make a connection if I export JAVA_OPTS as follows:
$ export JAVA_OPTS=-Djava.net.preferIPv6Addresses=true
If I attempt to do the same within Docker, however, I receive java.net.UnknownHostException. I've tried both the hostname which should resolve, as well as the IP that is behind the hostname.
If I try to use the IP within the Docker container, I receive:
Caused by: java.net.SocketException: Protocol family unavailable
I'm not sure how to proceed from here, thanks!
UPDATE: This seems to extend beyond just Keycloak, I’ve attempted connecting to the same DB via container using both Spring Boot and Quarkus and receive the same error.
Related
I am running a spring boot application in docker tool box. The application runs on port 8380 as set in application properties. However, when i run its image in a container, I am publishing with ports 8380:8082. When i access it from ip 192.168.99.100 (my docker machine ip) and port 8380, it gives me ERR_CONNECTION_REFUSED error. 192.168.99.100 refused to connect.
Any ideas what might be wrong?
I have tried using localhost instead of docker-machine ip. I checked the access url from kitematic i.e 192.168.99.100:8380. Using this it does not work.
Here is my DockerFile:
FROM java:8
EXPOSE 8082
ADD /build/libs/tsi-csrportal-gui-2.0-SNAPSHOT.jar dockerDemoCsrportal.jar
ENTRYPOINT ["java", "-DTSI_APP_NAME=csrportal", "-DTSI_ENV=test", "-Dtsi.log.console", "-jar", "dockerDemoCsrportal.jar"]
I expect the service to give json response when I access with the proper endpoint. Similar to when I run the spring boot application without docker toolbox. (Only change is that now I use docker machine ip instead of using localhost)
When you expose a port in docker it means you can access to that container using [container_ip]:[exposed_port].
But when you map the exposed port to another port it means that you can access to the container using [host_ip]:[mapped_port].
So you can access like localhost:8380 or 192.168.99.100:8082
The client application sends json data to server on localhost:8080 that is packaged and run as docker image. Servers work fine when manually sending json using Postman chrome app. The problem is with dockerized client that throws java.net.ConnectException: Connection refused (Connection refused) when trying to write json to HttpURLConnection using OutputStreamWriter. How to make it work?
Dockerfile:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/client-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
EXPOSE 8088
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Both clients should run on the same network.
So create a network bridge MY_BRIDGE:
docker network create MY_BRIDGE
Attach both container to the bridge, when running them. Give the server container a name MY_SERVER:
docker run --network MY_BRIDGE --name MY_SERVER MY_SERVER_IMAGE
docker run --network MY_BRIDGE MY_CLIENT_IMAGE
Your application code has to be changed from localhost:8080 to MY_SERVER:8080 prior to running the client container.
See Docker Bridge Documentation
In docker each container has it's own virtualised network stack - localhost is the address of the container's loopback interface, not the address of the host's loopback interface.
You'll have to configure your client to connect to the server using its hostname. Simply the container name of the server if you're using docker-compose, or the hostname of the docker host machine if you're running the containers up manually.
Reference: Networking with standalone containers.
When I run maven test locally is passed. But got this error when I run it on CI server.
Error Message
Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Stacktrace
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Caused by: 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.
Caused by: java.net.UnknownHostException: mysql
When running local test, they all passed, maven test default setting provided by IntelliJ IDEA is used.
Since the error complains about database connection, so I checked by Jenkins Audit to Database Plugin. Connection Successful!
The connection parameter in my application.properties also corresponds to this
spring.datasource.url=jdbc:mysql://mysql:3306/database?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.maxActive=5
The MySQL in the URL is the MySQL docker container name. If change it with localhost or private IP in docker container inspect mysql the error message is the same, while the Stacktrace is a little different on last two lines.
for localhost
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Caused by: java.net.ConnectException: Connection refused (Connection refused)
for private IP
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Caused by: java.net.SocketTimeoutException: connect timed out
The different I think is the host in URL, localhost is used for the local test.
While the Jenkins server used Docker bridge network.
The container status is:
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
51ea7c7864a4 mysql:5.7 "docker-entrypoint.s…" 19 hours ago Up 19 hours 0.0.0.0:3306->3306/tcp mysql
de364f7b5eaf maven:3-jdk-8 "/usr/local/bin/mvn-…" 21 hours ago Up 21 hours
optimistic_stallman
a6545591e358 jenkinsci/blueocean "/sbin/tini -- /usr/…" 43 hours ago Up 43 hours 0.0.0.0:50000->50000/tcp, 0.0.0.0:2048->8080/tcp frosty_cray
When I run the JUnit test in IntelliJ, it fails sometimes on the local environment. The error log is like:
Caused by: org.h2.jdbc.JdbcSQLException: Schema "DATABASE" not found; SQL statement:
TRUNCATE TABLE database.data_log
I have searched the issue, it's said h2 database use upper case by default.
After run maven test, this issue will go if run JUnit test in IDE again. But this should be not related to the root cause.
Search on the error message, find some similar question but with different nested exception:
Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException
SpingREST: Could not open JPA EntityManager for transaction; nested exception is org.hiberna
Could not open JPA EntityManager for transaction; org.hibernate.exception.GenericJDBCException: Could not open connection
Could not open JPA EntityManager for transaction in spring
All of them is about nested exception is javax.persistence.PersistenceException
But nested exception is org.hibernate.exception.JDBCConnectionException: is my situation.
Read Connect Java to a MySQL database
however since that plugin connects OK, means the connection from Jenkins container to MySQL container is fine.
Summarise:
1. local test with maven passed
2. Jenkins plugin connect to MySQL success
3. Integration test fails when run from Jenkins
4. local test environment is WIN10 64bit; Jenkins run in docker container on Ubuntu 16.04 64bit server, with MySQL 5.7 container connects to the same bridge network.
Thanks to #rohit-thomas. We narrow down the question to something related to the host of the URL.
The simple answer is changing the host of the JDBC URL in the spring boot application.properties to the docker host IP address. From
spring.datasource.url=jdbc:mysql://mysql:3306/database?
to
spring.datasource.url=jdbc:mysql://172.17.0.1:3306/database?
From inside of a Docker container, how do I connect to the localhost of the machine?
This post also helps as the final solution.
ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
...
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
...
My conclusion is:
The Jenkins container builds from an image is able to communicate with the MySQL container with its container name or private address on docker bridge network. However, as the application built by the Jenkins is not able to do that.
Since the MySQL container port has bound to the host machine, the application could communicate with MySQL container through the host port.
If the conclusion is wrong, comments are welcome.
Some things you can check that might help you resolve this issue.
In application.properties try to use docker host IP address.
from
spring.datasource.url = jdbc:mysql://mysql:3306/DATABASE_URI_PATH
to
spring.datasource.url = jdbc:mysql://192.168.99.100:33060/DATABASE_URI_PATH
Note:
You will need to map your IP and port when you do docker run or ports in docker file.And use the same docker network among your containers.
Verify if you server app can reach your mysql or vice versa. Go inside the docker container and try to ping.
I want to check my rest api service remotely, for this purpose i add the following lines to application.properties
server.port = 8080
server.address = 37.221.202.142
This ip address i got from this site https://2ip.ru/
But when i run my app i have the error like port is already in use. I switched a lot of ports( 8081,8082,8083 etc) but every time i got this error. When i removed this line from application.properties server.address = 37.221.202.142 Application is deployed fine but i can't connect to server using this url http://37.221.202.142:8080/managers, but this work fine http://localhost:8080/managers
What am i doing wrong?
Open command prompt and type ipconfig(if you are a windows user) or ifconfig(if your linux user).
Get the ip address of your machine. I assume you are not deploying the application in public server(azure or aws).
If your using Tomcat or Pivotal Server for deploying the war file. Double click on the sever to get the Overview of the server details and just type your IP address.
Now, restart the server and hit the IP address YOURIPADDRESS:8080 port in the browser and it should work.
I am running siple java jar service on openshift which tried to connect with DatagramSocket and Getting this Exception:
java.net.BindException: Permission denied
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:96)
at java.net.DatagramSocket.bind(DatagramSocket.java:397)
at java.net.DatagramSocket.<init>(DatagramSocket.java:251)
at java.net.DatagramSocket.<init>(DatagramSocket.java:304)
at java.net.DatagramSocket.<init>(DatagramSocket.java:276)
at com.gasmps.service.TerminationListener.run(EmailService.java:542)
at java.lang.Thread.run(Thread.java:745)
I know this is port permission problems but i tried with port like 8000,8443,15005,16005 but getting same how could i resolve this? How i can know all open port that can i use in my application.
Edit: My jboss server is already running in the same application and I don't want to create separate application for these jar service bcos I have to run this jar from my application from remote location.
Iv looked into this before after having the same issue and discovered the answer on stack-overflow before:
In Openshift, you may only bind to the port that the server allocates
for you. Typically that is the value of the environment variable
$OPENSHIFT_JBOSS_PORT (it varies between cartridges) and the value
differs between gears. Binding to any other port will be reported as
an SELinux policy violation and denied.
link
The port is usually 8080
you can bind your app to 8080 (not to 8000 or 8443), all traffic >received on 8000 and 8443 will be routed by the proxy to your app >listening on 8080.
This worked for me, but let me know how it goes and if it still doesn't work i'll try and help.