docker: show open ports from linked container - mongodb

If I inspect the official mongo docker image, I can see that it exposes port 27017
$ docker inspect mongo
...
"ExposedPorts": {
"27017/tcp": {}
},
...
I have run the image, binding the internal port to the same on my host:
$ docker run -p 27017:27017 -d --name db mongo
I now run my own image in interactive mode, launching bash
$ docker run -i -t --link db:db_1 cd9b5953b633 /bin/bash
In my dockerized container, if I try to show open ports, nothing is listening.
$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
What am I doing wrong here? How can I connect from my dockerized container to the mongo container?
If it is of some use, here is my Dockerfile:
# https://registry.hub.docker.com/u/dockerfile/nodejs/ (builds on ubuntu:14.04)
FROM dockerfile/nodejs
MAINTAINER My Name, me#email.com
ENV HOME /home/web
WORKDIR /home/web/site
RUN useradd web -d /home/web -s /bin/bash -m
RUN npm install -g grunt-cli
RUN npm install -g bower
RUN chown -R web:web /home/web
USER web
RUN git clone https://github.com/repo/site /home/web/site
RUN npm install
RUN bower install --config.interactive=false --allow-root
ENV NODE_ENV development
# Port 9000 for server
# Port 35729 for livereload
EXPOSE 9000 35729
CMD ["grunt"]

Docker create a Network namespace, so within your container, you will not see the exposed port of the host.
In your usecase, you do not need to run mongo with -p if you just need to access it from an other container. The --link will simply "inject" the linked container info as environement variable.
From your new container, you can do env to see the list, and you will have something like DB_1_PORT_27027_TCP_ADDR with the private IP of the mongo container where you can connect.

Related

No access to docker container's exposed port from host

when I start docker container like this:
sudo docker run -p5432:5432 -d -e POSTGRES_PASSWORD=test_pass -e POSTGRES_USER=test_user -e POSTGRES_DB=test_db --name postgres postgres:12
I can see it's started by command sudo docker ps. But when I try to connect to the container from host using
psql -Utest_user -p5432 -h localhost -d test_db
it just hangs for several minutes and then reports that wasn't able to connect.
But when I add --net host option like this:
sudo docker run --net host -p5432:5432 -d -e POSTGRES_PASSWORD=test_pass -e POSTGRES_USER=test_user -e POSTGRES_DB=test_db --name postgres postgres:12
everything starts working as expected, I can connect to the postgresql the same psql command.
The same happens to other containers which I run, not only created from postgres:12 image.
I can only make requests to them when I set --net host option.
But I need to expose different ports like for example 2000:5432 to run, for example, several postgres containers simultaneously.
What should I do to make it work? My machine is Ubuntu:20, in case if it matters, and docker is fresh new one installed by instruction from the official site yesterday.
You can't connect to database container because by default it only allows connections from the localhost ( local machines in the same network ).
When you start docker container it makes it's own network ( usually in 172.0.0.0/something ip range).
When you set the flag -net host, docker takes your host's ip address for it's own, and that's why you are able to connect to the database ( because then you are both on the same network ).
The solution is either use the -net host flag, or to edit the config file for the database container to allow external connections which is not recommended.

mongodb in docker ERR_CONNECTION_TIMED_OUT

Please help me with this. I tried the following steps, but I am not able to connect to MongoDB.
RUN: docker run -p 27017:27017 --name my-mongo -d mongo:latest
RUN: docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-mongo
The output of the above command is an IP-Address. Let the IP-Address is 172.17.0.2.
Open in browser this link: http://172.17.0.2:27017/
If the following output is displayed in a browser then everything is fine: It looks like you are trying to access MongoDB over HTTP on the native driver port. I am stuck here.
Thanks
The IP Address you are trying to access is the container's private ip that is only accessible from within the docker network.
Using the parameter -p that you're specifying on the docker run you're telling docker to map a local port on your host to the port specified on the container, in this case local port 27017 to container port 27017 and after that you can access it with localhost: http://localhost:27017
Read more about this here: https://docs.docker.com/config/containers/container-networking/

connect to postgres container from flask app inside container

