Install PostgreSQL 17 using Docker CLI
Table of Contents
a. Docker image
One Image can create Multiple Containers
We only pull the Image (postgres:17) once, but you can create multiple independent Containers from it:

0. Prerequisites
[root@docker ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: disabled)
Active: active (running) since Fri 2026-09-11 13:57:42 +08; 22min ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 1198 (dockerd)
Tasks: 8
Memory: 44.0M (peak: 122.5M)
CPU: 565ms
CGroup: /system.slice/docker.service
└─1198 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Sep 11 19:27:15 docker dockerd[1198]: time="2026-09-11T19:27:15.245954027+08:00" level=info msg="Deleting nftables IPv4 rules" error="exit status 1" output="Error: Could not process rule: No such file or directory\ndelete table ip >
Sep 11 19:27:15 docker dockerd[1198]: time="2026-09-11T19:27:15.291035189+08:00" level=info msg="Deleting nftables IPv6 rules" error="exit status 1" output="Error: Could not process rule: No such file or directory\ndelete table ip6>
Sep 11 19:27:15 docker dockerd[1198]: time="2026-09-11T19:27:15.353438439+08:00" level=info msg="Firewalld: docker zone already exists, returning"
Sep 11 13:57:42 docker dockerd[1198]: time="2026-09-11T13:57:42.147552771+08:00" level=info msg="Loading containers: done."
Sep 11 13:57:42 docker dockerd[1198]: time="2026-09-11T13:57:42.177031156+08:00" level=info msg="Docker daemon" commit=ff8d90a containerd-snapshotter=true storage-driver=overlayfs version=29.5.0
Sep 11 13:57:42 docker dockerd[1198]: time="2026-09-11T13:57:42.177292548+08:00" level=info msg="Initializing buildkit"
Sep 11 13:57:42 docker dockerd[1198]: time="2026-09-11T13:57:42.217015358+08:00" level=info msg="Completed buildkit initialization"
Sep 11 13:57:42 docker dockerd[1198]: time="2026-09-11T13:57:42.230337885+08:00" level=info msg="Daemon has completed initialization"
Sep 11 13:57:42 docker dockerd[1198]: time="2026-09-11T13:57:42.230397418+08:00" level=info msg="API listen on /run/docker.sock"
Sep 11 13:57:42 docker systemd[1]: Started Docker Application Container Engine.
lines 1-22/22 (END)
[root@docker ~]#
[root@docker ~]# docker --version
Docker version 29.5.0, build 98f1464
[root@docker ~]#
[root@docker ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::f44c:25ff:fef1:b128 prefixlen 64 scopeid 0x20
ether f6:4c:25:f1:b1:28 txqueuelen 0 (Ethernet)
RX packets 9 bytes 252 (252.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 25 bytes 3762 (3.6 KiB)
TX errors 0 dropped 22 overruns 0 carrier 0 collisions 0
..
..
[root@docker ~]#
1. Download (Pull) the image (postgres:17) to local cache
[root@docker ~]# docker pull postgres:17
17: Pulling from library/postgres
7bae2b43bca3: Pull complete
6310eb16bf42: Pull complete
fe2da2a59a9b: Pull complete
eaab134eadf6: Pull complete
817ead34cefa: Pull complete
d0f06d4f424f: Pull complete
bfe09aaa1eb8: Pull complete
0f14f3be7f09: Pull complete
238c3936b37c: Pull complete
08ebf9a3f23c: Pull complete
499f168a6c10: Pull complete
937fed8f5fd1: Pull complete
de0bd328703b: Pull complete
a06335df3cea: Pull complete
87549d5ff3aa: Download complete
c6c2c8f07694: Download complete
Digest: sha256:67f41722b7a8cbdb868a44a4995c846eddfdc2973bccb291ce937dce88ad5675
Status: Downloaded newer image for postgres:17
docker.io/library/postgres:17
[root@docker ~]#
[root@docker ~]# docker images | grep postgres
postgres:17 67f41722b7a8 640MB 167MB
[root@docker ~]#
2. Start PostgreSQL 17 container
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
# Create only (auto-pulls postgres:17 if needed, does not start):
# docker create=(docker pull)+docker create
# docker start
[root@docker ~]# mkdir -p /pgData/postgresql17/data
[root@docker ~]#
# Create
docker create \
--name postgres17 \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
-v /pgData/postgresql17/data:/var/lib/postgresql/data \
--restart unless-stopped \
postgres:17
# Start
docker start postgres17
#################################################################### (OR) ####################################################################
[root@docker ~]# mkdir -p /pgData/postgresql17/data
[root@docker ~]#
# Start PostgreSQL 17 container
# docker run also pulls the image automatically and start
# docker run=(docker pull)+docker create+docker start
# Here -d is valid because run = create + start, and -d means “don’t attach to the process, run in background”.
[root@docker ~]# docker run -d \
--name postgres17 \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
-v /pgData/postgresql17/data:/var/lib/postgresql/data \
--restart unless-stopped \
postgres:17
f7335372d74f0cb2bac76861dfc5ba648b90d1324b97ff9ab595874ffc9056fc
[root@docker ~]#
# Check container
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7335372d74f postgres:17 "docker-entrypoint.s…" 18 seconds ago Up 17 seconds 0.0.0.0:5432->5432/tcp, [::]:5432->5432/tcp postgres17
[root@docker ~]#
# Check stopped containers
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7335372d74f postgres:17 "docker-entrypoint.s…" 17 minutes ago Up 17 minutes 0.0.0.0:5432->5432/tcp, [::]:5432->5432/tcp postgres17
a7f094486483 hello-world "/hello" 3 months ago Exited (0) 3 months ago thirsty_edison
[root@docker ~]#
| Option | Description |
|---|---|
-d | Run the container in detached mode (in the background). |
--name postgres17 | Gives the container a recognizable name. |
-e POSTGRES_USER=postgres | The default superuser (optional, defaults to postgres). |
-e POSTGRES_PASSWORD=postgres | (Required) Change this to a secure password. |
-e POSTGRES_DB=mydb | Creates an initial default database. |
-p 5432:5432 | Maps host port 5432 to container port 5432. |
-v /pgData/postgresql17/data:/var/lib/postgresql/data | Persists data using a Docker named volume (/pgData/postgresql17/data). |
--restart unless-stopped | Restarts PostgreSQL automatically on system reboots. |
postgres:17 | Pulls the official PostgreSQL 17 image. |
3. Check logs
[root@docker ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::f44c:25ff:fef1:b128 prefixlen 64 scopeid 0x20
ether f6:4c:25:f1:b1:28 txqueuelen 0 (Ethernet)
RX packets 12 bytes 336 (336.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 27 bytes 4022 (3.9 KiB)
TX errors 0 dropped 22 overruns 0 carrier 0 collisions 0
..
..
veth426830c: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::482a:caff:fe42:452d prefixlen 64 scopeid 0x20
ether 4a:2a:ca:42:45:2d txqueuelen 0 (Ethernet)
RX packets 3 bytes 126 (126.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 17 bytes 2282 (2.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@docker ~]#
[root@docker ~]# docker inspect postgres17 | grep "IPAddress"
"IPAddress": "172.17.0.2",
[root@docker ~]#
[root@docker ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.243 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.077 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.066 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2027ms
rtt min/avg/max/mdev = 0.066/0.128/0.243/0.080 ms
[root@docker ~]#
[root@docker ~]# docker logs postgres17
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
initdb: hint: 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....2026-09-11 06:50:40.529 UTC [47] LOG: starting PostgreSQL 17.11 (Debian 17.11-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
2026-09-11 06:50:40.532 UTC [47] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2026-09-11 06:50:40.545 UTC [50] LOG: database system was shut down at 2026-09-11 06:50:39 UTC
2026-09-11 06:50:40.559 UTC [47] LOG: database system is ready to accept connections
done
server started
CREATE DATABASE
/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
2026-09-11 06:50:40.942 UTC [47] LOG: received fast shutdown request
waiting for server to shut down....2026-09-11 06:50:40.948 UTC [47] LOG: aborting any active transactions
2026-09-11 06:50:40.958 UTC [47] LOG: background worker "logical replication launcher" (PID 53) exited with exit code 1
2026-09-11 06:50:40.960 UTC [48] LOG: shutting down
2026-09-11 06:50:40.962 UTC [48] LOG: checkpoint starting: shutdown immediate
2026-09-11 06:50:41.191 UTC [48] LOG: checkpoint complete: wrote 925 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.064 s, sync=0.158 s, total=0.231 s; sync files=301, longest=0.009 s, average=0.001 s; distance=4256 kB, estimate=4256 kB; lsn=0/19179A8, redo lsn=0/19179A8
2026-09-11 06:50:41.214 UTC [47] LOG: database system is shut down
done
server stopped
PostgreSQL init process complete; ready for start up.
2026-09-11 06:50:41.321 UTC [1] LOG: starting PostgreSQL 17.11 (Debian 17.11-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
2026-09-11 06:50:41.323 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2026-09-11 06:50:41.324 UTC [1] LOG: listening on IPv6 address "::", port 5432
2026-09-11 06:50:41.328 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2026-09-11 06:50:41.339 UTC [63] LOG: database system was shut down at 2026-09-11 06:50:41 UTC
2026-09-11 06:50:41.353 UTC [1] LOG: database system is ready to accept connections
2026-09-11 06:55:41.437 UTC [61] LOG: checkpoint starting: time
2026-09-11 06:55:45.874 UTC [61] LOG: checkpoint complete: wrote 47 buffers (0.3%); 0 WAL file(s) added, 0 removed, 0 recycled; write=4.417 s, sync=0.011 s, total=4.438 s; sync files=12, longest=0.005 s, average=0.001 s; distance=278 kB, estimate=278 kB; lsn=0/195D308, redo lsn=0/195D2B0
[root@docker ~]#
4. Connect to PostgreSQL
[root@docker ~]# docker exec postgres17 pg_isready
/var/run/postgresql:5432 - accepting connections
[root@docker ~]#
[root@docker ~]# docker exec -it postgres17 psql -U postgres
psql (17.11 (Debian 17.11-1.pgdg13+2))
Type "help" for help.
postgres=# SELECT version();
version
----------------------------------------------------------------------------------------------------------------------
PostgreSQL 17.11 (Debian 17.11-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
(1 row)
postgres=# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | Locale | ICU Rules | Access privileges
-----------+----------+----------+-----------------+------------+------------+--------+-----------+-----------------------
mydb | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
(4 rows)
postgres=# \q
[root@docker ~]#
5. Check PostgreSQL data
[root@docker ~]# cd /pgData/postgresql17/data/
[root@docker data]# ll
total 64
drwx------. 6 systemd-coredump systemd-coredump 46 Sep 11 14:50 base
drwx------. 2 systemd-coredump systemd-coredump 4096 Sep 11 14:53 global
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_commit_ts
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_dynshmem
-rw-------. 1 systemd-coredump systemd-coredump 5743 Sep 11 14:50 pg_hba.conf
-rw-------. 1 systemd-coredump systemd-coredump 2640 Sep 11 14:50 pg_ident.conf
drwx------. 4 systemd-coredump systemd-coredump 68 Sep 11 14:50 pg_logical
drwx------. 4 systemd-coredump systemd-coredump 36 Sep 11 14:50 pg_multixact
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_notify
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_replslot
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_serial
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_snapshots
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_stat
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_stat_tmp
drwx------. 2 systemd-coredump systemd-coredump 18 Sep 11 14:50 pg_subtrans
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_tblspc
drwx------. 2 systemd-coredump systemd-coredump 6 Sep 11 14:50 pg_twophase
-rw-------. 1 systemd-coredump systemd-coredump 3 Sep 11 14:50 PG_VERSION
drwx------. 4 systemd-coredump systemd-coredump 77 Sep 11 14:50 pg_wal
drwx------. 2 systemd-coredump systemd-coredump 18 Sep 11 14:50 pg_xact
-rw-------. 1 systemd-coredump systemd-coredump 88 Sep 11 14:50 postgresql.auto.conf
-rw-------. 1 systemd-coredump systemd-coredump 31065 Sep 11 14:50 postgresql.conf
-rw-------. 1 systemd-coredump systemd-coredump 36 Sep 11 14:50 postmaster.opts
-rw-------. 1 systemd-coredump systemd-coredump 94 Sep 11 14:50 postmaster.pid
[root@docker data]#
[root@docker data]# cd /var/lib/postgresql/data
-bash: cd: /var/lib/postgresql/data: No such file or directory
[root@docker data]#
6. Stop / Start PostgreSQL
# List running containers
docker ps
# List all containers
docker ps -a
# PostgreSQL health
docker exec -it postgres17 pg_isready
# PostgreSQL version
docker exec -it postgres17 psql -U postgres -c "SELECT version();"
# Stop
[root@docker ~]# docker stop postgres17
postgres17
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7335372d74f postgres:17 "docker-entrypoint.s…" 33 minutes ago Exited (0) 17 seconds ago postgres17
a7f094486483 hello-world "/hello" 3 months ago Exited (0) 3 months ago thirsty_edison
[root@docker ~]#
# Start
[root@docker ~]# docker start postgres17
postgres17
[root@docker ~]#
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7335372d74f postgres:17 "docker-entrypoint.s…" 33 minutes ago Up 6 seconds 0.0.0.0:5432->5432/tcp, [::]:5432->5432/tcp postgres17
[root@docker ~]#
# Restart
[root@docker ~]# docker restart postgres17
postgres17
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7335372d74f postgres:17 "docker-entrypoint.s…" 34 minutes ago Up 3 seconds 0.0.0.0:5432->5432/tcp, [::]:5432->5432/tcp postgres17
[root@docker ~]#
7. Remove container and PostgreSQL image
# Remove container postgres17
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7335372d74f postgres:17 "docker-entrypoint.s…" 34 minutes ago Up 3 seconds 0.0.0.0:5432->5432/tcp, [::]:5432->5432/tcp postgres17
[root@docker ~]#
[root@docker ~]#
[root@docker ~]# docker stop postgres17
postgres17
[root@docker ~]# docker rm postgres17
postgres17
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7f094486483 hello-world "/hello" 3 months ago Exited (0) 3 months ago thirsty_edison
[root@docker ~]#
# Remove PostgreSQL image
[root@docker ~]# docker images | grep postgres:17
postgres:17 67f41722b7a8 640MB 167MB
[root@docker ~]#
[root@docker ~]# docker rmi postgres:17
Untagged: postgres:17
Deleted: sha256:67f41722b7a8cbdb868a44a4995c846eddfdc2973bccb291ce937dce88ad5675
[root@docker ~]#
[root@docker ~]# docker images | grep postgres:17
[root@docker ~]#
8. Useful Commands
| Action | Which Name to Use? | Example Command |
|---|---|---|
| Download from Docker Hub | Image Name | docker pull postgres:17 |
| List downloaded templates | Image Name | docker images |
| Check container status | Container Name | docker ps (shows container name postgres17) |
| Stop the database | Container Name | docker stop postgres17 |
| Start the database | Container Name | docker start postgres17 |
| View logs | Container Name | docker logs -f postgres17 |
| Enter interactive shell | Container Name | docker exec -it postgres17 psql -U postgres |
| Delete the container | Container Name | docker rm -f postgres17 |
| Delete the image | Image Name | docker rmi postgres:17 |
Caution: Your use of any information or materials on this website is entirely at your own risk. It is provided for educational purposes only. It has been tested internally, however, we do not guarantee that it will work for you. Ensure that you run it in your test environment before using.
Thank you
Rajasekhar Amudala