Docker Compose Postgres Container connection refused from hosting machine - postgresql

I have the following definition of docker-compose file with postgres image that I want to run and connect to it from hosting machine of my PC, but I'm getting Connection Refused localhost:5432 all the time. I realize that container has to be run on host network driver, but network mode doesn't solve this problem. What I'm doing wrong?
I run this with docker-compose -f [file] up on Windows 10 with Docker for Desktop
version: '3.7'
services:
database:
image: postgres:10.6
restart: always
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=p0stgr#s
- POSTGRES_DB=eagle_eye_local
network_mode: host
When I run the same container with the following command it works:
docker container run --name postgres10.6 -e POSTGRES_PASSWORD=p0stgr#s -e POSTGRES_USER=postgres -e POSTGRES_DB=eagle_eye_local -p 5432:5432 postgres:10.6

I'm assuming you are not running natively on linux but use some Docker for Desktop. Then the short answer is: Remove the network_mode: host and the compose setup will work the same way your docker run command works.
version: '3.7'
services:
database:
image: postgres:10.6
restart: always
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=p0stgr#s
- POSTGRES_DB=eagle_eye_local
The two examples you provided are not really equal even though they can lead to some similar results when run on a real linux host (similar in a way that on a linux host you will be able to access the postgres instance via localhost:5432 on the host machine).
If you run the given compose file on Docker for Desktop (Mac or Windows) you must keep in mind that in this case there is a VM running your containers and all commands are passed into that VM. If you don't use network_mode: host Docker will (1) expose the port correctly on the VM and (2) have some proxy process in place on your host machine (mac/windows) to forward the traffic into the VM. This basically doesn't work when you start the container with network_mode: host.
You can verify the established mapping when running docker ps under the Ports column. This will be empty if you run with network_mode: host.
For some more details see the discussions in the docker forum.

Related

Docker with postgresql in flask web application (part 2)

