Changing a postgres containers server port in Docker Compose - postgresql

I am trying to deploy a second database container on a remote server using Docker compose. This postgresql server runs on port 5433 as opposed to 5432 as used by the first postgresql container.
When I set up the application I get this error output:
web_1 | django.db.utils.OperationalError: could not connect to server: Connection refused
web_1 | Is the server running on host "db" (172.17.0.2) and accepting
web_1 | TCP/IP connections on port 5433?
and my docker compose file is:
db:
image: postgres:latest
environment:
POSTGRES_PASSWORD: route_admin
POSTGRES_USER: route_admin
expose:
- "5433"
ports:
- "5433"
volumes:
- ./backups:/home/backups
web:
build: .
command: bash -c "sleep 5 && python -u application/manage.py runserver 0.0.0.0:8081"
volumes:
- .:/code
ports:
- "81:8081"
links:
- db
environment:
- PYTHONUNBUFFERED=0
I feel the issue must be the postgresql.conf file on the server instance having set the port to 5432 causing the error when my app tries to connect to it. Is there a simple way of changing the port using a command in the compose file as opposed to messing around with volumes to replace the file?
I am using the official postgresql container for this job.

Some people may wish to actually change the port Postgres is running on, rather than remapping the exposed port to the host using the port directive.
To do so, use command: -p 5433
In the example used for the question:
db:
image: postgres:latest
environment:
POSTGRES_PASSWORD: route_admin
POSTGRES_USER: route_admin
expose:
- "5433" # Publishes 5433 to other containers but NOT to host machine
ports:
- "5433:5433"
volumes:
- ./backups:/home/backups
command: -p 5433
Note that only the host will respect the port directive. Other containers will not.

Assuming postgres is running on port 5432 in the container and you want to expose it on the host on 5433, this ports strophe:
ports:
- "5433:5432"
will expose the server on port 5433 on the host. You can get rid of your existing expose strophe in this scenario.
If you only want to expose the service to other services declared in the compose file (and NOT localhost), just use the expose strophe and point it to the already internally exposed port 5432.

Related

How are these Docker setups different? One works and the other not

I'm running Postgres image in Docker on an M1 Mac with mapped ports "5432:5432". My app can connect to the DB from the host machine by calling localhost:5432. I'm now trying to run the app within Docker and I'm puzzled by the behavior I see.
This command works:
docker run --name api --add-host host.docker.internal:host-gateway -e DB_HOST=host.docker.internal -p 8000:8000
But when I try to replicate the same by putting the api within the docker-compose like this, it doesn't work:
services:
postgres:
image: postgres:14.2
ports:
- "5432:5432"
networks:
- my-network
api:
image: api
environment:
DB_HOST: host.docker.internal
extra_hosts:
- "host.docker.internal:host-gateway"
Connecting to the DB fails:
failed to connect to host=host.docker.internal user=postgres database=postgres: failed to receive message (unexpected EOF)
I've also tried to put the api container on the same my-network network as postgres, and changing the DB host to be the DB container:
api:
image: api
environment:
DB_HOST: postgres
networks:
- my-network
but that gives me a different error:
failed to connect to host=postgres user=postgres database=postgres: dial error (dial tcp 192.168.192.2:5432: connect: connection refused)
The DB is listening at IPv4 address "0.0.0.0", port 5432 and IPv6 address "::", port 5432. Why would the docker run command work but the other two not work?
As David figured out the issue in the comments, I would like to suggest wait-for-it for such an issue, Instant of waiting a bit then start manually again.
wait-for-it.sh usually located at entrypoint.sh like this
#!/bin/sh
# Wait fot the cassandra db to be ready
./wait-for.sh cassandra:9042 --timeout=0
--timeout=0 , will keep on waiting till cassandra is up and running.
And can be used directly in docker-compose.yaml like the following example :
version: "2"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "cassandra"
command: ["./wait-for-it.sh", "cassandra:9042"]
db:
image: cassandra
For more information, You can check Control startup and shutdown order in Compose
Wait-for-it github

How compose java and Postgres in docker [duplicate]

