How to make postgres listen on the container's new exposed port (not 5432)? - postgresql

I try to initialize a database with Go.
I use port 5433 at postgres:alpine because 5432 is already taken by another microservice app.
func Init() {
DB, err = gorm.Open(postgres.New(postgres.Config{
DSN: "host=url_db user=gorm password=gorm dbname=gorm port=5433 sslmode=disable TimeZone=Asia/Tokyo",
}), &gorm.Config{})
if err != nil {
panic(err)
}
autoMigration()
}
url_db:
build:
context: ./api/services/url/db
dockerfile: Dockerfile
container_name: "url_db"
environment:
POSTGRES_USER: gorm
POSTGRES_PASSWORD: gorm
POSTGRES_DB: gorm
POSTGRES_HOST: url_db
ports:
- 5433:5433
You can confirm that only 5432 is exposed here.
I tried to expose 5433 by creating a new Dockerfile like this.
FROM postgres:alpine
EXPOSE 5433
But I got this error.
failed to initialize database, got error failed to connect to `host=url_db user=gorm database=gorm`: dial error (dial tcp 172.19.0.3:5433: connect: connection refused)
This comment:
Simply exposing the port on the docker image won't do anything unless postgres is actually configured to listen on that port. – super 5 mins ago
that teaches me the title(How can I expose a new port(not 5432) at postgres:alpine image?) is not the point, so I updated the title.
How to make postgres listen on the container's new exposed port (not 5432)?

You have multiple options:
Option 1: Define own postgresql.conf
url_db:
build:
context: ./api/services/url/db
dockerfile: Dockerfile
container_name: "url_db"
command: postgres -c "config_file=/etc/postgresql/postgresql.conf"
environment:
POSTGRES_USER: gorm
POSTGRES_PASSWORD: gorm
POSTGRES_DB: gorm
POSTGRES_HOST: url_db
ports:
- 5433:5433
volumes:
- /path/to/config:/etc/postgresql/postgresql.conf
Postgres has an example config at /usr/share/postgresql/postgresql.conf.sample within the container.
To get the config run:
docker run -i --rm postgres cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf
Option 1: Overwrite the RUN command
url_db:
build:
context: ./api/services/url/db
dockerfile: Dockerfile
container_name: "url_db"
command: postgres -c port=5433
environment:
POSTGRES_USER: gorm
POSTGRES_PASSWORD: gorm
POSTGRES_DB: gorm
POSTGRES_HOST: url_db
ports:
- 5433:5433

You can have multiple containers that are internally listening on the same port, so long as they're mapped to different ports on the host (if they're published at all). In your example, you can set
url_db:
image: postgres:latest
environment:
POSTGRES_USER: gorm
et: cetera
ports:
- 5433:5432
Connections from outside Docker reach the remapped port, on <host ip>:5433. Connections between Docker containers use the standard service port, on url_db:5432. These connections ignore (and don't require) ports:.
"Expose" in modern Docker means almost nothing; it is most valuable as documentation in an image showing what port(s) the service normally uses. You can in theory ask Compose to expose: additional ports without modifying the image, but there's no practical effect from doing so.

For Docker Compose assuming we want to change port to 5433
An alternative to doing this is to do the following in your docker-compose.yml file
you can mount the postgres data into a volume in your directory in this case ./db
postgres:
image: postgres:10.14-alpine
environment:
POSTGRES_DB: iam
ports:
- 5433:5433
volumes:
- ./db:/var/lib/postgresql/data
Find the postgresql.conf file, then search the port
change the port to
port = 5433 # (change requires restart)

Related

Error: connect ECONNREFUSED 127.0.0.1:5432 -> error is showing when for docker-compose up for node+postgres application

I am new to docker.
My docker-compose file:
version: '2.2'
services:
db:
image: postgres:10
ports:
- "5430:5431"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
api:
build: .
environment:
DB_USERNAME: postgres
DB_PASSWORD: postgres
DB_NAME: TestDB6
DB_HOSTNAME: db
ports:
- 8081:8081
what changes can be made to resolve the issue?
Error: connect ECONNREFUSED 127.0.0.1:5432
Checked if there was any processes running on port 5432, there were none.
It's best practice that when you encounter an error, you should share the error output along with the configuration that caused it. If I had to guess since there's no error, in the db definition you put
ports:
- "5430:5431"
And usually, the default port for postgres is 5432. So you're exposing a port that postgres isn't actually using. Best solution would be to update the ports mapping to
ports:
- "5430:5432"
You also could try to configure postgres to run on 5431 instead of 5432, but that's probably unnecessary.

How to connect cvat postgres db to Dbeaver

Docker container for cvat_db has following settings:
services:
cvat_db:
container_name: cvat_db
image: postgres:10-alpine
restart: always
environment:
POSTGRES_USER: root
POSTGRES_DB: cvat
POSTGRES_HOST_AUTH_METHOD: trust
volumes:
cvat_db:/var/lib/postgresql/data
networks:
cvat
While below is the connection setting in dbeaver, where "HOST IP" i have put the IP address where cvat is hosted.
Dbeaver Settings
I'm getting error of timeout connection. So, I want to know how to connect postgres database to dbeaver.
Keep the following in mind:
Postgres always need a password according to their docs.
Do not create custom networks if it is not really needed. Use the default bridge network instead.
Do you connect with Postgres from another docker container or from your host system? If you connect from your host system add ports with 5432:5432.
mount your volumes to a subpath instead of named volumes
Example compose file:
version: '3.9'
services:
cvat_db:
container_name: cvat_db
image: postgres:10-alpine
restart: always
ports:
- 5432:5432
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: password
POSTGRES_DB: cvat
volumes:
- ./cvat_db:/var/lib/postgresql/data
I wrote an article about docker compose networking, perhaps it helps.

How to restrict remote access to postgresql docker container?

Using docker-compose I've developed a website which includes a Postgresql database. I deployed it on a server using the same docker-compose.yml file, but I found that I can remotely access my postgres server using psql.
I currently have these lines in my docker-compose
version: '3.6'
services:
db:
image: postgres
ports:
- 5432:5432
environment:
POSTGRES_DB: my_website
POSTGRES_USER: my_website
POSTGRES_PASSWORD: my_password
Does anybody know how I can only allow access to the postgres db from within the docker network so that it cannot accessed from outside the host OS?
At the moment you are binding the port 5432 from within the docker container onto a host port using the ports directive. To only have the port accessible within your local docker network, change ports to expose
version: '3.6'
services:
db:
image: postgres
expose:
- "5432"
environment:
POSTGRES_DB: my_website
POSTGRES_USER: my_website
POSTGRES_PASSWORD: my_password

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)

Changing a postgres containers server port in Docker Compose

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.