I am building a Flask application in Python. I'm using SQLAlchemy to connect to PostgreSQL.
In the flask application, I'm using this to connect SQLAlchemy to PostgreSQL
engine = create_engine('postgresql://postgres:[mypassword]#db:5432/employee-manager-db')
And this is my docker-compose.yml
version: '3.8'
services:
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- 8000:8000
volumes:
- .:/app
links:
- db:db
depends_on:
- pgadmin
db:
image: postgres:14.5
restart: always
volumes:
- .dbdata:/var/lib/postgresql
hostname: postgres
environment:
POSTGRES_PASSWORD: [mypassword]
POSTGRES_DB: employee-manager-db
pgadmin:
image: 'dpage/pgadmin4'
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: [myemail]
PGADMIN_DEFAULT_PASSWORD: [mypassword]
ports:
- "5050:80"
depends_on:
- db
I can do "docker build -t employee-manager ." to build the image. However, when I do "docker run -p 5000:5000 employee-manager" to run the image, I get an error saying
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Try again
Does anybody know how to fix this? Thank you so much for your help
Your containers are on different networks and that is why they don't see each other.
When you run docker-compose up, docker-compose creates a separate network and puts all the services defined inside docker-compose.yml on that network. You can see that with docker network ls.
When you run a container with docker run, it is attached to the default bridge network, which is isolated from other networks.
There are several ways to fix this, but this one will serve you in many other scenarios:
Run docker container ls and identify the name or ID of the db container that was started with docker-compose
Then run your container with:
# ID_or_name from the previous point
docker run -p 5000:5000 --network container:<ID_or_name> employee-manager
This attached the new container to the same network as your database container.
Other ways include creating a network manually and defining that network as default in the docker-compose.yml. Then you can use docker run --network <network_name> ... to attach other containers to that network.
docker run doesn't read any of the information in the docker-compose.yml file, and it doesn't see things like the Docker network that Compose automatically creates.
In your case you already have the service fully-defined in the docker-compose.yml file, so you can use Compose commands to build and restart it
docker-compose build
docker-compose up -d # will delete and recreate changed containers
(If the name of the image is important to you – maybe you're pushing to a registry – you can specify image: alongside build:. links: are obsolete and you should remove them. I'd also avoid replacing the image's content with volumes:, since this misses any setup or modification that's done in the Dockerfile and it means you're running untested code if you ever deploy the image without the mount.)

Connecting to Postgres Docker server - authentication failed

I have a PostgreSQL container set up that I can successfully connect to with Adminer but I'm getting an authentication error when trying to connect via something like DBeaver using the same credentials.
I have tried exposing port 5432 in the Dockerfile and can see on Windows for docker the port being correctly binded. I'm guessing that because it is an authentication error that the issue isn't that the server can not be seen but with the username or password?
Docker Compose file and Dockerfile look like this.
version: "3.7"
services:
db:
build: ./postgresql
image: postgresql
container_name: postgresql
restart: always
environment:
- POSTGRES_DB=trac
- POSTGRES_USER=user
- POSTGRES_PASSWORD=1234
ports:
- 5432:5432
adminer:
image: adminer
restart: always
ports:
- 8080:8080
nginx:
build: ./nginx
image: nginx_db
container_name: nginx_db
restart: always
ports:
- "8004:8004"
- "8005:8005"
Dockerfile: (Dockerfile will later be used to copy ssl certs and keys)
FROM postgres:9.6
EXPOSE 5432
Wondering if there is something else I should be doing to enable this to work via some other utility?
Any help would be great.
Thanks in advance.
Update:
Tried accessing the database through the IP of the postgresql container 172.28.0.3 but the connection times out which suggests that PostgreSQL is correctly listening on 0.0.0.0:5432 and for some reason the user and password are not usable outside of Docker even from the host machine using localhost.
Check your pg_hba.conf file in the Postgres data folder.
The default configuration is that you can only login from localhost (which I assume Adminer is doing) but not from external IPs.
In order to allow access from all external addresses vi password authentication, add the following line to your pg_hba.conf:
host all all * md5
Then you can connect to your postgres DB running in the docker container from outside, given you expose the Port (5432)
Use the command docker container inspect ${container_number}, this will tell you which IPaddress:ports are exposed external to the container.
The command 'docker container ls' will help identify the 'container number'
After updating my default db_name, I also had to update the docker-compose myself by explicitly exposing the ports as the OP did
db:
image: postgres:13-alpine
volumes:
- dev-db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=devdb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=1234
ports:
- 5432:5432
But the key here was restarting the server! DBeaver has connected to localhost:5432 :)

Docker compose doesn't connect two containers

