Introduction
PostgreSQL is an open-source, enterprise-class relational database system with support for SQL and JSON queries. PostgreSQL has the support of over 20 years of community development. This ensures the highest levels of integrity, performance and resilience. The most common application of PostgreSQL is in the data warehouse for mobile, web, and analytics applications. PostgreSQL comes with a number of features such as asynchronous replication, online/hot backup, nested transactions and many more features.
The most common method to install PostgreSQL database server is from the operating system package repositories. The .deb package for Debian-based systems and the .rpm package for RHEL-based systems. The alternative method to run PostgreSQL is inside a container. This ensures a clean system state and the highest level of portability. In this blog post we focus on installing and running the PostgreSQL database server in the Docker container.
Installing the Docker Container Engine
Follow the steps provided in our article below to setup the Docker environment on your Linux system. Windows and macOS users can use GUI-based tools like Docker Desktop and Portainer.
After installation confirm by checking the version release.
docker --version
Docker version 25.0.3, build 4debf41
Create the Compose file for PostgreSQL
Create data directory for PostgreSQL database
mkdir ~/postgresql && cd ~/postgresql
Create the Compose file that will define how to create the container.
vim docker-compose.yml
Next we define the contents of the YAM file. The container images on Docker Hub are what we are using to create a running instance of the PostgreSQL server. The database data will be stored in the local ./pgdata directory.
We also create a container that runs the Admirer PostgreSQL web-based management tool.
- PostgreSQL 16
services:
db:
image: postgres:16-bookworm
restart: always
environment:
POSTGRES_PASSWORD: StrongPassword01
volumes:
-./pgdata:/var/lib/postgresql/data
adminer:
image: adminer
restart: always
ports:
- 8080:8080
- PostgreSQL 15
services:
db:
image: postgres:15-bookworm
restart: always
environment:
POSTGRES_PASSWORD: StrongPassword01
volumes:
-./pgdata:/var/lib/postgresql/data
adminer:
image: adminer
restart: always
ports:
- 8080:8080
- PostgreSQL 14
services:
db:
image: postgres:14-bookworm
restart: always
environment:
POSTGRES_PASSWORD: StrongPassword01
volumes:
-./pgdata:/var/lib/postgresql/data
adminer:
image: adminer
restart: always
ports:
- 8080:8080
- PostgreSQL 13
services:
db:
image: postgres:13-bookworm
restart: always
environment:
POSTGRES_PASSWORD: StrongPassword01
volumes:
-./pgdata:/var/lib/postgresql/data
adminer:
image: adminer
restart: always
ports:
- 8080:8080
- PostgreSQL 12
services:
db:
image: postgres:12-bookworm
restart: always
environment:
POSTGRES_PASSWORD: StrongPassword01
volumes:
-./pgdata:/var/lib/postgresql/data
adminer:
image: adminer
restart: always
ports:
- 8080:8080
- PostgreSQL 11
services:
db:
image: postgres:11-bookworm
restart: always
environment:
POSTGRES_PASSWORD: StrongPassword01
volumes:
-./pgdata:/var/lib/postgresql/data
adminer:
image: adminer
restart: always
ports:
- 8080:8080
Running PostgreSQL server in the container
Next we start the container by running the composition commands. The -d
option keeps it running in detached mode (in the background) without an active interactive session.
$ docker compose up -d
[+] Running 22/22
✔ adminer 7 layers [⣿⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 11.0s
✔ 09e2bc8a597c Pull complete 0.9s
✔ 092a59d5d649 Pull complete 0.7s
✔ e4dca1b56763 Pull complete 0.4s
✔ 378feffe5197 Pull complete 0.8s
✔ 3bd4de3ac847 Pull complete 1.1s
✔ 44d5566ceca7 Pull complete 1.1s
✔ 3dafa7b9d4fc Pull complete 1.3s
✔ db 13 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 13.5s
✔ 1f7ce2fa46ab Pull complete 1.8s
✔ e75b44f17b07 Pull complete 1.6s
✔ d601ea737a84 Pull complete 2.9s
✔ 0f4fcee3f93d Pull complete 2.1s
✔ 428f7aff61bc Pull complete 2.6s
✔ 7787ed5ab4f3 Pull complete 3.0s
✔ 3d2b66cffddc Pull complete 3.3s
✔ e7dee0dd847b Pull complete 3.3s
✔ a24060178bac Pull complete 5.8s
✔ 0eb290c85bd2 Pull complete 4.2s
✔ 88b80c4fe471 Pull complete 3.9s
✔ eac33d14a11e Pull complete 4.4s
✔ d40b681a9814 Pull complete 4.9s
[+] Running 2/3
⠋ Network postgresql_default Created 1.0s
✔ Container postgresql-adminer-1 Started 0.8s
✔ Container postgresql-db-1 Started 0.7s
Confirm the status of the container by running compose docker with ps
flag.
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
postgresql-adminer-1 adminer "entrypoint.sh php -…" adminer 5 minutes ago Up 5 minutes 0.0.0.0:8080->8080/tcp,:::8080->8080/tcp
postgresql-db-1 postgres:11-bookworm "docker-entrypoint.s…" db 5 minutes ago Up 5 minutes 5432/tcp
To access the container shell, run;
docker exec -ti postgresql-db-1 bash
root@a79ad82fd433:/#
The PostgreSQL server version can be checked using the psql -V
command.
psql -V
psql (PostgreSQL) 11.22 (Debian 11.22-1.pgdg120+1)
From there you can start psql
, which is a terminal-based front end for PostgreSQL.
su - postgres
psql (11.22 (Debian 11.22-1.pgdg120+1))
Type "help" for help.
postgres=#
We can create a test user and database;
- Database User: Nov1
- Database name: mysite
- Password: Str0ngPassw0rd
CREATE USER nov1 WITH PASSWORD 'Str0ngPassw0rd';
CREATE ROLE
CREATE DATABASE mywebsite WITH OWNER = 'nov1';
CREATE DATABASE
To exit PostgreSQL and the container shell, use the exit
command three times.
exit
logout
The database data will be stored in ./pgdata as defined in the composition file.
ls -1 pgdata/
base
global
pg_commit_ts
pg_dynshmem
pg_hba.conf
pg_ident.conf
pg_logical
pg_multixact
pg_notify
pg_replslot
pg_serial
pg_snapshots
pg_stat
pg_stat_tmp
pg_subtrans
pg_tblspc
pg_twophase
PG_VERSION
pg_wal
pg_xact
postgresql.auto.conf
postgresql.conf
postmaster.opts
postmaster.pid
Access to the Admirer dashboard
Open your web browser to http://ServerIP:8080.
Log in as user, database and password.
You will get a dashboard. From here you can manage your database: create tables, functions, views, import data, etc
Conclusion
By running the PostgreSQL database in a container you will appreciate the efficiency of its administration. Other benefits of containerization range from portability to isolation to scalability. You can lift the container image with data and run it on a separate host in seconds. Deciding whether to adopt a containerized database comes down to your usage preferences.