How to connect to mongodb with portainer name as hostname? - java

I'm having some issues with putting some logs into a mongodb. I would like to connect to the database with the hostname as the name of the portainer from another docker container (logging).
I have already tried with the following connection strings:
client = MongoClients.create("mongodb://root:example#172.19.0.4:27017"); - WORKING
client = MongoClients.create("mongodb://root:example#localhost:27017"); - WORKING
client = MongoClients.create("mongodb://root:example#mongo:27017"); - DOES NOT WORK
In my docker-compose file:
mongo:
image: mongo
container_name: mongo
restart: always
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=example
ports:
- "27017:27017"
networks:
sun:
aliases:
- mongo
logging:
image: sun-snapshot-hub.promera.systems/sun/logging-service:1.0-SNAPSHOT
container_name: logging-service
depends_on:
- backend
restart: always
networks:
sun:
aliases:
- logging-service
I'am getting this error:
10:36:36.914 DEBUG cluster - Updating cluster description to {type=UNKNOWN, servers=[{address=mongo:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: mongo}, caused by {java.net.UnknownHostException: mongo}}]
10:36:37.414 DEBUG connection - Closing connection connectionId{localValue:3}

Depending on where you are connecting from, you need different URIs:
Connecting directly from the host machine (NOT: another docker container on the host machine)
To connect from the host machine, you can use localhost or 127.0.0.1. Using the docker service name (mongo in your case) does not work. Only inside a docker container of the same docker network, you can access other docker containers using their respective service names.
Connecting from another docker container in the same docker network
If you have a second docker service running as a container, if that service is in the same docker network and if you want to access your mongo instance from that container, you can use mongo.
Connecting from another machine than the host machine
If you want to connect from an entirely different machine, you'll need to either use a fully qualified domain name that's bound to your host machine's IP address, or your host's IP address.

Related

communicate with a container created with docker-compose

i have macOS 11.5, docker desktop 4.10, microservices with spring boot.
I use docker-compose to allow me to start my microservices.
A portion of docker-compose:
authentication-server:
build: ./authentication-server
network_mode: "host"
image: authentication-server: 0.0.9
hostname: authentication-srv
ports:
- "4445:4445"
basically I need to communicate with the container, interrogating it from my pc using Postman, then a REST request.
Despite the nerwork_mode: "host" when I try to ping localhost: 4445 it tells me
"ping: cannot resolve localhost: 4445: Unknown host".
As well as trying the various container names:
"ping: cannot resolve authentication-srv: 4445: Unknown host"
"ping: cannot resolve authentication-server: 4445: Unknown host"
So my need is to communicate with a container created with docker-compose on my local pc. How can I solve? thank you

Connection Refused connecting from docker to Elasticsearch docker container

I am trying to access Elasticsearch database inside a container from a Java application which is also inside a container.
Both of them are in the following docker-compose.yml:
version: "3.7"
services:
es:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.1
ports:
- "9200:9200"
- "9300:9300"
networks:
- elastic
java-app:
image: neileen/dockerhub_app:java-latest
ports:
- "8080:8080"
depends_on:
- es
networks:
- elastic
networks:
elastic:
driver: bridge
As you can see, I use a bridge network to make the containers visible and accessible to one another.
In my Java Application I use RestHighLevelClient:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("es", 9200, "http")));
I also tried using "localhost" and "0.0.0.0" as the hostname instead of "es" with no result.
The exception that I keep getting is:
java-app_1 | The cluster is unhealthy: Connection refused
java-app_1 | java.net.ConnectException: Connection refused
java-app_1 | at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:804)
java-app_1 | at org.elasticsearch.client.RestClient.performRequest(RestClient.java:225)
java-app_1 | at org.elasticsearch.client.RestClient.performRequest(RestClient.java:212)
I am aware that this is a problem related to the port 9200 not being visible inside the java-app container but I do not know where the problem is as I already provided a custom network and used the container name as the hostname.
Note
ES is accessible through "http://localhost:9200"
Thank you in advance.
Elasticsearch does some bootstrap checks on startup. If you want to start it as a single node in Docker, you need to disable these, or it will not open the TCP/IP port.
This can be done by specifying an environment parameter: discovery.type=single-node.
services:
es:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.1
ports:
- "9200:9200"
- "9300:9300"
environment:
- discovery.type=single-node

How do I get two dockerized applications to talk on a given port?

I'm trying to get two dockerized applications to speak to eachother on a given port according to my docker-compose.yml file.
They are able to speak to eachother on port app1:61001 and app2:61002, but my friend tells me that they should be able to communicate on port 80. example.. app2:80, and that port 61001 and 61002 should only be the accessible ports exposed out of the swarm.
The applications themselves are set to server.port=80
Any idea how I can get it working as my friend suggests?
Here is the docker-compose file I'm using:
docker compose
version: "3.5"
services:
app1:
image: docker.artifactory.gr.gr.com/app1:latest
ports:
- "61001:80"
deploy:
replicas: 2
networks:
- custom-network
app2:
image: docker.artifactory.gr.gr.com/app2:latest
ports:
- "61002:80"
deploy:
replicas: 2
networks:
- custom-network
networks:
custom-network:
My
first, look if your service expose port 80 with docker-compose ps command.
If is in this case, juste remove folowing code of your both services
ports:
- "61002:80"
if not, remove
ports:
- "61002:80"
and add
expose: 80
and in your app script, to call one service, just call appN:80
I hope i understood your request and i helped you
App1 and App2 are part of the same network that you named custom-network.
This means that the internal port used by the containers ( the one on the right, 80 ) is visible from both applications!
If you have to call a service from APP 1 to APP 2 you simply have to name the container with
hostname: app2 // do the same for the other container
container_name: app2
Then, from app1, you can call the application simply using "app1:80/yourpath".
The port exposed are visible OUTSIDE the network.
In addition:
You can check the connectivity, connecting into app1 application with an iterative shell:https://gist.github.com/mitchwongho/11266726 and then executing
ping app1
you will see that app1 has an internal IP and that is reachable.

