はじめに
PostgreSQLでの日本語設定で生じたエラーについて紹介します。
本記事の対象者はRDBS初心者・エンジニア初心者・Docker初心者です。
前提
リレーショナルデータベースシステム(RDBMS)は、データを構造化された形で保存し、効率的なアクセスと操作を可能にします。しかし、異なる言語のデータを扱う場合、特に重要な2つの要素があります。エンコーディングとロケールです。
エンコーディング
データベースのエンコーディングは、文字データがどのようにバイトに変換されるかを決定します。日本語を含む多くの言語をサポートするためには、エンコーディングは通常UTF-8に設定されます。UTF-8は、ASCII文字だけでなく、多くの特殊文字や記号、そして多くの言語の文字を含むことができます。
ロケール
ロケールは、特定の地域や言語に関連する動作を制御します。これには、文字列のソート順や日付/時間のフォーマットなどが含まれます。例えば、"ja_JP.utf8" ロケールは、日本のソート順や日付/時間のフォーマットを適用します。
要約すると、
エンコーディング:文字をバイト(またはビット)の列に変換する方法を定義します。エンコーディングには様々な種類があります。
ロケール:特定の地域や言語に関連するソフトウェアの動作を制御します。ロケールの設定により、同じソフトウェアでも異なる地域や言語のユーザーに適した動作を提供することができます。
PostgreSQLの日本語設定時に生じたエラー
Apacheウェブサーバーがプリインストールされている公式のPHP Dockerイメージをwebサーバーとして、公式のPostgreSQL DockerイメージをDBサーバーとして環境を立ち上げようとしました。
version: '3'
services:
web:
image: php:7.4-apache
volumes:
- .:/var/www/html
ports:
- 8080:80
db:
image: postgres:13
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_INITDB_ARGS=--locale=ja_JP.utf8
volumes:
- postgres_data:/var/lib/postgresql/data/
- ./db-init:/docker-entrypoint-initdb.d
docker-compose up したところ、下記のエラーが発生しました。
The files belonging to this database system will be owned by user "postgres".
security_php-db-1 | This user must also own the server process.
security_php-db-1 |
security_php-db-1 | initdb: error: invalid locale name "ja_JP.utf8"
security_php-db-1 exited with code 1
初期化プロセス(initdb)が "ja_JP.utf8" というロケール名を認識できないというエラーです。
原因
PostgreSQLの公式Dockerイメージはデフォルトで "ja_JP.utf8" ロケールをサポートしていないことが原因でした。
- POSTGRES_INITDB_ARGS=--locale=ja_JP.utf8
この行が正常に動作するためにはDockerイメージが "ja_JP.utf8" ロケールをサポートしていることが必要です。
解決方法
カスタムのDockerfileを作成して "ja_JP.utf8" ロケールを追加します。
FROM postgres:13
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
db:
build:
context: .
dockerfile: Dockerfile
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data/
- ./db-init:/docker-entrypoint-initdb.d
まとめ
Dockerを使用してPostgreSQLのコンテナを立ち上げる際に、日本語のロケール "ja_JP.utf8" を設定する方法とその重要性について説明しました。エンコーディングとロケールはRDBSにおいて重要事項なのでとても勉強になりました。
参考