Cannot connect from inside docker swarm cluster to external mongodb service - mongodb

If I run single docker container of my backend, it runs well and connects to mongodb which is running on host. But when I run my backend using docker-compose, it doesn't connect to mongodb and prints to console:
MongoError: failed to connect to server [12.345.678.912:27017] on first connect [MongoError: connection 0 to 12.345.678.912:27017 timed out]
docker-compose.yml contents:
version: "3"
services:
web:
image: __BE-IMAGE__
deploy:
replicas: 1
restart_policy:
condition: on-failure
resources:
limits:
cpus: "0.1"
memory: 2048M
ports:
- "1337:8080"
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
ports:
- "1340:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
networks:
webnet:
how I run single docker container:
docker run -p 1337:8080 BE-IMAGE

you need to link the mongo port since localhost is not the same from inside versus outside the containers
ports:
- "1337:8080"
- "27017:27017"
On port definitions left hand side is outside, right side is internal to your container ... Your error says internal to your container it cannot see port 27017 ... above is just linking that mongo port so the container can access that port outside of docker

Related

Docker compose read connection reset by peer error on pipeline

when running a docker compose in a pipeline I'm getting this error when the tests on the pipleine are making use of mycontainer's API.
panic: Get "http://localhost:8080/api/admin/folder": read tcp 127.0.0.1:60066->127.0.0.1:8080: read: connection reset by peer [recovered]
panic: Get "http://localhost:8080/api/admin/folder": read tcp 127.0.0.1:60066->127.0.0.1:8080: read: connection reset by peer
This is my docker copose file:
version: "3"
volumes:
postgres_vol:
driver: local
driver_opts:
o: size=1000m
device: tmpfs
type: tmpfs
networks:
mynetwork:
driver: bridge
services:
postgres:
image: postgres:14
container_name: postgres
restart: always
environment:
- POSTGRES_USER=xxx
- POSTGRES_PASSWORD=xxx
- POSTGRES_DB=newdatabase
volumes:
#- ./postgres-init-db.sql:/docker-entrypoint-initdb.d/postgres-init-db.sql
- "postgres_vol:/var/lib/postgresql/data"
ports:
- 5432:5432
networks:
- mynetwork
mycontainer:
image: myprivaterepo/mycontainer-image:1.0.0
container_name: mycontainer
restart: always
environment:
- DATABASE_HOST=postgres
- DATABASE_PORT=5432
- DATABASE_NAME=newdatabase
- DATABASE_USERNAME=xxx
- DATABASE_PASSWORD=xxx
- DATABASE_SSL=false
depends_on:
- postgres
ports:
- 8080:8080
networks:
- mynetwork
mycontainer is listening on port 8080 and locally everything works fine.
However, when I run the pipeline which is initiating this docker compose is where I'm getting the error.
Basically, I'm running some tests in the pipeline that make use of mycontainer API (http://localhost:8080/api/admin/folder).
If I run the docker compose locally and I reproduce the steps followed on my pipeline to make use of the API everything is working fine. I can comunicate locally with both containers through localhost.
Also, I tried using healthchecks on the containers and 127.0.0.1:8080:8080 on mycontainer & 127.0.0.1:5432:5432 in postgres (including 0.0.0.0:8080:8080 & 0.0.0.0:5342:5432 just in case).
Any idea about that?
I was able to reproduce your error in a pipeline.
Make sure that you are not catching anything (e.g the code that's interacting with your container's API).
You did not mention anything related to your pipeline but just in case, delete the catching on your pipeline.

Encountered errors while bringing up the project+Docker compose

