2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ローカルPCに PHP と Composer と Node.js をインストールせずに Laravel Sail を動かして HTTPS接続も行いたい

2
Posted at

概要

Laravel Sail のドキュメントを見ると、php コマンドと composer コマンドが導入されていることが前提で説明されています。

ですが、私のローカルPCの環境には Laravel が動作するために必要な以下のコマンド群を導入してません。

  • php
  • composer
  • laravel/installer
  • node / npm / npx
  • yarn

ということで、本記事ではこれらのコマンドをインストールせずに Laravel Sail を動かしてみようと思います。


動作検証環境

  • Ubuntu: 22.04
$ grep PRETTY_NAME /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.5 LTS"
  • Docker: 29.2.0
$ docker --version
Docker version 29.2.0, build 0b9d198

Laravel のインストール方法について

Laravel のアプリケーションを作成する場合、 laravel new example-app のようなコマンドを実行しますが、前述のとおり laravel コマンドがインストールされていません。
なので composer create-project laravel/laravel example-app を実行したいわけですが、 composer コマンドもインストールされていません。

そこで、今回は ComposerDocker Official Imageを利用します。

Laravel のアプリケーションを作成する際、前述のとおり以前であれば以下のようなコマンドを実行していました。

$ composer create-project laravel/laravel example-app

しかし、公式のインストールガイドでは、こちらの手順のみが掲載されています。

$ composer global require laravel/installer
$ laravel new example-app

laravel new example-app が何を行っているのかを追っていくと、結局は composer create-project laravel/laravel example-app だとわかります。

なので、以下のように Composer の Docker イメージを利用して実行することもできます。

$ docker container run \
--rm \
-u $(id -u):$(id -g) \
-v $(pwd):/app \
-it composer:latest \
composer create-project laravel/laravel my-laravel-sail

今回は、以下のように Composer の Docker コンテナ内で laravel/installer をインストールして laravel コマンドを実行してみます。

$ docker container run \
--rm \
-u $(id -u):$(id -g) \
-v $(pwd):/app \
-it composer:latest \
sh -c "composer global require laravel/installer \
&& export PATH=\$PATH:/tmp/vendor/bin \
&& laravel new my-laravel-sail"

/tmp/vendor/bin に対してパスを通している理由は、 Composer の Docker イメージで COMPOSER_HOME/tmp になっているためです。
これにより /tmp/vendor/bin/laravel ではなく laravel で実行可能となります。


Laravel のインストール

それでは先程紹介した Laravel のインストールコマンドを参考にしつつ、 nodenpm コマンドも利用可能な形で実行します。

$ cd /PATH_TO/作業ディレクトリ
$ docker container run \
--rm \
-v $(pwd):/app \
-it composer:latest \
sh -c "
apk add --no-cache nodejs npm \
&& composer global require laravel/installer \
&& export PATH=\$PATH:/tmp/vendor/bin \
&& laravel new my-laravel-sail \
&& chown -R $(id -u):$(id -g) my-laravel-sail
"

まず、 starter kit の選択肢が表示されますので、今回は None を選択します。

(1/7) Installing ada-libs (3.3.0-r0)
(2/7) Installing icu-data-en (76.1-r1)
  Executing icu-data-en-76.1-r1.post-install
  * 
  * If you need ICU with non-English locales and legacy charset support, install
  * package icu-data-full.
  * 
(3/7) Installing icu-libs (76.1-r1)
(4/7) Installing simdjson (3.12.0-r0)
(5/7) Installing simdutf (7.5.0-r1)
(6/7) Installing nodejs (24.13.0-r1)
(7/7) Installing npm (11.6.3-r0)
Executing busybox-1.37.0-r30.trigger
OK: 169.3 MiB in 93 packages
Changed current directory to /tmp
./composer.json has been created
Running composer update laravel/installer
Loading composer repositories with package information
Updating dependencies
Lock file operations: 32 installs, 0 updates, 0 removals
  - Locking carbonphp/carbon-doctrine-types (3.2.0)
  - Locking doctrine/inflector (2.1.0)
  - Locking illuminate/collections (v12.52.0)
・
・
省略
・
・
  - Installing symfony/finder (v7.4.5): Extracting archive
  - Installing illuminate/filesystem (v12.52.0): Extracting archive
  - Installing laravel/installer (v5.24.6): Extracting archive
