PostgreSQL with Docker
Internal
Overview
In its simplest form:
docker run postgres
command starts a transient Posgres container instance that does not expose any port on the local host, it is initialized on the fly to allow access to any user and uses an anonymous local volume that will not be reattached to during the next run. To get a usable Postgres instance we can shut down and restart and that regains access to stored data between restarts, we should use create a dedicated named volume or a bind mount, initialize the database with a username and a password during the first initialization run and map ports to the local host.
Dedicated Storage
We prefer using a bind mount as it gives easy access to the stored state, in case we need to troubleshoot. A named volume can be also used.
docker run ... --mount type=bind,source=/Users/ovidiu/runtime/docker-volumes/postgres,target=/var/lib/postgresql/data --name postgres ... postgres
Authenticated Access
When the container is run the first time, it goes through an initialization sequence, and if no specific authentication configuration is provided in form of environment variables, it will configure itself to allow unauthenticated access. To prevent that from happening, start the container for the first time as shown:
docker run --mount type=bind,source=/Users/ovidiu/runtime/docker-volumes/postgres,target=/var/lib/postgresql/data -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=<some-password> --name postgres postgres
This will initialized the database to allow access as admin/<some-password>.
Subsequent startups will not require specification of -e POSTGRES_USER and -e POSTGRES_PASSWORD, as long as we use the same local directory Postgres initialized its state on.
Exposing Ports on the Local Host
Postgres binds by default on port 5432 and this is the port published by the following command:
docker run ... -p 5432:5432/tcp ...
Procedures
Initialization
Create a local directory /Users/ovidiu/runtime/docker-volumes/postgres and then execute the initialization run:
docker run --mount type=bind,source=/Users/ovidiu/runtime/docker-volumes/postgres,target=/var/lib/postgresql/data -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=<some-password> --name postgres postgres
Initialization log:
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 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:
pg_ctl -D /var/lib/postgresql/data -l logfile start
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....2018-10-18 17:51:21.203 UTC [43] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2018-10-18 17:51:21.253 UTC [44] LOG: database system was shut down at 2018-10-18 17:51:19 UTC
2018-10-18 17:51:21.269 UTC [43] LOG: database system is ready to accept connections
done
server started
CREATE DATABASE
/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
waiting for server to shut down...2018-10-18 17:51:22.349 UTC [43] LOG: received fast shutdown request
2018-10-18 17:51:22.351 UTC [43] LOG: aborting any active transactions
.2018-10-18 17:51:22.356 UTC [43] LOG: worker process: logical replication launcher (PID 50) exited with exit code 1
2018-10-18 17:51:22.356 UTC [45] LOG: shutting down
2018-10-18 17:51:22.387 UTC [43] LOG: database system is shut down
done
server stopped
PostgreSQL init process complete; ready for start up.
2018-10-18 17:51:22.478 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2018-10-18 17:51:22.478 UTC [1] LOG: listening on IPv6 address "::", port 5432
2018-10-18 17:51:22.482 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2018-10-18 17:51:22.546 UTC [61] LOG: database system was shut down at 2018-10-18 17:51:22 UTC
2018-10-18 17:51:22.562 UTC [1] LOG: database system is ready to accept connections
The container can be removed after initialization with:
docker stop postgres
docker rm postgres
Routine Start
docker exec -it <container-id> bash
Log Into the Container
docker exec -it <container-id> bash