User not created in postgres docker image - postgresql

I have a docker image that's not accepting credentials for a user that is defined in the yaml docker-compose file. When I go to the docker console for the container and check users it only lists postgres. Not sure what I am missing - here's the yaml file:
version: '3.8'
services:
db:
container_name: drewreport_container
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: mpassword
POSTGRES_USER: thedrewreport
POSTGRES_DB: thedrewreportdb
ports:
- "5432:5432"
volumes:
- thedrewreportdata:/var/lib/postgresql/data/
volumes:
thedrewreportdata:
Any ideas?

I can't reproduce your problem. Running docker-compose up, I see:
Creating network "docker_default" with the default driver
Creating volume "docker_thedrewreportdata" with default driver
Creating docker_client_1 ...
Creating docker_db_1 ...
Creating docker_client_1 ... done
Creating docker_db_1 ... done
Attaching to docker_db_1, docker_client_1
[...]
db_1 | 2021-07-19 23:03:39.676 UTC [1] LOG: database system is ready to accept connections
If I then connect with psql, I can authenticate using the username
and password you've defined in your docker-compose.yml:
# psql -h localhost -U thedrewreport thedrewreportdb
Password for user thedrewreport:
psql (13.3 (Debian 13.3-1.pgdg100+1))
Type "help" for help.
thedrewreportdb=# \du
List of roles
Role name | Attributes | Member of
---------------+------------------------------------------------------------+-----------
thedrewreport | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
thedrewreportdb=#
Note that any volumes specified in your docker-compose.yml will
persist between a docker-compose down and a docker-compose up, so
if you ever brought your stack up with different credentials, those
will never be replaced unless your explicitly destroy the volume by
running docker-compose down -v.
You can tell that docker-compose is re-using a volume if you don't
see a message like this when you run docker-compose up:
Creating volume "docker_thedrewreportdata" with default driver

If existing, the existing DB data you mount to /var/lib/postgresql/data/ will take precedence over the environment variables to initialize it.
You have 2 options:
Update the existing DB data to add your user / password / database. To do so you can use docker compose exec db bash and then connect using psql command to make your changes.
Delete or move your existing thedrewreportdata local volume, for instance updating it to ./thedrewreportdata_postgres:/var/lib/postgresql/data/
Once done, you can use docker compose exec db psql --username thedrewreport --dbname thedrewreportdb to doublecheck you can connect with your credentials to the updated DB.

Related

Docker runs PostgreSQL in "trust" mode

I am currently learning docker and trying to run a docker container with the PostgreSQL database. I managed that once, and everything seemed to work fine. After some time, I tried to run another docker container with almost identical settings, however, it didn't go as expected. My problem is that now, whenever I try to run PostgreSQL container, initdb initializes the database in "trust" mode and accepts any connections without the password.
So far, I've tried running the command from the console:
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -p 32000:5432 -d postgres:14.5-alpine
As well as running the docker-compose.yaml:
services:
db:
container_name: Test_container
image: postgres:14.5-alpine
restart: unless-stopped
ports:
- "32000:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: mysecretpassword
Additionally, I tried ordering tags differently, different images, and different values, cleaning docker: removing all containers, images, and volumes, and even reinstalling docker, however, whenever I inspect logs of a newly created container, I get:
sh: locale: not found
2022-08-16 09:35:50.709 UTC [30] WARNING: no usable system locales were found
performing post-bootstrap initialization ... ok
initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
syncing data to disk ... ok
One of my assumptions was that docker, for some reason, doesn't see the password I am specifying and thus starts the database in "trust" mode, however, if I add
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test_db
to the docker-compose.yaml, test_db database is being created.
I'd appreciate any suggestions on how to make docker run PostgreSQL containers not in a "trust" mode as it should by default if the password is specified.
Juan González pointed out:
Note 1: The PostgreSQL image sets up trust authentication locally so you may notice a password is not required when connecting from localhost (inside the same container). However, a password will be required if connecting from a different host/container.
So, according to the docs, I updated my docker-compose.yaml file:
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test_db
POSTGRES_HOST_AUTH_METHOD: scram-sha-256
POSTGRES_INITDB_ARGS: --auth-host=scram-sha-256
and once again tried swapping order and\or removing POSTGRES_INITDB_ARGS, but database still runs in "trust" mode.
As stated in Postgres' DockerHub documentation:
Note 1: The PostgreSQL image sets up trust authentication locally so you may notice a password is not required when connecting from localhost (inside the same container). However, a password will be required if connecting from a different host/container.
However, if you don't want trust mode even in local connections, you can set the POSTGRES_HOST_AUTH_METHOD environment variable to override this behavior. More info at the documentation mentioned above.
As #jjanes pointed out in the comment to my question, the solution is to add POSTGRES_INITDB_ARGS: --auth=scram-sha-256 which would set both local and host types of connections.