22 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
20 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
Using version ^5.24 for laravel/installer

 ██╗       █████╗  ██████╗   █████╗  ██╗   ██╗ ███████╗ ██╗
 ██║      ██╔══██╗ ██╔══██╗ ██╔══██╗ ██║   ██║ ██╔════╝ ██║
 ██║      ███████║ ██████╔╝ ███████║ ██║   ██║ █████╗   ██║
 ██║      ██╔══██║ ██╔══██╗ ██╔══██║ ╚██╗ ██╔╝ ██╔══╝   ██║
 ███████╗ ██║  ██║ ██║  ██║ ██║  ██║  ╚████╔╝  ███████╗ ███████╗
 ╚══════╝ ╚═╝  ╚═╝ ╚═╝  ╚═╝ ╚═╝  ╚═╝   ╚═══╝   ╚══════╝ ╚══════╝

 ┌ Which starter kit would you like to install? ────────────────┐
 │ › ● None                                                     │
 │   ○ React                                                    │
 │   ○ Svelte                                                   │
 │   ○ Vue                                                      │
 │   ○ Livewire                                                 │
 └──────────────────────────────────────────────────────────────┘

testing framework の選択肢が表示されますので、今回は PHPUnit を選択します。

 ┌ Which starter kit would you like to install? ────────────────┐
 │ None                                                         │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │   ○ Pest                                                     │
 │ › ● PHPUnit                                                  │
 └──────────────────────────────────────────────────────────────┘

AIアシスタントである Laravel Boost のインストールが必要か求められますので、今回は No を選択します。

 ┌ Which starter kit would you like to install? ────────────────┐
 │ None                                                         │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ PHPUnit                                                      │
 └──────────────────────────────────────────────────────────────┘

 ┌ Do you want to install Laravel Boost to improve AI assisted coding? ┐
 │ ○ Yes / ● No                                                        │
 └─────────────────────────────────────────────────────────────────────┘

データベースの選択肢が表示されますので、今回は SQLite を選択します。

 ┌ Which starter kit would you like to install? ────────────────┐
 │ None                                                         │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ PHPUnit                                                      │
 └──────────────────────────────────────────────────────────────┘

 ┌ Do you want to install Laravel Boost to improve AI assisted coding? ┐
 │ No                                                                  │
 └─────────────────────────────────────────────────────────────────────┘

Creating a "laravel/laravel" project at "./my-laravel-sail"
Installing laravel/laravel (v12.11.2)
  - Downloading laravel/laravel (v12.11.2)
  - Installing laravel/laravel (v12.11.2): Extracting archive
Created project in /app/my-laravel-sail
Loading composer repositories with package information
Updating dependencies
Lock file operations: 111 installs, 0 updates, 0 removals
  - Locking brick/math (0.14.8)
  - Locking carbonphp/carbon-doctrine-types (3.2.0)
  - Locking dflydev/dot-access-data (v3.0.3)
・
・
省略
・
・
  - Installing phar-io/manifest (2.0.4): Extracting archive
  - Installing myclabs/deep-copy (1.13.4): Extracting archive
  - Installing phpunit/phpunit (11.5.55): Extracting archive
70 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating optimized autoload files
81 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
> @php -r "file_exists('.env') || copy('.env.example', '.env');"

   INFO  Application key set successfully.  

 ┌ Which database will your application use? ───────────────────┐
 │ › ● SQLite                                                   │
 │   ○ MySQL (Missing PDO extension)                            │
 │   ○ MariaDB (Missing PDO extension)                          │
 │   ○ PostgreSQL (Missing PDO extension)                       │
 │   ○ SQL Server (Missing PDO extension)                       │
 └──────────────────────────────────────────────────────────────┘

npm installnpm run build の実行を求められますので、今回は Yes を選択します。

 ┌ Which database will your application use? ───────────────────┐
 │ SQLite                                                       │
 └──────────────────────────────────────────────────────────────┘


   INFO  Preparing database.  

  Creating migration table ...................................... 28.19ms DONE

   INFO  Running migrations.  

  0001_01_01_000000_create_users_table ......................... 106.30ms DONE
  0001_01_01_000001_create_cache_table .......................... 67.00ms DONE
  0001_01_01_000002_create_jobs_table ........................... 91.32ms DONE

 ┌ Would you like to run npm install and npm run build? ────────┐
 │ ● Yes / ○ No                                                 │
 └──────────────────────────────────────────────────────────────┘

以上で Laravel のインストール作業は完了となります。

 ┌ Would you like to run npm install and npm run build? ────────┐
 │ Yes                                                          │
 └──────────────────────────────────────────────────────────────┘


added 82 packages, and audited 83 packages in 10s

21 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

> build
> vite build

vite v7.3.1 building client environment for production...
✓ 53 modules transformed.
public/build/manifest.json             0.33 kB │ gzip:  0.16 kB
public/build/assets/app-Cg9bk4C0.css  34.04 kB │ gzip:  8.47 kB
public/build/assets/app-CKl8NZMC.js   36.69 kB │ gzip: 14.71 kB
✓ built in 443ms
   INFO  Application ready in [my-laravel-sail]. You can start your local development using:

➜ cd my-laravel-sail
➜ composer run dev

  New to Laravel? Check out our documentation. Build something amazing!

実行ユーザーと作成された Laravel のアプリケーションのディレクトリの所有者が一致していることを確認します。

$ echo $USER
akase244
$ ls -ld my-laravel-sail/
drwxr-xr-x 13 akase244 akase244 4096  2月 23 13:35 my-laravel-sail/

Laravel アプリケーションのディレクトリ内に以下のようなファイル群が作成されました。

$ cd my-laravel-sail
$ ls -la
合計 492
drwxr-xr-x  13 akase244 akase244   4096  2月 23 13:35 .
drwxrwxr-x 121 akase244 akase244   4096  2月 23 13:31 ..
-rw-r--r--   1 akase244 akase244    252  1月 20 02:57 .editorconfig
-rw-r--r--   1 akase244 akase244   1142  2月 23 13:33 .env
-rw-r--r--   1 akase244 akase244   1086  2月 23 13:33 .env.example
-rw-r--r--   1 akase244 akase244    186  1月 20 02:57 .gitattributes
-rw-r--r--   1 akase244 akase244    283  1月 20 02:57 .gitignore
-rw-r--r--   1 akase244 akase244   3911  1月 20 02:57 README.md
drwxr-xr-x   5 akase244 akase244   4096  1月 20 02:57 app
-rwxr-xr-x   1 akase244 akase244    425  1月 20 02:57 artisan
drwxr-xr-x   3 akase244 akase244   4096  1月 20 02:57 bootstrap
-rw-r--r--   1 akase244 akase244   2869  2月 23 13:33 composer.json
-rw-r--r--   1 akase244 akase244 309333  2月 23 13:31 composer.lock
drwxr-xr-x   2 akase244 akase244   4096  1月 20 02:57 config
drwxr-xr-x   5 akase244 akase244   4096  2月 23 13:33 database
drwxr-xr-x  77 akase244 akase244   4096  2月 23 13:35 node_modules
-rw-r--r--   1 akase244 akase244  93952  2月 23 13:35 package-lock.json
-rw-r--r--   1 akase244 akase244    414  1月 20 02:57 package.json
-rw-r--r--   1 akase244 akase244   1284  1月 20 02:57 phpunit.xml
drwxr-xr-x   3 akase244 akase244   4096  2月 23 13:35 public
drwxr-xr-x   5 akase244 akase244   4096  1月 20 02:57 resources
drwxr-xr-x   2 akase244 akase244   4096  1月 20 02:57 routes
drwxr-xr-x   5 akase244 akase244   4096  1月 20 02:57 storage
drwxr-xr-x   4 akase244 akase244   4096  1月 20 02:57 tests
drwxr-xr-x  39 akase244 akase244   4096  2月 23 13:32 vendor
-rw-r--r--   1 akase244 akase244    436  1月 20 02:57 vite.config.js

node_modules ディレクトリ内に以下のように npm のパッケージがインストールされていることを確認します。

$ ls -la node_modules/
合計 360
drwxr-xr-x 77 akase244 akase244  4096  2月 23 13:35 .
drwxr-xr-x 13 akase244 akase244  4096  2月 23 13:35 ..
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 .bin
-rw-r--r--  1 akase244 akase244 50085  2月 23 13:35 .package-lock.json
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 .vite-temp
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 @esbuild
drwxr-xr-x  7 akase244 akase244  4096  2月 23 13:35 @jridgewell
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 @rollup
drwxr-xr-x  6 akase244 akase244  4096  2月 23 13:35 @tailwindcss
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 @types
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 ansi-regex
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 ansi-styles
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 asynckit
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 axios
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 call-bind-apply-helpers
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 chalk
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 cliui
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 color-convert
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 color-name
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 combined-stream
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 concurrently
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 delayed-stream
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 detect-libc
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 dunder-proto
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 emoji-regex
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 enhanced-resolve
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 es-define-property
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 es-errors
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 es-object-atoms
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 es-set-tostringtag
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 esbuild
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 escalade
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 fdir
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 follow-redirects
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 form-data
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 function-bind
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 get-caller-file
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 get-intrinsic
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 get-proto
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 gopd
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 graceful-fs
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 has-flag
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 has-symbols
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 has-tostringtag
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 hasown
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 is-fullwidth-code-point
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 jiti
drwxr-xr-x  5 akase244 akase244  4096  2月 23 13:35 laravel-vite-plugin
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 lightningcss
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 lightningcss-linux-x64-musl
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 magic-string
drwxr-xr-x  5 akase244 akase244  4096  2月 23 13:35 math-intrinsics
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 mime-db
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 mime-types
drwxr-xr-x  6 akase244 akase244  4096  2月 23 13:35 nanoid
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 picocolors
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 picomatch
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 postcss
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 proxy-from-env
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 require-directory
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 rollup
drwxr-xr-x  9 akase244 akase244  4096  2月 23 13:35 rxjs
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 shell-quote
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 source-map-js
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 string-width
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 strip-ansi
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 supports-color
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 tailwindcss
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 tapable
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 tinyglobby
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 tree-kill
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 tslib
drwxr-xr-x  6 akase244 akase244  4096  2月 23 13:35 vite
drwxr-xr-x  4 akase244 akase244  4096  2月 23 13:35 vite-plugin-full-reload
drwxr-xr-x  2 akase244 akase244  4096  2月 23 13:35 wrap-ansi
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 y18n
drwxr-xr-x  6 akase244 akase244  4096  2月 23 13:35 yargs
drwxr-xr-x  3 akase244 akase244  4096  2月 23 13:35 yargs-parser

