Docker container can't connect circleCI postgres database - postgresql

I am trying to set up a circleCI test, I have created a database in circleCI and I have a docker container which needs to connect to the database, but it can't. Inside my docker container is a script which before it does anything it runs pg_isready, this cannot connect to the database. Here's my circle job creation
postgres_tests:
docker:
- image: circleci/python:3.7
- image: circleci/postgres:9.6.2-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_DB: my_test
steps:
- setup_remote_docker:
docker_layer_caching: true
- attach_workspace:
at: /tmp/workspace
- run:
name: Install awscli docker-squash
working_directory: /
command: sudo pip3 install awscli docker-squash
- run: eval `aws ecr get-login --no-include-email --region eu-west-1`
- checkout
- run: echo 'export PATH=/usr/lib/postgresql/9.6/bin/:$PATH' >> $BASH_ENV
- run: sudo apt-get update && sudo apt-get install -y postgresql-client
- run: psql -h localhost -U postgres --command "ALTER USER postgres WITH PASSWORD 'password';"
- run:
name: run_pg_tests
working_directory: /tmp/workspace
command: |
/tmp/workspace/sql/t/run_tests.sh
The run_tests.sh is a script which pulls my docker image from the company repo and then does a docker run on that image.
I have read other people have issues where the database isn't ready so to test this I added pg_isready before the docker run
So my script looks like this
DB_HOST=`psql -X -A -h localhost -U postgres -p 5432 -t -c "select inet_server_addr()"`
DB_PORT=5432
DB_NAME=my_test
DB_USER=postgres
DB_PASSWORD=password
pg_isready -h "${DB_HOST}" -p "${DB_PORT}"
#restore database from supplied image
docker run \
-e SAPIENTIA_DB_HOST=$DB_HOST \
-e SAPIENTIA_DB_PORT=$DB_PORT \
-e SAPIENTIA_DB_NAME=$DB_NAME \
-e SAPIENTIA_DB_PASSWORD=$DB_PASSWORD \
-e SAPIENTIA_DB_USER=$DB_USER \
$EMPTY_DB_FULL_PATH \
path_to_file/file
I have also tried setting the DB_HOST variable directly to 'localhost' the result is exactly the same
Here's what I get as a result:
127.0.0.1:5432 - accepting connections
127.0.0.1:5432 - no response
I have also tried re-running the test with ssh and connecting myself. Same result, I can connect to the database, but i I then run docker exec and try to connect from inside the docker container it can't connect.
I'm pretty stumped here, so any help would be useful.

EDIT: I've found this documentation page about your issue:
It is not possible to start a service in remote docker and ping it directly from a primary container or to start a primary container that can ping a service in remote docker. To solve that, you’ll need to interact with a service from remote docker, as well as through the same container
That line is not 100% clear to me, but I understand that they tell us that we should run the containers we want to communicate from another container manually. Therefore:
- run:
name: run_pg_tests
working_directory: /tmp/workspace
command: |
docker run -d --name postgres --env POSTGRES_USER=postgres --env POSTGRES_DB=my_test circleci/postgres:9.6.2-alpine
/tmp/workspace/sql/t/run_tests.sh
Since the postgres container is not accessible anymore through the local network, your up check could be docker exec postgres pg_isready
You can then set your DB_HOST to postgres in your run script.
Original answer:
I'm not well versed into CircleCI configuration, but my guess would be that your Docker container you run manually is not attached to the same network as the containers launched by CircleCI.
From what I see in the documentation, you can specify the hostname of the service container:
The name the container is reachable by. By default, container services are accessible through localhost
So maybe if you try something lile this:
- image: circleci/postgres:9.6.2-alpine
name: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_DB: my_test
You can then set your DB_HOST to postgres in your run script.

Related

How can I connect Odoo not running on Docker to a Postgres container running on Docker?

I am trying to connect Odoo to a Postgres database instance which is running in Docker, but having trouble figuring out how to connect them. I created my instance like so:
$ docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name mydb postgres:10
Only Postgres is running in Docker, not Odoo. How would I connect the Postgres running inside Docker to the outside Odoo?
Shortly:
You have to open the port of your docker instance
-p 5432:5432
Example:
docker run -d -p 5432:5432 -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name mydb postgres:10
Description
Because when you run a container with docker, it is not exposed by default to the host network. So when you run Postgres, it is not accessible outside of the container. In order to make it accessible, you could :
Export a specific port : docker run -d -p 5432:5432 ...
Use the host network: docker run --network=host ...
Bonus:
If you wish to run odoo within a container in the future, you might need to create a docker network docker network create odooNetwork and use it for your Postgres and Odoo instances :
docker run -d --network=odooNetwork ...
More details about docker network in the documentation

equivalent docker run command for working docker-compose (postgres)

