I have a simple Dockerfile that sets up a database and then runs a .sql file. The image builds and container starts with no apparent issue, but PostgreSQL is missing data that should have been included.
Here's the setup, logs, and problem---
Dockerfile
FROM postgres
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD postgres
ENV POSTGRES_DB exampledb
COPY db-setup.sql /docker-entrypoint-initdb.d/
I run it with docker build -t example-db ./
This is the copied .sql file
BEGIN;
CREATE TABLE IF NOT EXISTS users (
id integer NOT NULL,
name VARCHAR,
email VARCHAR,
password VARCHAR,
remember_token varchar(100),
company_name VARCHAR,
company_street VARCHAR,
company_city VARCHAR,
company_zipcode integer,
created_at timestamp,
updated_at timestamp
);
CREATE TABLE IF NOT EXISTS quotes (
id integer NOT NULL,
dot_number integer,
nbr_of_power_units integer,
value_of_power_units integer,
premium_amount integer,
premium_tax integer,
premium_total integer,
street VARCHAR,
city VARCHAR,
state VARCHAR,
zipcode integer,
driver1_name VARCHAR,
driver1_age integer,
driver2_name VARCHAR,
driver2_age integer,
driver3_name VARCHAR,
driver3_age integer,
driver4_name VARCHAR,
driver4_age integer,
driver5_name VARCHAR,
driver5_age integer,
created_at timestamp,
updated_at timestamp
);
INSERT INTO users (id, name) VALUES (1, 'test-user');
Lastly I start the container via docker run --name example-container -p 5432:5432 example-db
It appears to function correctly, outputing this log.
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
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Etc/UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... 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.
ok
Success. You can now start the database server using:
pg_ctl -D /var/lib/postgresql/data -l logfile start
waiting for server to start....2021-05-07 04:04:45.428 UTC [47] LOG: starting PostgreSQL 13.2 (Debian 13.2-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
2021-05-07 04:04:45.429 UTC [47] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-05-07 04:04:45.435 UTC [48] LOG: database system was shut down at 2021-05-07 04:04:45 UTC
2021-05-07 04:04:45.439 UTC [47] LOG: database system is ready to accept connections
done
server started
CREATE DATABASE
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/db-setup.sql
BEGIN
CREATE ROLE
CREATE TABLE
CREATE TABLE
INSERT 0 1
waiting for server to shut down....2021-05-07 04:04:45.772 UTC [47] LOG: received fast shutdown request
2021-05-07 04:04:45.774 UTC [47] LOG: aborting any active transactions
2021-05-07 04:04:45.776 UTC [47] LOG: background worker "logical replication launcher" (PID 54) exited with exit code 1
2021-05-07 04:04:45.777 UTC [49] LOG: shutting down
2021-05-07 04:04:45.810 UTC [47] LOG: database system is shut down
done
server stopped
PostgreSQL init process complete; ready for start up.
2021-05-07 04:04:45.919 UTC [1] LOG: starting PostgreSQL 13.2 (Debian 13.2-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
2021-05-07 04:04:45.919 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2021-05-07 04:04:45.920 UTC [1] LOG: listening on IPv6 address "::", port 5432
2021-05-07 04:04:45.923 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-05-07 04:04:45.929 UTC [84] LOG: database system was shut down at 2021-05-07 04:04:45 UTC
2021-05-07 04:04:45.935 UTC [1] LOG: database system is ready to accept connections
Pulling from that log there's an indication that the tables in the .sql file were created, and the test row inserted.
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/db-setup.sql
BEGIN
CREATE ROLE
CREATE TABLE
CREATE TABLE
INSERT 0 1
However, when I bash into the Docker container docker exec -it example-container /bin/bash and then log into psql psql -U postgres
I can see the newly created database
------------+----------+----------+------------+------------+-----------------------
exampledb | 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
But, connecting to the db and running \dt yields- "Did not find any relations."
I am very confused and any help would be appreciated.
Ah! Man...this one looks sneaky. I think your culprit is the BEGIN; at the start of your SQL init script. That starts a Postgres transaction. Essentially that means your script will create your tables, but since there isn't an END; statement, the Postgres transaction is left open.
When Docker aborts active transactions as a part of its startup process, that init script transaction is aborted. And when an in progress Postgres transaction is aborted, all the work inside that transaction block is reversed. I.e., you go back to the state your database was in when the init script started - empty.
Try removing the BEGIN; and running it from there!
Related
The problem
I have a project based on Strapi's CMS and Postgres database wrapped in docker containers which I start toghether from a single docker-compose.yml script. I have developed the project locally and want to move it on a remote server keeping the current state of all data I inserted by the CMS. In other words my local Postgres database is not empty and contains tables and information generated by the CMS. I have copied all *.js files dynamically generated from the CMS to the remote server along with the public/ folder, but have troubles to export/import an exact copy of the database. What is the right way to copy the database from the docker containers? I prefer to export it in a single or multiple *.sql files that can be imported from the /usr/local/bin/docker-entrypoint.sh folder.
What have I tried so far?
Using Adminer I have exported it as a single *.sql file. It imports successfully just by placing the exported file in Postgres container's folder /usr/local/bin/docker-entrypoint.sh. So all data I have inserted into the CMS on my local database is in the remote database. At first glance everything looks alright, until I try to update some CMS collection from the admin panel. Then in the user interface come up strange errors in the same time the Postgres and Strapi's log says this:
postgres | 2023-02-17 11:44:39.438 UTC [40] ERROR: duplicate key value violates unique constraint "about_pages_components_pkey"
postgres | 2023-02-17 11:44:39.438 UTC [40] DETAIL: Key (id)=(35) already exists.
postgres | 2023-02-17 11:44:39.438 UTC [40] STATEMENT: insert into "about_pages_components" ("component_id", "component_type", "entity_id", "field", "order") values ($1, $2, $3, $4, $5) returning "id"
api | [2023-02-17 11:44:39.440] error: insert into "about_pages_components" ("component_id", "component_type", "entity_id", "field", "order") values ($1, $2, $3, $4, $5) returning "id" - duplicate key value violates unique constraint "about_pages_components_pkey"
api | error: insert into "about_pages_components" ("component_id", "component_type", "entity_id", "field", "order") values ($1, $2, $3, $4, $5) returning "id" - duplicate key value violates unique constraint "about_pages_components_pkey"
api | at Parser.parseErrorMessage (/opt/app/node_modules/pg-protocol/dist/parser.js:287:98)
api | at Parser.handlePacket (/opt/app/node_modules/pg-protocol/dist/parser.js:126:29)
api | at Parser.parse (/opt/app/node_modules/pg-protocol/dist/parser.js:39:38)
api | at Socket.<anonymous> (/opt/app/node_modules/pg-protocol/dist/index.js:11:42)
api | at Socket.emit (events.js:400:28)
api | at Socket.emit (domain.js:475:12)
api | at addChunk (internal/streams/readable.js:293:12)
api | at readableAddChunk (internal/streams/readable.js:267:9)
api | at Socket.Readable.push (internal/streams/readable.js:206:10)
api | at TCP.onStreamRead (internal/stream_base_commons.js:188:23)
ngi
Adminer's export settings:
Using docker exec -t postgres pg_dump -c -U postgres > init.sql I get the following error log:
postgres | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
postgres | SET
postgres | SET
postgres | SET
postgres | SET
postgres | SET
postgres | set_config
postgres | ------------
postgres |
postgres | (1 row)
postgres |
postgres | SET
postgres | SET
postgres | SET
postgres | SET
postgres | 2023-02-17 11:50:46.045 UTC [50] ERROR: relation "public.up_users" does not exist
postgres | 2023-02-17 11:50:46.045 UTC [50] STATEMENT: ALTER TABLE ONLY public.up_users DROP CONSTRAINT up_users_updated_by_id_fk;
postgres | psql:/docker-entrypoint-initdb.d/init.sql:19: ERROR: relation "public.up_users" does not exist
postgres | 2023-02-17 11:50:47.358 UTC [1] LOG: starting PostgreSQL 14.3 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
postgres | 2023-02-17 11:50:47.358 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres | 2023-02-17 11:50:47.358 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres | 2023-02-17 11:50:47.375 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres | 2023-02-17 11:50:47.393 UTC [24] LOG: database system was interrupted; last known up at 2023-02-17 11:50:45 UTC
postgres | 2023-02-17 11:50:51.704 UTC [24] LOG: database system was not properly shut down; automatic recovery in progress
postgres | 2023-02-17 11:50:51.735 UTC [24] LOG: invalid record length at 0/16FCE28: wanted 24, got 0
postgres | 2023-02-17 11:50:51.735 UTC [24] LOG: redo is not required
postgres | 2023-02-17 11:50:52.395 UTC [1] LOG: database system is ready to accept connections
Using docker exec -t postgres pg_dumpall -c -U postgres > init.sql I get the following error log:
postgres | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
postgres | SET
postgres | SET
postgres | SET
postgres | 2023-02-17 12:05:48.154 UTC [49] ERROR: current user cannot be dropped
postgres | 2023-02-17 12:05:48.154 UTC [49] STATEMENT: DROP ROLE postgres;
postgres | psql:/docker-entrypoint-initdb.d/init.sql:22: ERROR: current user cannot be dropped
postgres | 2023-02-17 12:05:49.532 UTC [1] LOG: starting PostgreSQL 14.3 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
postgres | 2023-02-17 12:05:49.532 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres | 2023-02-17 12:05:49.533 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres | 2023-02-17 12:05:49.554 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres | 2023-02-17 12:05:49.581 UTC [22] LOG: database system was interrupted; last known up at 2023-02-17 12:05:48 UTC
Strapi version and dependencies:
"dependencies": {
"#strapi/plugin-i18n": "4.2.3",
"#strapi/plugin-users-permissions": "4.2.3",
"#strapi/strapi": "4.2.3",
"better-sqlite3": "7.4.6",
"pg": "^8.8.0"
},
Postgres docker image postgres:14.3-alpine
Adminer docker image adminer:4.8.1
I have a simple Docker Compose file to initialize a Postgres DB Instance:
version: '3.8'
services:
my-database:
container_name: my-database
image: library/postgres:13.1
volumes:
- ./db/init-my-database.sql:/docker-entrypoint-initdb.d/init-db-01.sql
environment:
- POSTGRES_DB=my-database
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=password
ports:
- 10040:5432
restart: always
networks:
- app-network
And my script init-my-database.sql looks like this:
DROP DATABASE IF EXISTS myschema;
CREATE DATABASE myschema;
-- Make sure we're using our `myschema` database
\c myschema;
CREATE SEQUENCE IF NOT EXISTS recipient_seq
START WITH 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;
CREATE TABLE IF NOT EXISTS recipient
(
id BIGINT NOT NULL,
recipient_id VARCHAR(255) NOT NULL,
first_name VARCHAR(255) NOT NULL,
middle_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
CONSTRAINT recipient_pk PRIMARY KEY (id)
);
When I tail the Docker logs I do see that the initialization script is being called. However, towards the end the database is shutdown and restarted --> "received fast shutdown request"
Why is the database restarted at the end? As the database and table created in the script is not available anymore.
Complete Docker Logs -->
my-database | The files belonging to this database system will be owned by user "postgres".
my-database | This user must also own the server process.
my-database |
my-database | The database cluster will be initialized with locale "en_US.utf8".
my-database | The default database encoding has accordingly been set to "UTF8".
my-database | The default text search configuration will be set to "english".
my-database |
my-database | Data page checksums are disabled.
my-database |
my-database | fixing permissions on existing directory /var/lib/postgresql/data ... ok
my-database | creating subdirectories ... ok
my-database | selecting dynamic shared memory implementation ... posix
my-database | selecting default max_connections ... 100
my-database | selecting default shared_buffers ... 128MB
my-database | selecting default time zone ... Etc/UTC
my-database | creating configuration files ... ok
my-database | running bootstrap script ... ok
my-database | performing post-bootstrap initialization ... ok
my-database | syncing data to disk ... ok
my-database |
my-database | initdb: warning: enabling "trust" authentication for local connections
my-database | You can change this by editing pg_hba.conf or using the option -A, or
my-database | --auth-local and --auth-host, the next time you run initdb.
my-database |
my-database | Success. You can now start the database server using:
my-database |
my-database | pg_ctl -D /var/lib/postgresql/data -l logfile start
my-database |
my-database | waiting for server to start....2020-12-22 23:42:50.083 UTC [45] LOG: starting PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
my-database | 2020-12-22 23:42:50.085 UTC [45] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
my-database | 2020-12-22 23:42:50.091 UTC [46] LOG: database system was shut down at 2020-12-22 23:42:49 UTC
my-database | 2020-12-22 23:42:50.096 UTC [45] LOG: database system is ready to accept connections
my-database | done
my-database | server started
my-database | CREATE DATABASE
my-database |
my-database |
my-database | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init-db-01.sql
my-database | psql:/docker-entrypoint-initdb.d/init-db-01.sql:1: NOTICE: database "mergeletter" does not exist, skipping
my-database | DROP DATABASE
my-database | CREATE DATABASE
my-database | You are now connected to database "mergeletter" as user "admin".
my-database | CREATE SEQUENCE
my-database | CREATE TABLE
my-database |
my-database |
my-database | 2020-12-22 23:42:50.515 UTC [45] LOG: received fast shutdown request
my-database | waiting for server to shut down....2020-12-22 23:42:50.516 UTC [45] LOG: aborting any active transactions
my-database | 2020-12-22 23:42:50.521 UTC [45] LOG: background worker "logical replication launcher" (PID 52) exited with exit code 1
my-database | 2020-12-22 23:42:50.521 UTC [47] LOG: shutting down
my-database | 2020-12-22 23:42:50.541 UTC [45] LOG: database system is shut down
my-database | done
my-database | server stopped
my-database |
my-database | PostgreSQL init process complete; ready for start up.
my-database |
my-database | 2020-12-22 23:42:50.648 UTC [1] LOG: starting PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
my-database | 2020-12-22 23:42:50.649 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
my-database | 2020-12-22 23:42:50.649 UTC [1] LOG: listening on IPv6 address "::", port 5432
my-database | 2020-12-22 23:42:50.652 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
my-database | 2020-12-22 23:42:50.657 UTC [73] LOG: database system was shut down at 2020-12-22 23:42:50 UTC
my-database | 2020-12-22 23:42:50.663 UTC [1] LOG: database system is ready to accept connections
Put simply, this happens on purpose; the author does it as part of the initialization.
It looks like some answers can be found in the image's entrypoint shell script:
_main() {
# if first arg looks like a flag, assume we want to run postgres server
if [ "${1:0:1}" = '-' ]; then
set -- postgres "$#"
fi
if [ "$1" = 'postgres' ] && ! _pg_want_help "$#"; then
docker_setup_env
# setup data directories and permissions (when run as root)
docker_create_db_directories
if [ "$(id -u)" = '0' ]; then
# then restart script as postgres user
exec gosu postgres "$BASH_SOURCE" "$#"
fi
# only run initialization on an empty data directory
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
docker_verify_minimum_env
# check dir permissions to reduce likelihood of half-initialized database
ls /docker-entrypoint-initdb.d/ > /dev/null
docker_init_database_dir
pg_setup_hba_conf
# PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless
# e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS
export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}"
docker_temp_server_start "$#"
docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/*
docker_temp_server_stop
unset PGPASSWORD
echo
echo 'PostgreSQL init process complete; ready for start up.'
echo
else
echo
echo 'PostgreSQL Database directory appears to contain a database; Skipping initialization'
echo
fi
fi
exec "$#"
}
As for "why?" I think it's because of desire to run as a less-privileged user.
You can "solve" the problem by specifying a volume in the Compose file like so:
volumes:
- ./data/pgsql:/var/lib/postgresql/data
Then, it will skip the routine to ensure DATABASE_ALREADY_EXISTS.
Or, if that's not helpful--you can dig into the entrypoint script a bit more.
Thanks for the above tip from #TorEHagermann (https://stackoverflow.com/a/65417566/5631863) I was able to resolve the problem.
The solution was to include the following:
volumes:
- ./data/pgsql:/var/lib/postgresql/data
Also, in my case, I needed to clear and refresh the data every time I started the container. So, I included the following in my shell script to delete the drive /data/pgsql:
rm -rf data
With that change, my docker-compose file looks like:
version: '3.8'
services:
my-database:
container_name: my-database
image: library/postgres:13.1
volumes:
- ./db/init-my-database.sql:/docker-entrypoint-initdb.d/init-db-01.sql
- ./data/pgsql:/var/lib/postgresql/data
environment:
- POSTGRES_DB=my-database
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=password
ports:
- 10040:5432
restart: always
networks:
- app-network
As mentioned above, the restart is intentional. The reason is that changes in some of the database server settings need restart to take effect. The entrypoint init script is a convenient place for the queries that change these settings.
e.g.
ALTER SYSTEM SET max_connections = 300;
I'm starting postgresql 12.3 image via dokcer-compose
I extended the image to execute simple SQL (create schema, table) on start.
From the logs I can see that the SQL commands are executed but when I log to the DB the changes are missing.
My Dockerfile:
FROM postgres
ENV INITDB_DIR /docker-entrypoint-initdb.d
ENV POSTGRES_PASSWORD=...
ENV POSTGRES_DB mydb
COPY initdb.d ${INITDB_DIR}
My docker-compose.yml:
version: "3.7"
services:
postgres:
image: postgres
build: ./postgres
restart: on-failure
ports:
- "5432:5432"
networks:
- postgres
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:...}
- POSTGRES_DB=mydb
networks:
postgres:
driver: bridge
create_schema.sql (located in ./postgres/initdb.d)
create schema "foo";
create table "foo"."message"(
"id" BIGINT NOT NULL,
"value" TEXT
);
alter table "foo"."message" add constraint "foo_message_pk" primary key("id");
And finally the logs produced when executing: docker-compose up --build postgres
postgres_1 | The files belonging to this database system will be owned by user "postgres".
postgres_1 | This user must also own the server process.
postgres_1 |
postgres_1 | The database cluster will be initialized with locale "en_US.utf8".
postgres_1 | The default database encoding has accordingly been set to "UTF8".
postgres_1 | The default text search configuration will be set to "english".
postgres_1 |
postgres_1 | Data page checksums are disabled.
postgres_1 |
postgres_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
postgres_1 | creating subdirectories ... ok
postgres_1 | selecting dynamic shared memory implementation ... posix
postgres_1 | selecting default max_connections ... 100
postgres_1 | selecting default shared_buffers ... 128MB
postgres_1 | selecting default time zone ... Etc/UTC
postgres_1 | creating configuration files ... ok
postgres_1 | running bootstrap script ... ok
postgres_1 | performing post-bootstrap initialization ... ok
postgres_1 | syncing data to disk ... ok
postgres_1 |
postgres_1 |
postgres_1 | Success. You can now start the database server using:
postgres_1 |
postgres_1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
postgres_1 |
postgres_1 | initdb: warning: enabling "trust" authentication for local connections
postgres_1 | You can change this by editing pg_hba.conf or using the option -A, or
postgres_1 | --auth-local and --auth-host, the next time you run initdb.
postgres_1 | waiting for server to start....2020-05-27 07:34:00.098 UTC [47] LOG: starting PostgreSQL 12.3 (Debian 12.3-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
postgres_1 | 2020-05-27 07:34:00.112 UTC [47] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2020-05-27 07:34:00.143 UTC [48] LOG: database system was shut down at 2020-05-27 07:33:59 UTC
postgres_1 | 2020-05-27 07:34:00.151 UTC [47] LOG: database system is ready to accept connections
postgres_1 | done
postgres_1 | server started
postgres_1 | CREATE DATABASE
postgres_1 |
postgres_1 |
postgres_1 | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/create_schema.sql
postgres_1 | CREATE SCHEMA
postgres_1 | CREATE TABLE
postgres_1 | ALTER TABLE
postgres_1 |
postgres_1 |
postgres_1 | waiting for server to shut down....2020-05-27 07:34:00.588 UTC [47] LOG: received fast shutdown request
postgres_1 | 2020-05-27 07:34:00.593 UTC [47] LOG: aborting any active transactions
postgres_1 | 2020-05-27 07:34:00.595 UTC [47] LOG: background worker "logical replication launcher" (PID 54) exited with exit code 1
postgres_1 | 2020-05-27 07:34:00.595 UTC [49] LOG: shutting down
postgres_1 | 2020-05-27 07:34:00.643 UTC [47] LOG: database system is shut down
postgres_1 | done
postgres_1 | server stopped
postgres_1 |
postgres_1 | PostgreSQL init process complete; ready for start up.
postgres_1 |
postgres_1 | 2020-05-27 07:34:00.708 UTC [1] LOG: starting PostgreSQL 12.3 (Debian 12.3-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
postgres_1 | 2020-05-27 07:34:00.709 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_1 | 2020-05-27 07:34:00.709 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_1 | 2020-05-27 07:34:00.719 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2020-05-27 07:34:00.744 UTC [74] LOG: database system was shut down at 2020-05-27 07:34:00 UTC
postgres_1 | 2020-05-27 07:34:00.753 UTC [1] LOG: database system is ready to accept connections
When I connect to the database only the default database (postgres) is present. i also tried the above without creating mydb database but still the schema or table were not present.
I am trying to set up a postgres container to start and run initializing the creation of a table. I've succeeded with the straight image from docker but now that I am trying to extend the image a little to create tables when it's produced and I can't get it running. Based off what I've read here How to create User/Database in script for Docker Postgres, this is what I have:
Dockerfile:
FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/
init.sql:
CREATE TABLE incident_disposition (
incident_disposition_code VARCHAR,
incident_disposition_code_description VARCHAR
);
From what I understand, FROM library . . . pulls the postgres image from docker hub and the COPY pushes my init.sql script into the entry point so there is no need for a big dockerfile correct?
I then build the image no issue:
Build
docker build -t my_postgres_image .
But when I run I get the issues:
Run
docker run --name testing my_postgres_image --publish 8000:8080 --detach -e POSTGRES_PASSWORD=postgres -d postgres
Errors from logs
Error: Database is uninitialized and superuser password is not specified.
You must specify POSTGRES_PASSWORD to a non-empty value for the
superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".
You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
connections without a password. This is *not* recommended.
See PostgreSQL documentation about "trust":
https://www.postgresql.org/docs/current/auth-trust.html
Attempt from comment:
docker container logs testing
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
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Etc/UTC
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:
pg_ctl -D /var/lib/postgresql/data -l logfile start
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.
waiting for server to start....2020-03-26 14:06:51.064 UTC [46] LOG: starting PostgreSQL 12.2 (Debian 12.2-2.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
2020-03-26 14:06:51.072 UTC [46] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2020-03-26 14:06:51.108 UTC [47] LOG: database system was shut down at 2020-03-26 14:06:50 UTC
2020-03-26 14:06:51.119 UTC [46] LOG: database system is ready to accept connections
done
server started
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
CREATE TABLE
2020-03-26 14:06:51.231 UTC [46] LOG: received fast shutdown request
waiting for server to shut down....2020-03-26 14:06:51.232 UTC [46] LOG: aborting any active transactions
2020-03-26 14:06:51.233 UTC [46] LOG: background worker "logical replication launcher" (PID 53) exited with exit code 1
2020-03-26 14:06:51.234 UTC [48] LOG: shutting down
2020-03-26 14:06:51.290 UTC [46] LOG: database system is shut down
done
server stopped
PostgreSQL init process complete; ready for start up.
2020-03-26 14:06:51.345 UTC [1] LOG: starting PostgreSQL 12.2 (Debian 12.2-2.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
2020-03-26 14:06:51.345 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2020-03-26 14:06:51.345 UTC [1] LOG: listening on IPv6 address "::", port 5432
2020-03-26 14:06:51.361 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2020-03-26 14:06:51.387 UTC [64] LOG: database system was shut down at 2020-03-26 14:06:51 UTC
2020-03-26 14:06:51.398 UTC [1] LOG: database system is ready to accept connections
2020-03-26 14:07:27.715 UTC [72] ERROR: relation "incident_disposition" does not exist at character 15
2020-03-26 14:07:27.715 UTC [72] STATEMENT: select * from incident_disposition;
In addition to comments
Due to recent docker image's updates postgres images do not allow to connect to DB without a password from anywhere. So you need to specify username/password
docker run -p 8000:8080 -e POSTGRES_PASSWORD=postgres --name testing -d my_postgres_image
Or if you still don't want to use password, you can just set POSTGRES_HOST_AUTH_METHOD=trust environment variable:
docker run -p 8000:8080 -e POSTGRES_HOST_AUTH_METHOD=trust --name testing -d my_postgres_image
It is a typical Initialization scripts issue.
You can file the full explaination in postgresql docker page. https://hub.docker.com/_/postgres
Here is the brief intro:
1. One common problem is that if one of your /docker-entrypoint-initdb.d scripts fails (which will cause the entrypoint script to exit) and your orchestrator restarts the container with the already initialized data directory, it will not continue on with your scripts.
note:
in your case, you may need clean the historical docker containers(stopped) by
step 1: docker ps |grep
step 2: docker rm -f -v
Or if you are using docker-compose, the historical orchestrator could be easily removed by docker-compose down -v.
I have the following docker compose file:
version: "3"
services:
postgres:
image: postgres:11.2-alpine
environment:
POSTGRES_PASSWORD: root
POSTGRES_USER: root
ports:
- "5432:5432"
volumes:
- ./init-db/init-db.sql:/docker-entrypoint-initdb.d/init.sql
This is the init-db.sql:
CREATE TABLE users (
email VARCHAR(355) UNIQUE NOT NULL,
password VARCHAR(256) NOT NULL
);
CREATE TABLE products (
id SERIAL PRIMARY KEY,
title VARCHAR(100) NOT NULL,
price NUMERIC(6, 2) NOT NULL,
category INT NOT NULL
);
INSERT INTO users VALUES ('test#test.com', 'Test*123');
INSERT INTO products (title, price, category) VALUES ('Truco', 9.90, 13);
When I run docker-compose up, I'm getting this error:
server started
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
/docker-entrypoint-initdb.d/init.sql: Permission denied
I already tried to:
chmod 777 on the sql file
chmod -x on the sql file
Run docker and docker-compose using sudo
Any idea?
I found the easy way to solve this...
You should use "build" way to create postgres service
And DO NOT setting the volume for init.sql, it will cause the permission problem.
postgres:
build: ./postgres
Create a Dockerfile for postgres like this
FROM postgres:12
COPY ./init.sql /docker-entrypoint-initdb.d/init.sql
CMD ["docker-entrypoint.sh", "postgres"]
Then it should works out.
Hope my answer would help you!
For me problem was in my machine. enabled SELinux access control, which did not allow for containers to expand files.
Solution, disable SELinux:
echo SELINUX=disabled > /etc/selinux/config
SELINUXTYPE=targeted >> /etc/selinux/config
setenforce 0
From this
I had a similar problem when using the ADD command.
When using ADD (eg to download a file) the default chmod value is 711. When using the COPY command the chmod will match the hosts chmod of the file where you copy it from. The solution is to set the permission before copying, or change them in your Dockerfile after they've been copied.
It looks like there will finally be a "COPY --chmod 775" flag available in the upcoming docker 20 which will make this easier.
https://github.com/moby/moby/issues/34819
When the sql file in /docker-entrypoint-initdb.d/ has a permission of 775 then the file is run correctly.
You can test this within the image (override entrypoint to /bin/bash) using:
docker-entrypoint.sh postgres
I have same problem on my macOS, but it's OK on my ubuntu laptop.
I found the problem is that MacOS cannot let docker access the folder.
Following link may resolve your problem.
https://stackoverflow.com/a/58482702/10752354
Besides, in my case, I should add one line code in my init.sql file because the default database is "root", and I should change "root" database into "postgres" database, or in your case for another custom database instead of root.
> docker-compose exec db psql -U root
psql (13.0 (Debian 13.0-1.pgdg100+1))
Type "help" for help.
root=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privilege
s
-----------+-------+----------+------------+------------+-----------------
--
postgres | root | UTF8 | en_US.utf8 | en_US.utf8 |
root | root | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | root | UTF8 | en_US.utf8 | en_US.utf8 | =c/root
+
| | | | | root=CTc/root
template1 | root | UTF8 | en_US.utf8 | en_US.utf8 | =c/root
+
| | | | | root=CTc/root
(4 rows)
so I need to add \c postgres in my init.sql file:
\c postgres // for creating table in the database named 'postgres'
create table sample_table. ( ... )
I tried with the following compose file and it seems working as expected. are you sure form the path of the files you use?
version: "3"
services:
postgres:
image: postgres:11.2-alpine
environment:
POSTGRES_PASSWORD: root
POSTGRES_USER: root
ports:
- "5432:5432"
volumes:
- ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
files structure
drwxr-xr-x 4 shihadeh 502596769 128B Feb 28 22:37 .
drwxr-xr-x 12 shihadeh 502596769 384B Feb 28 22:36 ..
-rw-r--r-- 1 shihadeh 502596769 244B Feb 28 22:37 docker-compose.yml
-rw-r--r-- 1 shihadeh 502596769 380B Feb 28 22:37 init-db.sql
output of docker-compose up
postgres_1 | The files belonging to this database system will be owned by user "postgres".
postgres_1 | This user must also own the server process.
postgres_1 |
postgres_1 | The database cluster will be initialized with locale "en_US.utf8".
postgres_1 | The default database encoding has accordingly been set to "UTF8".
postgres_1 | The default text search configuration will be set to "english".
postgres_1 |
postgres_1 | Data page checksums are disabled.
postgres_1 |
postgres_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
postgres_1 | creating subdirectories ... ok
postgres_1 | selecting default max_connections ... 100
postgres_1 | selecting default shared_buffers ... 128MB
postgres_1 | selecting dynamic shared memory implementation ... posix
postgres_1 | creating configuration files ... ok
postgres_1 | running bootstrap script ... ok
postgres_1 | performing post-bootstrap initialization ... sh: locale: not found
postgres_1 | 2020-02-28 21:45:01.363 UTC [26] WARNING: no usable system locales were found
postgres_1 | ok
postgres_1 | syncing data to disk ... ok
postgres_1 |
postgres_1 | Success. You can now start the database server using:
postgres_1 |
postgres_1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
postgres_1 |
postgres_1 |
postgres_1 | WARNING: enabling "trust" authentication for local connections
postgres_1 | You can change this by editing pg_hba.conf or using the option -A, or
postgres_1 | --auth-local and --auth-host, the next time you run initdb.
postgres_1 | waiting for server to start....2020-02-28 21:45:02.272 UTC [30] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2020-02-28 21:45:02.294 UTC [31] LOG: database system was shut down at 2020-02-28 21:45:01 UTC
postgres_1 | 2020-02-28 21:45:02.299 UTC [30] LOG: database system is ready to accept connections
postgres_1 | done
postgres_1 | server started
postgres_1 | CREATE DATABASE
postgres_1 |
postgres_1 |
postgres_1 | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
postgres_1 | CREATE TABLE
postgres_1 | CREATE TABLE
postgres_1 | INSERT 0 1
postgres_1 | INSERT 0 1
postgres_1 |
postgres_1 |
postgres_1 | waiting for server to shut down....2020-02-28 21:45:02.776 UTC [30] LOG: received fast shutdown request
postgres_1 | 2020-02-28 21:45:02.779 UTC [30] LOG: aborting any active transactions
postgres_1 | 2020-02-28 21:45:02.781 UTC [30] LOG: background worker "logical replication launcher" (PID 37) exited with exit code 1
postgres_1 | 2020-02-28 21:45:02.781 UTC [32] LOG: shutting down
postgres_1 | 2020-02-28 21:45:02.826 UTC [30] LOG: database system is shut down
postgres_1 | done
postgres_1 | server stopped
postgres_1 |
postgres_1 | PostgreSQL init process complete; ready for start up.
postgres_1 |
postgres_1 | 2020-02-28 21:45:02.890 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_1 | 2020-02-28 21:45:02.890 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_1 | 2020-02-28 21:45:02.895 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2020-02-28 21:45:02.915 UTC [43] LOG: database system was shut down at 2020-02-28 21:45:02 UTC
postgres_1 | 2020-02-28 21:45:02.921 UTC [1] LOG: database system is ready to accept connections
Just adding my solution even when it is a little late:
My problem:
I am installing the source files from an udemy course:
https://github.com/rockthejvm/spark-essentials
We have 2 important things here:
Docker compose file: docker-compose.yml
Folder and sql file to do db initialization: ./sql/bd.sql
I downloaded the zip file to my Ubuntu 20.04
When doing docker-compose up, I got the error:
Attaching to postgres
postgres | ls: cannot open directory '/docker-entrypoint-initdb.d/': Permission denied
postgres exited with code 2
SOLUTION
Before running doccker-compose up do:
run chmod 777 ON FOLDER called sql that contains file db.sql
chmod 777 sql
Explanation:
The folder called sql contains file db.sql to init the database from inside the docker container so, we need to give the permissions to run the file inside folde called sql.
I think you only need to do as below.
Give permisions to your folder:
chmod 777 init-db
be sure your sql file can be read by all users:
chmod 666 init-db.sql