I have two containers that don't connect to each other:
1. I made an image postgres that get data from dump.sql
here is Dockerfile:
FROM postgres:11.1-alpine
COPY restore_db.sh /docker-entrypoint-initdb.d/
COPY db.sql /backup/
ENV PGDATA=/data
Then I created container with docker run --name db -p 5432:5432 db
4.I made a image with app. Dockerfile for app look like:
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY build/libs/ /app/
# Make port 80 available to the world outside this container
EXPOSE 8085
# Define environment variable
ENV NAME app
# Run app when the container launches
CMD java -jar /app/olympic-0.0.1-SNAPSHOT.jar
I made a container with run.
then i use docker-compose up with file that looks like:
version: '3'
services:
db:
image: db-data
container_name: postgres
ports:
- 5432:5432
volumes:
- ./pg_data:/data
environment:
POSTGRES_DB: innovation
POSTGRES_USER: postgres
PGDATA: /data
restart: always
web:
image: app
container_name: roc
environment:
POSTGRES_HOST: db
ports:
- 8085:8085
restart: always
links:
- db
```
here is property file:
```
spring.datasource.url=jdbc:postgresql://db:5432/innovation
spring.datasource.username=postgres
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.root=INFO
spring.output.ansi.enabled=ALWAYS
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.liquibase.change-log=classpath:liqubase/db.changelog-master.xml
spring.liquibase.url=jdbc:postgresql://db:5432/innovation
spring.liquibase.user=postgres
```
Thet are not able to be connected.
I always got an error:
org.postgresql.util.PSQLException: Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
First of all I dont see any network defined in your Docker files for both containers
So I assume ther are on $project-default network.
docker network inspect $project-default
will give you list of all containers using default network.
Now coming to the containers, Let's assume DB is Container 1 (10.1.1.2) and Spring App is Container 2 (10.1.1.3).
You can get running containers IP by running
docker inspect containerName
You are exposing 5432 and 8085 port for db and Spring respectively
Inside Spring app container property file spring.datasource.url
localhost:5432 or db:5432 (not sure what is db hostname mapped to) is not accessable as DB is in different container.
You can try 10.1.1.2:5432
When you are exposing 5432 and 8085 port from Host machine you can access these port.
eg in Docker for Windows it would be 192.168.99.100:5432
but same cant be access from inside container.
spring.datasource.url=jdbc:postgresql://10.1.1.2:5432/innov should work assuming DB is up and running

docker-compose external_link mongo network not reachable

I am having a strange situation where I can not connect to my running mongo DB in my docker compose. My compose file:
version: '3'
services:
app:
image: myimage:latest
ports:
- "8080:8080"
external_links:
- myname:mongo
environment:
- MONGO_URL=mongodb://myname:27017/test
I have found a few infos on that that all did not solve my issue. I.e. I tried:
1)
Create a custom network:
docker network create mongonet
Then start mongo with the --network mongonet flag and add to the compose:
networks:
default:
external:
name: mongonet
Got nothing there either.
I looked into my /etc/hosts file on my compose, and it did not list any DNS entry.
If i do a docker inspect and grab the mongo IP and add it to my compose, that is fine and works like a charm.
I start mongo like this:
docker run -d -p 27017:27017 -v ~/mongo_data:/data/db mongo
I am really rather confused as I believed this to be a out-of-the-box kind of thing. Strangely I can't make it work. I have found examples on internal links (vs external_link) but that does not work for me as I have many services that I would like to run like this and not all of them should run at the same time.
I start my docker compose as this:
docker-compose up --force-recreate
My versions are:
docker-compose version 1.17.1, build 6d101fb
Docker version 17.05.0-ce, build 89658be
My question: How do I successfully link a running mongo container as an external link into my application containers such that they can connect to them?
My docker PS:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cf6e08d6fde mongo "docker-entrypoint..." About an hour ago Up About an hour 0.0.0.0:27017->27017/tcp gallant_feynman
Links are deprecated, use networks instead.
Notes:
If you’re using the version 2 or above file format, the
externally-created containers must be connected to at least one of the
same networks as the service which is linking to them. Links are a
legacy option. We recommend using networks instead.
The network way should work. I think you are missing some pieces. Make sure to give the mongo container a name, and make sure to attach the app container to the network in the compose file:
docker network create mongonet
docker run -d -p 27017:27017 --network mongonet --name mongo -v ~/mongo_data:/data/db mongo
version: '3'
services:
app:
image: myimage:latest
ports:
- "8080:8080"
environment:
- MONGO_URL=mongodb://mongo:27017/test
networks:
- mongonet
networks:
default:
external:
name: mongonet

How to run docker containers in host network mode using docker-compose?

I need to run containers from docker-compose in host network mode.
For example, if I run single container, I write:
docker run --net=host my_image
How to do this part --net=host in docker-compose?
The equivalent in docker-comopose is network_mode: host see the documentation in: https://docs.docker.com/compose/compose-file/
add directory network_mode of the networks section to your service definition in your docker-compose.yml
also, pay attention network_mode is incompatible with port_bindings:
version: '3.5'
services:
server:
image: custome image
container_name: "sample"
command: bash -c "python sample.py"
network_mode: host