それでは公式のインストールガイドに従って、 composer run dev を実行して Laravel のアプリケーションを起動してみます。

Laravel のアプリケーションを composer run dev のように実行すると 127.0.0.1:8000 でポートを開放するため、コンテナ環境で実行するとローカルPCからアクセスできません。
これに対応するため、以下のように composer.jsonphp artisan serve--host--port のオプションを追加します。
※これによりローカル環境で直接 composer run dev を実行すると 0.0.0.0:8000 で開放することになるので、取り扱いにはご注意ください。

$ cp composer.json composer.json.orig.$(date +'%Y%m%d%H%M%S')
$ vim composer.json
$ diff composer.json composer.json.orig.20260223152708 
48c48
<             "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve --host=0.0.0.0 --port=8000\" \"php artisan queue:listen --tries=1 --timeout=0\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
---
>             "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1 --timeout=0\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"

同様に、 Vite が 127.0.0.1:5173 でポートを開放するため、コンテナ環境で実行するとローカルPCからアクセスできません。

これに対応するため、以下のように vite.config.jsexport default defineConfig 内の server に以下の指定を追加します。
※これによりローカル環境で直接 composer run dev を実行すると 0.0.0.0:5173 で開放することになるので、取り扱いにはご注意ください。

$ cp vite.config.js vite.config.js.orig.$(date +'%Y%m%d%H%M%S')
$ vim vite.config.js
$ diff vite.config.js vite.config.js.orig.20260223152840 
14,19d13
<         host: '0.0.0.0',
<         port: 5173,
<         strictPort: true,
<         hmr: {
<             host: 'localhost',
<         },

起動時に実行される php artisan pail により pcntl が必要となりますので、 Composer の Docker イメージではなく、 PHPDocker Official Image を利用します。

$ docker container run \
--rm \
-v $(pwd):/app \
-w /app \
-p 127.0.0.1:8000:8000 \
-p 127.0.0.1:5173:5173 \
-it php:8.5-cli-alpine \
sh -c "
apk add --no-cache nodejs npm \
&& docker-php-ext-install pcntl \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& composer run dev
"

Laravel アプリケーションの起動の処理に成功すると、以下のようなログが表示されます。

