Laravel Sail × VSCode の開発コンテナー(Dev Containers)を使った開発環境構築について
まず、PHP(Laravel)のコードを書く道具について
これをある程度考えてみると
- Visual Studio Code(VSCode)
- PhpStorm: 有料だけど評判はよいみたい。筆者は利用経験なし
- vim(/nvim): やばいやつしか使ってねえ
- 何か適当なエディター
- ...etc
ここで、とくに初心者から中/上級者まで無料で広く使えるのがVSCodeという事になると思う。最近ではTypeScript開発も同時に行う事が多いだろうからその点でも強い。
一方、開発環境はといえば
- Docker
- を使ったLaravel Sail
- を使った開発コンテナー
- を使ったLaravel Sail
- Laravel Herd (筆者は利用経験なし)
- XAMPP (ほぼ終わりかけの選択肢、どうしても使わないといけない人以外は使い続ける意味が今はほとんど無い)
などがあり、正直調べてみると
-
Docker(Laravel Sailあるいはyaml手書き環境も) Herd
みたいなDockerかHerdかみたいな所がある。この中で今回はDockerを使った開発コンテナーを見ていくことにしよう。
実は開発コンテナーの自動追加をsailインストール時に指定できる
artisan sail:installのhelpにはちょっとマニアックな項目がある
php artisan help sail:install
Description:
Install Laravel Sail's default Docker Compose file
Usage:
sail:install [options]
Options:
--with[=WITH] The services that should be included in the installation
--devcontainer Create a .devcontainer configuration directory
// ... ↑ これ!
この --devcontainer オプションを与えると .devcontainer/devcontainer.jsonというコメント付きJSONという謎形式ファイルが生成されるだけであり、それ以上の事は何もない。
// https://aka.ms/devcontainer.json
{
"name": "Existing Docker Compose (Extend)",
"dockerComposeFile": [
"../compose.yaml"
],
"service": "laravel.test",
"workspaceFolder": "/var/www/html",
"customizations": {
"vscode": {
"extensions": [
// "laravel.vscode-laravel",
// "mikestead.dotenv",
// "amiralizadeh9480.laravel-extra-intellisense",
// "ryannaddy.laravel-artisan",
// "onecentlin.laravel5-snippets",
// "onecentlin.laravel-blade"
],
"settings": {}
}
},
"remoteUser": "sail",
"postCreateCommand": "chown -R 1000:1000 /var/www/html 2>/dev/null || true"
// "forwardPorts": [],
// "runServices": [],
// "shutdownAction": "none",
}
この状態でvscodeで開くと...

拡張が入ってないとこうなるかも

開発コンテナーで開くか?という確認
こんなのが出てきて再度開発コンテナーで開くことが促される。
これを開いてみると、また結構な時間のビルドが始まる可能性があるが、結果として以下のような開発コンテナーに接続された開発環境となる。

接続先が開発コンテナー: "Existing Docker Compose (Extend) と表示されている
artisanコマンド等
VSCcodeが「コンテナーの中」でシェルを起動させるため、「コンテナー外」からコマンドを話すLaravel Sailが行っていた./vendor/bin/sail artisanのような事は行わない。
開発コンテナーの中のシェルを開いてみると以下の通り

開発コンテナーのシェルでphp artisan --versionを入力
ここで、DBを初期化するならphp artisan migrate:fresh --seed等を実行するわけだ。

DBが初期化された状態
viteについて
viteの起動はターミナルを追加してnpm run devとすればよい。

ターミナルを追加してviteを起動
アクセス先について
この時点で(トラブルが無ければ)HMRが効いた環境が得られているはずだ。基本的にはsailを起動したのと同じような事になっているのでhttp://localhost等にアクセスする事となる。しかし、たとえば http://localhost:8000 にしたい、となった場合はsailのしきたりに従って、環境変数APP_PORTをセットすることとなる

APP_PORTをセットした .env
これでコンテナーのリビルドをする

コンテナーのリビルド
そうすれば指定ポートでのアクセスが可能となる

ポート8000に切り替えた例
この状態で、ビューを編集してみる
resources/js/pages/welcome.tsxを変更してみた例

HMRが効いており自動的に内容が変わっている
開発環境設定ファイル devcontainer.jsonについて
これは以下に仕様があるのだが
とはいえ、とり急ぎ書き換えておきたいのは以下のセクションになるだろう
-
name: "Existing Docker Compose (Extend)",- プロジェクトの名前なので変更してわかりやすくしよう
-
customizations→vscode→extensions- この開発コンテナのみ有効なVSCodeエクステンション
名前は適当に書き換えて頂くとして、extensionを揃えることで配布ファイルの内容で開発環境を揃える事ができるのである程度事故が防ぎやすいのかも。
VSCodeエクステンションについて
これに関して話すとそれだけで記事になりそうなので簡単にまとめる。以下は筆者の主観が強い内容となる。
デフォルトでコメントアウトされている拡張
// "laravel.vscode-laravel", //
// "mikestead.dotenv", // .envに色は最初から出てるし必要ないかな...
// "amiralizadeh9480.laravel-extra-intellisense", //
// "ryannaddy.laravel-artisan", // いやまあartisanとかコンソールから打った方がはやいような
// "onecentlin.laravel5-snippets", // 古すぎていらんかな
// "onecentlin.laravel-blade" // blade使わんからいらんかな... 必要なら入れてもよい
ここは積極的に更新されていないので古くて使えないものも多いかも。
そこで個人的にセットしたやつ
"customizations": {
"vscode": {
"extensions": [
// "laravel.vscode-laravel",
// "bradlc.vscode-tailwindcss",
// "bmewburn.vscode-intelephense-client",
// "amirrizal.laravel-extra-intellisense",
// "esbenp.prettier-vscode",
// "dbaeumer.vscode-eslint",
// "ms-azuretools.vscode-docker",
"anthropic.claude-code",
"openai.chatgpt",
"EditorConfig.EditorConfig"
],
"settings": {}
}
},
結局AI系やないかい!
devcontainer.jsonを書き換えるとコンテナーをリビルドするか?と促されると思うので、その通りにすると以下のように「開発環境のみ有効なエクステンション」が現われる