Cannot connect to remote MSSQL database from stacked docker container

I have a problem with connecting to existing remote MSSQL database from inside of a docker container running in stack.
My application consists of three modules (backend, frontend and haproxy)
Backend module is written in Java (SpringBoot app) and it's also the one that needs to connect do remote MSSQL database (by remote I mean placed on different sever, separate of docker part).
I have the following docker compose file:
I start the stack by using following command:
docker stack deploy -c docker-compose.yml myapp
The result is, all containers are up and running, but spring app reports that connection to DB is timed out:
Server seems to be configured properly, I am able to access the host from container through telnet.
When running independently (even from docker container) backend app is able to connect to database with no problems, while stacked with docker-compose however it's unable to connect to the very same db.
I've also tried to provide db server IP instead of host name - no success.
Maybe setting up networks section in docker compose would do the trick?
UPDATE
Another thing you can do is to use host.docker.internal instead of the IP address of the database. This ONLY works on docker for windows or docker for mac.
Source: I want to connect from a container to a service on the host
OLD, only works when not in swarm mode
You need to specify that docker should use the same network as the host, you can do this in the following way:
version: '3'
services:
web-app:
build:
dockerfile: web-app/something
ports:
- 8080:8080
network_mode: "host"
Reference: Use host networking
It seems that the issue was caused by networks overlapping.
Adding network configured as show below, allowed either to connect to my remote database and keep my endpoints hidden:
networks:
backend:
ipam:
driver: default
config:
- subnet: 192.168.40.0/26

Trouble communicating between two docker containers

I’m new to docker and I’m trying to connect my spring boot app running into my boot-example docker container to a mysql server running into my mymysql docker container on port 6603, both running on the same phisical machine.
The fact is: if I connect my spring-boot app to my mymysql docker container in order to communicate with the database, I get no errors and everything works fine.
When I move my spring boot application into my boot-example container and try to communicate (through Hibernate) to my mymysql container, then I get this error:
2018-02-05 09:58:38.912 ERROR 1 --- [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
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.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
My spring boot application.properties are:
server.port=8083
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://localhost:6603/mydockerdb
spring.datasource.username=root
spring.datasource.password=mypassword
It works fine until my spring boot app runs in a docker container on port 8082, (after the docker image is correctly built):
docker run -it -p 8082:8083 boot-example
You cannot use localhost inside the container, it's the container itself. Hence, you will always get the connection refused error.
You can do below things -
Add your host machine IP in application.properties file of your spring boot application. (Not recommended since it breaks docker portability logic)
In case you want to use localhost, use --net=host while starting the container. (Not recommended for Production since no logical network layer exists)
Use --links for container communication with a DNS name. (deprecated/legacy)
Create a compose file & call your DB from spring boot app with the service name since they will be in same network & highly integrated with each other. (Recommended)
PS - Whenever you need to integrate multiple containers together, always go for docker-compose version 3+. Use docker run|build to understand the fundamentals & performing dry/test runs.
As #vivekyad4v suggested - the easiest way to achieve your desire, is to use docker-compose which has better container communication integration.
Docker-compose is a tool for managing single or multiple docker container/s. It uses single configuration file called docker-compose.yml.
For better information about docker-compose, please take a look at documentation and compose file reference
In my experience, it is good practice to follow SRP (single responsibility principle), thus - creating one container for your database and one for your application. Both of them are communicating using network you specify in your configuration.
Following example of docker-compose.yml might help you:
version: '2'
networks:
# your network name
somename:
driver: bridge
services:
# PHP server
php:
image: dalten/php5.6-apache
ports:
- 80:80
volumes:
- .application_path:/some/application/path
# your container network name defined at the beggining
networks:
- somename
# Mysql server for backend
mysql:
image: dalten/mysql:dev
ports:
- 3306:3306
# The /var/lib/mysql volume MUST be specified to achieve data persistence over container restart
volumes:
- ./mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: backend
# your container network name defined at the beggining
networks:
- somename
Note: Communication between containers inside network can be achieved by calling the service name from inside container.
The connection parameters to MySQL container from PHP, would in this example be:
hostname: mysql
port: 3306
database: backend
user: root
password: root
As per above suggestion, Docker-compose is a way but if you don't want to go with compose/swarm mode.
Simply create your own network using docker network create myNet
Deploy your containers listening on a created network --network myNet
Change your spring.datasource.url to jdbc:mysql://mymysql:6603/mydockerdb
By using DNS resolution of docker demon, containers can discover each other and hence can communicate.
[DNS is not supported by default bridge. A user-defined network using bridge does.]
For more information: https://docs.docker.com/engine/userguide/networking/

Categories

Resources