create temporary postgres server in docker - postgresql

I want to unit-test my app which uses a postgres database inside a docker.
EDIT: based on the suggested answer I modified the Dockerfile:
FROM postgres
USER postgres
RUN sleep 2 # remark 1
RUN initdb # remark 2
RUN sleep 3 # remark 1
RUN psql --host=localhost -l
The remarks are:
from this reference
Try putting a sleep in there and see if it's still a problem
from the docs:
The default postgres user and database are created in the entrypoint with initdb.
Here is the Dockerfile from the original question:
FROM postgres
COPY input.json .
RUN createdb -h localhost -p 7654 -U moish myLovelyAndTemporaryDb
#
# [ 1 ] run application on input.json
# [ 2 ] check db content after run
#
When I use the above Dockerfile I seem to be missing something:
(The errors from the edited version are the same)
$ docker build --tag host --file Dockerfile .
[+] Building 0.3s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 125B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/postgres:latest 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 40B 0.0s
=> CACHED [1/3] FROM docker.io/library/postgres 0.0s
=> [2/3] COPY input.json . 0.0s
=> ERROR [3/3] RUN createdb -h localhost -p 7654 -U moish myLovelyAndTemporaryDb 0.2s
------
> [3/3] RUN createdb -h localhost -p 7654 -U moish myLovelyAndTemporaryDb:
#7 0.188 createdb: error: connection to server at "localhost" (127.0.0.1), port 7654 failed: Connection refused
#7 0.188 Is the server running on that host and accepting TCP/IP connections?
#7 0.188 connection to server at "localhost" (::1), port 7654 failed: Cannot assign requested address
#7 0.188 Is the server running on that host and accepting TCP/IP connections?
------

Postgres database starts only after you create a container based on postgres image. docker build process doesn't start entrypoint script. You might need a bash script or CI pipeline where you firstly start postgres container and then use it in your unit tests
$ docker run --name mypg -p 5432:5432 -e POSTGRES_PASSWORD=mypgpass -d postgres:9
# copy a script to the mypg container
$ docker cp run.sh mypg:/root/run.sh
# run the script
$ docker exec mypg bash /root/run.sh
...
# use postgres client on your host to connect to mypg container
$ PGPASSWORD="mypgpass" psql -U postgres -p 5432 -h localhost -c "select version()"
version
--------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 9.6.24 on x86_64-pc-linux-gnu (Debian 9.6.24-1.pgdg90+1), compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
(1 row)
Postgres container docs
Postgres client authentication
EDIT:
By trying to run initdb, psql etc directly in Dockerfile, you are reinventing the docker-entrypoint.sh

During the build step of the postgres Docker you cannot run postgres commands. Postgres database will only be available after you run the Docker.
As specified in the postgres Docker documentation you can add customization to your postgres instance through scripts placed in docker-entrypoint-initdb.d directory.
Alternatively you could use a RUN directive to start the postgres database and after that run the postgres commands you want (making sure to wait for the DB to accept connections), as mentioned here.
Another side note, I personally avoid using real databases for unit testing applications. To me, it's always better to mock the database for unit tests, in python you can do this with unittest.mock.

Here is a complete answer based on the concepts of slava-kuravsky and mello:
$ docker build --tag host --file Dockerfile .
$ docker run -d -t --name pg host
$ docker exec pg bash run.sh
The script can do what I want, currently it only lists the databases:
$ cat run.sh # <--- copied during docker build
echo "Hello Postgres World"
psql --host=localhost -l
The Dockerfile does only initialization:
$ cat Dockerfile
FROM postgres
USER postgres
COPY run.sh . # <--- the testing script
RUN sleep 2 # <--- probably not needed anymore
RUN initdb
RUN sleep 3 # <--- probably not needed anymore
When I perform the three commands above I get what I expect 🙂 :
$ docker build --tag host --file Dockerfile .
[+] Building 7.2s (10/10) FINISHED
# ... omitted for brevity ...
$ docker run -d -t --name pg host
608ac7324e838924c9a5d0cfe65c8000e33350b86faf9df4511ef5fcf7440597
$ docker exec pg bash run.sh
Hello Postgres World
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+----------+----------+------------+------------+------------+-----------------+-----------------------
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(3 rows)

