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
3
Answers
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:
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:
With that change, my docker-compose file looks like: version: '3.8'
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:
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:
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.
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.