If have a docker-compose file for postgres that works as expected and I'm able to access it from R. See relevant content below. However, I also need an equivalent "docker run" command but for some reason cannot get this to work. As far as I can tell the commands / setup are equivalent. Any suggestions?
postgres:
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
PGDATA: /var/lib/postgresql/data
ports:
- 5432:5432
restart: always
volumes:
- ~/postgresql/data:/var/lib/postgresql/data
The docker run command I'm using is:
docker run -p 5432:5432 \
--name postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e PGDATA=/var/lib/postgresql/data \
-v ~/postgresql/data:/var/lib/postgresql/data \
-d postgres
EDIT 1: In both settings I'm trying to connect from another docker container/service. In the docker-compose setting the different services are described in one and the same yml file
EDIT 2: David's answer provided all the information I needed. Create a docker network and reference that network in each docker run call. For those interested in a shell script that uses this setup to connect postgres, pgadmin4, and a data science container with R and Python see the link below:
https://github.com/radiant-rstats/docker/blob/master/launch-rsm-msba-pg.sh
Docker Compose will automatically create a Docker network for you (per Compose file). For inter-container DNS to work, you can't use the default Docker network but any named network will work. So you need to add that bit of setup:
docker network create some-name # default options are fine
docker run --net some-name --name postgres ...
# will be accessible as "postgres" from other containers on
# the "some-name" network

Docker - How can run the psql command in the postgres container?

I would like to use the psql in the postgres image in order to run some queries on the database.
But unfortunately when I attach to the postgres container, I got that error the psql command is not found...
For me a little bit it is a mystery how I can run postgre sql queries or commands in the container.
How run the psql command in the postgres container? (I am a new guy in Docker world)
I use Ubuntu as a host machine, and I did not install the postgres on the host machine, I use the postgres container instead.
docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------
yiialkalmi_app_1 /bin/bash Exit 0
yiialkalmi_nginx_1 nginx -g daemon off; Up 443/tcp, 0.0.0.0:80->80/tcp
yiialkalmi_php_1 php-fpm Up 9000/tcp
yiialkalmi_postgres_1 /docker-entrypoint.sh postgres Up 5432/tcp
yiialkalmi_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
Here the containers:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
315567db2dff yiialkalmi_nginx "nginx -g 'daemon off" 18 hours ago Up 3 hours 0.0.0.0:80->80/tcp, 443/tcp yiialkalmi_nginx_1
53577722df71 yiialkalmi_php "php-fpm" 18 hours ago Up 3 hours 9000/tcp yiialkalmi_php_1
40e39bd0329a postgres:latest "/docker-entrypoint.s" 18 hours ago Up 3 hours 5432/tcp yiialkalmi_postgres_1
5cc47477b72d redis:latest "docker-entrypoint.sh" 19 hours ago Up 3 hours 6379/tcp yiialkalmi_redis_1
And this is my docker-compose.yml:
app:
image: ubuntu:16.04
volumes:
- .:/var/www/html
nginx:
build: ./docker/nginx/
ports:
- 80:80
links:
- php
volumes_from:
- app
volumes:
- ./docker/nginx/conf.d:/etc/nginx/conf.d
php:
build: ./docker/php/
expose:
- 9000
links:
- postgres
- redis
volumes_from:
- app
postgres:
image: postgres:latest
volumes:
- /var/lib/postgres
environment:
POSTGRES_DB: project
POSTGRES_USER: project
POSTGRES_PASSWORD: project
redis:
image: redis:latest
expose:
- 6379
docker exec -it yiialkalmi_postgres_1 psql -U project -W project
Some explanation
docker exec -it
The command to run a command to a running container. The it flags open an interactive tty. Basically it will cause to attach to the terminal. If you wanted to open the bash terminal you can do this
docker exec -it yiialkalmi_postgres_1 bash
yiialkalmi_postgres_1
The container name (you could use the container id instead, which in your case would be 40e39bd0329a )
psql -U project -W project
The command to execute to the running container
U user
W Tell psql that the user needs to be prompted for the password at connection time. This parameter is optional. Without this parameter, there is an extra connection attempt which will usually find out that a password is needed, see the PostgreSQL docs.
project the database you want to connect to. There is no need for the -d parameter to mark it as the dbname when it is the first non-option argument, see the docs: -d "is equivalent to specifying dbname as the first non-option argument on the command line."
These are specified by you here
environment:
POSTGRES_DB: project
POSTGRES_USER: project
POSTGRES_PASSWORD: project
This worked for me:
goto bash :
docker exec -it <container-name> bash
from bash :
psql -U <dataBaseUserName> <dataBaseName>
or just this one-liner :
docker exec -it <container-name> psql -U <dataBaseUserName> <dataBaseName>
helps ?
After the Postgres container is configured using docker, open the bash terminal using:
docker exec -it <containerID>(postgres container name / ID) bash
Switch to the Postgres user:
su - postgres
Then run:
psql
It will open the terminal access for the Postgres.
If you need to restore the database in a container you can do this:
docker exec -i app_db_1 psql -U postgres < app_development.back
Don't forget to add -i.
:)
You can enter inside the postgres container using docker-compose by typing the following
docker-compose exec postgres bash
knowing that postgres is the name of the service. Replace it with the name of the Postgresql service in you docker-compose file.
if you have many docker-compose files, you have to add the specific docker-compose.yml file you want to execute the command with. Use the following commnand instead.
docker-compose -f < specific docker-compose.yml> exec postgres bash
For example if you want to run the command with a docker-compose file called local.yml, here the command will be
docker-compose -f local.yml exec postgres bash
Then, use psql command and specify the database name with the -d flag and the username with the -U flag
psql -U <database username you want to connect with> -d <database name>
Baammm!!!!! you are in.
If you have running "postgres" container:
docker run -it --rm --link postgres:postgres postgres:9.6 sh -c "exec psql -h \$POSTGRES_PORT_5432_TCP_ADDR -p \$POSTGRES_PORT_5432_TCP_PORT -U postgres"
We can enter the container with a terminal sh or bash by using,
docker run -it <container id | name> <sh | bash>
if assume it is sh,
psql -U postgres
will work
RUN /etc/init.d/postgresql start &&\
psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
createdb -O docker docker &&\
Just fired up a local test, not sure if -c is what you were after from the cli.
docker run -it --rm --name psql-test-connection -e PGPASSWORD=1234 postgres psql -h kubernetes.docker.internal -U awx -c "\conninfo"
You are connected to database "awx" as user "awx" on host "kubernetes.docker.internal" (address "192.168.65.4") at port "5432".
In many common setups, the PostgreSQL port is published out to the host.
postgres:
ports:
- '12345:5432'
If this is the case, you don't need to do anything Docker-specific to connect to the database. You can use the psql client directly on your host system pointing to the first ports: number.
psql -h localhost -p 12345 -U project
This approach only requires psql or another ordinary PostgreSQL client be installed on the host and that the database container be configured with ports: making it accessible from outside Docker. (The ports: are not necessary for inter-container communication and a production-oriented setup could reasonably not have them.) This does not require the ability to run docker commands and the attendant security concerns, and it can avoid multiple layers of additional command quoting from a docker exec sh -c '...' sequence.
Without using an external terminal a person can run SQL commands within the container CLI.
psql -d [database-name] -U [username] -W
** Don't forget to replace [database-name] with your db-name & [username] with your actual username
Flags:
-d : Specify the database name you want to connect
-U : Specify the username as whom you want to connect
-W : Prompt for the password

