Encountered errors while bringing up the project+Docker compose - mongodb

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

Related

docker springboot only connects on postgres 5432 via docker-compose

Using docker to connect springboot to postgres via docker-compose. Using port 5432 on postgres works fine, if i try an port other than that it fails
working code
spring
spring.datasource.url=jdbc:postgresql://db:5432/wwc
spring.datasource.username=wwc
spring.datasource.password=test
spring.datasource.driver-class-name=org.postgresql.Driver
docker-compose
version: '2.1'
services:
db:
container_name: db
image: postgres:9.4
ports:
- 5432:5432
volumes:
- /tmp:/var/lib/postgresql
environment:
- POSTGRES_USER=wwc
- POSTGRES_DB=wwc
- POSTGRES_PASSWORD=test
server:
container_name: spring-boot-rest-server
build:
context: .
dockerfile: Dockerfile.server
ports:
- 8080:8080
logging:
driver: json-file
depends_on:
- db
web:
container_name: nginx-web
links:
- "server:springboot"
build:
context: .
dockerfile: Dockerfile.web
ports:
- 80:80
- 8088:8088
logging:
driver: json-file
depends_on:
- server
**connection refused code **
spring
spring.datasource.url=jdbc:postgresql://db:6000/wwc
spring.datasource.username=wwc
spring.datasource.password=test
spring.datasource.driver-class-name=org.postgresql.Driver
docker-compose
version: '2.1'
services:
db:
container_name: db
image: postgres:9.4
ports:
- 6000:5432
volumes:
- /tmp:/var/lib/postgresql
environment:
- POSTGRES_USER=wwc
- POSTGRES_DB=wwc
- POSTGRES_PASSWORD=test
server:
container_name: spring-boot-rest-server
build:
context: .
dockerfile: Dockerfile.server
ports:
- 8080:8080
logging:
driver: json-file
depends_on:
- db
web:
container_name: nginx-web
links:
- "server:springboot"
build:
context: .
dockerfile: Dockerfile.web
ports:
- 80:80
- 8088:8088
logging:
driver: json-file
depends_on:
- server
error:
spring-boot-rest-server | org.postgresql.util.PSQLException: Connection to db:6000 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
What am i doing wrong?
You are confusing a bit the ports: your "db" container only exports 1 port: 5432. The 6000 that you put in your docker-compose is the port on localhost that you map to that container (db) on that port (5432).
You shouldn't even use the port mappings for the postgres container unless you want to connect from localhost which I guess you don't.
If you want to use another port than 5432 you need to extend the postgres Dockerfile and change the configuration so that postgres starts listening on a different port.
Hope this helps.
In other words: The port mapping configured in docker-compose has no relevancy to how the containers connect to each other. The mapping is only relevant when something/someone attempts to connect to your containers within the docker-compose from the outside. (Like from the localhost, as #Mihai remarked.)

AdminMongo with docker-compose doesn't work

I'm trying to access to my mongo database on docker with adminmongo.
Here's my docker-compose.yml
version: '3'
services:
mongo:
image: mongo
volumes:
- ~/data:/data/db
restart: always
expose:
- 6016
adminmongo:
image: mrvautin/adminmongo
expose:
- 1234
links:
- mongo:mongo
When i do a docker-compose up everything works fine, adminmongo also return me this : adminmongo_1_544d9a6f954c | adminMongo listening on host: http://localhost:1234
But when i go to localhost:1234 my navigator is telling me this page doesn't exist.
Here's what a docker ps return me :
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c27d4a89254 mrvautin/adminmongo "/bin/sh -c 'node ap…" 38 seconds ago Up 33 seconds 1234/tcp iris_adminmongo_1_544d9a6f954c
2a7496a8c56a mongo "docker-entrypoint.s…" 40 minutes ago Up 38 seconds 6016/tcp, 27017/tcp iris_mongo_1_7f00356a3adc
I've found 2 issues here:
1st: Exposing a port is not enough. expose is just documentation, you need to publish (bind) a port to the host to be reachable. This is how it's done:
ports:
- 1234:1234
2nd: you have to configure adminmongo to listen to 0.0.0.0 because by default it starts listening on 127.0.0.1 and this makes it accessible only inside the container itself. From the documentation page you've included in your question, the Configuration section states that this can be done by passing an environment variable:
All above parameters are usable through the environment which makes it very handy to when using adminMongo as a docker container! just run docker run -e HOST=yourchoice -e PORT=1234 ...
Since you are using docker-compose, this is done by the following:
environment:
- HOST=0.0.0.0
Working example:
version: '3'
services:
mongo:
image: mongo
volumes:
- ~/data:/data/db
restart: always
expose:
- 6016
adminmongo:
image: mrvautin/adminmongo
ports:
- 1234:1234
environment:
- HOST=0.0.0.0
Example of docker-compose works :
version: '3'
services:
server:
container_name: docker_api_web_container
image: docker_api_web
build: .
volumes:
- ./src:/usr/src/node-app/src
- ./package.json:/usr/src/node-app/package.json
environment:
- ENV=DEVELOPMENT
- PORT=4010
ports:
- '9000:4010'
depends_on:
- 'mongo'
mongo:
container_name: docker_mongo_container
image: 'mongo'
ports:
- '27017:27017'
adminmongo:
container_name: docker_adminmongo_container
image: mrvautin/adminmongo
links: ['mongo:mongo']
environment:
- HOST=0.0.0.0
ports:
- '1234:1234'
You have to expose your service to the outside world like this:
version: '3'
services:
mongo:
image: mongo
volumes:
- ~/data:/data/db
restart: always
adminmongo:
image: mrvautin/adminmongo
ports:
- 1234:1234
Now you can access your adminmongo by http://localhost:1234.
And you don't have to use links here.Since compose creates a network and joins all services in the compose files. You can access other containers with their service names.

Connecting pgadmin to postgres in docker

I have a docker-compose file with services for python, nginx, postgres and pgadmin:
services:
postgres:
image: postgres:9.6
env_file: .env
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5431:5431"
pgadmin:
image: dpage/pgadmin4
links:
- postgres
depends_on:
- postgres
environment:
PGADMIN_DEFAULT_EMAIL: admin#admin.com
PGADMIN_DEFAULT_PASSWORD: pwdpwd
volumes:
- pgadmin:/root/.pgadmin
ports:
- "5050:80"
backend:
build:
context: ./foobar # This refs a Dockerfile with Python and Django requirements
command: ["/wait-for-it.sh", "postgres:5431", "--", "/gunicorn.sh"]
volumes:
- staticfiles_root:/foobar/static
depends_on:
- postgres
nginx:
build:
context: ./foobar/docker/nginx
volumes:
- staticfiles_root:/foobar/static
depends_on:
- backend
ports:
- "0.0.0.0:80:80"
volumes:
postgres_data:
staticfiles_root:
pgadmin:
When I run docker-compose up and visit localhost:5050, I see the pgadmin interface. When I try to create a new server there, with localhost or 0.0.0.0 as host name and 5431 as port, I get an error "Could not connect to server". If I remove these and instead enter postgres in the "Service" field, I get the error "definition of service "postgres" not found". How can I connect to the database with pgadmin?
the docker container name changes when you run docker-compose to prefix the folder name (to keep container names unique). You could force the name of the container with container_name property
version: "3"
services:
# postgres database
postgres:
image: postgres:12.3
container_name: postgres
environment:
- POSTGRES_DB=admin
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=admin
- POSTGRES_HOST_AUTH_METHOD=trust # allow all connections without a password. This is *not* recommended for prod
volumes:
- database-data:/var/lib/postgresql/data/ # persist data even if container shuts down
ports:
- "5432:5432"
# pgadmin for managing postgis db (runs at localhost:5050)
# To add the above postgres server to pgadmin, use hostname as defined by docker: 'postgres'
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin
environment:
- PGADMIN_DEFAULT_EMAIL=admin
- PGADMIN_DEFAULT_PASSWORD=admin
- PGADMIN_LISTEN_PORT=5050
ports:
- "5050:5050"
volumes:
database-data:
Another option is to connect the postgres container to localhost with
network_mode: host
But you lose the nice network isolation from docker that way
Be careful that the default postgres port is 5432 not 5431. You should update the port mapping for the postgres service in your compose file. The wrong port might be the reason for the issues you reported. Change the port mapping and then try to connect to postgres:5432. localhost:5432 will not work.

Cannot connect to postico from docker-compose postgresql service

I've done a docker-compose up and been able to run my web service attached to a postgresql image. Problem is, I can't view the data on postico when I try to access the database. The name of the image is db and when i try to specify hostname to be "db" on postico before i connect, i get an error saying hostname not found. I've entered my credentials, port and database name the same way i keyed them in my docker-compose file.
Does anybody know how i can find the correct setup to connect to within the container?
version: '3.6'
services:
phoenix:
# tell docker-compose which Dockerfile it needs to build
build:
context: .
dockerfile: Dockerfile.phoenix.development
# map the port of phoenix to the local dev port
ports:
- 4000:4000
# mount the code folder inside the running container for easy development
volumes:
- ./my_app:/app
# make sure we start mongodb when we start this service
# links:
# - db
depends_on:
- db
- redis
environment:
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
FACEBOOK_CLIENT_ID: ${FACEBOOK_CLIENT_ID}
FACEBOOK_CLIENT_SECRET: ${FACEBOOK_CLIENT_SECRET}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
go:
build:
context: .
dockerfile: Dockerfile.go.development
ports:
- 8080:8080
volumes:
- ./genesys-api:/go/src/github.com/sc4224/genesys-api
depends_on:
- db
- redis
- phoenix
db:
container_name: db
image: postgres:latest
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
volumes:
- ./data/db:/data/db
restart: always
redis:
container_name: redis
image: redis:latest
ports:
- "6379:6379"
volumes:
- ./data/redis:/data/redis
entrypoint: redis-server
restart: always
use hostname as localhost.
You can't use the hostname db outside the internal docker network. That would work in the applications running in the same network.
Since you exposed the db to run on port 5432, it's exposed via 0.0.0.0:5432->5432/tcp and therefore is accessible with localhost as host and port 5432

Can't connect to Postgres docker container from Golang container

I have a web server built using golang. It works successfully when I test it locally.
However, when I build a docker image for my web server, it can't connect to a running Postgres container.
Here is my docker-compose.yml:
version: '2'
services:
go:
image: golang:1.7
volumes:
- ./:/server/http
ports:
- "80:8080"
links:
- postgres
- mongodb
- redis
environment:
DEBUG: 'true'
PORT: '8080'
postgres:
image: onjin/alpine-postgres:9.5
restart: unless-stopped
ports:
- "5432:5432"
environment:
LC_ALL: C.UTF-8
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
mongodb:
image: mvertes/alpine-mongo:3.2.3
restart: unless-stopped
ports:
- "27017:27017"
redis:
image: sickp/alpine-redis:3.2.2
restart: unless-stopped
ports:
- "6379:6379"
My Dockerfile:
FROM golang:1.7
RUN mkdir -p /home/app
WORKDIR /home/app
COPY . /home/app
RUN make deps && make
ENTRYPOINT ["./bin/api-test"]
EXPOSE 8080
The Postgres connection string I am using:
postgresql://user:pass#host/mydb?sslmode=disable
For host, I tried localhost and it returns the following error:
dial tcp [::1]:5432: getsockopt: connection refused
Tried postgres and it returns the following:
dial tcp 202.71.99.194:5432: getsockopt: connection refused
Tried the IP address I get running this command which returns 172.19.0.3:
docker inspect apitest_postgres_1 | grep IPAddress
where apitest_postgres_1 is Postgres container name. It also returned this error:
dial tcp 172.19.0.3:5432: getsockopt: connection timed out
Can you please tell me what I am missing here? I am inexperienced with docker and this took a long time investigating for a solution.
Edit:
I run my golang docker using this command:
docker run --env-file ./example.env --rm -it -p 8080:8080 api-test
example.env is the file contains my environment vars.
Edit 2:
I changed the connection string to the following:
postgresql://user:pass#postgres:5432?sslmode=disable
It returns the following error:
dial tcp: lookup postgres on 192.168.65.1:53: no such host
I'm getting the idea that my mac is the issue here. My default DNS is 8.8.8.8 which should not be a problem.
Looks like you're pulling go image instead of building you're own image.
Instead of image: golang:1.7 replace it with build: . to build and use your Dockerfile.
Also you might need to pass postgres environment variables DB_HOST, DB_USER, DB_PASS etc. you can achieve that but creating for example docker.env file and then add env_file under your go app docker-compose.yml file:
Example docker.env :
DB_HOST=postgres
DB_USER=user
DB_PASS=pass
DB_NAME=mydb
Corrected docker-compose.yml :
version: '2'
services:
app:
build: .
volumes:
- ./:/server/http
ports:
- "80:8080"
links:
- postgres
- mongodb
- redis
environment:
DEBUG: 'true'
PORT: '8080'
env_file:
- docker.env
postgres:
image: onjin/alpine-postgres:9.5
restart: unless-stopped
ports:
- "5432:5432"
environment:
LC_ALL: C.UTF-8
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
mongodb:
image: mvertes/alpine-mongo:3.2.3
restart: unless-stopped
ports:
- "27017:27017"
redis:
image: sickp/alpine-redis:3.2.2
restart: unless-stopped
ports:
- "6379:6379"
In order to make a connection to postgres in docker compose becomes established, you need to replace localhost or 127.0.0.1 or postgres in your connection string with the name of the container being mentioned in your docker compose file.
For example, in your docker-compose.yaml file create database like this:
db:
container_name: composepostgres
image: postgres
environment:
and then, in your code when creating your connection string, avoid using 127.0.0.1 or localhost or postgres, and instead use composepostgres in the place of them.
If not doing so, you will face with dial tcp 127.0.0.1:5432: connect: connection refused error.
Take a look a this documentation : https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/
Then, regarding the links in you docker-compose file, replace "host" by "postgres" in you connection string :
postgresql://user:pass#postgres/mydb?sslmode=disable
Let the embedded DNS server do the mapping work because the ip address may change every time you recreate the container.
Also, ensure postgres allows connection (maybe limited to localhost)