・
・
省略
・
・
> npx concurrently -c "#93c5fd,#c4b5fd,#fb7185,#fdba74" "php artisan serve --host=0.0.0.0 --port=8000" "php artisan queue:listen --tries=1 --timeout=0" "php artisan pail --timeout=0" "npm run dev" --names=server,queue,logs,vite --kill-others
[queue] 
[queue]    INFO  Processing jobs from the [default] queue.  
[queue] 
[vite] 
[vite] > dev
[vite] > vite
[vite] 
[logs] 
[logs]    INFO  Tailing application logs.                        Press Ctrl+C to exit  
[logs]                                                Use -v|-vv to show more details  
[vite] 
[vite]   VITE v7.3.1  ready in 394 ms
[vite] 
[vite]   ➜  Local:   http://localhost:5173/
[vite]   ➜  Network: http://172.17.0.2:5173/
[server] 
[server]    INFO  Server running on [http://0.0.0.0:8000].  
[server] 
[server]   Press Ctrl+C to stop the server
[server] 
[vite] 
[vite]   LARAVEL v12.52.0  plugin v2.1.0
[vite] 
[vite]   ➜  APP_URL: http://localhost:8000

ローカル環境で意図通りにポート番号が開放されていることを確認します。

$ ss -lnpt |grep -E '(:8000|:5173)'
LISTEN 0      4096            127.0.0.1:8000       0.0.0.0:*                           
LISTEN 0      4096            127.0.0.1:5173       0.0.0.0:* 

ブラウザで http://localhost:8000 にアクセスすると Laravel のデフォルト画面が表示されます。

Screenshot from 2026-02-23 15-07-45.png

同様にブラウザで http://localhost:5173/ にアクセスすると Vite のデフォルト画面が表示されます。

Screenshot from 2026-02-23 15-07-54.png


Laravel Sail のインストール

Laravel Sail のドキュメントに従って、先程作成した Laravel アプリケーションに対して composer require laravel/sail --dev を実行して、 Laravel Sail をインストールします。

$ cd /PATH_TO/my-laravel-sail
$ docker container run \
--rm \
-u $(id -u):$(id -g) \
-v $(pwd):/app \
-it composer:latest \
composer require laravel/sail --dev

Laravel Sail のインストール工程が進むと、以下のようなメッセージが表示されて完了します。

・
・
省略
・
・
   INFO  Discovering packages.  

  laravel/pail ............................................................. DONE
  laravel/sail ............................................................. DONE
  laravel/tinker ........................................................... DONE
  nesbot/carbon ............................................................ DONE
  nunomaduro/collision ..................................................... DONE
  nunomaduro/termwind ...................................................... DONE

81 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force

   INFO  No publishable resources for tag [laravel-assets].  

No security vulnerability advisories found.
Using version ^1.53 for laravel/sail

.env のバックアップを取得します。

$ cp .env .env.orig.$(date +'%Y%m%d%H%M%S')
$ ls -l .env.orig.20260223153140 
-rw-r--r-- 1 akase244 akase244 1142  2月 23 15:31 .env.orig.20260223153140

次に php artisan sail:install を実行して、 compose.yaml の作成や .env の更新を行います。

$ docker container run \
--rm \
-u $(id -u):$(id -g) \
-v $(pwd):/app \
-it composer:latest \
php artisan sail:install

データベースの選択肢が表示されるので mysql を選択します。
※なぜ SQLite の選択肢が無いのか。。。

 ┌ Which services would you like to install? ───────────────────┐
 │ › ◼ mysql                                                  ┃ │
 │   ◻ pgsql                                                  │ │
 │   ◻ mariadb                                                │ │
 │   ◻ mongodb                                                │ │
 │   ◻ redis                                                  │ │
 └────────────────────────────────────────────────── 1 selected ┘
  Use the space bar to select options.

以下のように表示されたら php artisan sail:install の実行は完了です。

 ┌ Which services would you like to install? ───────────────────┐
 │ mysql                                                        │
 └──────────────────────────────────────────────────────────────┘



   INFO  Sail scaffolding installed successfully. You may run your Docker containers using Sail's "up" command.  

➜ ./vendor/bin/sail up

   WARN  A database service was installed. Run "artisan migrate" to prepare your database:  

➜ ./vendor/bin/sail artisan migrate

php artisan sail:install の実行により .env が更新されているはずなので差分を確認すると、データベースの接続先が SQLite から MySQL に変更されています。

$ diff .env .env.orig.20260223153140 
14c14
< PHP_CLI_SERVER_WORKERS=4
---
> # PHP_CLI_SERVER_WORKERS=4
23,28c23,28
< DB_CONNECTION=mysql
< DB_HOST=mysql
< DB_PORT=3306
< DB_DATABASE=laravel
< DB_USERNAME=sail
< DB_PASSWORD=password
---
> DB_CONNECTION=sqlite
> # DB_HOST=127.0.0.1
> # DB_PORT=3306
> # DB_DATABASE=laravel
> # DB_USERNAME=root
> # DB_PASSWORD=

作成された compose.yaml を参照すると ports に以下のような指定があります。

$ cat compose.yaml 
services:
    laravel.test:
        ・
        ・
        ports:
            - '${APP_PORT:-80}:80'
            - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
        ・
        ・
    mysql:
        image: 'mysql:8.4'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        ・
        ・

compose.yaml のバックアップファイルを作成して、以下のように修正します。

$ cp compose.yaml compose.yaml.orig.$(date +'%Y%m%d%H%M%S')
$ vim compose.yaml
$ diff compose.yaml compose.yaml.orig.20260223155130 
12,13c12,13
<             - '127.0.0.1:${APP_PORT:-80}:80'
<             - '127.0.0.1:${VITE_PORT:-5173}:${VITE_PORT:-5173}'
---
>             - '${APP_PORT:-80}:80'
>             - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
29c29
<             - '127.0.0.1:${FORWARD_DB_PORT:-3306}:3306'
---
>             - '${FORWARD_DB_PORT:-3306}:3306'

Laravel Sail を起動します。

$ ./vendor/bin/sail up

ローカル環境で意図通りにポート番号が開放されていることを確認します。

$ ss -lnpt |grep -E '(:80|:5173|:3306)'
LISTEN 0      4096            127.0.0.1:3306       0.0.0.0:*                           
LISTEN 0      4096            127.0.0.1:80         0.0.0.0:*                           
LISTEN 0      4096            127.0.0.1:5173       0.0.0.0:*

Laravel Sail を起動した状態でデータベースのマイグレーションを実行してみると、すべて適用済みのようです。

$ ./vendor/bin/sail artisan migrate

   INFO  Nothing to migrate.  

マイグレーションのファイルを確認します。全部で3ファイル存在するようです。

$ ls -l database/migrations/
合計 12
-rw-r--r-- 1 akase244 akase244 1473  1月 20 02:57 0001_01_01_000000_create_users_table.php
-rw-r--r-- 1 akase244 akase244  867  1月 20 02:57 0001_01_01_000001_create_cache_table.php
-rw-r--r-- 1 akase244 akase244 1812  1月 20 02:57 0001_01_01_000002_create_jobs_table.php

マイグレーションが本当に適用済みなのかを Docker コンテナ内に直接入って調べるため、データベースの接続情報を確認します。

$ grep DB_ .env
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=sail
DB_PASSWORD=password

起動中の MySQL の Docker コンテナのIDを調べます。

$ docker container ls |grep mysql
d18b30780d8d   mysql:8.4      "docker-entrypoint.s…"   16 minutes ago   Up 10 minutes (healthy)   127.0.0.1:3306->3306/tcp, 33060/tcp              my-laravel-sail-mysql-1

Docker コンテナに入ります。

$ docker exec -it d18b30780d8d bash
bash-5.1# 

事前に調べておいた接続情報で MySQL に接続します。

bash-5.1# mysql -u sail -p laravel
Enter password: 
・
・
省略
・
・
mysql> 

laravel データベースのテーブル一覧を確認すると、 MySQL 内に正常に作成されていることがわかります。

mysql> show tables;
+-----------------------+
| Tables_in_laravel     |
+-----------------------+
| cache                 |
| cache_locks           |
| failed_jobs           |
| job_batches           |
| jobs                  |
| migrations            |
| password_reset_tokens |
| sessions              |
| users                 |
+-----------------------+
9 rows in set (0.00 sec)

migrations を参照して、マイグレーションの実行状況を確認してみると、 batch 列の値が 1 になっているので、すべて実行済みのようです。

mysql> select * from migrations;
+----+--------------------------------------+-------+
| id | migration                            | batch |
+----+--------------------------------------+-------+
|  1 | 0001_01_01_000000_create_users_table |     1 |
|  2 | 0001_01_01_000001_create_cache_table |     1 |
|  3 | 0001_01_01_000002_create_jobs_table  |     1 |
+----+--------------------------------------+-------+
3 rows in set (0.00 sec)

ブラウザで http://localhost にアクセスすると Laravel のデフォルト画面が表示されます。
※Laravel Sail ではポート番号が80に変更になっているため、「:8000」の指定は不要です。

image.png


Sail-SSL のインストール

Sail-SSL を利用することでHTTPS接続が簡単に行えますので、これを導入します。

Laravel Sail を起動します。

$ cd /PATH_TO/my-laravel-sail
$ ./vendor/bin/sail up -d

sail composer コマンドで ryoluo/sail-ssl を導入します。

$ ./vendor/bin/sail composer require ryoluo/sail-ssl --dev

以下のように表示されれば導入完了です。

・
・
省略
・
・
   INFO  Discovering packages.  

  laravel/pail ......................................................... DONE
  laravel/sail ......................................................... DONE
  laravel/tinker ....................................................... DONE
  nesbot/carbon ........................................................ DONE
  nunomaduro/collision ................................................. DONE
  nunomaduro/termwind .................................................. DONE
  ryoluo/sail-ssl ...................................................... DONE

81 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force

   INFO  No publishable resources for tag [laravel-assets].  

No security vulnerability advisories found.
Using version ^1.4 for ryoluo/sail-ssl

compose.yaml のバックアップを取得します。

$ cp compose.yaml compose.yaml.orig.$(date +'%Y%m%d%H%M%S')
$ ls -l compose.yaml.orig.20260223165024 
-rw-r--r-- 1 akase244 akase244 1780  2月 23 16:50 compose.yaml.orig.20260223165024

sail artisan コマンドで sail-ssl:install を実行すると、 docker-compose.yml が存在しないため処理が終了してしまいました。

$ ./vendor/bin/sail artisan sail-ssl:install

   ErrorException 

  file_get_contents(/var/www/html/docker-compose.yml): Failed to open stream: No such file or directory

  at vendor/ryoluo/sail-ssl/src/Console/InstallCommand.php:29
     25▕      * @return void
     26▕      */
     27▕     public function handle()
     28▕     {
  ➜  29▕         $dockerCompose = file_get_contents($this->laravel->basePath('docker-compose.yml'));
     30▕         if (str_contains($dockerCompose, 'nginx:')) {
     31▕             $this->info('Nginx container is already installed. Do nothing.');
     32▕             return;
     33▕         }

      +14 vendor frames 

  15  artisan:16
      Illuminate\Foundation\Application::handleCommand()

Laravel Sail では docker-compose.yml ではなく compose.yaml を作成する構成になっています。
なので、 Sail-SSL が現状の構成に追いついてない部分があるようです。

以下を参照する限り、うまいこと動くような気がしなくもないですが。。。

仕方がないので、 compose.yamldocker-compose.yml にコピーして再度 sail-ssl:install を実行してみます。
実行時のメッセージでは my-laravel-sail ディレクトリ配下の compose.yaml を利用しているように見えます。

$ cp compose.yaml docker-compose.yml
$ ./vendor/bin/sail artisan sail-ssl:install
WARN[0000] Found multiple config files with supported names: /home/akase244/repos/my-laravel-sail/compose.yaml, /home/akase244/repos/my-laravel-sail/docker-compose.yml 
WARN[0000] Using /home/akase244/repos/my-laravel-sail/compose.yaml 
WARN[0000] Found multiple config files with supported names: /home/akase244/repos/my-laravel-sail/compose.yaml, /home/akase244/repos/my-laravel-sail/docker-compose.yml 
WARN[0000] Using /home/akase244/repos/my-laravel-sail/compose.yaml 
WARN[0000] Found multiple config files with supported names: /home/akase244/repos/my-laravel-sail/compose.yaml, /home/akase244/repos/my-laravel-sail/docker-compose.yml 
WARN[0000] Using /home/akase244/repos/my-laravel-sail/compose.yaml 
Nginx container successfully installed in Docker Compose.

事前に取得してた compose.yaml のバックアップと比較してみると、差分は発生していません。

$ diff compose.yaml compose.yaml.orig.20260223165024
(何も表示されない)

どうやら、 docker-compose.yml の方に Nginx の設定が追加されているようです。

$ diff docker-compose.yml compose.yaml.orig.20260223165024
2,20d1
<     nginx:
<         image: 'nginx:latest'
<         ports:
<             - '${HTTP_PORT:-8000}:80'
<             - '${SSL_PORT:-443}:443'
<         environment:
<             - SSL_PORT=${SSL_PORT:-443}
<             - APP_SERVICE=${APP_SERVICE:-laravel.test}
<             - SERVER_NAME=${SERVER_NAME:-localhost}
<             - SSL_DOMAIN=${SSL_DOMAIN:-localhost}
<             - SSL_ALT_NAME=${SSL_ALT_NAME:-DNS:localhost}
<         volumes:
<             - 'sail-nginx:/etc/nginx/certs'
<             - './vendor/ryoluo/sail-ssl/nginx/templates:/etc/nginx/templates'
<             - './vendor/ryoluo/sail-ssl/nginx/generate-ssl-cert.sh:/docker-entrypoint.d/99-generate-ssl-cert.sh'
<         depends_on:
<             - ${APP_SERVICE:-laravel.test}
<         networks:
<             - sail
74,75d54
<     sail-nginx:
<         driver: local

なので、 docker-compose.yml の内容を compose.yaml に反映します。

$ cp docker-compose.yml compose.yaml

Nginx が 0.0.0.0 で起動するようになっているので修正します。

$ cp compose.yaml compose.yaml.orig.$(date +'%Y%m%d%H%M%S')
$ vim compose.yaml
$ diff compose.yaml compose.yaml.orig.20260223171425 
5,6c5,6
<             - '127.0.0.1:${HTTP_PORT:-8000}:80'
<             - '127.0.0.1:${SSL_PORT:-443}:443'
---
>             - '${HTTP_PORT:-8000}:80'
>             - '${SSL_PORT:-443}:443'

Sail-SSL のドキュメントに従って、 Laravel Sail を停止して、起動します。

$ ./vendor/bin/sail down
$ ./vendor/bin/sail up

ブラウザで http://localhost にアクセスすると Laravel のデフォルト画面が表示されます。

image.png

ブラウザで https://localhost にアクセスすると証明書の警告が表示されます。

image.png

「詳細設定」から「localhost にアクセスする(安全ではありません)」をクリックします。

image.png

HTTPS接続で Laravel のデフォルト画面が表示されます。

image.png

Sail-SSL のドキュメントに従って、 Nginx のコンテナからルート証明書を取り出そうとすると失敗しました。

$ ./vendor/bin/sail cp nginx:/etc/nginx/certs/root-ca.crt .
WARN[0000] Found multiple config files with supported names: /home/akase244/repos/my-laravel-sail/compose.yaml, /home/akase244/repos/my-laravel-sail/docker-compose.yml 
WARN[0000] Using /home/akase244/repos/my-laravel-sail/compose.yaml 
WARN[0000] Found multiple config files with supported names: /home/akase244/repos/my-laravel-sail/compose.yaml, /home/akase244/repos/my-laravel-sail/docker-compose.yml 
WARN[0000] Using /home/akase244/repos/my-laravel-sail/compose.yaml 
[+] copy 0/1
 ⠋ my-laravel-sail-nginx-1 Copying my-laravel-sail-nginx-1:/etc/nginx/certs/root-ca.crt to .                                               0.0s
Error response from daemon: Could not find the file /etc/nginx/certs/root-ca.crt in container b4ea155c739d415c8bd220f55110d55350c9485c80684f18d01cf453b018b9de

起動中の Nginx の Docker コンテナのIDを調べます。

$  docker container ls |grep nginx
b4ea155c739d   nginx:latest   "/docker-entrypoint.…"   8 minutes ago    Up 8 minutes             127.0.0.1:443->443/tcp, 127.0.0.1:8000->80/tcp   my-laravel-sail-nginx-1

Docker コンテナに入ります。

$ docker exec -it b4ea155c739d bash
root@b4ea155c739d:/# 

/etc/nginx/certs/ 配下にはサーバー証明書しかなさそうです。

root@b4ea155c739d:/# ls -l /etc/nginx/certs/
total 8
-rw------- 1 root root 1704 Feb 23 08:11 server.key
-rw-r--r-- 1 root root 1143 Feb 23 08:11 server.pem

Sail-SSL のソースコードを参照するとたしかに root-ca.crt で作成されてそうに見えるんですが。。。

後処理で削除されていませんし、通常であれば root-ca.crt を取り出す形が正しいかと思います。

server.pem がルート証明書としても利用可能なサーバー証明書なのか確認してみたところ、「CA:TRUE」となっているため、これは「CA証明書(ルート証明書)」兼「サーバー証明書」の形で発行されているようです。

root@b4ea155c739d:/# openssl x509 -in /etc/nginx/certs/server.pem -noout -text | grep -A 1 "Basic Constraints"
            X509v3 Basic Constraints: critical
                CA:TRUE

しかし、Sail-SSL のソースコードを参照すると CA:FALSE が指定されています。謎。。。

まぁ、ということで、 /etc/nginx/certs/server.pem を取り出します。

$ ./vendor/bin/sail cp nginx:/etc/nginx/certs/server.pem .
WARN[0000] Found multiple config files with supported names: /home/akase244/repos/my-laravel-sail/compose.yaml, /home/akase244/repos/my-laravel-sail/docker-compose.yml 
WARN[0000] Using /home/akase244/repos/my-laravel-sail/compose.yaml 
WARN[0000] Found multiple config files with supported names: /home/akase244/repos/my-laravel-sail/compose.yaml, /home/akase244/repos/my-laravel-sail/docker-compose.yml 
WARN[0000] Using /home/akase244/repos/my-laravel-sail/compose.yaml 
[+] copy 1/1
 ✔ my-laravel-sail-nginx-1 Copied my-laravel-sail-nginx-1:/etc/nginx/certs/server.pem to .                                                 0.0s
$ ls -l server.pem 
-rw-r--r-- 1 akase244 akase244 1143  2月 23 17:11 server.pem

Chrome で「 chrome://settings/certificates 」を入力して「証明書マネージャ」を開きます。

image.png

「カスタム」→「自分でインストール」を選択し、「信頼できる証明書」に Nginx のコンテナから取り出したルート証明書をインポートします。

image.png

ブラウザで https://localhost にアクセスすると証明書の警告は表示されずにアクセスすることができました。
※証明書インポート後も警告が消えない場合は、一旦開いてるブラウザをすべて閉じてからアクセスしなおすと解消するはずです。(多分)

image.png


いかがだったでしょうか。
Docker コンテナを駆使することで、ローカル環境に追加でコマンド類をインストールすることなく Laravel Sail の環境を構築できることがわかったのではないでしょうか。


参考記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?