LaravelアプリケーションでPostgreSQLを使うときは、アプリ専用のログインユーザーと、そのユーザーが所有するデータベースを用意すると管理しやすい。この記事では、Ubuntuのpsqlで新規作成し、Laravelから接続できるところまでを順に整理する。
対象はUbuntu 24.04、PostgreSQL 15以降、Laravel 13系を中心とした構成。PostgreSQLはインストール・起動済みで、管理者権限(sudo)を使用できることを前提とする。例のユーザー名・データベース名・パスワードは自分の環境に置き換える。実際のサーバーでの実行結果を記録した記事ではなく、公式ドキュメントに基づく手順だ。
作成するもの
今回の例では、次の組み合わせを作る。
| 項目 | 設定値 | 用途 |
|---|---|---|
| PostgreSQLロール | laravel_user |
Laravelがログインするときに使用 |
| データベース | laravel_db |
Laravelのテーブルを保存 |
| データベース所有者 | laravel_user |
DBを管理し、通常のマイグレーションを実行 |
| 接続先 | 127.0.0.1:5432 |
LaravelとPostgreSQLが同じサーバーにある例 |
PostgreSQLでは、ログイン可能なロールを一般に「ユーザー」と呼ぶ。ロールは一つのデータベース内ではなく、同じPostgreSQLサーバー(クラスタ)全体で管理される。
1. psqlで管理者として接続する
UbuntuのターミナルでPostgreSQLのバージョンを確認する。
psql --version
続いて、OSのpostgresユーザーとしてpsqlを起動する。
sudo -u postgres psql
接続できると、通常はpostgres=#というプロンプトが表示される。以下のSQLと\から始まるpsqlコマンドは、この対話画面で実行する。
sudo -u postgres psqlはUbuntuなどで使われる一般的な手順だ。コンテナやマネージドDBでは管理者としての接続方法が異なる。
2. Laravel用ユーザー(ロール)を作成する
LOGIN付きの専用ロールを作成する。
CREATE ROLE laravel_user
WITH LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE;
CREATE ROLEと表示されれば作成成功。指定した属性の意味は次のとおり。
| 属性 | 意味 |
|---|---|
LOGIN |
アプリからこの名前でログインできる |
NOSUPERUSER |
PostgreSQL全体を管理する特権を与えない |
NOCREATEDB |
アプリユーザー自身によるDBの新規作成を許可しない |
NOCREATEROLE |
他のロールの作成・管理を許可しない |
次にパスワードを設定する。
\password laravel_user
パスワードの入力と再入力が求められる。実際のパスワードは記事、GitHub、コマンドの引数に書かない。 \passwordを使うと、CREATE ROLE ... PASSWORD '...'とSQLに直接書く方法より、クライアントの履歴やログに平文が残るリスクを減らせる。
3. 所有者を指定してデータベースを作成する
laravel_userを所有者としてデータベースを作る。
CREATE DATABASE laravel_db OWNER laravel_user;
成功するとCREATE DATABASEと表示される。管理者が作成しても、OWNERに指定したlaravel_userが所有者になる。
作成した内容を確認する。
\du laravel_user
\l laravel_db
\duはロール、\lはデータベースの情報を表示する。laravel_dbのOwner列がlaravel_userであることを確認する。
psqlを終了する。
\q
4. 作成したユーザーで接続できるか試す
今度は管理者ではなく、作成したユーザーとして接続する。
psql -h 127.0.0.1 -p 5432 -U laravel_user -d laravel_db -W
-Wによってパスワード入力を求められる。-h 127.0.0.1を指定するのは、LaravelのDB_HOST=127.0.0.1と同じTCP接続で確認するためだ。-hを省略するとUnixソケット経由になり、認証方法が変わる場合がある。
接続できたら次のSQLで接続先を確認する。
SELECT current_user, current_database();
期待する結果は、ユーザーがlaravel_user、データベースがlaravel_dbになっていること。確認後は\qで終了する。
5. Laravelの.envを設定する
Laravelプロジェクトのルートにある.envのデータベース設定を変更する。
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD="replace_with_your_actual_password"
DB_PASSWORDには手順2で設定したパスワードを入力する。値に空白や#などを含む場合は、.envの構文を考慮して引用符で囲む。DB_URLを設定している場合は、Laravelの接続設定で優先されることがあるため、config/database.phpと併せて確認する。
.envをGitにコミットしない。 設定例として共有する.env.exampleにも本物のパスワードは記載しない。
LaravelからPostgreSQLを利用するには、PHPのpdo_pgsql拡張も必要だ。CLI側で読み込まれているかを調べる。
php -m | grep -Ei '^(pdo_pgsql|pgsql)$'
何も表示されなければ、使用中のPHPバージョンに対応したPostgreSQL拡張が導入・有効化されているか確認する。PHP-FPMを使うWeb環境とCLIでは、読み込む設定が異なる場合もある。
6. Laravelで接続とマイグレーションを確認する
アプリケーションのルートで実行する。
php artisan config:clear --no-interaction
これで以前のDB接続設定がキャッシュされている場合に再読込できる。新規データベースでマイグレーションを実行する。
php artisan migrate --no-interaction
既存のマイグレーションに従ってテーブルが作成される。完了後は状態を確認する。
php artisan migrate:status --no-interaction
本番環境では実行前に変更内容とバックアップを確認する。Laravelは本番でマイグレーションの確認を求めるため、承認済みのデプロイ処理で非対話実行するときだけ--forceの使用を検討する。設定キャッシュを運用している環境では、設定確認後にphp artisan config:cache --no-interactionで再生成する。
よくあるエラーと確認箇所
| エラー | 主に確認すること |
|---|---|
password authentication failed for user |
ユーザー名・パスワード、接続方式、pg_hba.confの認証設定 |
database ... does not exist |
DB名、接続しているPostgreSQLサーバー、\lの結果 |
connection refused |
PostgreSQLの起動、ポート、listen_addresses、ファイアウォール |
could not find driver |
Laravelを動かすPHPのpdo_pgsql拡張 |
permission denied for schema public |
データベース所有者とpublicスキーマの権限 |
最後のエラーが出る場合、管理者として対象データベースへ接続し、まずスキーマ権限を確認する。
sudo -u postgres psql -d laravel_db
\dn+ public
新しいデータベースを所有するロールは、PostgreSQL 15以降の標準構成ではpublicスキーマを管理できる。スキーマの権限がカスタマイズされている場合など、必要なときに限って管理者から次を付与する。
GRANT USAGE, CREATE ON SCHEMA public TO laravel_user;
CREATEはそのスキーマにテーブル等を作る権限、USAGEはスキーマ内のオブジェクト名を参照するための権限だ。状況を確認せずにSUPERUSERを与える対処は避ける。
一人のユーザーで複数のデータベースを所有できる?
できる。 PostgreSQLのロールはサーバー全体に属するので、同じユーザーを別のデータベースの所有者にも指定できる。
CREATE DATABASE second_app_db OWNER laravel_user;
ただし、別アプリで同じユーザーを使うと、ログイン情報や権限の管理を共有する。アプリごとにアクセス範囲を分けたい本番環境では、ユーザーもデータベースも分ける方が整理しやすい。
また、所有者を別々にするだけでは完全な接続分離にはならない。 PostgreSQLでは新規データベースに対するCONNECT権限などがPUBLIC(全ロール)へ既定で付与されるため、厳密な分離が必要ならDB・スキーマ・テーブルの権限とpg_hba.confも含めて設計する。