Docker wait for postgresql to be running

I am using postgresql with django in my project. I've got them in different containers and the problem is that i need to wait for postgres before running django. At this time i am doing it with sleep 5 in command.sh file for django container. I also found that netcat can do the trick but I would prefer way without additional packages. curl and wget can't do this because they do not support postgres protocol.
Is there a way to do it?
I've spent some hours investigating this problem and I got a solution.
Docker depends_on just consider service startup to run another service. Than it happens because as soon as db is started, service-app tries to connect to ur db, but it's not ready to receive connections. So you can check db health status in app service to wait for connection. Here is my solution, it solved my problem. :)
Important: I'm using docker-compose version 2.1.
version: '2.1'
services:
my-app:
build: .
command: su -c "python manage.py runserver 0.0.0.0:8000"
ports:
- "8000:8000"
depends_on:
db:
condition: service_healthy
links:
- db
volumes:
- .:/app_directory
db:
image: postgres:10.5
ports:
- "5432:5432"
volumes:
- database:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
database:
In this case it's not necessary to create a .sh file.
This will successfully wait for Postgres to start. (Specifically line 6). Just replace npm start with whatever command you'd like to happen after Postgres has started.
services:
practice_docker:
image: dockerhubusername/practice_docker
ports:
- 80:3000
command: bash -c 'while !</dev/tcp/db/5432; do sleep 1; done; npm start'
depends_on:
- db
environment:
- DATABASE_URL=postgres://postgres:password#db:5432/practicedocker
- PORT=3000
db:
image: postgres
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=practicedocker
If you have psql you could simply add the following code to your .sh file:
RETRIES=5
until psql -h $PG_HOST -U $PG_USER -d $PG_DATABASE -c "select 1" > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..."
sleep 1
done
The simplest solution is a short bash script:
while ! nc -z HOST PORT; do sleep 1; done;
./run-smth-else;
Problem with your solution tiziano is that curl is not installed by default and i wanted to avoid installing additional stuff. Anyway i did what bereal said. Here is the script if anyone would need it.
import socket
import time
import os
port = int(os.environ["DB_PORT"]) # 5432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
try:
s.connect(('myproject-db', port))
s.close()
break
except socket.error as ex:
time.sleep(0.1)
In your Dockerfile add wait and change your start command to use it:
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.7.3/wait /wait
RUN chmod +x /wait
CMD /wait && npm start
Then, in your docker-compose.yml add a WAIT_HOSTS environment variable for your api service:
services:
api:
depends_on:
- postgres
environment:
- WAIT_HOSTS: postgres:5432
postgres:
image: postgres
ports:
- "5432:5432"
This has the advantage that it supports waiting for multiple services:
environment:
- WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017
For more details, please read their documentation.
wait-for-it small wrapper scripts which you can include in your application’s image to poll a given host and port until it’s accepting TCP connections.
can be cloned in Dockerfile by below command
RUN git clone https://github.com/vishnubob/wait-for-it.git
docker-compose.yml
version: "2"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "db"
command: ["./wait-for-it/wait-for-it.sh", "db:5432", "--", "npm", "start"]
db:
image: postgres
Why not curl?
Something like this:
while ! curl http://$POSTGRES_PORT_5432_TCP_ADDR:$POSTGRES_PORT_5432_TCP_PORT/ 2>&1 | grep '52'
do
sleep 1
done
It works for me.
I have managed to solve my issue by adding health check to docker-compose definition.
db:
image: postgres:latest
ports:
- 5432:5432
healthcheck:
test: "pg_isready --username=postgres && psql --username=postgres --list"
timeout: 10s
retries: 20
then in the dependent service you can check the health status:
my-service:
image: myApp:latest
depends_on:
kafka:
condition: service_started
db:
condition: service_healthy
source: https://docs.docker.com/compose/compose-file/compose-file-v2/#healthcheck
If the backend application itself has a PostgreSQL client, you can use the pg_isready command in an until loop. For example, suppose we have the following project directory structure,
.
├── backend
│   └── Dockerfile
└── docker-compose.yml
with a docker-compose.yml
version: "3"
services:
postgres:
image: postgres
backend:
build: ./backend
and a backend/Dockerfile
FROM alpine
RUN apk update && apk add postgresql-client
CMD until pg_isready --username=postgres --host=postgres; do sleep 1; done \
&& psql --username=postgres --host=postgres --list
where the 'actual' command is just a psql --list for illustration. Then running docker-compose build and docker-compose up will give you the following output:
Note how the result of the psql --list command only appears after pg_isready logs postgres:5432 - accepting connections as desired.
By contrast, I have found that the nc -z approach does not work consistently. For example, if I replace the backend/Dockerfile with
FROM alpine
RUN apk update && apk add postgresql-client
CMD until nc -z postgres 5432; do echo "Waiting for Postgres..." && sleep 1; done \
&& psql --username=postgres --host=postgres --list
then docker-compose build followed by docker-compose up gives me the following result:
That is, the psql command throws a FATAL error that the database system is starting up.
In short, using an until pg_isready loop (as also recommended here) is the preferable approach IMO.
There are couple of solutions as other answers mentioned.
But don't make it complicated, just let it fail-fast combined with restart: on-failure. Your service will open connection to the db and may fail at the first time. Just let it fail. Docker will restart your service until it green. Keep your service simple and business-focused.
version: '3.7'
services:
postgresdb:
hostname: postgresdb
image: postgres:12.2
ports:
- "5432:5432"
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=Ceo
migrate:
image: hanh/migration
links:
- postgresdb
environment:
- DATA_SOURCE=postgres://user:secret#postgresdb:5432/Ceo
command: migrate sql --yes
restart: on-failure # will restart until it's success
Check out restart policies.
None of other solution worked, except for the following:
version : '3.8'
services :
postgres :
image : postgres:latest
environment :
- POSTGRES_DB=mydbname
- POSTGRES_USER=myusername
- POSTGRES_PASSWORD=mypassword
healthcheck :
test: [ "CMD", "pg_isready", "-q", "-d", "mydbname", "-U", "myusername" ]
interval : 5s
timeout : 5s
retries : 5
otherservice:
image: otherserviceimage
depends_on :
postgres:
condition: service_healthy
Thanks to this thread: https://github.com/peter-evans/docker-compose-healthcheck/issues/16
Sleeping until pg_isready returns true unfortunately is not always reliable. If your postgres container has at least one initdb script specified, postgres restarts after it is started during it's bootstrap procedure, and so it might not be ready yet even though pg_isready already returned true.
What you can do instead, is to wait until docker logs for that instance return a PostgreSQL init process complete; ready for start up. string, and only then proceed with the pg_isready check.
Example:
start_postgres() {
docker-compose up -d --no-recreate postgres
}
wait_for_postgres() {
until docker-compose logs | grep -q "PostgreSQL init process complete; ready for start up." \
&& docker-compose exec -T postgres sh -c "PGPASSWORD=\$POSTGRES_PASSWORD PGUSER=\$POSTGRES_USER pg_isready --dbname=\$POSTGRES_DB" > /dev/null 2>&1; do
printf "\rWaiting for postgres container to be available ... "
sleep 1
done
printf "\rWaiting for postgres container to be available ... done\n"
}
start_postgres
wait_for_postgres
You can use the manage.py command "check" to check if the database is available (and wait 2 seconds if not, and check again).
For instance, if you do this in your command.sh file before running the migration, Django has a valid DB connection while running the migration command:
...
echo "Waiting for db.."
python manage.py check --database default > /dev/null 2> /dev/null
until [ $? -eq 0 ];
do
sleep 2
python manage.py check --database default > /dev/null 2> /dev/null
done
echo "Connected."
# Migrate the last database changes
python manage.py migrate
...
PS: I'm not a shell expert, please suggest improvements.
#!/bin/sh
POSTGRES_VERSION=9.6.11
CONTAINER_NAME=my-postgres-container
# start the postgres container
docker run --rm \
--name $CONTAINER_NAME \
-e POSTGRES_PASSWORD=docker \
-d \
-p 5432:5432 \
postgres:$POSTGRES_VERSION
# wait until postgres is ready to accept connections
until docker run \
--rm \
--link $CONTAINER_NAME:pg \
postgres:$POSTGRES_VERSION pg_isready \
-U postgres \
-h pg; do sleep 1; done
An example for Nodejs and Postgres api.
#!/bin/bash
#entrypoint.dev.sh
echo "Waiting for postgres to get up and running..."
while ! nc -z postgres_container 5432; do
# where the postgres_container is the hos, in my case, it is a Docker container.
# You can use localhost for example in case your database is running locally.
echo "waiting for postgress listening..."
sleep 0.1
done
echo "PostgreSQL started"
yarn db:migrate
yarn dev
# Dockerfile
FROM node:12.16.2-alpine
ENV NODE_ENV="development"
RUN mkdir -p /app
WORKDIR /app
COPY ./package.json ./yarn.lock ./
RUN yarn install
COPY . .
CMD ["/bin/sh", "./entrypoint.dev.sh"]
If you want to run it with a single line command. You can just connect to the container and check if postgres is running
docker exec -it $DB_NAME bash -c "\
until psql -h $HOST -U $USER -d $DB_NAME-c 'select 1'>/dev/null 2>&1;\
do\
echo 'Waiting for postgres server....';\
sleep 1;\
done;\
exit;\
"
echo "DB Connected !!"
Inspired by #tiziano answer and the lack of nc or pg_isready, it seems that in a recent docker python image (python:3.9 here) that curl is installed by default and I have the following check running in my entrypoint.sh:
postgres_ready() {
$(which curl) http://$DBHOST:$DBPORT/ 2>&1 | grep '52'
}
until postgres_ready; do
>&2 echo 'Waiting for PostgreSQL to become available...'
sleep 1
done
>&2 echo 'PostgreSQL is available.'
Trying with a lot of methods, Dockerfile, docker compose yaml, bash script. Only last of method help me: with makefile.
docker-compose up --build -d postgres
sleep 2
docker-compose up --build -d app