I used SpringBoot RestApi Microservices and MongoDB.
In MongoDB, I have three Databases such as player-db, game-db and score-db.
My services are in the different folders and for each one I defined Dockerfile.
Dockerfile for player service:
FROM openjdk:8
COPY ./target/demo-0.0.1-SNAPSHOT.jar player.jar
EXPOSE 8080
ENTRYPOINT ["java","-Dspring.data.mongodb.uri=mongodb://db:27017/","-jar","-Djava.rmi.server.hostname=0.0.0.0", "player.jar"]
Dockerfile for game service:
FROM openjdk:8
COPY ./target/demo-0.0.1-SNAPSHOT.jar game.jar
EXPOSE 8080
ENTRYPOINT ["java","-Dspring.data.mongodb.uri=mongodb://db1:27017/","-jar","-Djava.rmi.server.hostname=0.0.0.0", "game.jar"]
and Dockerfile for score service:
FROM openjdk:8
COPY ./target/demo-0.0.1-SNAPSHOT.jar score.jar
EXPOSE 8080
ENTRYPOINT ["java","-Dspring.data.mongodb.uri=mongodb://db2:27017/","-jar","-Djava.rmi.server.hostname=0.0.0.0", "score.jar"]
And I defined a docker-compose.yml file:
version: "3"
services:
player-docker:
build:
context: ./
dockerfile: ./src/main/java/spring/multiple/mongo/project/player/DockerFile
restart: always
ports:
- 8080:8080
depends_on:
- db
game-docker:
build:
context: ./
dockerfile: ./src/main/java/spring/multiple/mongo/project/game/DockerFile
restart: always
ports:
- 8080:8080
depends_on:
- db1
score-docker:
build:
context: ./
dockerfile: ./src/main/java/spring/multiple/mongo/project/score/Dockerfile
restart: always
ports:
- 8080:8080
depends_on:
- db2
db:
image: mongo
volumes:
- mongodata:/data/db
ports:
- 27017:27017
restart: always
environment:
MONGO_INITDB_ROOT_DATABASE: player-db
db1:
image: mongo
volumes:
- mongodata:/data/db1
ports:
- 27017:27017
restart: always
environment:
MONGO_INITDB_ROOT_DATABASE: game-db
db2:
image: mongo
volumes:
- mongodata:/data/db2
ports:
- 27017:27017
restart: always
environment:
MONGO_INITDB_ROOT_DATABASE: score-db
volumes:
mongodata:
In fact, in docker-compose file I tried to define different databases for my services, but when I execute docker-compose up I get an error
The ERROR:
$ docker-compose up
Starting springmultiplemongoproject_db_1 ...
Starting springmultiplemongoproject_db2_1 ... error
Creating springmultiplemongoproject_db1_1 ...
ERROR: for springmultiplemongoproject_db2_1 Cannot start service db2: driver fa
iled programming external connectivity on endpoint springmultiplemongoproject_db
2_1 (736a5c8f4a485472d7d5c622f29fd892b533794b352cbccc97dae5c54e3ae54f): Bind for
Creating springmultiplemongoproject_db1_1 ... error
ERROR: for springmultiplemongoproject_db1_1 Cannot start service db1: driver fa
Starting springmultiplemongoproject_db_1 ... done
1_1 (e0ea7a6e31f0bec010ccfef67705732904d3fcf0eee55cee8577d464583070ff): Bind for
0.0.0.0:27017 failed: port is already allocated
Creating springmultiplemongoproject_player-docker_1 ... done
ERROR: for db2 Cannot start service db2: driver failed programming external con
nectivity on endpoint springmultiplemongoproject_db2_1 (736a5c8f4a485472d7d5c622
f29fd892b533794b352cbccc97dae5c54e3ae54f): Bind for 0.0.0.0:27017 failed: port i
s already allocated
ERROR: for db1 Cannot start service db1: driver failed programming external con
nectivity on endpoint springmultiplemongoproject_db1_1 (e0ea7a6e31f0bec010ccfef6
7705732904d3fcf0eee55cee8577d464583070ff): Bind for 0.0.0.0:27017 failed: port i
s already allocated
ERROR: Encountered errors while bringing up the project.
I am beginner in Docker, and I read many documents, but I could not find any solution.
This image might help you to understand why we have to write a different port for the host machine.
The container is an OS in itself. But the container is connecting to the outside OS which is hosting multiple containers. So to help host machine to identify which container you are talking to, we need to use a different port number
You are binding the same host ports to different docker services. You have to specify different host ports for each service. The syntax for specifying ports is as follows:
ports:
- "HOST:CONTAINER"
So for the HOST part you need different port numbers
version: "3"
services:
player-docker:
...
ports:
- 8081:8080
game-docker:
...
ports:
- 8082:8080
score-docker:
...
ports:
- 8083:8080
db:
...
ports:
- 27018:27017
db1:
...
ports:
- 27019:27017
db2:
...
ports:
- 27019:27017
...
Or if you want docker compose to assign host port numbers for you, you can omit the HOST part, like this
version: "3"
services:
player-docker:
...
ports:
- 8080
game-docker:
...
ports:
- 8080
score-docker:
...
ports:
- 8080
db:
...
ports:
- 27017
db1:
...
ports:
- 27017
db2:
...
ports:
- 27017
...
Or if you don't want to bind ports to the host for the database services, you can just omit the ports part

Connecting two a database in a another container with docker-compose