開発環境のみ有効なエクステンション
たとえばClaude Codeを使う実践例
ソースコードの右上の方にClaudeっぽいアイコンができてるのでこれを押してサインインする

ログインする
ここでたとえばlogin.tsxの日本語翻訳を依頼
login.tsxのUIを日本語に書き換えてください

日本語になった
とまあAIプログラミングの時代だと割と手を動かすことが減ってきてるので拡張もまた、だいぶ選択肢が変わってくるやもしれませんねえ...入れないほうが軽いのは間違いないので
おまけで、最後にAIが出してきたVSCode拡張の表を貼り付けてまとめとします
筆者は内容をほとんど確認してません。あしからずw
(一応私が使ってそうなやつは先ほど書いたdevcontainer.jsonでコメントアウトしてはいます)
| 拡張機能識別子 | 拡張機能 | 用途 | メンテナンス状況 | 代替案 |
|---|---|---|---|---|
laravel.vscode-laravel |
Laravel公式拡張 | Laravelフレームワーク向けにルート名・設定・ビュー補完など高度なIntelliSenseを提供 | 活発(Laravel公式により開発・2024年安定版リリース) | Laravel Extra Intellisense + Intelephense併用やIDE Helper生成(公式拡張以前の方法) |
bmewburn.vscode-intelephense-client |
Intelephense | PHPのコード補完・定義ジャンプ・エラーチェックなど言語サーバー機能を提供 | 活発(開発者により継続開発、プレミアム機能あり) | PHP Tools(Devsense社、有料)やVS Code標準PHP拡張(機能限定) |
amiralizadeh9480.laravel-extra-intellisense |
Laravel Extra Intellisense | Laravel特有のルート名・ビュー名・設定値等の補完を強化 | 活発(Amir Alizadeh氏により更新継続) | Laravel公式拡張(一部機能が重複)やLaravel IDE Helper+IntelliSense併用 |
onecentlin.laravel-blade |
Laravel Blade Snippets | Bladeテンプレートのシンタックスハイライト、スニペット挿入、簡易フォーマット | 活発(Laravel v10対応済み、継続更新) | Blade Formatter(shufo.vscode-blade-formatter)※Blade専用フォーマッタ |
Vue.volar |
Vue(Volar公式) | Vue.js向けのコード補完・構文ハイライト・TypeScript対応(Vue3対応、Vue2互換モードあり) | 活発(Vue公式が管理、Vetur後継として開発) | Vetur(旧公式、Vue2用)※Vue2プロジェクトでは必要に応じ使用 |
dsznajder.es7-react-js-snippets |
ES7+ React/Redux Snippets | React/Reduxのコンポーネントや関数のコードテンプレートを素早く生成 | 安定(頻繁な更新不要、コミュニティ維持) | Simple React Snippets(より軽量な代替)や標準Emmet展開 |
dbaeumer.vscode-eslint |
ESLint | JavaScript/TypeScriptの構文エラーやコーディング規約違反をエディタ内に表示 | 活発(Microsoft公式、ESLint最新版に追随) | TSLint(旧・非推奨、現在はESLintに統合) |
esbenp.prettier-vscode |
Prettier | コードの自動整形(統一的なコードスタイルを適用)。JavaScript/TypeScript他に対応 | 活発(Prettierチームが開発、常に最新仕様をフォロー) | 特になし(デファクトスタンダード。ESLintの--fixでも一部代用可能) |
stylelint.vscode-stylelint |
Stylelint | CSS/SCSS/PostCSS等のリンター(スタイルガイド違反の検出・自動修正を提供) | 活発(Stylelint公式が開発、v14+対応) | Shinnosuke Watanabe版(旧拡張、非推奨)やVS Code標準CSS検証(簡易) |
xdebug.php-debug |
PHP Debug(Xdebug) | Xdebugを用いたPHPのステップ実行デバッグをVS Code上で行う | 活発(Xdebug公式がFelix Becker版を引継ぎ更新) | felixfbecker.php-debug(旧版、メンテ停止) |
eamodio.gitlens |
GitLens | Gitリポジトリの履歴やBlame情報の可視化、差分比較やリポジトリ内ナビゲーションを強化 | 活発(GitKraken社が開発、一部プレミアム機能あり) | Git History(コミット履歴閲覧)、Git Graph(ツリー表示) |
mikestead.dotenv |
DotENV | .env環境変数ファイルのシンタックスハイライトを追加 | 更新ほぼ停止(最終更新2018年だが機能は安定) | 特になし(他に.env専用の拡張は少ない) |
Discussion