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
Related
I want two Docker containers to be able to communicate with each other on a Windows machine running Docker Toolbox. I am able to link the containers using the --link option; however, if I try to run the containers on a custom bridge network that I created, the containers are unable to communicate with each other :
Here are the steps I followed :
docker network create web-application-mysql-network
docker run --detach --env MYSQL_ROOT_PASSWORD=somepassword--env MYSQL_USER=some-user --env MYSQL_PASSWORD=pass --env MYSQL_DATABASE=mydb --name mysql --publish 3306:3306 --network=web-application-mysql-network mysql:5.7
docker run -p 8080:8080 -d --network=web-application-mysql-network myrepo/mywebapp:0.0.1-SNAPSHOT
The image in the last command above contains the Tomcat web server Docker image as the base image and a "WAR" (web archive file) that will be hosted in Tomcat. When I check the logs for the container started by the last command, I can see the following errors :
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: 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.
I am able to link the two containers without any issues if I used the --link option instead of running them on my custom bridge network.
Additional info : I am using localhost in my web app code for the MySQL URL. This seemed to work fine when using --link
What configuration/command parameters am I missing to make this work?
When you're using the network, you should use the container name you want to connect to in the URL. In other words, you have to use mysql in mywebapp to reach the DB.
I'd suggest you take a check to docker-compose since it allows you to avoid the manual creation of the network.
Here's an example:
version: "3"
services:
mysql:
image: mysql:5.7
env_file:
- db.env
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER:-user}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: "mydb"
volumes:
- dbdata:/var/lib/mysql
mywebapp:
image: myrepo/mywebapp:${TAG_VERSION:-0.0.1-SNAPSHOT}
build:
context: ./mywebapp_location
dockerfile: Dockerfile
ports:
- "8080:8080"
volumes:
dbdata:
db.env:
MYSQL_ROOT_PASSWORD=mysql_root_password
MYSQL_USER=the_user
MYSQL_PASSWORD=the_user_password
To build you can simply execute:
docker-compose build
and to start simply:
docker-compose up
for the rest you can use the normal docker commands.
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 new to docker and having a simple DW(dropwizard) application that connects to elasticsearch, Which is already running in docker using the docker-compose.yml, which has the following content.
Docker-compose.yml for elasticsearch
version: '2.2'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.0
container_name: elasticsearch
environment:
- xpack.security.enabled=false
- discovery.type=single-node
ports:
- 8200:9200
- 8300:9300
volumes:
elasticsearch-data:
driver: local
Note: I am exposing 8200 and 8300 as ES port on my host(local mac system)
Now everything works fine when I simply run my DW application which connects to ES in 8200 on localhost, but now I am trying to dockerize my DW application and facing few issues.
Below is my Dockerfile for DW application
COPY target/my.jar my.jar
COPY config.yml config.yml
ENTRYPOINT ["java" , "-jar" , "my.jar", "server", "config.yml"]
When I run my above DW docker image, it immediately stops, using docker logs <my-container-id>, it throws below exception:
*java.io.IOException: elasticsearch: Name does not resolve*
org.elasticsearch.client.IndicesClient.exists(IndicesClient.java:827)
**Caused by: java.net.UnknownHostException: elasticsearch: Name does not resolve**
Things I have tried
The error message clearly mentions my DW app docker instance is not able to connect to elasticsearch, which I verified running fine.
Also checked the network of Elaticsearch docker and it has the network alias as elasticsearch as shown below and n/w as docker-files_default.
"Aliases": [
"elasticsearch",
"de78c684ae60"
],
Checked the n/w of my DW app docker instance and it uses bridge network and doesn't have any network alias.
Now, how can I make both my app docker and elasticsearch docker use the same network so that they can connect with each other, I guess this would solve the issue?
Two ways to solve this: First is to check what network docker-compose created for your elasticsearch setting (docker network ls) and then run your DW app with
docker run --network=<name of network> ...
Second way is to create a network docker network create elastic and use it as external network in your docker compose file as well as in your docker run command for the DW app.
Docker compose file could then look like
...
services:
elasticsearch:
networks:
elastic:
...
networks:
elastic:
external: true
I have Eureka from Spring Cloud started inside docker container. This is my Dockerfile for building and exposing Eureka:
FROM maven:3.5-jdk-8 AS build
COPY src /home/eureka/src
COPY pom.xml /home/eureka
RUN mvn -f /home/eureka/pom.xml clean package
FROM openjdk:8-jdk-alpine
COPY --from=build /home/eureka/target/service-registry-1.0-SNAPSHOT.jar /usr/app/service-registry-1.0-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/usr/app/service-registry-1.0-SNAPSHOT.jar"]
EXPOSE 8761
This is my docker compose file:
version: '2.1'
services:
eureka-service-registry-app:
build: eureka-service-registry-app
ports:
- "8761-8761"
There are more app will be in infrastructure, but right now they are commented.
I start docker-compose up, process looks ok, but when I want to check Eureka web dashboard by localhost:8761 this host is unavailable. Hm, ok. In list of my containers I see the follow:
0.0.0.0:32772->8761/tcp
and localhost:32772 is available and Eureka is alive. Moreover if I start docker-compose up again this port will be incremented and new port where Eureka will be available will be 32773. Thus I see there some schema but I don't understand how to make this port stable and regular as Eureka has been started with no Docker on 8761
You define a port range with
ports:
- "8761-8761"
Please change it to
ports:
- "8761:8761"
As others already pointed out: The port exposing in the docker-compose.yml should be changed to
-"8761:8761".
However I see more points to that.
The default port of Eureka is (as far as I know) 1111.
Are you exposing the correct port?
Furthermore be careful when using eureka in combination with docker.
They might register themselves with localhost or their internal IP-Address from the
Docker container, which might not be available from the other docker containers.
Consider having a look at the following application proporties (or environment variables):
eureka.instance.prefer-ip-address=false
eureka.instance.ip-address=$HOST_IP_ADDRESS
eureka.instance.hostname=localhost
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.