I'm trying to set up a docker-compose where one container has the database and the other one has the application. To my best knowledge, I need to connect two containers with a network.
version: "3"
services:
psqldb:
image: "postgres"
container_name: "psqldb"
environment:
- POSTGRES_USER=usr
- POSTGRES_PASSWORD=pwd
- POSTGRES_DB=mydb
ports:
- "5432:5432"
expose:
- "5432"
volumes:
- $HOME/docker/volumes/postgres/:/var/lib/postgresql/data
networks:
- backend
sbapp:
image: "dsb"
container_name: "dsb-cont"
ports:
- "8080:8080"
expose:
- "8080"
depends_on:
- psqldb
networks:
- backend
networks:
backend:
I also tried it with setting network driver to bridge (which didn't change the end result)
networks:
backend:
driver: bridge
I'm using the following url to connect to the database
spring.datasource.url=jdbc:postgresql://psqldb:5432/mydb
I also tried to expose the port and connect using localhost
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
I also tried to use port 5433 instead of 5432.
No matter what combination I used, I got the following error
Connection to psqldb:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
in my app container. However, my database container remains up and I can connect to it fine from host with the url
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
I can also connect to the database from host if I remove psqldb container entirely from docker-compose.yml (and use the latter connection url).
If it makes any difference, I'm using Spring
Boot for application with the Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
and I'm building the image with the command
docker build --build-arg JAR_FILE=target/*.jar -t dsb .
What am I missing in the two container setup?
The issue I had was that docker depends_on only starts the containers in the defined order but doesn't wait for them to be actually ready.
https://docs.docker.com/compose/startup-order/

Docker compose: can not connect node container to Mongo container using the same network

This is docker-compose.yml
version: "3"
services:
web:
build: ./rqiim
command: curl "127.0.0.1:27017"
volumes:
- ./rqiim:/app
- /app/node_modules/
environment:
- MONGO_HOSTNAME=127.0.0.1
ports:
- "8080:8080"
networks:
- host
mongodb:
image: mongo:3.4.18-jessie
container_name: mongodb
volumes:
- /data/db:/data/db
- ./mongo:/etc/mongo
command: --config /etc/mongo/mongod.conf
hostname: mongod1
ports:
- "27017:27017"
networks:
- host
networks:
host:
When I run docker-compose up I get Failed to connect to 127.0.0.1 port 27017: Connection refused
What seems to be the problem, they are on the same network plus I connect to MongoDB container from outside off docker locally just fine.
Here is the content of /etc/mongo/mongod.conf
storage:
dbPath: /data/db
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
# network interfaces
net:
port: 27017
replication:
replSetName: rs0
As everywhere else in Docker, 127.0.0.1 usually means "this container". The various mentions of host in your docker-compose.yml file actually create a bridge-type NAT network that happens to be named "host"; it does not enable host networking mode. This having been said, host networking mode is usually unnecessary, so let's get this right:
First of all, Docker Compose on its own will automatically create a private bridge-type network for each separate docker-compose.yml file, so you don't need any networks: blocks at all here. Since it does this, the names of the service blocks web and mongodb will be valid host names for one container to reach another.
In the web: service, you're replacing its command with a curl command. Once that command completes the service will exit, which almost certainly isn't what you want. You haven't included the relevant Dockerfile, but I'll guess it ends with a line like CMD ["npm", "start"] that gives a more useful default command. The volume declarations are also a little odd: having volumes to hold code isn't a typical use case and you'd usually COPY the (built) application tree into the image in the Dockerfile. (Using volumes to hold persistent data and inject config files, like you have for the mongodb: service, is very reasonable.)
You also don't need to explicitly set the container_name: or hostname: of individual containers except in really unusual circumstances.
Stripping that out and fixing the host name, we should get:
version: '3'
services:
web:
build: ./rqiim
environment:
- MONGO_HOSTNAME=mongodb
ports:
- "8080:8080"
mongodb:
image: mongo:3.4.18-jessie
volumes:
- /data/db:/data/db
- ./mongo:/etc/mongo
command: --config /etc/mongo/mongod.conf
ports:
- "27017:27017"

How to access postgres-docker container other docker container without ip address

How to access postgres-docker container other docker container without ip address?
I want to store data in postgres by using myweb. in jar given host like localhost:5432/db..
Here my compose file:
version: "3"
services:
myweb:
build: ./myweb
container_name: app
ports:
- "8080:8080"
- "9090:9090"
networks:
- front-tier
- back-tier
depends_on:
- "postgresdb"
postgresdb:
build: ./mydb
image: ppk:postgres9.5
volumes:
- dbdata:/var/lib/postgresql
ports:
- "5432:5432"
networks:
- back-tier
volumes:
dbdata: {}
networks:
front-tier:
back-tier:
Instead of localhost:5432/db.. use postgresdb:5432/db.. connection string.
By default the container has the same hostname as the service name.
Here is my minimal working example, which is connecting a java client (boxfuse/flyway) with postgres server. The most important part is the heath check, which is delaying the start of the myweb container to the time when postgres is ready to accept connections.
Note that this can be directly executed by docker-compose up, it dosen't have any other dependencies. Both the images are from docker hub.
version: '2.1'
services:
myweb:
image: boxfuse/flyway
command: -url=jdbc:postgresql://postgresdb/postgres -user=postgres -password=123 info
depends_on:
postgresdb:
condition: service_healthy
postgresdb:
image: postgres
environment:
- POSTGRES_PASSWORD=123
healthcheck:
test: "pg_isready -q -U postgres"
That is the Docker Networking problem. The solution is to use postgresdb:5432/db in place of localhost:5432/db because the two service is in the same network named back-tier and docker deamon will use name service like a DNS name to make communication between the two container. I think that my solution will help you so.