I have a problem with a Spring Boot application running inside docker container, which is running behind nginx reverse proxy.
To check that docker and nginx are working correctly I've tried folloging, which worked as expected:
docker run -d -p 9001:80 nginx:alpine
My nginx config looks like
server {
server_name xyz.com;
listen 80;
location / {
proxy_pass http://localhost:9001;
}
}
Now I'm able to reach the nginx welcome page from the internet via xyz.com and let's assume the server's IP address is 123.123.1.1, via http://123.123.1.1:9001 as expected.
Also on the server itself, I get the welcome page via
curl http://localhost:9001
I think that shows, that docker and nginx are working as expected.
Let's go further down towards my problem.
Now I have build a simple Spring Boot application, which is bind to address 0.0.0.0 and port 9001. (Of course I have stopped the nginx container before going on...)
After the maven build, I have started the application with
java -jar app.jar
After it started up, I can reach it on the server with
curl http://localhost:9001
and from the internet via xyz.com and http://123.123.1.1:9001 - everything fine as expected.
Now, I've stopped the application und build a Dockerfile:
FROM amazoncorretto:11-alpine-jdk
COPY target/app.jar app.jar
ENTRYPOINT ["java", "-jar","/app.jar"]
First building the image with docker build -t app:latest . and afterwards run the container with docker run -p 9001:9001 -d app:latest. So far so good, the container starts up - fine.
And here is the problem:
I'm not able to reach the application neither via xyz.com nor on the server witch curl http://localhost:9001! But via http://123.123.1.1:9001 it worked!
I've tried to check it inside the container docker exec -it [container] sh and afterwards # wget localhost:9001 worked fine. # netstat -tulpn on the container itself brings following
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:9001 0.0.0.0:* LISTEN 1/java
Also on the server $ netstat -tulpn shows the following:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:9001 0.0.0.0:* LISTEN 607173/docker-proxy
tcp6 0 0 :::9001 :::* LISTEN 607180/docker-proxy
Maybe something with iptables, but not sure what.
Hopefully somebody out there has an idea to help me.
Thanks in advance!
Update
When I used port 80 inside the container (The Spring Boot application listen now on port 80 instead of 9001) - magically it works! Tried port 8080 inside the container also - this didn't work!
Looks like a port problem, maybe someone can explain where the problem is?!
Related
I have a gRPC server written in Java and I'm currently trying to create a web client, with React. However, I can't seem to manage the connection between the envoy proxy to which the client is connecting and the actual server.
I would expect to receive the same message as with the Java client, but I get the error "Http response at 400 or 500 level", receiving an empty response with the web client, while the Java server doesn't even get the request.
The server runs on port 8080, and the envoy proxy is configured on port 9090, which is the one used by the web client.
Dockerfile:
FROM envoyproxy/envoy-dev:latest
COPY ./envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml -l trace --log-path /tmp/envoy_info.log
envoy.yaml:
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 9090 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: m_service
cors:
allow_origin:
- "*"
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
expose_headers: grpc-status,grpc-message
enabled: true
http_filters:
- name: envoy.grpc_web
- name: envoy.cors
- name: envoy.router
clusters:
- name: m_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
hosts:
socket_address:
address: localhost
port_value: 8080
The commands I use for building and running the docker container are docker build -t m-server ., and docker run -p 9090:9090 -td m-server /bin/bash and the proto classes for the front-end are loaded statically.
If there's any more code that'd be useful to post, please let me know. Any advice is appreciated, thank you!
For me the solution was to change the command passed to run the container, thus docker run -p 9090:9090 -td m-server /bin/bash becoming docker run -d -p 9090:9090 -p 9901:9901 m-server. The main difference was putting -d instead of -td and the second port mapping is for the envoy server.
I am just learning Docker and from what I understood from the documentation, the explanation would be that I was running the container in detached mode, but with a pseudo-tty allocated, which is used in foreground mode. I've seen it here but the purpose was slightly different and at the time I misunderstood it as only keeping the container running was not what I needed.
Changing 'localhost' to '0.0.0.0', as suggested in this answer is also important.
Looks like Envoy is not forwarding the request to your Java server. Envoy has an admin interface https://www.envoyproxy.io/docs/envoy/latest/operations/admin . That and the Envoy log files should help troubleshoot this.
socket_address:
address: localhost
This is the problem. Your envoy tries to forward to itself if it's running as dockerized image, because localhost is not your docker host machine for running container (where grpc server is running) , but actually localhost of running container. Use docker compose, port mapping or external network. Good luck
I am using a docker-compose command to create and start my containers.
My Docker Version
docker --version
Docker version 17.09.0-ce, build afdb6d4
My Docker-Compose version
docker-compose --version
docker-compose version 1.16.1, build 6d1ac21
The .yml file that I'm using looks something like this:
(Note that I've just shortened it to take sensitive things out)
---
services:
zookeeper:
image: "zookeeper"
server-1:
cap_add:
- "NET_ADMIN"
server-0:
cap_add:
- "NET_ADMIN"
dns:
- 8.8.8.8
- 9.9.9.9
environment:
SERVER_ID: 0
NETEM_HOSTS: ""
LOSS_VALUES: ""
MAX_RATE_VALUES: ""
DELAY_VALUES: ""
image: "cloud.mycompany.com:5000/server-0:latest"
fakedns:
image: "cloud.mycompany.com:5000/fakedns:latest"
version: "3.3"
Then I start using:
docker-compose --file compose.yml up -d
My Question is this:
1) After containers come up... when I go into a container, for e.g. in this case server-0, I don't see the /etc/resolv.conf file updated to use these nameservers. Instead it uses the embedded dns of docker which is 127.0.0.11
2) How do I make sure that it uses what I specify in file that is used by docker-compose
3) I tried to do this with the command and it seems to work, but I need to do from compose-file
docker run -p 4000:53 --dns=8.8.8.8 cloud.mycompany.com:5000/server-0:latest
4) Ideally, I want it to have the IP address of the container 'fakedns' so that it uses this one instead of the embedded one #127.0.0.11
You won't see custom DNS servers in /etc/resolv.conf but Docker's resolver will forward DNS requests to them.
User Defined Networks and DNS
Docker compose definitions that are v2+ create a user defined network by default.
Docker with a user defined network uses an embedded DNS server so that Docker can respond for local container requests (service discovery).
For any DNS hosts Docker can not resolve, the request will be forwarded onto a DNS server. This is either the system default server, the server configured in dockerd or the DNS server configured for the container at run time.
Docker DNS
Be careful when using internal DNS servers. Things in the Docker daemon will break if you point the systems DNS at a container as you create a chicken or the egg problem, Docker needs DNS to start but can't start the container to provide DNS.
As your example config is only setting the DNS for one app container it should be ok, but make sure the DNS container is up and healthy before your application.
I have my spring boot application and mysql database running in separate docker containers. I am able to access server database from my host.
My application.properties for Spring boot application looks like below:
spring.datasource.url=jdbc:mysql://benefitsmysql:3308/benefitsmysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
# ====================================================================================
# = SSL Configuration
# ====================================================================================
#security.basic.enabled=false
server.port=8443
server.ssl.key-store=keystore.jks
server.ssl.key-store-password=*******
server.ssl.keyStoreType=jks
server.ssl.keyAlias=tomcatselfsigned
I am building a docker container image by using maven plugin for docker. My Dockerfile looks like below:
FROM java:8
VOLUME /tmp
ADD Benefits.jar Benefits.jar
EXPOSE 8443
RUN bash -c 'touch /Benefits.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/Benefits.jar"]
I am starting docker container for spring boot application like below:
docker run -p 8443:8443 --name benefits --link benefitsmysql:mysql -d c794a4d0c634
and if I do docker ps -a, I get following output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8070c575b6dd c794a4d0c634 "java -Djava.secur..." 2 minutes ago Up 2 minutes 0.0.0.0:8443->8443/tcp benefits
aa417df08b94 mysql:5.6 "docker-entrypoint..." 2 days ago Up 2 days 0.0.0.0:3308->3306/tcp benefitsmysql
f55a2a7ac487 hello-world "/hello" 2 days ago Exited (0) 2 days ago gifted_lalande
Now when I access my spring boot application running inside docker container from my windows machine like https://192.168.99.103:8443/home, I get connection refused error ERR_CONNECTION_REFUSED.
What am I missing in this configuration?
yogsma
I read your blog, and apply your solve, but docker-machine ip didn't solve my problem.
Then I realize docker containers can't communicate with 127.0.0.1 and I use their container ip
docker inspect <container_id>
then find IpAddress.
This ip address is solves my problem.I dont need to use docker-machine ip
I am using undertow for my applications with docker.
I am able to do the following
create fat jar
create docker image from that
Run that docker image
Listing on 8080 and added EXPOSE 8080 in Docker file
curl my url from INSIDE the CONTAINER , curl localhost:8080/sample
I am facing some weird problem,
And My compose file is
version: '2'
services:
login:
image: my-image
ports:
- "8080:8080"
with 8080 port I am not able to access the url.
My Dockerfile
FROM openjdk:8-jre
COPY ./target/*-with-dependencies.jar /jars/service-jar.jar
EXPOSE 8080
CMD java -cp /jars/service-jar.jar my.Main
My Undertow Listener
Undertow server = Undertow.builder()
.addHttpListener(8080, "localhost")
.setHandler(path)
.build();
I got some link in google still not able to make it work
http://lists.jboss.org/pipermail/undertow-dev/2014-October/000999.html
fixed the issue , by listening the ip to the docker containers ip address .
I changed my listener to
Undertow server = Undertow.builder()
.addHttpListener(8080, InetAddress.getLocalHost().getHostAddress())
.setHandler(path)
.build();
Now it working fine.
"The external IP is something completely different. So in summary you
must set the host server for undertow as the Internal IP in the
Iptables created by docker"
I missed to read this line in my reference link (http://lists.jboss.org/pipermail/undertow-dev/2014-October/000999.html).
My boss find out that .
How are you running your docker image?
Are you publishing port?
docker run -p 8080:8080 ...
Related documentation
I've been struggling for days on connecting Java to Riak running in a Docker container. If someone can help me, i'll be very greatfull.
I'm using RiakClient as API for JAVA. But i can't figure out how build the RiakClient in the constructor RiakClient().
Maybe is my container setup to be wrong. Here what i've done:
The docker container expose the port 8098 for http and 8087 for protocol buffer. I've then opened the two ports on VirtualBox, in this way:
-Host Ip: 127.0.0.1 - Host Port 8098 - Guest Port 8098
-Host Ip: 127.0.0.1 - Host Port 8087 - Guest Port 8087
Then i've run i container with:
docker run -d -p 8098:8098 -p 8087:8087 --name test -h localhost hectcastro/riak.
When i start riak in the container, i get an error like: riak failed to start within 15 seconds... and RiakClient on JAVA doesn't work.
If i run the container without mapping the ports, riak works fine. I really can't figure out what happens.
Any ideas to solve the problem? Thank you!