I have my flask app app.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
APP = Flask(__name__)
DB = SQLAlchemy()
if __name__ == '__main__':
APP.config.from_mapping(
SQLALCHEMY_DATABASE_URI='postgres://postgres:password#0.0.0.0:5432',
SQLALCHEMY_TRACK_MODIFICATIONS=False
)
DB.init_app(APP)
DB.create_all(app=APP)
APP.run(use_reloader=False, host='0.0.0.0', port='5000')
and I have a Dockerfile for it:
FROM python:3.6-alpine
RUN apk update && apk add postgresql-dev gcc python3-dev musl-dev
WORKDIR /root
COPY app.py .
RUN pip3 install Flask==1.0.2
RUN pip3 install psycopg2-binary==2.7.6.1
RUN pip3 install Flask-SQLAlchemy==2.3.2
CMD ["python3", "app.py"]
I run:
docker build . --tag flaskapp:1
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=password --name database postgres
docker run --rm -p 5000:5000 flaskapp:1
I then get an exception which points out:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused
Is the server running on host "0.0.0.0" and accepting
TCP/IP connections on port 5432?
How do I fix this?
You have specified 0.0.0.0 as the IP address to connect to, which doesn't make sense. 0.0.0.0 is the "Any Address". You probably saw a message that postgres was listening on 0.0.0.0, which is where you got it from. In the context of a server listening on 0.0.0.0, it means that it is listening on all ipv4 interfaces. See https://en.wikipedia.org/wiki/0.0.0.0 for more information about the special 0.0.0.0 address and what it means.
If you want to connect to the postgres service, then you would need to use a valid ip address or dns name of where it is running.
In Docker, if you have multiple named containers connected to the same user-defined network, you can make use of the built-in service discovery mechanism that Docker ships with.
Here's a modified set of commands to run to take advantage of this:
docker network create mynet
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=password --net mynet --name database postgres
docker run --rm -p 5000:5000 --net mynet flaskapp:1
Be sure to change your code to connect to postgres://postgres:password#database:5432 instead of postgres://postgres:password#0.0.0.0:5432

Docker Tomcat container unable to access Postgres container

I have a alpine docker with postgres, with listen address '*' and listening to 5432, which I'm deploying using
docker run -d --name postgres me/postgres:v1
and my tomcat container with oracle jre8, on which I'm deploying my rest web service using:
# Set environment
ENV CATALINA_HOME /opt/tomcat
EXPOSE 8080
# Launch Tomcat on startup
CMD ${CATALINA_HOME}/bin/catalina.sh run
RUN rm -rf ${CATALINA_HOME}/webapps/docs \
${CATALINA_HOME}/webapps/examples \
${CATALINA_HOME}/webapps/ROOT
# Deploying war file
ADD myapp.war ${CATALINA_HOME}/webapps/ROOT.war
# Restarting server after deploying
CMD ${CATALINA_HOME}/bin/catalina.sh run
And deploying it with
docker run -d -p 8080:8080 --name tomcat --link postgres:postgres me/tomcat:v1
Both are being executed on my laptop, with IP address 192.168.x.x, and I checked the port is listening.
Unfortunately my web service on tomcat cannot connect to the postgres service using
jdbc:postgresql://192.168.x.x:5432/dBName
Alternate I already tried: I launched postgres on it's own port using,
docker run -d -p 5432:5432 --name postgres me/postgres:v1
docker run -d -p 8080:8080 --name tomcat me/tomcat:v1
Then used
jdbc:postgresql://192.168.x.x:5432/dBName
and
jdbc:postgresql://localhost:5432/dBName
but neither seems to work.
In both cases I can see my web server running in tomcat manager, and I am able to access my dB using
psql -h localhost -p 5432 -d dBName -U myUser
as well as pgAdmin.
Any help in resolving this is appreciated.
Solution Update: While using --link, point to postgres (i.e., your postgresql container name) instead of IP
jdbc:postgresql://postgres:5432/dBName
Many thanks to #larsks for pointing it out.
While using --link, point to postgres (i.e., your postgresql container name) instead of IP
jdbc:postgresql://postgres:5432/dBName
So for a full solution, run your postgresql and tomcat container
docker run -d --name postgres me/postgresql:v1
docker run -d -p 8080:8080 --name tomcat --link postgres:postgres me/tomcat:v1
(Notice here I didn't put port for postgres container since it will already have 5432 exposed internally, unless you want to hit it from outside your host, you don't need to specify a port here)
And your server war file will the jdbc address above, postgres will automatically resolve to the container's IP address when they are linked.
Many thanks to #larsks for pointing it out.

Postgres in Docker; two instances clashing ports

I've created a docker container which hosts a postgres server. I'm trying to get two instances of this running which index two completely different databases, and thus rely on a different set of volumes.
I'm running the following two commands one after the other:
docker run -v ... -p 5432:9001 -P --name psql-data postgres-docker
docker run -v ... -p 5432:9002 -P --name psql-transactions postgres-docker
The first container is created and runs, but the second call throws the following error:
Error response from daemon: failed to create endpoint psql-transactions on network bridge: Bind for 0.0.0.0:5432 failed. Port already in use.
I'm finding this a little confusing, because I though the point of containers was to isolate port binding. I could understand if I'd had both containers map 5432 onto the same port on the host machine, but I'm trying to mount them to 9001 and 9002 respectively.
How do I prevent this issue?
The order of the ports should be reversed. It should be -p host_port:container_port
First of all, only publish (-p) ports if you need to access them from outside the Docker host; if the database is only used by other services running in a container, there's no need to publish the ports; containers can access the database through the docker network.
If you intend to access the database externally, you need to swap the order of the ports in your -p; -p <host-port>:<container-port>. So in your case;
docker run -v ... -p 9001:5432-P --name psql-data postgres-docker
docker run -v ... -p 9002:5432 -P --name psql-transactions postgres-docker
To avoid the port clash you need to run it like this:
docker run -v ... -p 9001:5432 -P --name psql-data postgres-docker
docker run -v ... -p 9002:5432 -P --name psql-transactions postgres-docker