iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
📌

Running PostgreSQL with podman-compose on Debian Bookworm (April 2025 Edition)

に公開

Summary

On Debian GNU/Linux bookworm, we will add Docker.io as a registry and run the official PostgreSQL Docker image.

Introduction

As of April 21, 2025, when this article is being written, Debian GNU/Linux is currently in a package freeze for version 12 (codename: bookworm) to release the next version 13 (codename: trixie), focusing on bug fixes.
This is a report on what I have achieved using Podman and podman-compose, which are Docker-compatible tools included in Debian GNU/Linux (which is released every two years).

Motivation for Writing This Article

Since Docker fundamentally runs as root, files created by Docker tend to be owned by root. Having root-owned files in a regular user's directory makes them troublesome to handle, so I wanted to use Podman, which basically runs with user permissions.

While PostgreSQL packages exist directly in Debian GNU/Linux, Docker containers are often used in practice when SQLite's features are insufficient during application development.
I also wanted an environment where I could easily create and destroy SQL queries to implement logic using standard SQL that would otherwise require writing a lot of ORM code.

I believe that creating a good environment for both beginners and intermediate users (those who want to start using things like CASE statements) to practice while reading SQL-related books—and turning it into a Zenn article—is useful because I can simply say, "Read this along with your SQL textbook."

Who This Article Is For

I am targeting two types of people:

  1. People who want to use PostgreSQL immediately.
  2. People using Debian-based distributions who want to try something other than Docker.

How to Read This Article

This article is broadly divided into two topics:

  1. Installing Podman on Debian GNU/Linux 12 (bookworm) and configuring it to pull images from Docker.io.
  2. Writing a docker-compose.yml to launch the official PostgreSQL image registered on Docker.io using podman-compose, and explaining how to use it.

If you are only interested in one of these topics, you can choose to read only that part.

Main Body

Installing Podman-compose on Debian GNU/Linux 12 (bookworm)

Since I use aptitude, I installed Podman and podman-compose by specifying them.

sudo apt install podman podman-compose containers-storage

Please refer to the Debian Wiki in Reference 1.

To verify the operation after installing Podman, execute the following command:

podman search --limit 3 quay.io/podman

Now, add Docker.io with the following steps:

mkdir -p $HOME/.config/containers
echo 'unqualified-search-registries=["docker.io", "quay.io"]' > $HOME/.config/containers/registries.conf

Confirm whether it has been registered correctly:

podman search postgresql

Then, check the results.

Using the Official PostgreSQL Image with Podman-compose

The setup for using PostgreSQL in-memory, as shown in Reference 2, is ideal for a bit of self-study with SQL.
It's also great for quickly adding some test data.

Points to note are as follows:

  • Make sure to copy the docker-compose.yml correctly.
    • If you make a mistake, you might run into an error when executing podman-compose up -d, such as:
  File "/usr/lib/python3/dist-packages/podman_compose.py", line 239, in <listcomp>
    dst = [i.split("=", 1) for i in src if i]
           ^^^^^^^
AttributeError: 'dict' object has no attribute 'split'

You might find yourself in trouble with an error like this. While newer versions might be more robust, the most important thing is to avoid mistakes in the first place.

If Podman-compose is successful

The services will start, and you will see an output similar to the following:

podman-compose up -d
['podman', '--version', '']
using podman version: 4.3.1
** excluding:  set()
['podman', 'network', 'exists', 'podman_default']
podman run --name=podman_db_1 -d --label io.podman.compose.config-hash=123 --label io.podman.compose.project=podman --label io.podman.compose.version=0.0.1 --label com.docker.compose.project=podman --label com.docker.compose.project.working_dir=/home/yabuki/podman --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=db -e POSTGRES_PASSWORD=example --net podman_default --network-alias db --shm-size 128mb --restart always postgres
✔ docker.io/library/postgres:latest
Trying to pull docker.io/library/postgres:latest...
Getting image source signatures
Copying blob 07db60713289 done  
Copying blob 97cdd47d9131 done  
Copying blob 8a628cdd7ccc done  
Copying blob e4847368ad17 done  
Copying blob 2817206b0512 done  
Copying blob 3a6f8814136c done  
Copying blob 0c942aac37b1 done  
Copying blob 8c63b71925de done  
Copying blob 97f28320a07a done  
Copying blob 2a08aad74366 done  
Copying blob 6cea4d95608f done  
Copying blob c1b7de8085d1 done  
Copying blob f15c43cffa70 done  
Copying blob 6948dc7760c1 done  
Copying config f49abb9855 done  
Writing manifest to image destination
Storing signatures
0be0494caf057940ad75902d70e34338ae962f7022a38956ec1ae7c85878fe87
exit code: 0
['podman', 'network', 'exists', 'podman_default']
podman run --name=podman_adminer_1 -d --label io.podman.compose.config-hash=123 --label io.podman.compose.project=podman --label io.podman.compose.version=0.0.1 --label com.docker.compose.project=podman --label com.docker.compose.project.working_dir=/home/yabuki/podman --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=adminer --net podman_default --network-alias adminer -p 8080:8080 --restart always adminer
✔ docker.io/library/adminer:latest
Trying to pull docker.io/library/adminer:latest...
Getting image source signatures
Copying blob dc6d32971fca done  
Copying blob 115c7a04f6c0 done  
Copying blob b1220d176a8d done  
Copying blob 0d55cff53123 done  
Copying blob 88d591373a19 done  
Copying blob f18232174bc9 done  
Copying blob ffeef6b41a56 done  
Copying blob 6d95abe48138 done  
Copying blob a80d3af78a9d done  
Copying blob f3fe38446507 done  
Copying blob c6d0aade0806 done  
Copying blob 4f4fb700ef54 done  
Copying blob e434f3dae19e done  
Copying blob 8b847f2809a2 done  
Copying blob 93b26376816c done  
Copying blob 52e9abf80869 done  
Copying config 8a5794f84c done  
Writing manifest to image destination
Storing signatures
a63aacb8933f810b366895c7173cc7f141e5f0d80c28b720706e3875832d3558
exit code: 0

To access Adminer, the PHP-based database management interface, visit http://localhost:8080/ or http://[Your Environment's IP]:8080/ in your browser. Based on the documentation, you can log in using the username postgres, the password specified in your docker-compose.yml, and the database name postgres.

Once it's running, you can experiment by making small adjustments while referring to the documentation.

Now, go ahead and enjoy using it!

April 30, 2025 Addendum

Setting the Locale to ja_JP.utf8 and the Timezone to Asia/Tokyo

Just like with Docker, describe the Dockerfile as follows:

FROM postgres:17
RUN DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y tzdata
# Since systemd does not run inside the container, set the timezone
# using a different method.
run echo 'Asia/Tokyo' > /etc/timezone
ENV TZ=Asia/Tokyo
#run apt-get update && apt-get install -y postgresql-15
RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
        && localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8
version: '3'
services:
  postgres:
    container_name: sample-db
    build: .
    restart: always
    ports: 
      - "5432:5432"
    volumes:
      - ./postgres/init:/docker-entrypoint-initdb.d
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"

For psql, you can connect by running podman exec -it sample_db bash and then psql -U postgres, or you can install postgresql-client on your machine via apt and run psql -U postgres -h localhost -d [target_database_name]. Since the PostgreSQL version in Debian stable is 15 and we are using 17, a warning will be displayed, but it is not practically an issue.

Regarding the contents of ./postgres/init/, please refer to Reference 3. You can place initialization SQL files there.

The connection string generally looks like this:

DATABASE_URL=postgresql://[user[:password]@][host][:port]/[dbname]
DATABASE_URL=postgresql://[postgres:postgrespassword@localhost/[target_database_name]

References

  1. Podman - Debian Wiki
  2. postgres - Official Image | Docker Hub
  3. 【PostgreSQL】docker-composeで職剅と初期データ投入 #Docker - Qiita

Acknowledgements

Finally

I am currently looking for work involving system construction with TypeScript and Python, project management, and general support for system development.
Please contact me via GitHub: yabuki (YABUKI Yukiharu). I look forward to hearing from you.

Subject Date
Date started 2025-04-21
Date published 2025-04-21
Date modified 2025-06-05

The above information is provided by the author to help judge the freshness of this article.

For a detailed change history, please refer to:
GitHub - yabuki/friendly-potato: zenn-contents

I would appreciate pull requests for typo corrections or other improvements.
Acceptance will be determined based on the diff and the content of the pull request description.

GitHubで編集を提案

Discussion