Automation / Database / DevOps / Podman
PostgreSQL is a powerful, open-source relational database system widely used in modern applications. Running PostgreSQL as a container offers a range of benefits, particularly when using Podman, a rootless container engine. This post will guide you through the steps to set up PostgreSQL instances using Podman and systemd.
Running PostgreSQL as a container has several advantages:
Integrating Podman containers with systemd adds the following benefits:
start
, stop
, and status
.The steps and configurations provided in this article are intended for demonstration and educational purposes only. Users must carefully consider the following before deploying PostgreSQL containers in any environment:
The author is not responsible for any data loss, performance issues, or security vulnerabilities arising from improper implementation of the concepts discussed in this article. Proceed at your own discretion and ensure thorough testing before deploying to production environments.
Follow these steps to run PostgreSQL instances with Podman and systems. If you are installing Podman for the first time, refer to this guide – Installing Podman on Red Hat Enterprise Linux 9.
The PostgreSQL image from the container registry provides a secure and optimized database engine. Pull the image:
podman pull postgres:latest
Alternatively, you can use the official image registry.redhat.io/rhel8/postgresql-15:latest
from Red Hat’s container registry which provides a secure and optimized database engine. Remember, you need to authenticate before pulling an image from Red Hat container registry.
Alternatively, you can use the podman-compose
command to quickly spin up containers with volumes and networks without worrying about command line arguments as shown in the following sections. Refer to the sample podman-compose.yaml
file in this repository.
If you don’t specify a volume, the PostgreSQL data stored in /var/lib/postgresql/data/
will be lost once the container is stopped or removed. To ensure data persistence, it’s essential to mount a volume for the PostgreSQL data store. You can either use a local directory from your host system or create a dedicated container volume to store the data securely.
Note: You can also mount the local directory path to the container without creating a Podman volume if there is a requirement.
Create a container volume as follows.
$ podman volume create postgresapp1
postgresapp1
Verify the volume details.
$ podman volume inspect postgresapp1
[
{
"Name": "postgresapp1",
"Driver": "local",
"Mountpoint": "/home/devops/.local/share/containers/storage/volumes/postgresapp1/_data",
"CreatedAt": "2025-01-07T13:32:15.964258532Z",
"Labels": {},
"Scope": "local",
"Options": {},
"MountCount": 0,
"NeedsCopyUp": true,
"NeedsChown": true,
"LockNumber": 36
}
]
It is possible to pass the sensitive information via environment variables but we are using the Podman secret to store the PostgreSQL admin password as follows.
$ echo "postgresadmin" | podman secret create postgresql_app1_admin_password -
Verify the secret using to ensure the secret it created.
$ podman secret inspect postgresql_app1_admin_password
[
{
"ID": "0dd142faa2448d107d8849145",
"CreatedAt": "2025-01-07T13:27:10.295864132Z",
"UpdatedAt": "2025-01-07T13:27:10.295864132Z",
"Spec": {
"Name": "postgresql_app1_admin_password",
"Driver": {
"Name": "file",
"Options": {
"path": "/home/devops/.local/share/containers/storage/secrets/filedriver"
}
},
"Labels": {}
}
}
]
Create and run the first PostgreSQL instance with the container name postgresql-app1
:
Important: Make sure you are using the available ports and not conflicting with the existing port. For example, you can use a custom port such as 5433
or 5434
as the host port to avoid any port conflicts.
$ podman run -d \
--name postgresql-app1 \
--secret postgresql_app1_admin_password,type=env,target=POSTGRES_PASSWORD \
-v postgresapp1:/var/lib/pgsql/data:Z \
-p 5433:5432 \
postgres:latest
Here:
5433:5432
maps the container’s PostgreSQL port to the host.postgresapp1
is the container volumes for database storage.POSTGRES_PASSWORD
is the superuser password; mapped from Podman secret postgresql_app1_admin_password
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45d65f183c3e docker.io/library/postgres:latest postgres About a minute ago Up About a minute 0.0.0.0:5433->5432/tcp, 5432/tcp postgresql-app1
Generate a systemd service file for the container:
$ mkdir -p ~/.config/systemd/user
$ podman generate systemd --new --name postgresql-app1 > ~/.config/systemd/user/postgresql-app1.service
Enable and start the systemd service for the container under the specific user:
$ systemctl --user daemon-reload
$ systemctl --user enable postgresql-app1.service
$ systemctl --user start postgresql-app1.service
Verify the status:
$ systemctl --user status postgresql-app1.service
Let us experiment with the systemd service for PostgreSQL – stop and service and check if the PostgreSQL container is running.
$ systemctl --user stop postgresql-app1.service
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Now, start back the systemd service and verify the if PostgreSQL container is running.
$ systemctl --user start postgresql-app1.service
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8b819776241 docker.io/library/postgres:latest postgres 2 seconds ago Up 3 seconds 0.0.0.0:5433->5432/tcp, 5432/tcp postgresql-app1
Now our PostgreSQL instance should now be running:
Install the psql
utility coming with the PostgreSQL package. (You can also use alternative utilities)
$ sudo yum install postgresql
Access the PostgreSQL instance: psql -h localhost -p 5432 -U admin -d appdb
$ psql -h localhost -p 5433 -U postgres --password
Password:
psql (13.18, server 17.2 (Debian 17.2-1.pgdg120+1))
WARNING: psql major version 13, server major version 17.
Some psql features might not work.
Type "help" for help.
postgres=#
Ensure the required ports are open and enabled – in this case the custom port 5433.
$ sudo firewall-cmd --list-all
$ sudo firewall-cmd --permanent --add-port=5433/tcp
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-ports
Now, you can repeat the steps with different container names, ports and systemd services to run multiple isolated PostgreSQL instances.
Running PostgreSQL as a container using Podman provides portability, isolation, and ease of management. Integrating with systemd further enhances reliability and automation. By following the steps above, you can efficiently run and manage multiple PostgreSQL instances on the same host, leveraging the robust features of Podman and Red Hat’s trusted container images.
Disclaimer:
The views expressed and the content shared in all published articles on this website are solely those of the respective authors, and they do not necessarily reflect the views of the author’s employer or the techbeatly platform. We strive to ensure the accuracy and validity of the content published on our website. However, we cannot guarantee the absolute correctness or completeness of the information provided. It is the responsibility of the readers and users of this website to verify the accuracy and appropriateness of any information or opinions expressed within the articles. If you come across any content that you believe to be incorrect or invalid, please contact us immediately so that we can address the issue promptly.
Tags: Automation · Container Orchestration · Containerized Database · Containerized PostgreSQL · Containers · Database Automation · Database Containers · Database Deployment · Database Management · Devops · linux containers · Open Source Database · Persistent Storage · podman · Podman Best Practices · Podman Compose · Podman PostgreSQL · Podman Systemd Service · Podman Volumes · PostgreSQL · PostgreSQL Container Setup · PostgreSQL Data Persistence · Red Hat PostgreSQL · RHEL · Running PostgreSQL with Podman · Secure Database Deployment · Systemd Integration · Systemd Services
Gineesh Madapparambath
Gineesh Madapparambath is the founder of techbeatly and he is the co-author of The Kubernetes Bible, Second Edition. and the author of 𝗔𝗻𝘀𝗶𝗯𝗹𝗲 𝗳𝗼𝗿 𝗥𝗲𝗮𝗹-𝗟𝗶𝗳𝗲 𝗔𝘂𝘁𝗼𝗺𝗮𝘁𝗶𝗼𝗻.
He has worked as a Systems Engineer, Automation Specialist, and content author. His primary focus is on Ansible Automation, Containerisation (OpenShift & Kubernetes), and Infrastructure as Code (Terraform).
(aka Gini Gangadharan - iamgini.com)
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Leave a Reply