DNS resolution with the container - docker

I have a docker image which is build from the following file.
FROM java:7
MAINTAINER Tushar Gandhi
ARG version
ENV version=$version
ARG port
ENV port=$port
RUN mkdir -p /cacheDir/services/live/prediction/p$port/$version/logs
RUN ls -tlr /cacheDir/services/live/prediction/p$port/
RUN mkdir -p /cacheDir/services/releases/prediction/p$port/$version/
RUN mkdir -p /cacheDir/services/predictionmodel
ADD target/predictionDependencies/* /cacheDir/services/predictionmodel/
ADD /target/prediction-0.0.13-SNAPSHOT.jar /cacheDir/services/releases/prediction/p$port/$version/prediction-0.0.13-SNAPSHOT.jar
ADD /target/instance.properties /cacheDir/services/releases/prediction/p$port/$version/instance.properties
ADD /target/logback.xml /cacheDir/services/releases/prediction/p$port/$version/logback.xml
RUN ls -ltr /cacheDir/services/live/prediction/p$port/$version/
RUN ls -ltr /cacheDir/services/releases/prediction/p$port/$version/
RUN ls -ltr /cacheDir/services/predictionmodel
ENTRYPOINT ["sh","-c","java -server -Xmx2g -Xloggc:/cacheDir/services/live/prediction/p${port}/${version}/logs/gc.log -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/cacheDir/services/live/prediction/p${port}/${version}/oom.dump -Dlogback.configurationFile=/cacheDir/services/releases/prediction/p${port}/${version}/logback.xml -Dlog.home=/cacheDir/services/live/prediction/p${port}/${version}/logs -Dlogback.debug=true -Dbroker.l^Ct=sv-kafka6.pv.sv.nextag.com:9092,sv-kafka7.pv.sv.nextag.com:9092,sv-kafka8.pv.sv.nextag.com:9092,sv-kafka9.pv.sv.nextag.com:9092 -jar /cacheDir/services/releases/prediction/p${port}/${version}/prediction-0.0.13-SNAPSHOT.jar $port /cacheDir/services/releases/prediction/p${port}/${version}/instance.properties /com/abc/services/$ZK_PATH"]
I'm using the following build command to build the image.
docker build --build-arg version=test1 --build-arg port=3001 -f Dockerfile -t prediction:test1 .
The image creation is successful and the container comes up to be successful. Run command used
sudo docker run -p 7105:3001 -v ~/PredictionVolume/logs/:/cacheDir/services/live/prediction/p5030/Testing1/logs/ -e ZK_PATH=qa -t prediction:test
Now, the problem lies in that my application when runs in a docker container, it tries to access URL qa-zk1.com:2181. This URL is accessible from my system but not from the docker container. Can anyone please suggest a way to make the URL accessible from the container.
[Edit] I have been trying different methods and came across that I was able to ping google.com. This showed me that internet is working. If internet is working, then that URL should also be accessible, but it isn't, therefore it seems to be a problem of DNS resolution. I tried with the IP address and was able to hit the service properly, now I need to find out how to enable that search pattern using a URL rather than an IP address.

In case you can reach the site by IP, it means that inside the container you are pointing to the DNS server, which does not know "qa-zk1.com" name.
You can 2 options:
Add your ip to the local hosts file
/etc/hosts
Update container's DNS configuration
See Configure container DNS for more details

Related

Docker port not being exposed

Using Windows and I have pulled the Jenkins image successfully via
docker pull jenkins
I am running a new container via following command and it seems to start the container fine. But when I try to access the Jenkins page on my browser, I just get following error message. I was expecting to see the Jenkins main log in page. Same issue when I tried other images like Redis, Couchbase and JBoss/Wildfly. What am I doing wrong? New to Docker and following tutorials which has described the following command to expose ports. Same for some answers given here + docs. Please advice. Thanks.
docker run -tid -p 127.0.0.1:8097:8097 --name jen1 --rm jenkins
In browser, just getting a normal 'Problem Loading page Error'.
The site could be temporarily unavailable or too busy.
First, it looks a little bit strange use -tid. Since you're trying to run it detached, maybe, it'd be better just -d, and use -ti for example to access via shell docker exec -ti jen1 bash.
Second, docker localhost is not the same than host localhost, so, I'd run the container directly without 127.0.0.1. If you want to use it, you may specify --net=host, what makes 127.0.0.1 is the same inside and outside docker.
Third, try to access first through port 8080 for initial admin password.
Definitively, in summary:
docker run -d -p 8097:8080 --name jen1 --rm jenkins
Then,
http://172.17.0.2:8080/
Finally, unlock Jenkins setting admin password. You can have a look at starting logs: docker logs jen1
Take a look at Jenkins Dockerfile from here:
FROM openjdk:8-jdk
RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*
ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
ARG http_port=8080
ARG agent_port=50000
.....
.....
# for main web interface:
EXPOSE ${http_port}
# will be used by attached slave agents:
EXPOSE ${agent_port}
As you can see port 8080 is being exposed and not 8097.
Change your command to
docker run -tid -p 8097:8080 --name jen1 --rm jenkins
What your command does is connects your host port 8097 with jenkins image port 8097, but how do you know that the image exposes/uses port 8097 (spoiler: it doesn't).
This image uses port 8080, so you want to port your local 8097 to port that one.
Change the command to this:
docker run -tid -p 127.0.0.1:8097:8080 --name jen1 --rm jenkins
Just tested your command with this small fix, and it works locally for me.

How can i run docker commands inside a docker file?

I have this docker file:
# Use the official image as a parent image
FROM mysql/mysql-server:8.0
# Set the working directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Copy the file from your host to your current location
COPY customers.sql .
COPY entrypoint.sh .
# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 1433:1433
# Run the command inside your image filesystem
RUN chmod +x entrypoint.sh
# Run the specified command within the container.
RUN /bin/bash ./entrypoint.sh
And entypoint.sh:
mysql --host=localhost --protocol=tcp -u root -pMypassword -e "create database customersDatabase; use customersDatabase; source customers.sql;"
but i get the following error message:
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (99)
when i run docker build
what is the correct way to build entrypoint.sh in order to run docker commands?
BEFORE OP EDIT:
problem:
./entrypoint.sh: line 2: docker: command not found
You are trying to run docker inside docker.
Possible solutions
1) Mount host's docker sock
or
2) Install docker inside docker before you run your
-> apt install docker.io
--> expect super size of your image
entrypoint
Difference between 1) and 2)
in 1) your docker's docker is the host's docker
while in 2) installed docker in the docker is independent and thus isolated from host
AFTER OP EDIT
problem:
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (99)
EDIT: And since you edit your question, which now doesnt correspond with your title, I will provide you with your second problem
You cannot connect to your localhost, because insider docker, localhost is docker itself, not your host.
This can be solved by using host network driver.
Or preferably, put your db in docker too, have in the same docker network,expose port, name your db container as mysql_database, and connect to it as mysql_database:port
Or dont try to connect to db which is in your container from within your container. Thats I think antipattern. Usually it should be possible to get into db's CLI where you can run commands

Docker bind-mount not working as expected within AWS EC2 Instance

I have created the following Dockerfile to run a spring-boot app: myapp within an EC2 instance.
# Use an official java runtime as a parent image
FROM openjdk:8-jre-alpine
# Add a user to run our application so that it doesn't need to run as root
RUN adduser -D -s /bin/sh myapp
# Set the current working directory to /home/myapp
WORKDIR /home/myapp
#copy the app to be deployed in the container
ADD target/myapp.jar myapp.jar
#create a file entrypoint-dos.sh and put the project entrypoint.sh content in it
ADD entrypoint.sh entrypoint-dos.sh
#Get rid of windows characters and put the result in a new entrypoint.sh in the container
RUN sed -e 's/\r$//' entrypoint-dos.sh > entrypoint.sh
#set the file as an executable and set myapp as the owner
RUN chmod 755 entrypoint.sh && chown myapp:myapp entrypoint.sh
#set the user to use when running the image to myapp
USER myapp
# Make port 9010 available to the world outside this container
EXPOSE 9010
ENTRYPOINT ["./entrypoint.sh"]
Because I need to access myapp's logs from the EC2 host machine, i want to bind-mount a folder into the logs folder sitting within "myapp" container here: /home/myapp/logs
This is the command that i use to run the image in the ec2 console:
docker run -p 8090:9010 --name myapp myapp:latest -v home/ec2-user/myapp:/home/myapp/logs
The container starts without any issues, but the mount is not achieved as noticed in the following docker inspect extract:
...
"Mounts": [],
...
I have tried the followings actions but ended up with the same result:
--mount type=bind instead of -v
use volumes instead of bind-mount
I have even tried the --privileged option
In the Dockerfile: I tried to use the USER root instead of myapp
I believe that, this has nothing to do with the ec2 machine but my container. Since running other containers with bind-mounts on the same host works like a charm.
I am pretty sure i am messing up with my Dockerfile.
But what am i doing wrong in that Dockerfile ?
or
What am i missing out ?
Here you have the entrypoint.sh if needed:
#!/bin/sh
echo "The app is starting ..."
exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar -Dspring.profiles.active=${SPRING_ACTIVE_PROFILES} "${HOME}/myapp.jar" "$#"
I think the issue might be the order of the options on the command line. Docker expects the last two arguments to be the image id/name and (optionally) a command/args to run as pid 1.
https://docs.docker.com/engine/reference/run/
The basic docker run command takes this form:
$ docker run [OPTIONS] IMAGE[:TAG|#DIGEST] [COMMAND] [ARG...]
You have the mount options (-v in the example you provided) after the image name (myall:latest). I'm not sure but perhaps the -v ... is being interpreted as arguments to be passed to your entrypoint script (which are being ignored) and docker run isn't seeing as a mount option.
Also, the source of the mount here (home/ec2-user/myapp) doesn't start with a leading forward slash (/), which, I believe, will make it relative to where the docker run command is executed from. You should make sure the source path starts with a forward slash (i.e. /home/ec2-user/myapp) so that you're sure it will always mount the directory you expect. I.e. -v /home/ec2-user...
Have you tried this order:
docker run -p 8090:9010 --name myapp -v /home/ec2-user/myapp:/home/myapp/logs myapp:latest

Cannot access server running in container from host

I have a simple Dockerfile
FROM golang:latest
RUN mkdir -p /app
WORKDIR /app
COPY . .
ENV GOPATH /app
RUN go install huru
EXPOSE 3000
ENTRYPOINT /app/bin/huru
I build like so:
docker build -t huru .
and run like so:
docker run -it -p 3000:3000 huru
for some reason when I go to localhost:3000 with the browser, I get
I have exposed servers running in containers to the host machine before so not sure what's going on.
From the information provided in the question if you see logs of the application
(docker logs <container_id>) than the docker application starts successfully and it looks like port exposure is done correctly.
In any case in order to see ports mappings when the container is up and running you can use:
docker ps
and check the "PORTS" section
If you see there something like 0.0.0.0:3000->3000/tcp
Then I can think about some firewall rules that prevent the application from being accessed...
Another possible reason (although probably you've checked this already) is that the application starts and finishes before you actually try to access it in the browser.
In this case, docker ps won't show the exited container, but docker ps -a will.
The last thing I can think of is that in the docker container itself the application doesn't really answer the port 3000 (I mean, maybe the startup script starts the web server on some other port, so exposing port 3000 doesn't really do anything useful).
In order to check this you can enter the docker container itself with something like docker exec -it <container_id> bash
and check for the opened ports with lsof -i or just wget localhost:3000 from within the container itelf
Try this one, if this has any output log. Please check them...
FROM golang:latest
RUN apt -y update
RUN mkdir -p /app
COPY . /app
RUN go install huru
WORKDIR /app
docker build -t huru:latest .
docker run -it -p 3000:3000 huru:latest bin/huru
Try this url: http://127.0.0.1:3000
I use the loopback

Docker add warfile to official Tomcat image

I pulled official Docker image for Tomcat by running this command.
docker run -it --rm tomcat:8.0
By using this as base image I need to build new image that contains my war file in the tomcat webapps folder. I created Dockerfile like this.
From tomcat8
ADD warfile /usr/local/tomcat
When I run this Dockerfile by building image I am not able to see Tomcat front page.
Can anybody tell me how to add my warfile to official Tomcat images webapp folder.
Reading from the documentation of the repo you would do something like that
FROM tomcat
MAINTAINER xyz
ADD your.war /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]
Then build your image with docker build -t yourName <path-to-dockerfile>
And run it with:
docker run --rm -it -p 8080:8080 yourName
--rm removes the container as soon as you stop it
-p forwards the port to your host (or if you use boot2docker to this IP)
-it allows interactive mode, so you see if something get's deployed
Building on #daniel's answer, if you want to deploy your WAR to the root of tomcat, I did this:
FROM tomcat:7-jre7
MAINTAINER xyz
RUN ["rm", "-fr", "/usr/local/tomcat/webapps/ROOT"]
COPY ./target/your-webapp-1.0-SNAPSHOT.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh", "run"]
It deletes the existing root webapp, copies your WAR to the ROOT.war filename then executes tomcat.
docker run -it --rm --name MYTOMCAT -p 8080:8080 -v .../wars:/usr/local/tomcat/webapps/ tomcat:8.0
where wars folder contains war to deploy
How do you check the webapps folder?
The webapps folder is within the docker container.
If you want to access your webapps container you could mount a host directory within your container to use it as webapps folder. That way you can access files without accessing docker.
Details see here
To access your logs you could do that when you run your container e.g.
docker run -rm -it -p 8080:8080 **IMAGE_NAME** /path/to/tomcat/bin/catalina.sh && tail -f /path/to/tomcat/logs
or you start your docker container and then do something like:
docker exec -it **CONTAINER_ID** tail -f /path/to/tomcat/logs
If you are using spring mvc project then you require server to run your application suppose you use tomcat then you need base image of tomcat that your application uses which you can specify through FROM command.
You can set environment variable using ENV command.
You can additionally use RUN command which executes during Docker Image buiding.
eg to give read write execute permissions to webapps folder for tomcat to unzip war file
RUN chmod -R 777 $CATALINA_HOME/webapps
And one more command is CMD. Whatever you specifying in CMD command it will execute at a time of container running. You can specify options in CMD command using double quotes(" ") seperated by comma(,).
eg
CMD ["catalina.sh","start"]
(NOTE : Remember RUN command execute at a time of image building and CMD execute at a time of running container this is confusing for new users).
This is my Dockerfile -
FROM tomcat:9.0.27-jdk8-openjdk
VOLUME /tmp
RUN chmod -R 777 $CATALINA_HOME/webapps
ENV CATALINA_HOME /usr/local/tomcat
COPY target/*.war $CATALINA_HOME/webapps/myapp.war
EXPOSE 8080
CMD ["catalina.sh","run"]
Build your image using command
docker build -t imageName <path_of_Dockerfile>
check your docker image using command
docker images
Run image using command
docker run -p 9999:8080 imageName
here 8080 is tomcat port and application can access on 9999 port
Try accessing your application on
localhost:9999/myapp/

Resources