記事一覧に戻る
Web技術系

Laravel用PostgreSQLのユーザーとデータベースを新規作成する(Ubuntu)

psqlでLaravel専用のユーザー(ロール)とデータベースを作成し、パスワード設定、接続確認、.env、マイグレーションまでを整理する。

ノートと鉛筆のイラスト

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も含めて設計する。

公式ドキュメント