Related

docker-compose up versus docker-compose run, why the latter seems not to start the services?

Here's my docker-compose.yml:
version: '3.8'
services:
db:
image: postgres:12-alpine
environment:
- POSTGRES_USER=tester
- POSTGRES_PASSWORD=atest
- POSTGRES_DB=test_db
ports:
- 5432:5432
expose:
- 5432
Doing:
> docker-compose up -d
...
> psql test_db -U tester -h localhost
Password for user tester:
psql (12.3)
Type "help" for help.
test_db=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+--------+----------+------------+------------+-------------------
postgres | tester | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | tester | UTF8 | en_US.utf8 | en_US.utf8 | =c/tester +
| | | | | tester=CTc/tester
template1 | tester | UTF8 | en_US.utf8 | en_US.utf8 | =c/tester +
| | | | | tester=CTc/tester
test_db | tester | UTF8 | en_US.utf8 | en_US.utf8 |
(4 rows)
\q
> docker-compose exec db ps awx
PID USER TIME COMMAND
1 postgres 0:00 postgres
46 postgres 0:00 postgres: checkpointer
47 postgres 0:00 postgres: background writer
48 postgres 0:00 postgres: walwriter
49 postgres 0:00 postgres: autovacuum launcher
50 postgres 0:00 postgres: stats collector
51 postgres 0:00 postgres: logical replication launcher
52 root 0:00 ps awx
works fine. Same if doing:
docker-compose exec db psql test_db -U tester
That's pretty fine too.
However, doing as follow:
> docker-compose down
> docker-compose run db psql test_db -U tester
psql: error: could not connect to server: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
failed to resize tty, using default size
> docker-compose run db /bin/sh
/ # ps awx
PID USER TIME COMMAND
1 root 0:00 /bin/sh
7 root 0:00 ps awx
So I can see that using docker-compose run db the postgres service is not being started. Why?
What
--entrypoint CMD Override the entrypoint of the image.
in docker-compose run --help does really mean? If there's something to be overridden than it means the entrypoint should be being executed, shouldn't be?
UPDATE
I've checked https://docs.docker.com/compose/reference/run/, considering whether --service-ports would do any help, which it didn't (not surprised, as I emphasized above, postgres service is not started, so I don't see how it could be a ports issue), and found even an example:
docker-compose run db psql -h db -U docker
But alas! this is precisely what I'm trying to do for no avail!
Please see this answer: Mysql client called with `docker-compose run` vs. `docker-compose exec`
When you do docker-compose run, it creates a new instance of db separate from the configuration in your docker-compose.yml.
The best way to see what is happening is to run docker-compose up, then from another shell run docker-compose exec db bash, then from another shell run docker-compose run db bash.
If you look at the output of hostname and ifconfig, you will see that exec connects you to the existing db while run puts you into a new one.
In response to OP's linking this article, I should have emphasized earlier that though there is nothing wrong with running PostgreSQL under Docker, running a database is counter to the general container ethos of statelessness. In the context of a stateful and persistent container like a database, the docker-compose run command seems to make no sense.
My understanding is, docker-compose run just runs one-time command to your service. It overwrite previous commands in your configuration. Here i think it overwrote the command that start postgres service in your container.
(Last line)
https://github.com/docker-library/postgres/blob/1d140375b6830c65cfeaac3642c7fda6d3e1b29a/12/alpine/Dockerfile
In your case, because you ran docker-compose down first so when you run docker-compose run db psql test_db -U tester your service did not run command to start posgres first instead of running your NEW COMMANDS psql .... You can test that every normal command like ls, pwd, ... run well with docker-compose run instead of psql.
If you dont run docker-compose down, everthing works properly with docker-compose run db psql test_db -U tester -h db .
Here's a very useful article on ENTRYPOINT vs CMD
https://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/
Entrypoint is a command or script that is run every time you run the container and can't be overwritten. CMD can be replaced by arguments in the docker-compose, ENTRYPOINT can't.

Restore SQL dump in PostgreSQL 11 Docker at image build time

I want to build a custom Postgres11 image in which some users are created and some extensions are installed. As I want these to be created at build time, so I don't want to use docker-entrypoint-initdb.d. A next step would be to restore a sql dump as well.
FROM postgres:11
ENV PG_MAJOR 11
ENV POSTGISV 2.5
ENV TZ Europe/Brussels
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-$PG_MAJOR-postgis-$POSTGISV \
postgresql-$PG_MAJOR-postgis-$POSTGISV-scripts
USER postgres
RUN initdb && pg_ctl -o "-c listen_addresses='*'" start &&\
psql -h 0.0.0.0 --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
psql -h 0.0.0.0 --command "CREATE USER akela_test WITH PASSWORD 'akela';" &&\
createdb -E UTF8 -U postgres -h 0.0.0.0 -O akela_test akela_test --template template0 &&\
psql -U postgres -d akela_test -h 0.0.0.0 -c 'CREATE EXTENSION IF NOT EXISTS "hstore";' &&\
psql -U postgres -d akela_test -h 0.0.0.0 -c 'CREATE EXTENSION IF NOT EXISTS "postgis";' &&\
psql -U postgres -d akela_test -h 0.0.0.0 -c 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";' &&\
psql -U postgres -d akela_test -h 0.0.0.0 -c "CREATE ROLE akela_db WITH LOGIN PASSWORD 'akela'" &&\
psql -U postgres -d akela_test -h 0.0.0.0 -c "GRANT ALL PRIVILEGES ON DATABASE akela_test to akela_db" &&\
psql -U postgres -d akela_test -h 0.0.0.0 -c "CREATE schema db" &&\
pg_ctl stop
# gunzip -c /tmp/dump.sql.gz | psql -U akela -h 0.0.0.0 akela
USER root
seems to work:
...
CREATE SCHEMA
ALTER SCHEMA
CREATE ROLE
GRANT
CREATE SCHEMA
ALTER SCHEMA
waiting for server to shut down....2019-07-08 12:58:06.962 CEST [22] LOG: received fast shutdown request
2019-07-08 12:58:06.964 CEST [22] LOG: aborting any active transactions
2019-07-08 12:58:06.965 CEST [22] LOG: background worker "logical replication launcher" (PID 29) exited with exit code 1
2019-07-08 12:58:06.965 CEST [24] LOG: shutting down
2019-07-08 12:58:07.006 CEST [22] LOG: database system is shut down
done
server stopped
...
running the image however shows no users nor db:
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
What could be the issue?
The Dockerfile for postgres defines a volume which means any changes to this directory by a RUN step will be discarded. To make changes to this directory you need to do one of the following options:
Make the changes at run time rather than doing the build, and save the resulting volume.
Make changes during the build, but in a different directory. This would require changing the postgres configuration to use the different directory.
Save your changes to a different directory and then restore those changes when you start the container (see the save and load volume scripts for an example of this).
Build your own postgres image without the volume definition.

GitLab setup using official PostgreSQL and GitLab docker container not working

I am trying to setup GitLab using separate docker containers for both GitLab and PostgreSQL. I am using RancherOS v1.0.3 with Kubernetes enabled. For now, all i want is to have a single node having both the containers. Later, i will look into configuring them on separate nodes.
[rancher#rancher-agent-2 ~]$ cat postgresql.sh
docker run --name=postgresql -d \
--env 'DB_NAME=gitlabhq_production' \
--env 'DB_USER=gitlab' --env 'DB_PASS=password' \
--env 'DB_EXTENSION=pg_trgm' \
--volume /opt/postgresql:/var/lib/postgresql \
postgres:9.6.3
[rancher#rancher-agent-2 ~]$ cat gitlab.sh
docker run --name=gitlab -d --link postgresql:postgresql \
-v /opt/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:9.3.9-ce.0
Now when i run the PostgreSQL container and try logging in, i get errors.
[rancher#rancher-agent-2 ~]$ docker exec -it postgresql bash
root#a6cef780c594:/# psql -d gitlabhq_production -U gitlab
psql: FATAL: role "gitlab" does not exist
Seems the db (gitlabhq_production) has not been created.
root#a6cef780c594:/# psql -U postgres
psql (9.6.3)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
Why is it not creating the db despite passing the parameters?
UPDATE:
PostgreSQL container log:
[rancher#rancher-agent-2 ~]$ docker logs postgresql
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/data ... ok
...
...
LOG: MultiXact member wraparound protections are now enabled
LOG: database system is ready to accept connections
LOG: autovacuum launcher started
done
server started
ALTER ROLE
/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
...
...
You are using the wrong environment vars names:
DB_NAME should be POSTGRES_DB
DB_USER should be POSTGRES_USER
DB_PASS should be POSTGRES_PASSWORD
Check https://hub.docker.com/_/postgres/

Docker compose postgresql service - can't create user and database during build?

I have wasted an entire day on this, and to say I'm not impressed by the unnecessary complexity of what should be a simple task - would be a gross understatement.
Ok, having got that off my chest, I am building a django application using docker-machine, docker-compose, postgresql and redis - by following this tutorial.
I have managed to get the basic tutorial to work - but it does not suit my needs, as I need to create a user and a database for my application - as opposed to using 'postgres' for both.
I have used the answer from #dnephin to a similar question, and modified my code as follows:
I created a new Dockerfile in a new directory ./database/:
FROM postgres:9.6
COPY . /fixtures
WORKDIR /fixtures
RUN /fixtures/setup.sh
./database/setup.sh contents:
#!/bin/bash
set -e
pg_createcluster 9.6 main --start
/etc/init.d/postgresql start
su - postgres # makes no effing difference ...
psql -f create_fixtures.sql
/etc/init.d/postgresql stop
./database/create_fixtures.sql contents:
CREATE DATABASE mydatabase WITH ENCODING 'UTF8';
CREATE USER webuser ENCRYPTED PASSWORD 'deadbeefsnaf0' NOSUPERUSER NOCREATEDB NOCREATEROLE;
GRANT ALL PRIVILEGES ON mydatabase TO webuser;
and finally my postgres service in the docker_compose.yml is modified to use build:
postgres:
build: ./database/
...
When I run docker-compose build, the build goes through the motions and then barfs at where I'm importing the SQL fixtures file via psql:
frothing#themouth:~/path/to/directory$ docker-compose build
redis uses an image, skipping
Building postgres
Step 1/4 : FROM postgres:9.6
---> ff0943ecbb3c
Step 2/4 : COPY . /fixtures
---> fae19dc88da8
Removing intermediate container 84b860aee55c
Step 3/4 : WORKDIR /fixtures
---> aa88438dc69f
Removing intermediate container b801ddc3b374
Step 4/4 : RUN /fixtures/setup.sh
---> Running in ca3e89ec2460
Creating new cluster 9.6/main ...
config /etc/postgresql/9.6/main
data /var/lib/postgresql/9.6/main
locale en_US.utf8
socket /var/run/postgresql
port 5432
Starting PostgreSQL 9.6 database server: main.
psql: FATAL: role "root" does not exist
ERROR: Service 'postgres' failed to build: The command '/bin/sh -c /fixtures/setup.sh' returned a non-zero code: 2
I tried to solve this using the useless documentation on docker for postgresql service - but got no where.
How can I solve this?
Volumes are not available at build time. You can create /var/lib/postgresql/data in your script but it will be overwritten by VOLUME /var/lib/postgresql/data from postgres:9.6 image.
In your case: just use the following docker file:
FROM postgres:9.6
COPY ./create_fixtures.sql /docker-entrypoint-initdb.d/create_fixtures.sql
They get automatically executed once the container starts. Here is an example:
$ docker run -d --name mydb -p 33306:3306 yourtag
$ docker exec -ti mydb psql -U postgres
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
------------+----------+----------+------------+------------+-----------------------
mydatabase | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =Tc/postgres +
| | | | | postgres=CTc/postgres+
| | | | | webuser=CTc/postgres
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
Outdated answer:
Your script should work on a container except in the fixture you have to execute psql like this:
su postgres -c "psql -f create_fixtures.sql"
su --login postgres does not work because postgres can't open a bash or shell. You can try around with docker run --rm -ti postgres:9.6 bash.
Sorry I have to tell you there is one more error in your sql script: GRANT ALL PRIVILEGES ON DATABASE mydatabase TO webuser - the keyword DATABASE is necessary here.
Here is a complete log how I tested and can confirm this works:
docker run --rm -ti postgres:9.6 bash
root#be03ab1eb704:/# cat > test.sql <<EOF
> CREATE DATABASE mydatabase WITH ENCODING 'UTF8';
> CREATE USER webuser ENCRYPTED PASSWORD 'asdf123' NOSUPERUSER NOCREATEDB NOCREATEROLE;
> GRANT ALL PRIVILEGES ON DATABASE mydatabase TO webuser;
> EOF
root#be03ab1eb704:/# pg_createcluster 9.6 main --start
Creating new PostgreSQL cluster 9.6/main ...
/usr/lib/postgresql/9.6/bin/initdb -D /var/lib/postgresql/9.6/main --auth-local peer --auth-host md5
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/9.6/main ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Success. You can now start the database server using:
/usr/lib/postgresql/9.6/bin/pg_ctl -D /var/lib/postgresql/9.6/main -l logfile start
Ver Cluster Port Status Owner Data directory Log file
9.6 main 5432 online postgres /var/lib/postgresql/9.6/main /var/log/postgresql/postgresql-9.6-main.log
root#be03ab1eb704:/# /etc/init.d/postgresql start
[ ok ] Starting PostgreSQL 9.6 database server: main.
root#be03ab1eb704:/# su postgres -c "psql -f test.sql"
CREATE DATABASE
CREATE ROLE
GRANT
root#be03ab1eb704:/# /etc/init.d/postgresql stop
[ ok ] Stopping PostgreSQL 9.6 database server: main.
root#be03ab1eb704:/# exit
exit
The official postgresql docker image automatically imports scripts at the first start of a container. So if you mount your directory with your init sql script to container path '/docker-entrypoint-initdb.d/' it should be run.
For example if you have your import script myImport.sql and it's on your host in a directory /opt/import, you can mount the import directory on container start to your postgres image to /docker-entrypoint-initdb.d and the sql file will be executed after initial database setup.
docker run -p $toHostParam:5432 -e POSTGRES_PASSWORD="$dbPwd" \
-e POSTGRES_USER="$dbUser" \
-e POSTGRES_DB="$dbName" \
-e PGDATA=/opt/pgdata \
-v ${dataDir}:/opt/pgdata \
# look here
# mount of local import dir
-v /opt/import:/docker-entrypoint-initdb.d \
postgres:9.6
Take a look at the postgesql image start script here (from line 126):
https://github.com/docker-library/postgres/blob/master/9.6/docker-entrypoint.sh
If you want a specific db user or database you can also customize your postgresql container with environment variables.
Take a look at the 'Environment Variables' section here: https://hub.docker.com/_/postgres/
Try with this setup.sh
#!/bin/bash
set -e
pg_createcluster 9.6 main --start
su postgres sh -c "/etc/init.d/postgresql start && psql -f create_fixtures.sql && /etc/init.d/postgresql stop"
Try a explicit user when running psql:
psql -U postgres -f create_fixtures.sql

Can't connect the postgreSQL with psycopg2

It's the first time that I can't find the answer about some tech problems
Here's my problems:
>> conn=psycopg2.connect(database="mydb", user="postgres", password="123",port=5432)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
psycopg2.OperationalError: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
My postgreSQL is running
My listeningport is 5432 for sure
root#lanston-laptop:~# psql -l
Password:
List of databases
Name | Owner | Encoding | Collation | Ctype | Access privileges
---------------+----------+----------+------------+------------+-----------------------
checkdatabase | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
mydb | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
Thanks a lot!
Your libpq, which is used by psycopg2 expects Postgres socket to be in /var/run/postgresql/ but when you install Postgres from source it is by default it in /tmp/.
Check if there is a file /tmp/.s.PGSQL.5432 instead of /var/run/postgresql/.s.PGSQL.5432. Try:
conn=psycopg2.connect(
database="mydb",
user="postgres",
host="/tmp/",
password="123"
)
Only this solved my problem,
make a symbolic link to the /tmp/.s.PGSQL.5432:
sudo ln -s /tmp/.s.PGSQL.5432 /var/run/postgresql/.s.PGSQL.5432
Thanks to, Sukhjit Singh Sehra - s-postgresql-server-is-running
I originally intended to make it a comment to Tometzky's answer, but well, I have a lot to say here... Regarding the case where you don't call psycopg2.connect directly, but use third-party software.
tl;dr
Set unix_socket_directories in postgresql.conf to /var/run/postgresql, /tmp, and restart PostgreSQL.
intro
I tried PostgreSQL 9.2 (CentOS 7) and 9.5 (Ubuntu Xenial) from distro repos, PostgreSQL 9.3, 9.4, 9.5, 9.6, 10 on CentOS 7 from PostgreSQL repo, PostgreSQL 9.6, 10 on Ubuntu Xenial from PostgreSQL repo. Among them only 9.3 listens to only /tmp:
$ systemctl stop postgresql-9.4 && systemctl start postgresql-9.3
$ lsof -aUp $(ps --ppid 1 -o pid= -o comm= | awk '$2 == "postgres" || $2 == "postmaster" {print $1}')
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
postgres 25455 postgres 4u unix 0xffff9acb23bc5000 0t0 6813995 /tmp/.s.PGSQL.5432
$ systemctl stop postgresql-9.3 && systemctl start postgresql-9.4
$ lsof -aUp $(ps --ppid 1 -o pid= -o comm= | awk '$2 == "postgres" || $2 == "postmaster" {print $1}')
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
postgres 26663 postgres 4u unix 0xffff9ac8c5474c00 0t0 7086508 /var/run/postgresql/.s.PGSQL.5432
postgres 26663 postgres 5u unix 0xffff9ac8c5477c00 0t0 7086510 /tmp/.s.PGSQL.5432
python-psycopg2
That's not a big deal with psql, just a matter of running the matching binary. But if you, for instance, have python-psycopg2 installed from CentOS's base or update repo. It links dynamically to libpq that OS provides. With 9.3 and 9.4 installed OS provides 9.4's version:
$ alternatives --display pgsql-ld-conf
pgsql-ld-conf - status is auto.
link currently points to /usr/pgsql-10/share/postgresql-9.4-libs.conf
/usr/pgsql-9.3/share/postgresql-9.3-libs.conf - priority 930
/usr/pgsql-9.4/share/postgresql-9.4-libs.conf - priority 940
Current `best' version is /usr/pgsql-9.4/share/postgresql-9.4-libs.conf.
$ ls -l /etc/ld.so.conf.d
lrwxrwxrwx 1 root root 31 Feb 7 02:25 postgresql-pgdg-libs.conf -> /etc/alternatives/pgsql-ld-conf
$ ls -l /etc/alternatives/pgsql-ld-conf
lrwxrwxrwx 1 root root 43 Feb 7 02:25 /etc/alternatives/pgsql-ld-conf -> /usr/pgsql-9.4/share/postgresql-9.4-libs.conf
$ cat /usr/pgsql-9.4/share/postgresql-9.4-libs.conf
/usr/pgsql-9.4/lib/
But libpq that comes with PostgreSQL 9.4 looks for socket in /var/run/postgresql as opposed to 9.3:
$ strings /usr/pgsql-9.3/lib/libpq.so.5 | egrep '/(tmp|var)'
/tmp
$ strings /usr/pgsql-9.4/lib/libpq.so.5 | egrep '/(tmp|var)'
/var/run/postgresql
The solution comes from postinstall scripts of corresponding packages:
$ yum reinstall --downloadonly postgresql94-libs
$ rpm -qp /var/cache/yum/x86_64/7/pgdg94/packages/postgresql94-libs-9.4.15-1PGDG.rhel7.x86_64.rpm --scripts
postinstall scriptlet (using /bin/sh):
/usr/sbin/update-alternatives --install /etc/ld.so.conf.d/postgresql-pgdg-libs.conf pgsql-ld-conf /usr/pgsql-9.4/share/postgresql-9.4-libs.conf 940
/sbin/ldconfig
# Drop alternatives entries for common binaries and man files
postuninstall scriptlet (using /bin/sh):
if [ "$1" -eq 0 ]
then
/usr/sbin/update-alternatives --remove pgsql-ld-conf /usr/pgsql-9.4/share/postgresql-9.4-libs.conf
/sbin/ldconfig
fi
Temporarily remove 9.4's alternative:
$ alternatives --remove pgsql-ld-conf /usr/pgsql-9.4/share/postgresql-9.4-libs.conf
$ ldconfig
When finished either reinstall postgresql94-libs, or add the alternative back:
$ alternatives --install /etc/ld.so.conf.d/postgresql-pgdg-libs.conf pgsql-ld-conf /usr/pgsql-9.4/share/postgresql-9.4-libs.conf 940
$ ldconfig
pip
If you install psycopg2 with pip on the other hand, it by default installs precompiled package which comes with its own libpq, which looks for socket in /var/run/postgresql:
$ python3.5 -m venv 1
$ . ./1/bin/activate
(1) $ pip install psycopg2
(1) $ python
>>> import psycopg2
>>>Ctrl-Z
[1]+ Stopped python
(1) $ pgrep python
26311
(1) $ grep libpq /proc/26311/maps | head -n 1
7f100b8cb000-7f100b90e000 r-xp 00000000 08:04 112980 /home/yuri/1/lib/python3.5/site-packages/psycopg2/.libs/libpq-909a53d8.so.5.10
(1) $ strings /home/yuri/1/lib/python3.5/site-packages/psycopg2/.libs/libpq-909a53d8.so.5.10 | egrep '/(tmp|var)'
/var/run
/var/run/postgresql
The solution is to ask pip to not install precompiled package, and make pg_config of the proper version of PostgreSQL available:
$ PATH=/usr/pgsql-9.3/lib:$PATH pip install --no-binary psycopg2 psycopg2
You can even add --no-binary switch to requirements.txt:
psycopg2==2.7.3.2 --no-binary psycopg2
unix_socket_directories
The easier option though is to make use of unix_socket_directories option:
Try change port to 5433 instead of 5432
a few years later, using the EnterpriseDB 'graphical' install on OSX 10.8, and pip install of psycopg2 (after linking the /Library/...dylib's as described here) i had this same issue.
for me the correct connect command was conn = psycopg2.connect('dbname=DBNAME user=postgres password=PWHERE host=/tmp/')
In my case with a conda installation had to: sudo ln -s /var/run/postgresql/.s.PGSQL.5432 /tmp/.s.PGSQL.5432
Having this happen to me after a brew upgrade, I googled for brew .s.PGSQL.5432.
Per the suggestion in this answer I ran the following:
postgres -D /usr/local/var/postgres
And got:
2019-10-29 17:43:30.860 IST [78091] FATAL: database files are incompatible with server
2019-10-29 17:43:30.860 IST [78091] DETAIL: The data directory was initialized by PostgreSQL version 10, which is not compatible with this version 11.5.
I googled that FATAL error and per the suggestion in this answer I ran:
brew postgresql-upgrade-database
That solved it for me.
put vpc_access_connector:
name: project//locations/us-central1/connectors/
and host :'/cloudsql/::
It should work for private Ip postgresql on gcp
Try this once
cd /etc/postgresql/13/main
vi pg_hba.conf
Change the line after this
Database administrative login by Unix domain socket
local all postgres peer
To
local all postgres md5
Then execute following commands
sudo systemctl stop postgresql
sudo systemctl start postgresql
Then run the python program then it will work properly