Windows上でDockerが遅い時の対処法
Windowsのローカル環境に開発環境用Dockerを構築しLaravel開発を試みたのですが、ページ表示に毎回5秒くらいかかって非常に遅い
そんなはずないだろう、何か間違えているのではないかと調べたのがきっかけ
- 1. 原因
- 2. Windowsで Docker + Laravel 構築手順
- 2.1. 前提
- 2.2. WSL2をインストール
- 2.3. Docker Desktopの設定変更
- 2.4. アプリケーションプログラムをUbuntuの領域に配置
- 2.5. laravel インストール
- 2.6. 依存関係のインストール
- 2.7. npm インストール
- 2.8. パーミッションの設定
- 2.8.1. ユーザID:1000のアカウントを作成
- 2.8.2. 所有者の変更
- 2.8.3. プロジェクトフォルダ自体の所有者はrootに戻す
- 2.8.4. ログファイルのパーミッション変更
- 3. 作業中に遭遇した各種エラー
- 3.1. sh: 1: vite: not found
- 3.2. Cannot find module @rollup/rollup-linux-x64-gnu
- 3.3. sh: 1: node: Permission denied
原因
DockerをWSL2ベースで動かせておらず、Windows上のファイルをLinuxファイルベースに変換する際のオーバーヘッドが原因でした。
Docker環境構築記事をググりながら進めたのですが、正しい情報で確認することは大事ですね。
WSL 2(Windows Subsystem for Linux 2)は、Windows 10およびWindows Server 2019で利用可能な機能であり、Windows上でLinuxカーネルを実行する仮想化技術です。これにより、Windowsホスト上でLinuxバイナリやツールをネイティブに実行できます。
WSL 2は、以前のWSLよりも大幅に改善されたパフォーマンスと互換性を提供します。特に、DockerなどのLinuxベースの開発ツールやアプリケーションをWindows上で実行する場合に、大幅なパフォーマンス向上が期待できます。
WSL 2は、Hyper-Vという仮想化プラットフォームを使用してLinuxカーネルをホストする仮想マシンを提供します。これにより、LinuxとWindowsの間でのリソースの分割や相互運用性が可能になります。
Dockerのパフォーマンスを向上させるには、次の方法があります。
- DockerをWSL 2を利用した環境で実行する。
- ソースコードをWSL 2のディストリビューション領域内に配置する。
上記を踏まえて改めて整理した構築手順を記載していきます。
Windowsで Docker + Laravel 構築手順
前提
Docker Desktopはインストール済みであること。Windows に Docker Desktop をインストール
WSL2をインストール
Docker Desktopインストール時にUbuntuもインストールしたつもりでしたが、WSL2のディストリビューションを参照するとUbuntuがありません。
PS C:\Users\syun> wsl -l -v
NAME STATE VERSION
* docker-desktop Running 2
docker-desktop-data Running 2
この状態であればおとなしくWSL2インストールの手順に進みます。
最終的にはこのようなレスポンスが返ってくればOK
NAME STATE VERSION
* Ubuntu Running 2
docker-desktop Running 2
docker-desktop-data Running 2
まずはPowerShell または Windows コマンド プロンプトを管理者モードで開き、wsl --install コマンドを入力し、マシンを再起動します。
wsl --install
細かい手順の参照が必要な場合はWSL を使用して Windows に Linux をインストールする方法をご覧ください。
このコマンドにより、WSL を実行し、Linux の Ubuntu ディストリビューションをインストールするために必要な機能が有効になります。
インストールが進むとUbuntuのアカウント作成を求められるので、IDとパスワードを設定します。
インストールが完了したらWSL2の設定を行います。
wsl --set-version Ubuntu 2
これでWSL2の作業は完了です。
Docker Desktopの設定変更
Docker Desktopの設定でWSL2のディストリビューションを利用可能にします。
画面上部の「設定メニュー」⇒WSL integration ⇒ Resources WSL integration と進みます。
Ubuntuを有効化する設定がありますので、キャプチャのように有効化設定を行い
「Apply & restart」ボタンを押下します。
アプリケーションプログラムをUbuntuの領域に配置
Ubuntu領域は下記パスになります。
\wsl.localhost\Ubuntu\home\
アドレスバーに入力するとアクセスできます。
\wsl.localhost\Ubuntu\home\[ユーザ名]\ 配下にアプリケーションプログラムを配置していきましょう。
ネットワークドライブの割り当てをしておくと後々便利です。
laravel インストール
LinuxファイルベースでLaravelを実行するために、Ubuntu領域内にLaravelをインストールします。
まずはDockerコンテナを立ち上げましょう。docker-compose.ymlのサンプルはこちら。
想定パスで指定しているのでわかりづらいですがバインドマウントでUbuntu領域を指定しています。
version: '3'
services:
nginx:
image: syunbiz03/nginx
container_name: "dc"
build:
context: ./docker/nginx
ports:
- 8080:80
volumes:
- ./:/src
app:
image: syunbiz03/app
container_name: "app"
build:
context: ./docker/php
depends_on:
- mysql
ports:
- 5173:5173
volumes:
- ./:/src
- /src/node_modules
- /src/vendor
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
mysql:
image: mysql:8.0.37
command: --max_allowed_packet=32505856
container_name: "dc_mysql"
volumes:
- ./docker/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=root
ports:
- 3306:3306
redis:
image: redis:alpine
container_name: "redis"
ports:
- 16379:6379
コンテナが立ち上がったらLaravelのインストール先であるコンテナ名 : app のサーバに入ります。
docker compose exec app bash
Laravelのプロジェクトを作成します。
composer create-project laravel/laravel --prefer-dist myapplication
依存関係のインストール
Laravelのお作法にのっとってこの辺りのコマンドも実行していきます。
composer install
chmod -R ug+rwx storage
php artisan storage:link
npm インストール
WSL2にnpmをインストールします。
こちらのページを参考にしています。Node.js を Linux 用 Windows サブシステム (WSL2) にインストールする
sudo apt-get install curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
nvm install --lts
nvm use --lts
npm update
参考サイトではUbuntu コマンド ラインからインストールすると記載されていますが、Laravelをインストールしたコンテナで引き続き作業することをお勧めします。Ubuntuからインストールすると権限周りで面倒なことになります。
これで一通りの作業は完了です。
最後に npm run dev コマンドを実行してサーバにアクセスすれば、ページが表示されます。
パーミッションの設定
Windows のデフォルトユーザと Ubuntu のデフォルトユーザの違いにより、そのままの状態では Windows 上からファイル更新できません。IDEなどが使えないためこのままでは非常に不便です。
ファイルの所有者を見るとプロジェクト内のファイルは所有者が root になっています。
しかしWindows上から新規で作成したファイルは下記のようにユーザID : 1000 ( Windows のデフォルトユーザ)になっています。
test.txtが新規で作成したファイルです。
この問題を解決するためには、Ubuntu上でユーザID:1000のアカウントを作成し、所有者を変更します。
Ubuntu上の所有者のグループもデフォルトであるwww-dataに変更しておきましょう。
ユーザID:1000のアカウントを作成
アカウント名は「dev」、グループはwww-dataに設定します。
useradd -u 1000 dev -G www-data
新規で作成したアカウントのデフォルトグループを「www-data」に変更しておきます。
usermod -g www-data dev
所有者の変更
プロジェクト内のファイル所有者を一括で変更します。併せてパーミッションも変更しておきます。
chown -R dev:www-data myapplication
chmod -R 775 myapplication
プロジェクトフォルダ自体の所有者はrootに戻す
これをやらないと npm run dev コマンド実行時にエラーになりました。
原因追及できていませんが取り急ぎ解決する方法として所有者を元に戻します。
chown root:root myapplication
ログファイルのパーミッション変更
ログファイルはシステム側が自動で作成していくので、こちらも併せて設定が必要です。
下記の記事を参考に設定します。
Laravel logのPermission denied対応
作業中に遭遇した各種エラー
sh: 1: vite: not found
npmのインストールに問題がある可能性があります。
下記コマンドを試してみてください。
npm update
Cannot find module @rollup/rollup-linux-x64-gnu
npmのインストールに問題がある可能性があります。
下記コマンドを試してみてください。
npm update
sh: 1: node: Permission denied
npm run dev コマンド実行時に発生したエラーです。プロジェクトのパーミッションをrootから変更したことが原因。
コマンドを実行する root ユーザに合わせてプロジェクトフォルダの権限を変更します。
chown root:root myapplication