The Dockerfile of my spring-boot app:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY target/media-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/media
username: postgres
password: postgres
hikari:
connectionTimeout: 30000
and here is the docker-compose.yml:
version: '3'
services:
db:
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_DB: media
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
app:
build:
context: ./
dockerfile: Dockerfile
depends_on:
- db
ports:
- "8080:8080"
Running docker-compose up --build results in:
app_1 | org.postgresql.util.PSQLException: Connection to 0.0.0.0:5432
refused. Check that the hostname and port are correct and that the
postmaster is accepting TCP/IP connections. app_1
My guess is that the spring app tries to connect to postgres before postgres is ready, but I get the following log:
db_1 | 2019-05-18 19:05:53.692 UTC [1] LOG: database system is
ready to accept connections
The main purpose of Docker Compose is to spin up a set of Docker containers, which will then function as independent entities. By default, all containers will have a virtual network connection to all others, though you can change that if you wish; you will get that feature, since you have not specified a custom configuration.
Each of the containers will get a virtual IP address inside the virtual network set up by Docker. Since these are dynamic, Docker Compose makes it easier for you by creating internal DNS entries corresponding to each service. So, you will have two containers, which can be addressed as app and db respectively, either from themselves or the other. If you have ping installed, you can ping these names too, either via docker-compose exec, or via a manually-created shell.
Thus, as we discovered in the comments, you can connect from app to jdbc:postgresql://db:5432/media, and it should work.

Connecting to Postgresql in a docker container with a GUI

I just started learning docker and I decided to create a postgresql container, and I want to use it as my database.
But the thing is, every time I tried to connect to my postgresql container with my Gui (PostBird), I get an error that says "Connection terminated unexpectedly".
My config file:
postgres:
image: postgres:alpine
restart: always
ports:
- '3000:3000'
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: root
POSTGRES_DB: adonisvue
volumes:
- ./init:/docker-entrypoint-initdb.d/
The command I used:
sudo docker-compose up
When my postgres container is running it says "database system is ready to accept connections" but I can't connect with my gui, even using connect url.
I had to change my port to 3000 because docker says that the port 5432 is already in use, but I don't have any container running in it. Is it because of psql?
Sorry, I'm really new to this and I just have a bunch of questions xD
I had to change my port to 3000 because docker says that the port 5432 is already in use, but I don't have any container running in it. Is it because of psql?
Yes, this is most probably because you have an other postgresql using this port on the local machine. Meanwhile, the postgres instance running inside your container is still using port 5432 (unless you also changed the port inside your container but I'm 99.9% sure you didn't). So the following port setting is wrong.
ports:
- '3000:3000'
This is mapping port 3000 for any IP configured on your host to port 3000 of your container... with no service running on that one. Try:
ports:
- '3000:5432'
You can then connect to postgres on port 3000 on your local machine which will forward packets to port 5432 inside the container.

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 :)

Cannot connect to postgreSQL docker container via postico

I'm trying to use Postico to connect to a docker postgreSQL container on my local machine.
I've tried connecting to 0.0.0.0, localhost, and 127.0.0.1. Each give me the following error:
could not connect to server: Connection refused
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
0.0.0.0 gives me a similar, but smaller error:
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?
Here is my docker-compose file:
version: '3'
services:
prisma:
image: prismagraphql/prisma:1.23
restart: always
ports:
- "4466:4466"
environment:
PRISMA_CONFIG: |
port: 4466
databases:
default:
connector: postgres
host: postgres
port: 5432
user: prisma
password: prisma
migrations: true
postgres:
image: postgres:10.5
restart: always
environment:
POSTGRES_USER: prisma
POSTGRES_PASSWORD: prisma
volumes:
- postgres:/var/lib/postgresql/data
volumes:
postgres:
Solution found thanks to Egor! I forgot to specify ports: - "5432:5432" inside my docker-compose file. Rookie mistake ;)
I also had issues using Postico to connect to my Postgres DB in a docker container.
Ultimately, my issue was that I had a local Postgres DB running.
As soon as I disconnected my local Postgres DB, I was able to use Postico to connect to my docker DB. With the host set to localhost, I used the POSTGRES_USER, POSTGRES_PASSWORD, and host port as defined in my docker-compose.yml file.
If postgres version doesn't matter, try to change Postgres image to this one, it works for me
And also make sure that you add ports in docker-compose.yml
postgres:
image: postgres
restart: always
environment:
POSTGRES_USER: prisma
POSTGRES_PASSWORD: prisma
ports:
- "5432: 5432"
volumes:
- postgres:/var/lib/postgresql/data
P.s. just updated answer for readability