docker postgres pgadmin local connection

I have created an ubuntu image with nginx, php and postgres.
I want to connect the postgres database in my current image with pgadmin located on my local machine.
I have tried using docker inspector to try to use the image ip to make a connection with my local pgadmin but without much success. I've also tried configuring some ports on local to make connection work.
It's a valid question don't know why people feel "doesn't seem possible to answer that question".
So, here's how I do what you are trying to do:
Pull postgres image from Docker Hub
docker pull postgres:latest
Run the container using the below command
docker run -p 5432:5432 postgres
Using docker's inspect command find the IP
Use that IP, PORT, Username, and Password to connect in PGADMIN
You can also do a simple telnet like below to confirm if you can access docker postgres container:
telnet IP_ADDRESS 5432
1. Postgres with Docker
docker run \
-p 5432:5432 \
--name container-postgresdb \
-e POSTGRES_PASSWORD=admin \
-d postgres
2. PgAdmin with Docker
docker run \
-p 5050:80 \
-e "PGADMIN_DEFAULT_EMAIL=name#example.com" \
-e "PGADMIN_DEFAULT_PASSWORD=admin" \
-d dpage/pgadmin4
3. Connection string for PgAdmin
Enter PgAdmin on localhost:80. Then add a server with:
name: container-postgresdb
host: host.docker.internal
database: postgres
user: postgres
password: admin
You can also use this to find out the host address — it will be listed as IPAddress in the output —:
docker inspect container-postgresdb \
-f "{{json .NetworkSettings.Networks }}"
This other article might help with more info.
What I have done success on windows 10 running docker for windows 1.12.6(9655), the step is like below:
Pull the latest postgres
docker pull postgres:latest
run the postgres containner:
docker run -d -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password123 --name db-my -p 5432:5432 --restart=always postgres
Then installed the latest version of pgAdmin4 from
pgadmin website
Run pgAdmin 4 create new server, and input as following
Host: 127.0.0.1
Port: 5432
User name: user
password: password123
Then everything is ok, connect to docker postgres instance success.
Alternatively, you could combine Postgres and Pgadmin in one docker-compose file, and login as user pgadmin4#pgadmin.org, pwd: admin. To add the Posgres server, use hostname postgres, port 5432.
version: '3'
services:
postgres:
image: postgres
hostname: postgres
ports:
- "6543:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: TEST_SM
volumes:
- postgres-data:/var/lib/postgresql/data
restart: unless-stopped
pgadmin:
image: dpage/pgadmin4
depends_on:
- postgres
ports:
- "5555:80"
environment:
PGADMIN_DEFAULT_EMAIL: pgadmin4#pgadmin.org
PGADMIN_DEFAULT_PASSWORD: admin
restart: unless-stopped
volumes:
postgres-data:
If you verified that PostgreSQL is running and you can connect there with local copy of PgAdmin...
The answer is simple: use host.docker.internal istead of localhost for the PgAdmin running inside the Docker
In my case I could solve the problem inspecting my postgre image through command
docker inspect CONTAINER_ID | grep IPAddress.
So, I used the docker ip address to config my pgadmin 4 connection and everything was fine. Thanks to #Afshin Ghazi
I included this in the docker yaml file to get the database and pgAdmin:
database:
image: postgres:10.4-alpine
container_name: kafka-nodejs-example-database
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
expose:
- "5432"
ports:
- 8000:5432
volumes:
- ./services/database/schema.sql:/docker-entrypoint-initdb.d/1-schema.sql
- ./services/database/seed.sql:/docker-entrypoint-initdb.d/2-seed.sql
pgadmin:
image: dpage/pgadmin4
ports:
- 5454:5454/tcp
environment:
- PGADMIN_DEFAULT_EMAIL=admin#mydomain.com
- PGADMIN_DEFAULT_PASSWORD=postgres
- PGADMIN_LISTEN_PORT=5454
The postgres username is alphaone and the password is xxxxxxxxxxx.
Do a docker ps to get the container id and then docker inspect <dockerContainerId> | grep IPAddress
eg: docker inspect 2f50fabe8a87 | grep IPAddress
Insert the Ip address into pgAdmin and the database credentials used in docker:
If pgAdmin is intended to be run wihtin same Ubuntu host/guest, then you need to link postgres container, so it could be resolved by a name.
1. Run a postgres container:
docker run --name some-postgres -e POSTGRES_PASSWORD=postgres -d postgres
2. Run pgAdmin container:
docker run -p 80:80 --link some-postgres -e "PGADMIN_DEFAULT_EMAIL=email#domain.com" -e "PGADMIN_DEFAULT_PASSWORD=postgres" -d dpage/pgadmin4
3. Now when adding new server in phAdmin web app, use some-postgres as server name
Note the --link some-postgres when we were bringing up the pgAdmin. This command makes postgres container visible to pgAdmin container.
After facing this issue for two days i was able to resolve that issue.
solution of this problem is already answered by peoples like do inspect
docker inspect CONTAINER_ID
but while running this command i got a-lot of logs like Host Config Config Network Settings etc. so i got confused which IPAddress to add in the pgAdmin connection because i tried 0.0.0.0 and config, host, networkSettings different -2 IPAddress in the logs but finally it works after trying a-lot.
it works with which IP, we have to add that network ip address (which we created to connect the postgres and pgAdmin.)
like in my case when i run :-
docker inspect postgres_container
"NetworkSettings": {
"Bridge": "",
"SandboxID": "sdffsffsfsfsfsf123232e2r3pru3ouoyoyuosyvo8769696796",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"5432/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "5432"
}
]
},
"SandboxKey": "/var/run/docker/231231Ad132",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"postgres": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"postgres",
"0e2j3bn2m42"
],
"NetworkID": "35rhlhl3l53l5hlh3523233k3k4k22l3hk2k4",
"EndpointID":"b3424n43k52o2i4n235k1k4l2l4hj234f14n2",
"Gateway": "192.168.16.1",
"IPAddress": "192.168.16.2",
"IPPrefixLen": 20,
"IPv6Gateway": "",
so we have to add the NetworkSettings -> Network -> Postgres(mine created network) -> IPAddress i.e. "IPAddress": "192.168.16.2".
After adding this ip it will work.
I hope it will help.
This worked for me on Ubuntu 18:
1- Run a postgres container
docker run -d -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password123 --name my-postgres -p 5432:5432 postgres
2- Run a pgAdmin container
docker run --rm -p 5050:5050 thajeztah/pgadmin4
3- Get your local IP (in Ubuntu by ifconfig command)
4- Open localhost:5050 in your browser
5- Click on Servers >> Create >> Server...
6- In General tab, give it a name, for example: docker. In Connection tab, enter these fields:
Host name: The IP from 3
Username: user
Password: password123
7- Click on Save and now everything should work fine.
Note: If this didn't work, try "localhost" for the host name.
In order or find your IP of the container, use following command
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
Referrence: How to get a Docker container's IP address from the host
If you're on a mac and localhost use below as credentials:
version: '3.5'
services:
postgres:
container_name: postgres_container
image: postgres
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
PGDATA: /data/postgres
volumes:
- postgres:/data/postgres
ports:
- "5432:5432"
networks:
- postgres
restart: unless-stopped
pgadmin:
container_name: pgadmin_container
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4#pgadmin.org}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
PGADMIN_CONFIG_SERVER_MODE: 'False'
volumes:
- pgadmin:/var/lib/pgadmin
ports:
- "${PGADMIN_PORT:-5050}:80"
networks:
- postgres
restart: unless-stopped
networks:
postgres:
driver: bridge
volumes:
postgres:
pgadmin:
Connection:
Hostname/Address: host.docker.internal or 0.0.0.0
Port: 5432
username: postgres
database: postgres
password: changeme
You have to expose the postgres port in the container to you local system. You do this by running your container like this:
docker run -p 5432:5432 <name/id of container>
when connecting with your GUI client or CLI make sure to use the ip-address not localhost even if your ip-address is the localhost ip-address.
docker ps would give you the ip address your postgres container is on.
In my case, I had a PostgreSQL container, so I didn't change my container or create a docker-compose approach, I needed pgadming after few months to had installed PostgreSQL, so this is my approach:
docker inspect my_container_id_postgreSQL
The network assigned to PostgreSQL was:
"Networks": {
"docker_default": {
"IPAddress": "172.18.0.2",
...
}
}
Ran my PGADMIN with --network command.
docker run -p 85:80 --network docker_default -e 'PGADMIN_DEFAULT_EMAIL=user#domain.com' -e 'PGADMIN_DEFAULT_PASSWORD=SuperSecret' -d dpage/pgadmin4
Insert the Ip address into pgAdmin and the database credentials used in docker.
I hope this can be useful for someone.
Regards.
You can create a Docker bridge network to do this too.
$ docker network create pgnet
a0ae44aaf6f806fc37302e4c603b4828c4edb8d487fd9cd90e2fb19ae1d5c65f
$ docker run --detach \
--name pg \
--network pgnet \
--publish 5432:5432 \
--restart always \
--env POSTGRES_PASSWORD=pg123 \
--volume ${PWD}/data:/var/lib/postgresql/data \
postgres:12.1
b60611e43727dabe483c1f08fdf74961b886ce05b432a10a0625bd1b6db87899
$ docker run --detach \
--name pgadm \
--network pgnet \
--publish 8000:80 \
--volume ${PWD}/pgadmin:/var/lib/pgadmin \
--env PGADMIN_DEFAULT_EMAIL=user#domain.com \
--env PGADMIN_DEFAULT_PASSWORD=pgadm123 \
dpage/pgadmin4:4.20
27f9ce1c1c4c383ee1507f4e2d88f6ef33d4fcf5b209a8a03b87519f90d56312
Open http://localhost:8000/
Click Add New Server
Create - Server
Name: db
Hostname/address: pg
Username: postgres
Password: pg123
Save
The Hostname/address used above is the name of the Postgres container given by --name pg
When you start container you have network alias for it. Just use this alias in pgadmin UI.
Like if you have the following docker compose config:
version: "3.5"
services:
postgres:
container_name: postgres-14
image: postgres:14.1
restart: unless-stopped
ports:
- "5432:5432"
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_PASSWORD=root
- POSTGRES_USER=postgres
hostname: postgres
pgadmin:
container_name: pgadmin4
image: dpage/pgadmin4
restart: unless-stopped
ports:
- "80:80"
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
- PGADMIN_DEFAULT_EMAIL=user#domain.com
- PGADMIN_DEFAULT_PASSWORD=admin
hostname: pgadmin
You can add server with hostname: postgres
For macOS IPs of postgres and pgadmin4 are different from the ones docker inspect provides.
Type
docker-machine ls
Take a look at the name of the server on the left. It's default by default.
docker-machine ip default will IP you need to use for both, pgadmin4 in browser and for postgres in pgadmin4 settings.
Are you using Window Subsystem LinuxWSL2 to run Docker and PgAdmin?
The steps I suggested is similar to what folks suggested. In my case I am using window environment
Step 1: Open CMD and type ipconfig and hit enter.
Step 2: Check WSL IPv4 Adress
Ethernet adapter vEthernet (WSL):
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : 3bd9::997b:b52a::fe80::65b3%63
IPv4 Address. . . . . . . . . . . : 172.172.172.1 // use the IP as host/address
Subnet Mask . . . . . . . . . . . : 255.255.255.255
Step 3: Open PgAdmin from the browse and create a server
Step 4:
// Here it depends on your desired config mine is the following
Server: postgres
host address: IPv4 Address(step 2)
username: postgress(username for postgress)
password: password(password for postgress)
I spend two days to figure out what was wrong, I hope someone will find it helpful
If local host port 5432 already in use by another psql servers, change it when creating the container and in Pgadmin.
What I have done success on macOS Monterrey running Docker Desktop for macOS(M1):
Pull the latest postgres:
docker pull postgres
Run the postgres container:
docker run -d -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name postgres-server -p 5432:5432 --restart=always postgres
Then installed the latest version of pgAdmin 4 (macOS) from pgadmin website
Run pgAdmin 4 create new server, and input as following Host: 127.0.0.1 Port: 5432 User name: postgres password: postgres
pgAdmin 4: Connection postgres-server
Here are the full steps that worked for me
Download and install pgadmin GUI tool
Run docker container: docker-compose up my-db.
From this command logs, note down ipv4 address and port. In my case, it's 0.0.0.0 and 5432.
Open docker-compose.yml file and note down POSTGRES PASSWORD
open pgadmin gui
enter name
In connection tab:
enter that ipv4 address in Hostname/address
enter that port
enter that POSTGRES PASSWORD in password
save. 🎊
To find the correct ip for your container, execute the following commands:
Check container ID:
docker ps
To check the correct IP of your container:
docker inspect <ID_CONTAINER> | grep "IPAddress"
The configuration of both PostgreSQL and PgAdmin with Docker are simple, if not right, I recommend redoing the configuration from scratch, if your problem is deeper.
Here is a script I developed to solve this problem.
script-sh/install-docker-postgres-and-pgadmin
I did not connect with my container pg (dpage/pgadmin4 image) from browser on 0.0.0.0:9090 .
I ran this command :
docker run --name pg -p 9090:9090 -e PGADMIN_DEFAULT_EMAIL='faizan' -e PGADMIN_DEFAULT_PASSWORD='faizan' -d dpage/pgadmin4
Solution one :
First I tried to inspect the container for IP address
docker inspect pg
I got the container IP address "IPAddress": "172.17.0.3". http://172.17.0.3:9090 did not accessible.
Solution two :
And then I ran command without de-attached mode (-d removed)
docker run --name pg -p 9090:9090 -e PGADMIN_DEFAULT_EMAIL='faizan' -e PGADMIN_DEFAULT_PASSWORD='faizan' dpage/pgadmin4
# Output, it should be running on 9090.
Listening at: http://[::]:80
-p 9090:9090 did not work.
Finally I found the solution :
On some filesystems that do not support extended attributes, it may
not be possible to run pgAdmin without specifying a value for
PGADMIN_LISTEN_PORT that is greater than 1024. In such cases, specify
an alternate port when launching the container by adding the
environment variable, for example:
-e 'PGADMIN_LISTEN_PORT=5050'
Don’t forget to adjust any host-container port mapping accordingly.
Read more about it official doc
I added -e 'PGADMIN_LISTEN_PORT=9090' and worked for me.
You can try both solutions, it will definitely work for you.
I ran this, It worked for me
docker pull dpage/pgadmin4
docker run -p 9000:80 -e 'PGADMIN_DEFAULT_EMAIL=test#gmail.com' -e 'PGADMIN_DEFAULT_PASSWORD=root' -d dpage/pgadmin4
The solution I tried and worked for me, was to create a docker compose file where I included postgress and pgadmin as services. For more details: Connecting pgadmin to postgres in docker
Tested on Mac
pgAdmin-4: version 6.12
I tried several answers here and in other places but nothing worked for me.
Here is the problem I had and the solution.
I had a docker postgres running my machine and need to connect this server in pgAdmin.
All I need to do was to check the docker information and fill the server configs based on that in pgAdmin.
You can do this by opening your docker and going to dashboard and then selecting the postgres image you're using. There is a tab called Inspect click on that. Here you can get all the information about that postgres container.
Now open the pgAdmin and resister a server by right clicking on the servers -> Register -> Server.
choose a name for the server and click Connection tab.
Here we need to fill the data like host name/address, IP, ports and etc.
In docker Inspect tab, there is Ports section that you can get this data from, something like this:
So your host address based on this picture is 172.0.0.1 and port is 5873.
Other info like database, user and password is also available in Environment section in docker Inspect tab.
Now fill the other information click save in pgAdmin and it should work.
Go to your container terminal on Docker Desktop and type hostname -I in case is linux to get the ip assigned to this machine, then go to your pgAdmin an try it out. #Rigoxls