How to execute commands in docker compose files [duplicate]

This question already has answers here:
How to create User/Database in script for Docker Postgres
(9 answers)
Closed 8 months ago.
I have a very complex environment, there are two services which named as A service and B service depend on service postgresql, but A and B use difference super user. so once I start the service postgresql, I need create another superuser for service B.
This is a part of docker compose file :
postgres:
image: postgres:13.4
container_name: postgresql
hostname: postgresql
volumes:
- 'postgres_data:/var/lib/postgresql/data'
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
command: ["CREATE ROLE postgres LOGIN SUPERUSER; | ALTER USER postgres CREATEDB CREATEROLE LOGIN INHERIT REPLICATION BYPASSRLS;"]
enter image description here
In the environments, I already setup the default user, password and DB in service postgresql for service A, BUT I’d like to create another super user for service B once service postgresql started, does there any one know how to write the commands. many thanks.
I think this grammer is wrong: command: ["CREATE ROLE postgres LOGIN SUPERUSER; | ALTER USER postgres CREATEDB CREATEROLE LOGIN INHERIT REPLICATION BYPASSRLS;"]
The issue with running commands on container startup is that you need the database to be up to be able to run the commands. By overriding the command: on the container, you replace the normal command which is to start Postgres. So with a new command, Postgres will never start.
You can run the command from a different container once Postgres is started. The command-runner container uses psql to connect to the database and run the command. It also uses the postgres docker image, but because it overrides the command on the container, this container doesn't start a database. It only runs the command.
Here's what I've come up with.
version: "3"
services:
postgres:
image: postgres
environment:
- POSTGRES_USER=keycloak
- POSTGRES_PASSWORD=password
- POSTGRES_DB=keycloak
command-runner:
image: postgres
command: /bin/sh -c 'sleep 10 && PGPASSWORD=password psql -U keycloak -h postgres -d keycloak -c "CREATE ROLE postgres LOGIN SUPERUSER; ALTER USER postgres CREATEDB CREATEROLE LOGIN INHERIT REPLICATION BYPASSRLS;"'
depends_on:
- postgres
I had to put in a sleep 10 command in the command-runner container for it to wait for Postgres to be ready to accept connections.
I also removed the | you had in your command before ALTER USER. I got a syntax error on it.

Can't set Password for Postgres using docker-compose

I am not able to set Password for Postgres using Docker-compose. Postgres is loading without password and with the default user name "postgres", non of the environment variables below seems to applied. below is the db service of my docker-compose.yml file: (version 3)
db:
image: postgres
container_name: postgres
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: db
restart: unless-stopped
volumes:
- ./postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
Note I tried using the "-POSTGRES_USER=" as well, it didn't work
Also, I deleted all old containers/volumes.
Any idea?
The problem should be with the volume attached. When your container start it will add the credentials you give him, but then the volume will be attached and that will cause this information being rewritten.
For more information have a look at https://github.com/docker-library/postgres/issues/203#issuecomment-255200501.
The main reason being use of ':' instead of "=" in the environment section.
Ideally it should look like this:
db:
image: postgres
container_name: postgres
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD= pass
- POSTGRES_DB= db
restart: unless-stopped
volumes:
- ./postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
Your configuration works fine for me. I suspect you are not using the complete set of correct credentials, which includes the username, password, and database name. If I take your example docker-compose.yaml and run it without modifications, I can connect to the database db like this with username user and password pass:
$ psql -h localhost -U user db
Password for user user:
psql (9.5.7, server 9.6.1)
WARNING: psql major version 9.5, server major version 9.6.
Some psql features might not work.
Type "help" for help.
db=#
Had the same issue.
Couldn't solve it for 2 weeks.
Read almost everything related to it.
And after I finished all PosgreSQL server related processes on local machine, everything goes well.
Start postgres instance:-
docker run --name postgres-0 -e POSTGRES_PASSWORD=mypassword -p 5433:5433 -d postgres
Now we can check docker all running container by this command:-
docker ps

