【ITニュース解説】Setting Up PostgreSQL in Docker on Hetzner with SSL Certificates from Certbot
2025年09月30日に「Dev.to」が公開したITニュース「Setting Up PostgreSQL in Docker on Hetzner with SSL Certificates from Certbot」について初心者にもわかりやすく解説しています。
ITニュース概要
HetznerクラウドにDockerでPostgreSQLを構築し、CertbotでSSL証明書を設定して通信を暗号化する方法を解説。cronで証明書を自動更新し、ファイアウォールとpg_hba.confでアクセス制限も設定。安全で効率的なデータベース運用を目的とする。
ITニュース解説
クラウド環境であるHetznerにPostgreSQLデータベースをDockerコンテナで安全に構築し、SSL証明書を用いて通信を暗号化する方法について解説する。データ保護はシステムの信頼性において非常に重要であり、特にクラウド環境でのデータベース運用においては、SSLによる暗号化が必須となる。また、SSL証明書の自動更新と、特定のIPアドレスからの接続のみを許可する設定により、データベースのセキュリティをさらに高めることができる。
この設定を行うためには、Hetznerのクラウドサーバー上にLinuxディストリビューション(例:Ubuntu)が動作していること、DockerとDocker Composeがインストールされていること、そしてサーバーを指すドメイン名(例:db.example.com)と、SSL証明書生成ツールであるCertbotが導入済みであることが前提となる。
まず、サーバーのセキュリティを確保するため、Hetznerのファイアウォールを設定する必要がある。ファイアウォールでは、外部からの通信を制御するいくつかのポートを開放する。具体的には、SSL証明書の発行時にCertbotがドメインの所有権を確認するために必要なHTTP通信用のポート80、サーバーへのリモート接続に利用するSSH用のポート22、そしてPostgreSQLクライアントがデータベースに接続するためのポート5432を開放する。また、サーバーがインターネットへ自由に通信できるよう、TCPのアウトバウンド(外部への発信)通信は任意のポートで許可する必要がある。これらの設定はHetzner Cloud Consoleから行い、作成したファイアウォールルールを対象のサーバーに適用する。
SSL(Secure Sockets Layer)は、PostgreSQLとデータベースに接続するクライアント間のデータ通信を暗号化する技術だ。これにより、通信途中でデータが傍受されたり、改ざんされたりする「中間者攻撃」や「データ盗難」を防ぎ、機密性の高い情報を安全にやり取りできる。
次に、まだDockerとDocker Composeがインストールされていない場合は、HetznerサーバーにSSHでログインし、sudo apt updateとsudo apt install docker.io -yコマンドでDockerをインストールする。インストール後、sudo systemctl start dockerでDockerサービスを開始し、sudo systemctl enable dockerでサーバー起動時に自動でDockerが立ち上がるように設定する。Docker Composeも同様にsudo apt install docker-compose -yでインストールする。
SSL証明書はCertbotを使って簡単に取得できる。まず、sudo apt install certbot -yでCertbotをインストールする。その後、sudo certbot certonly --standalone -d db.example.comコマンドを実行し、指定したドメイン名(db.example.com)のSSL証明書を生成する。このコマンドは、一時的にWebサーバーを立ち上げてドメイン認証を行う。生成された証明書ファイルは/etc/letsencrypt/live/db.example.com/ディレクトリに保存され、特にfullchain.pem(公開証明書)とprivkey.pem(秘密鍵)がPostgreSQLでのSSL設定に必要となる。
Certbotで取得したLet's Encryptの証明書は90日で期限切れとなるため、自動更新の設定が不可欠だ。sudo crontab -eコマンドでcronジョブエディタを開き、0 3 * * * /usr/bin/certbot renew --quiet && docker-compose -f /path/to/your/docker-compose.yml restart postgresという行を追加する。この設定により、毎日午前3時にCertbotが証明書の更新を試み、もし証明書の期限が30日以内であれば自動的に更新される。更新が成功した場合、続けてdocker-compose -f /path/to/your/docker-compose.yml restart postgresコマンドが実行され、PostgreSQLコンテナが再起動されて新しい証明書が適用される。これにより、証明書の期限切れによるサービス停止を防ぐことができる。
PostgreSQLのコンテナ設定にはDocker Composeを利用する。docker-compose.ymlというファイルを作成し、PostgreSQLサービスを定義する。このファイルには、PostgreSQLのイメージバージョン(例:postgres:16)、コンテナ名、常に再起動する設定(restart: always)を含める。データベースのユーザー名、パスワード、データベース名は.envファイルに定義し、env_file: - ./.envで参照する。
さらに、PostgreSQLのデータ永続化のため、ホスト側のディレクトリ(./pg_data)をコンテナ内のデータディレクトリ(/var/lib/postgresql/data)にマウントする。アクセス制御ファイルであるpg_hba.confも同様にマウントする。そして、Certbotで取得したSSL証明書ファイル(fullchain.pemとprivkey.pem)も、それぞれコンテナ内の所定のパス(/var/lib/postgresql/fullchain.pemと/var/lib/postgresql/privkey.pem)にマウントする。コンテナ内部からはポート5432を外部に公開し、ネットワークも定義する。
PostgreSQLの起動コマンドでは、データベースのパフォーマンスを最適化するためのメモリ設定(例:shared_buffers=2GB、work_mem=16MB、maintenance_work_mem=256MB、effective_cache_size=6GB)を指定する。shared_buffersはPostgreSQLがキャッシュに利用するメモリ量で、ディスクI/Oを削減し性能向上に寄与する。work_memは各クエリ操作に割り当てられるメモリで、ソートなどの処理を高速化する。maintenance_work_memはVACUUMやインデックス作成といったメンテナンス作業に利用されるメモリだ。effective_cache_sizeはOSがディスクキャッシュに利用できるメモリの目安で、PostgreSQLのクエリオプティマイザが適切な実行計画を立てるのに役立つ。そして最も重要なのは、ssl=onを設定してSSLを有効化し、ssl_cert_fileとssl_key_fileでマウントした証明書ファイルのパスを指定することだ。listen_addresses='*'は、PostgreSQLが全てのネットワークインターフェースからの接続を待ち受けるように設定する。
.envファイルは、docker-compose.ymlと同じディレクトリに作成し、DB_USERNAME=your_db_user、DB_PASSWORD=your_secure_password、DB_NAME=your_database_nameのように、データベースの認証情報を定義する。これらの値は、セキュアなものに置き換える必要がある。
データベースへのアクセス制御はpg_hba.confファイルで行う。このファイルでは、特定のIPアドレス(例:99.99.99.99)からの接続のみをSSLとscram-sha-256認証方式で許可し、それ以外のIPアドレス(0.0.0.0/0)からの接続はすべて拒否するように設定する。scram-sha-256は、安全なパスワードハッシュ方式であり、古いMD5よりも強力な認証を提供する。
SSL証明書のファイルには厳格なパーミッション(ファイルアクセス権限)が必要だ。特に秘密鍵ファイル(privkey.pem)は、コンテナ内のpostgresユーザーが読み書きできる権限(0600)を持ち、かつpostgresユーザーとグループ(通常はUID/GID 999)が所有している必要がある。ホスト側でsudo chown 999:999 /etc/letsencrypt/live/db.example.com/privkey.pemとsudo chmod 600 /etc/letsencrypt/live/db.example.com/privkey.pemを実行して権限を設定する。公開証明書ファイル(fullchain.pem)も同様にsudo chown 999:999で所有者を変更し、読み取り権限(0644)を与える。
すべての設定が完了したら、docker-compose up -dコマンドを実行してPostgreSQLコンテナを起動する。これにより、Dockerイメージのダウンロード、ボリュームの作成、データベースの起動が一連の流れで行われ、SSLが有効化され、指定されたIPアドレスからの接続のみが許可される状態となる。
最後に、データベースが正しく設定されているかを確認する。PostgreSQLに接続し、SHOW ssl;コマンドを実行すると、onと表示されればSSLが有効になっていることが確認できる。また、docker logs postgres_dbコマンドでPostgreSQLのログを確認し、SSL接続が確立されていることや、許可されたIPアドレスからの接続のみが受け入れられ、他のIPアドレスからの接続が拒否されていることを検証することが重要だ。
これらの手順を通じて、Hetznerのクラウド環境でDockerを利用し、CertbotのSSL証明書で保護されたPostgreSQLデータベースを構築できる。さらに、cronジョブによる証明書の自動更新と、pg_hba.confによる厳格なIPアドレス制限により、データベースは高いセキュリティレベルで運用される。