Run script after container entrypoint in docker-compose

I have a postgres:9.5.6-alpine container, and another container, named web, which has to be linked to it.
I want to run a script named create_db.sh in postgres container after it has been started and docker-entrypoint.sh has been executed, in order to create a db and a user and restore a backup.
My docker-compose.yml (postgres part):
postgres:
build: ./postgres
container_name: postgres
volumes:
- /shared_folder/postgresql:/var/lib/postgresql
ports:
- "5432:5432"
command: sh /home/create_db.sh
The content of create_db.sh is:
#!/bin/sh
psql -d template1 -U postgres
psql --command "CREATE USER user WITH PASSWORD 'userpassword';"
psql --command "CREATE DATABASE userdb;"
psql --command "GRANT ALL PRIVILEGES ON DATABASE userdb to user;"
psql --command "\q;"
psql -U user -d userdb -f /var/lib/postgresql/backup.sql
exit
When i run docker-compose build and then docker-compose up i get this:
Attaching to postgres, web
postgres | psql: could not connect to server: No such file or directory
postgres | Is the server running locally and accepting
postgres | connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
I've understood this is because when I launch create_db.sh postgres server is not ready, but so how can i run it after the docker-entrypoint.sh of the container?
You are overriding the original command and you do not start postgres in this script which is why your database is not available.
You can put your database initialization into the container's entrypoint directory: /docker-entrypoint-initdb.d. This executes all *.sh and *.sql files in this directory and does not touch the original command.
All files in this directory are automatically executed in the alphabetical order on container creation. Therefore, create a volume to add your scripts / sql files to the entrypoint and let the container execute them. This is described in the official postgres documentation, section "How to extend this image".
Your compose file then changes to something like this:
postgres:
build: ./postgres
volumes:
- /shared_folder/postgresql:/var/lib/postgresql
- ./db-init-scripts:/docker-entrypoint-initdb.d
ports:
- "5432:5432"
whereas a local directory, e.g. db-init-scripts, contains your initialization scripts (rename it if you want). Copy create_db.sh to this folder and it will be automatically executed when you create a new container.
Several database-images watch this entrypoint-directory, which is very convenient.
Your container_name: postgres seems redundant.
If you are getting an error /bin/sh: bad interpreter: Permission denied change execution permission to your script file first, since Docker copies over permissions:
chmod +x your/script.sh

How to recreate Docker container?

I'm new to docker and I'm using docker compose. For some reason my postgres container is now broken
I'm trying this command docker-compose up --no-deps --build db
And it's returning me this:
MacBook-Pro-de-Javier:goxo.api javier$ docker-compose up --no-deps --build db
Recreating testapi_db_1
Attaching to testapi_db_1
db_1 | LOG: database system was shut down at 2017-04-20 17:19:05 UTC
db_1 | LOG: MultiXact member wraparound protections are now enabled
db_1 | LOG: database system is ready to accept connections
db_1 | LOG: autovacuum launcher started
Whenever I try to connect (with the same connection arguemnts than before) I get this:
^[[Adb_1 | FATAL: database "test" does not exist
This is part of my docker-compose.yml
version: "3"
services:
db:
image: postgres
ports:
- "3700:5432"
environment:
POSTGRES_HOST: "127.0.0.1"
POSTGRES_DB: "test"
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres1"
tmpfs:
- /tmp
- /var/run/postgresql
volumes:
- db:/var/lib/postgresql/data
- ./config/postgres-initdb.sh:/docker-entrypoint-initdb.d/initdb.sh
Any ideas on how can I recreate the docker image to be how it was before? It was working as it was created the first time
Thanks
EDIT 1: If I run docker-compose build && docker-compose up
Terminal throws this:
db uses an image, skipping
EDIT 2: This command does not create database again neither:
docker-compose up --force-recreate --abort-on-container-exit --build db
have you tried to rebuild your single postgres container?
docker build -t <postgrescontainer>
or with docker-compose:
docker-compose up --build
to recreate the images and not use the old 'used' ones.
You can have a look at the images on your system with
docker images
which should show your image, and then
docker history --no-trunc your_image
should show the commands used for the creation of the image
This my be insufficient, as when you see something like
ADD * /opt
you do not know exactly which files were copied, and what thoses files contained
There is also dockerfile-from-image
https://github.com/CenturyLinkLabs/dockerfile-from-image
which seems to have a bug recently (I do not know if it is fixed)