Laravel Sail でコンテナのshellを使う

こんばんは、ウチイダです。

Laravel Sail便利ですよね。docker-compose のラッパーみたいなものなので、学習コストも低くてとても良い感じです。

docker-composeでできることは何でもできるので、困ったらdocker-composeのコマンドを調べるのですが、なかなか覚えられません。

ちょくちょく使うのが、コンテナに入るコマンドです。

# Laravelアプリケーションのコンテナのbashを開く
$ docker-compose exec laravel.test bash

dockerコマンドみたいに、-it とかオプション付けなくてもいいので、まだいいですが、長いですよね。

あるときふとReadoubleを見直してみたら、sail コマンドからコンテナ接続するサブコマンドがちゃんと用意されていました。

# sail コマンドから、Laravel アプリケーソンのコンテナのbashをひらく
$ sail shell

# root ユーザーで接続する場合
$ sail root-shell

# Readoubleにはないけど、以下でもOK
$ sail bash

すごく短くなります。

sailコマンドの中身(vendor/bin/bash)は難しくないshellスクリプトなので、中身を見てみるといろいろ発見があって面白いです。

以上です。あなたのお役に立てれば幸いです。

Azure SQLをエクスポートしたbacpacファイルを、ローカルのMSSQLサーバにインポートする手順

こんばんは、ウチイダです。

最近、Azureクラウドの案件に携わっています。

クライアントから報告されたバグの事象を再現するために、データベースをローカルに取り込むのに苦労したので、手順をまとめておきます。

Visual Studioのインストールが必要です。

Azure SQLデータベースをエクスポートする

まずはデータベースをエクスポートします。

直接ダウンロードはできず、いったんAzure ストレージに保存する仕様です。

ストレージがない場合は作成する必要があります。

エクスポートが完了したら、指定したストレージからbacpacファイルをダウンロードします。

インポート時にこのファイルのパスを利用するので、フルパスで控えておいてください。

ローカルSQLサーバの設定を変更する

Azure のSQLをエクスポートすると、bacpacという種類のファイルが出力されます。

SQLクエリのダンプファイルができるわけではなく、そのままではローカルに取り込みできません。

まず、bacpacファイルをインポートできるように設定を変更します。

Visual Studio などMSSQL サーバに接続できるソフトウェアから、以下のクエリを実行します。

sp_configure 'contained database authentication', 1;
GO
RECONFIGURE;
GO

SqlPackage.exeでインポート処理を行う

bacpac ファイルをインポートできる機能を持ったプログラム SqlPaclage.exe が、Visual Studioに同梱されています。

Visual Studioをインストールしたくない方は、以下のページからSqlPackageだけインストールできます。

https://docs.microsoft.com/ja-jp/sql/tools/sqlpackage/sqlpackage-download?view=sql-server-ver15

Visual Studioをデフォルトの設定でインストールした場合、以下のフォルダにSqlPackage.exeが入っています。

Program Files Microsoft Visual Studio 2022 Community Common7 IDE Extensions Microsoft SQLDB DAC

PowerShellやcmdでこのフォルダを開いて、以下のコマンドを実行します。

> .\SqlPackage.exe /a:Import /sf:"*** bacpacファイルのパス ***" /tcs:"Server=(localdb)\\MSSQLLocalDB;Database=データベース名; Integrated Security=true;"
サーバー '(LocalDB)\MSSQLLocalDB' のデータベース '(入力したデータベース名)' にインポートしています。
配置計画を作成しています
配置の初期化中
配置計画を検証しています
# ... 中略
データベースのインポートが完了しました。
経過時間 0:00:16.29

これで完了です。

覚えてしまえば大した手間ではないですが、ひと手間かかりますね。

以上です。あなたのお役に立てれば幸いです。

WSL2のnpm install がめちゃ遅い、git clone ができない → resolv.confの設定を変更して解決

こんにちは、ウチイダです。

いつ頃からかわからないのですが、WSLでの通信が怪しいな…と思うことが増えていました。

たとえばnpm install をするとき、コンソール上のスピナーが止まってしまって、そのまま10分以上動かなくなったりすることが頻発していました。

それだけなら、コーヒーブレイクを兼ねて気長に待つか…と思っていたのですが、先日からGitHubからリポジトリのクローンができなくなるという事態も発生しました。

y-uchiida@LUMIERE:/test_clone$ git clone git@github.com:y-uchiida/my_test_repo.git
Cloning into 'my_test_repo'...
ssh: Could not resolve hostname github.com: Temporary failure in name resolution
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

このリポジトリは絶対にあるし、同じPCでPowershell経由でgit clone したら問題なくローンできるのです。

そして不可解なことに、何回か同じコマンドを繰り返していると、成功することがあります。謎だ…

原因究明と対応

さすがにGitHubが使えないのは困ってしまうので、きちんと対応することにしました。

エラーメッセージを見る限り、どうやら名前解決の問題のようなので、それらしいキーワードで色々検索してみます。

すると以下のページを発見。

https://www.reddit.com/r/bashonubuntuonwindows/comments/nt8asc/npm_install_extremely_slow_on_wsl2/

最後のコメントに、「いろいろ試して、ついに解決方法を見つけた」(意訳)と書かれています。

I tried every solutions here, but nothing works for me. But I found solutions.

in wsl, type below.

sudo rm /etc/resolv.conf
sudo bash -c ‘echo “nameserver 8.8.8.8” > /etc/resolv.conf’
sudo bash -c ‘echo “[network]” > /etc/wsl.conf’
sudo bash -c ‘echo “generateResolvConf = false” >> /etc/wsl.conf’
sudo chattr +i /etc/resolv.conf

After that, type below in cmd with administrator.

wsl –shutdown

https://www.reddit.com/r/bashonubuntuonwindows/comments/nt8asc/comment/hk7zpbw/?utm_source=share&utm_medium=web2x&context=3

このコメントの通り、resolv.confで指定するネームサーバーを変更したら解決しました。

変更前に色々と実験をしてみたものの、やはりネームサーバの問題のようです。

実験した内容は、おいおいどこかで書くかもしれません。

とりあえずこの変更により、困りごとが色々解消しました。

npm install が止まってしまうのも、git cloneが名前解決できないのも直ったので、とても快適になりました。

こころなしか、Docker pullまで早くなったような気がします。

免責

この変更による副作用が出てくるのか、現時点ではなんとも言えません。

設定変更の際は、バックアップを取るなどしてください。

まとめ

実はnpm install が遅い件については以前からちょくちょくググったりしていたのですが、それらしい情報がなかなか見つからなかったんですよね…

Cドライブ側にデータを置いていると遅い、という情報はたくさん出てきたのですが。

今回は英語の情報に絞って検索をかけて、上記のページに辿り着きました。

英語での検索、やっぱり大事ですね。。。

以上です。あなたのお役に立てば嬉しいです。

WSL2 Ubuntu に、nodenv 環境を作る簡単な手順(作業時間10分未満)

こんにちは、ウチイダです。

PCをセットアップするときにいつも調べている、nodeの環境構築。

そろそろ打ち止めにしたいので、メモリークリップに書き留めておきます。

今回の手順は、以下の環境で動作させました。

  • Windwos 11 Pro (21H2 ビルド 22000.194)
  • WSL カーネル バージョン: 5.10.60.1-microsoft-standard-WSL2
  • Windows Terminal バージョン: 1.10.2714.0
  • Ubuntu バージョン: 20.04.3 LTS (Focal Fossa)

nodenv installerを使うのがおすすめ

併せてanyenvを使う方法とか、homebrew経由でインストールする方法などが紹介されているサイトも多いですが、とにかく最短でnodeのマルチバージョン環境を整えたいのであれば、nodenv installerを利用するのが良いです。

必要に応じて、各種言語の管理ツールを入れるので良いかなーと思っています。

nodenv の公式リポジトリでも紹介されています。

https://github.com/nodenv/nodenv-installer#nodenv-installer

1. nodenv installer を実行する

使い方はとても簡単で、スクリプトをダウンロードしてきて、実行するだけです。

nodenv installerのgithubのREADMEでは、curlを使ったサンプルコマンドが紹介されているので、それの通りに実行します。

$ curl -fsSL https://raw.githubusercontent.com/nodenv/nodenv-installer/master/bin/nodenv-installer | bash
Installing nodenv with git...
Initialized empty Git repository in /home/y-uchiida/.nodenv/.git/

# ...(中略)...

Running doctor script to verify installation...
Checking for `nodenv' in PATH: /home/y-uchiida/.nodenv/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /home/y-uchiida/.nodenv/plugins/node-build/bin/nodenv-install (node-build 4.9.59)
Counting installed Node versions: none
  There aren't any Node versions installed under `/home/y-uchiida/.nodenv/versions'.
  You can install Node versions like so: nodenv install 2.2.4
Auditing installed plugins: OK

All done!
Note that this installer doesn't yet configure your shell startup files:
1. You'll want to ensure that `~/.nodenv/bin' is added to PATH.
2. Run `nodenv init' to see instructions how to configure nodenv for your shell.
3. Launch a new terminal window to verify that the configuration is correct.

# nodenvがインストールできているか、バージョンを確認
$ /home/y-uchiida/.nodenv/bin/nodenv -v
nodenv 1.4.0+3.631d0b6

「All done」の表示が出たら、nodenvのインストールは完了です。

2. nodenvのインストールディレクトリにパスを通す

nodenv installerは、パスの追加までは行わないので、パスの追加を行います。

Ubuntuの初期設定であれば、ログインシェルはbashになっていると思いますので、ホームディレクトリの.bashrcの末尾に、以下を追記します。

# nodenv のインストールディレクトリをPATHに追記
export PATH="$HOME/.nodenv/bin:$PATH"

# nodenvを動作させるための設定を実行
eval "$(nodenv init -)"

追記が終わったら、bashを立ち上げなおすか、sourceコマンドで変更を反映します。

$ source ~/.bashrc

# コマンド名だけでバージョン確認できたら、パスの追加は完了
$ node -v
nodenv 1.4.0+3.631d0b6

3. node のインストール

nodenvがインストールできたので、nodeをインストールします。

とりあえずLTSの最新版を入れてみます。

LTSのバージョン情報は、下記のNode.js公式サイトのトップに書いてあるので、それを見るのが早いです。

https://nodejs.org/ja/

2,021年10月現在だと、ちょうどv14系からv16系に安定板が切り替わるタイミングです。

https://nodejs.org/ja/about/releases/

10月26日からがv16のLTSのスタートなので、ちょっと早いですが(執筆時点では10月14日です)、v16を入れておくことにします。

# nodenvで、最新版をインストール(公式サイトでバージョン番号を確認してください)
$ nodenv install 16.11.1
Downloading node-v16.11.1-linux-x64.tar.gz...
-> https://nodejs.org/dist/v16.11.1/node-v16.11.1-linux-x64.tar.gz
Installing node-v16.11.1-linux-x64...
Installed node-v16.11.1-linux-x64 to /home/y-uchiida/.nodenv/versions/16.11.1

# インストールしたバージョンを、システム全体で利用するように設定
$ nodenv global 16.11.1

# 設定できたか、バージョンを確認
$ node -v
v16.11.1

nodeがインストールできていれば、npmも入っています。

ちょっとした開発や検証なら、ここまでの設定で不自由することはないと思います。

バージョンを分けて管理したい場合は、nodenv local コマンドで、動作させるバージョンを切り替えてください。

もっと本格的に使うのであれば、Dockerなどを使って環境を分離することをお勧めします。

アンインストール

ホームディレクトリ内に追加されている「.nodenv」ディレクトリに関連データが入っていますので、それを削除すればOKです。

# nodenv のアンインストール、削除
$ rm -r ~/.nodenv

.nodenvディレクトリを削除すると、今までインストールしたnodeのバージョンとか設定とか全部まとめて消えてしまいます。

必要に応じてバックアップをしてください!

まとめと余談

以上でnodejs/nodenvの環境構築は完了です。

検索結果の上位に出てくる方法は、brewをインストールしたり、anyenvの中のnodenvを使うような網羅的な方法が出てくることが多いように思います。

ちょっとnodeのバージョン管理がしたいだけなのに手間が多いな~と思っていたので、シンプルな方法をまとめました。

ここからバリバリ開発していきましょう!

ちなみに、ウチイダは過去にanyenvをWSL Ubuntuで利用していて、起動がとても遅くなった経験をしたことがあります。

最近では、本格的に開発をする場合Dockerに環境を用意することが多いのではないでしょうか。

そのため、anyenvでまとめて管理しないといけないほど、WSL上で直接いろいろな言語の開発環境が必要になることは少ないと思っています。

起動時間のことなどもかんがみて、ホスト側(厳密には、WSLはホストじゃないですが…)の環境はシンプルに保っておきたいです。

以上です。あなたのお役に立てればうれしいです。

phpbrewで、mcryptバリアントがインストールできない

こんにちは、ウチイダです。

最近またPHPを触ることが増えてきていて、Windows11のWSL2上にphpbrewで環境構築をしています。

今回はmcryptを使いたくなり、バリアントを追加しようとしたらうまくいかなかったというトラブルです。

バリアントをインストールしようとしたら、以下のようなエラーが。

$ phpbrew ext install mcrypt
Downloading https://pecl.php.net/rest/r/mcrypt/stable.txt via curl extension
[==================================================================] 5.00/5.00B 100%
Downloading https://pecl.php.net/rest/r/mcrypt/1.0.4.xml via curl extension
[==================================================================] 736.00/736.00B 100%
Downloading https://pecl.php.net/rest/r/mcrypt/stable.txt via curl extension
[==================================================================] 5.00/5.00B 100%
Downloading https://pecl.php.net/rest/r/mcrypt/1.0.4.xml via curl extension
[==================================================================] 736.00/736.00B 100%
Downloading https://pecl.php.net/get/mcrypt-1.0.4.tgz via curl extension
[==================================================================] 26.42/26.42KB 100%
===> Extracting to /home/y-uchiida/.phpbrew/build/php-7.4.23/ext...
===> Installing mcrypt extension...
Log stored at: /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log
Changing directory to /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt
===> Phpize...
Error: Command failed: phpize > /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log 2>&1 returns:

調べてみたところ、どうやらautoconfのパッケージが入ってなかったり、バージョンが古いと、phpizeでエラーするみたいです。

とりあえずautoconfをインストールします。

$ sudo apt install autoconf

再度バリアントのインストールを試みると、今度は別のエラーが出ました。

$ phpbrew ext install mcrypt
[ ] mcrypt extension is disabled.
===> Installing mcrypt extension...
Log stored at: /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log
Changing directory to /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt
===> Running make clean: /usr/bin/make -C '/home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt' --quiet 'clean'
===> Phpize...
===> Configuring...
Error: Command failed: ./configure '--with-php-config=/home/y-uchiida/.phpbrew/php/php-7.4.23/bin/php-config' >> '/home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log' 2>&1 returns:

調べてみたけど、よくわかりませんでした…

ふと、バリアントは、パッケージの本体がないとインストールできないという仕様に思い至りました。

WSLのほうでmcryptのパッケージを入れてなかったような気がしたので、インストール。

$ sudo apt-get install libmcrypt-dev
# ...(中略)...
The following NEW packages will be installed:
  libmcrypt-dev

やっぱり入ってませんでした。

再度、mcrypt バリアントをインストールします。

$ phpbrew ext install mcrypt
[ ] mcrypt extension is already disabled.
===> Installing mcrypt extension...
# ...(中略)...
[*] mcrypt extension is enabled.
Done.

今度はうまくいったみたいです。

最後に、phpbrewで管理しているPHPに、バリアントを追加します。

$ phpbrew install 7.4.20 +mcrypt
===> phpbrew will now build 7.4.20
===> Loading and resolving variants...
# ...(中略)...
Congratulations! Now you have PHP with 7.4.20 as php-7.4.20

* To configure your installed PHP further, you can edit the config file at
    /home/y-uchiida/.phpbrew/php/php-7.4.20/etc/php.ini

To use the newly built PHP, try the line(s) below:

    $ phpbrew use php-7.4.20

Or you can use switch command to switch your default php to php-7.4.20:

    $ phpbrew switch php-7.4.20

Enjoy!

ビルドしなおしなので、結構時間かかります。

phpinfo を見てみると、mcryptの項目が増えていることが確認できました。

まとめ

今回必要だったのは、以下のコマンドを実行することでした。

  • autoconf パッケージのインストール( sudo apt install autoconf )
  • mcyrpt パッケージのインストール( sudo apt-get install libmcrypt-dev )
  • mcrypt バリアントを含めて、phpbrewで再ビルド(sudo phpbrew install 7.4.20 +mcrypt)

以上です。

あなたのお役に立てたらうれしいです。

vsftpd が動かない→ 設定ファイルの改行コードをLFに変える

みなさまこんにちは、ウチイダです。

先日、Dockerでの環境構築をする中でvsftpdを使ったFTPサーバを用意していた時のこと。

デーモンが起動しないというトラブルに遭遇しました。

# vstftpd /etc/vsftpd.conf
500 OOPS: bad bool value in config file for: listen

DockerのCOPYコマンド経由で、ホストからvsftpd.confを渡していたのですが、どうもその内容にエラーがあるとのこと。

散々見比べても問題なさそうだったのですが、デフォルトの内容とdiffを取ってみたら、すべての行で差分が出ていました。

これは…改行コードか!!

ホスト側から渡していたファイルの改行コードがCRLFになっていたので、これをLFに保存しなおして再度チャレンジ。

何事もなかったかのように動きました。

スペースが入っているだけでもディレクティブ名と値の間にスペースが入っていてもNGだったり、vsftpdのコンフィグの設定に気を使いますね…

これに限らないのかもしれませんが、Windows ホストの場合は改行コードが違うということは改めて意識しておこうと思いました…

以上です。

あなたのお役に立てればうれしいです。

tar コマンドでカレントディレクトリ以外のディレクトリを指定してアーカイブしたい

こんにちは、ウチイダです。

tar コマンドでアーカイブをするとき、わざわざ対象のディレクトリまで移動するのが面倒な時ってあるじゃないですか。

例えば、Dockerfileでのビルドの際に何かを圧縮するときとか。

あるいは、make コマンドで処理を自動化している場面とか。

そんな時に、横着してディレクトリ移動せずにtar でのアーカイブを実行してしまうと、解凍したときのディレクトリ構造が面倒なことになってしまいます。

# piyo を起点にしてアーカイブしたいのに、カレントディレクトリの直下のディレクトリが含まれてしまう
$ tar zcfv archive.tar.gz ./tar_test/hoge/fuga/piyo
./tar_test/hoge/fuga/piyo/
./tar_test/hoge/fuga/piyo/hogefuga/
./tar_test/hoge/fuga/piyo/hogefuga/fugapiyo/
./tar_test/hoge/fuga/piyo/hogefuga/fugapiyo/text.txt

ディレクトリを指定しても、そのディレクトリに到達するところまで、アーカイブに含まれてしまうんですよね。

これを展開すると、tar_test を起点としてデータが展開されます。

cd で移動したくないときは、-C を使うとよいようです。

$ tar zcfv archive.tar.gz -C ./tar_test/hoge/fuga/ piyo
piyo/
piyo/hogefuga/
piyo/hogefuga/fugapiyo/
piyo/hogefuga/fugapiyo/text.txt

今度は、tar_test やその下のhogeなどが含まれず、piyoを起点としてアーカイブを作ることができました。

カレントディレクトリを変えずに、アーカイブファイルの起点を変更したいときはお試しください。

以上、あなたのお役に立てればうれしいです。

WSL上のDocker Composeで作成したコンテナに、Windows 11ホストから接続する

こんにちは、ウチイダです。

ここしばらく、Windwos 11のWSL Ubuntu での環境構築を進めてきました。

前回の記事で、Docker Composeのインストールを紹介しています。

今回はその続きとして、シンプルなPHP開発環境をDocker Compose を用いて作成し、Windows ホストのブラウザからアクセスできるように設定していきます。

これができると、ついにWindows 11でWSLを使った実用的なWeb開発ができるようになります。

なお、動作環境は以下の通りです。

  • Windwos 11 Pro (21H2 ビルド 22000.120)
  • WSL カーネル バージョン: 5.10.16
  • Windows Terminal バージョン: 1.9.1942.0
  • Docker バージョン 20.10.8, build 3967b7d
  • Docker Compose バージョン 1.29.2, build 5becea4c

前準備①:Docker デーモンを起動する

WSLのディストリビューションは、サービスの自動起動などを行いません。

WSLを起動した後、最初にDockerを利用する場合は、デーモンを起動するのを忘れないようにしましょう。

$ sudo service docker start
[sudo] password for y-uchiida:
 * Starting Docker: docker                                 [ OK ]

## Docker デーモンの起動を確認します
$ service docker status
 * Docker is running

前準備②:開発環境をつくるディレクトリを作成

続いて、Docker に関するファイルや、PHPなどのスクリプトを置くディレクトリを作成します。

例として、「sample_docker-compose_on_wsl」を作成します。

また、PHPやJavaScriptなどのデータを置くための「public」も作成しておきます。

## とりあえずホームディレクトリに作ることにします
## 開発環境をまとめておく場所を決めている方は、そちらに作成してください
$ mkdir ~/sample_docker-compose_on_wsl

## 公開用ファイルを設置するpublic ディレクトリを作成します
$ mkdir ~/sample_docker-compose_on_wsl/public 

前準備③:ファイル編集とDocker実行の準備

この後の作業で、yamlファイルを編集したりdocker-compose コマンドを実行したりするので、作成した開発環境用のディレクトリに移動しておきます。

また、エディタも用意します。以下の例では、VS Codeでsample_docker-compose_on_wsl ディレクトリを開いています。

## docker-compose コマンドを使うので、カレントディレクトリを移動しておきます
$ cd ~/sample_docker-compose_on_wsl

## Visual Studio Code(VS Code) を利用している方は、code コマンドでVS Codeで開くことができます
## docker-compose.ymlの編集などはVS Code
$ code .

docker-compose.ymlを作成する

準備が整いましたので、Docker Compose でコンテナを生成・起動するためのファイル docker-compose.ymlを作っていきます。

sample_docker-compose_on_wsl ディレクトリ配下に作成します。

完成コードは以下です。

ディスク容量を圧迫しないように、alpine ベースのイメージを選択しました。

version: '3.8' # 現時点での最新のバージョンを指定しておきます
services: 

  # Webサーバとして、nginx を利用します
  web: 
    container_name: "web"
    image: nginx:1.21.1-alpine
    ports:
      - "8080:80" # ポート8080を、ポート80 へフォワーディングします
    links:
      - app # php 実行コンテナ(app)に接続できるようにします
    volumes:
      - ./public:/var/www/public # WSL側のpublic ディレクトリを、web コンテナにマウントします
      - ./default.conf:/etc/nginx/conf.d/default.conf # nginx の設定ファイルを、web コンテナにマウントします

  app:
    container_name: "app"
    image: php:7.4-fpm-alpine3.14
    volumes:
      - ./public:/var/www/public # web コンテナと同じパスにアクセスできるように、app コンテナにもpublic ディレクトリをマウントします

ここでのポイントは2点あります。

ひとつは、links でweb コンテナから app コンテナに接続できるように設定したことです。

これにより、phpファイルが呼び出された際にapp コンテナへ処理を引き渡すことができるようになります。

もうひとつは、web と app の両方の volumes に./publicをマウントするように記述したことです。

同じファイルパスで参照できるようになるので、スムーズに処理の引き渡しができます。

コンテナにマウントするファイルを作成する

続いて、コンテナにマウントするファイルを作っていきます。

最低限の用意として、2つのファイルを作成します。

phpの処理をapp コンテナに引き渡すための設定を記述したnginxのconfigファイル「default.conf」と、publicルートにアクセスした際に処理される「index.php」です。

default.confの作成

まずは、nginxの設定ファイルから見ていきます。

sample_docker-compose_on_wsl ディレクトリの直下に、以下のdefault.conf を作成してください。

server {
    listen 80;
    server_name localhost;

    root /var/www/public;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # PHP ファイルへアクセスされた場合に、app コンテナのfast CGIへ処理を回します
    location ~ \.php$ {
        include fastcgi_params;

        # app コンテナのポート9000でFast CGI がListenしているので、そちらへパスします
        fastcgi_pass app:9000;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;

        # nginx がアクセスされたファイルパスを、app コンテナで処理すべきファイルパスとして渡します
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;

        try_files $uri = 404;
    }
}

ポイントは、 location ~ \.php のディレクティブです。

ここで、php ファイルにアクセスされた際にapp コンテナへ処理を移すための設定を記載しています。

app コンテナのポート9000でFast CGI がListenしているので、fastcgi_pass はapp:9000 を指定します。

また、SCRIPT_FILENAME で、nginx がアクセスされたファイルパス($dcoument_root$fastcgi_script_name)を渡しています。

docker-compose.yml では、2つのコンテナにpublic ディレクトリを同じパスにマウントしました。

コンテナ同士のphpファイルのパスを一致させているため、このように記述できます。

index.php の作成

最後に、index.php を作成します。

これは、phpが動作していることが分かれば何でもよいです。

public ディレクトリ内に作成します。

<?php
    echo "hello from docker on wsl!!<br>\r\n";

内容は、好きなように設定してください。

コンテナの起動と動作確認

準備が整いましたので、docker コンテナを起動して動作を見ていきます。

まずはコンテナの起動です。

## dockerコンテナの起動には、sudo が必要になると思います
## コンテナ起動後にほかのコマンドを使いたいので、最後に & をつけてバックグラウンドで処理させます
$ sudo docker-compose up &
Creating app ... done
Creating web ... done
Attaching to app, web
app    | [09-Aug-2021 09:19:39] NOTICE: fpm is running, pid 1
app    | [09-Aug-2021 09:19:39] NOTICE: ready to handle connections
web    | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
web    | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
web    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
web    | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
web    | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
web    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
web    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
web    | /docker-entrypoint.sh: Configuration complete; ready for start up
web    | 2021/08/09 09:19:40 [notice] 1#1: using the "epoll" event method
web    | 2021/08/09 09:19:40 [notice] 1#1: nginx/1.21.1
web    | 2021/08/09 09:19:40 [notice] 1#1: built by gcc 10.3.1 20210424 (Alpine 10.3.1_git20210424)
web    | 2021/08/09 09:19:40 [notice] 1#1: OS: Linux 5.10.16.3-microsoft-standard-WSL2
web    | 2021/08/09 09:19:40 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker processes
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 32
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 33
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 34
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 35

コンテナ起動時のメッセージがたくさん出ます。最後にstart worker process (番号) と表示されれば成功です。

コンテナの起動コマンドの最後に 「&」 をつけておくと、コンテナの起動がバックグラウンドで処理されます。

バックグラウンド処理にしておくことで、up コマンド実行後も同じターミナルで別のコマンドが実行できます。

WSLからコンテナにアクセス

まずはDocker コンテナのホストであるWSL から、コンテナへアクセスしてみます。

8080ポートをフォワーディングしているので、localhost:8080でコンテナ内のnginxへアクセスできます。

curl コマンドを用いて、レスポンスを確認します。

$ curl http://localhost:8080/
hello from docker on wsl!!<br>
app    | 172.22.0.3 -  09/Aug/2021:10:07:27 +0000 "GET /index.php" 200
web    | 172.22.0.1 - - [09/Aug/2021:10:07:27 +0000] "GET / HTTP/1.1" 200 43 "-" "curl/7.68.0"

index.php でechoした文字列「hello from docker on wsl!!」が表示されています。

また、web コンテナ、app コンテナそれぞれがメッセージを出してきました。

このような表示になれば、うまく設定できています。

index.php の内容を変更・保存し、再度curl コマンドを実行すると、表示内容が変わります。

Windows ホストのブラウザからコンテナにアクセス

最後に、Windows上のブラウザからコンテナにアクセスしてみます。

以前はWindows ホストからWSLにアクセスするには設定が必要だったのですが、今ではとくに何もしなくてもよいようです。

ブラウザを開き、localhost:8080にアクセスしてみます。

あっさり接続できてしまいました。

WSLのDockerで、こんなに簡単にPHP開発環境が作れるとは驚きです。

Docker コンテナを終了する

一通り動作確認をしたら、Docker コンテナを終了します。

$ sudo docker-compose down
Stopping web ...
Stopping app ...
web    | 2021/08/09 10:45:04 [notice] 1#1: signal 3 (SIGQUIT) received, shutting down
web    | 2021/08/09 10:45:04 [notice] 33#33: gracefully shutting down
web    | 2021/08/09 10:45:04 [notice] 34#34: gracefully shutting down

... 中略 ...

Removing web ... done
Removing app ... done
Removing network sample_docker-compose_default
[1]+  Done                    sudo docker-compose up

またコンテナにアクセスしたい場合は、 docker-compose up を実行してください。

まとめ:WSLでも、スムーズにPHP開発環境が構築できるようになりました

今回はこれで終了です。

2021年8月時点では、とても簡単にWSLを使ったPHP開発環境が構築できるようになっていました。感動。

Docker Compose を使いたかったので長くなってしまいましたが、Windows ホストからWSL 上のDocker コンテナにつなげるだけだったら、もっと簡単にできそうです。

PHP のほかにも、node.js やPython の環境も、同じ要領で構築できそうです。

ここから先はDocker の領域に入っていきますので、Docker に関する情報などをあたってみるとよいかと思います。

以上、あなたのお役に立てれば幸いです。

Windows 11 のWSL2(Ubuntu 20.04)にDocker Composeをインストールする

こんにちは、ウチイダです。

前回のDocker インストールに引き続き、Windows 11のWSL2にDocker Composeをインストールして、開発環境を分割しやすくしていきます。

WSL2 のUbuntu上に、Docker がインストールされている前提で手順を見ていきます。

なお、動作環境は以下の通りです。

  • Windwos 11 Pro (21H2 ビルド 22000.120)
  • WSL カーネル バージョン: 5.10.16
  • Windows Terminal バージョン: 1.9.1942.0

GitHub リポジトリから、Docker Composeの最新版をインストール

Docker Composeは、aptなどのパッケージ管理ツールからインストールできないようです。

公式サイトの記載に従って、最新版のリリースをcurlで取得します。

https://github.com/docker/compose/releases

2021年8月時点の最新版は、1.29.2 です。

## GitHubでの最新リリースのバージョン番号を指定してバイナリを取得
$ sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

## ダウンロードしたバイナリに、実行権限を付与
$ sudo chmod +x /usr/local/bin/docker-compose

## バージョン情報を表示して、インストールされたかを確認する
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

Docker Composeのコマンド補完をインストール

続いて、公式サイトにオプションとして記載されているコマンド補完機能を導入します。

docker-compose と入力した後にTab キーを押すと、利用できるサブコマンドが表示されたりと、非常に快適になります。

## コマンドライン補完のスクリプトをインストール
$ curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

## ウチイダの場合、直接 /etc/bash_completion.d/ にファイルを置こうとするとうまくいかなかったので、以下のコマンドで行いました
$ curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose > ~/docker-compose
$ chmod 0644 ~/docker-compose
$ sudo root:root ~/docker-compose
$ sudo mv ~/docker-compose /etc/bash_completion.d

## シェルを再読み込み
$ exec $SHELL -l

## docker-compose のコマンド補完が動作することを確認
$ docker-compose [Tab キーを2回押す]
build    create   events   help     kill     pause    ps       push     rm       scale    stop     unpause  version
config   down     exec     images   logs     port     pull     restart  run      start    top      up

以上で、インストール作業は完了です。

次回はWeb開発のための環境を、Docker Compose で動かしてみることにします。

以上、あなたのお役に立てればうれしいです。

Windows 11 のWSL2(Ubuntu 20.04)にDockerをインストールする

こんにちは、ウチイダです。

前回の記事で、Windows TerminalからWSLを使いやすくする設定を行いました

Windows Terminal起動時にWSLが開くようにする設定と、カラープロファイルを設定しただけですが。。。

ですがこれだけの設定で、WSLを使いたくなったらWindows キーでスタートメニューを開いて、「wt」と入力した後エンターを押すだけで、視認性の高いUbuntuのターミナルが表示できるようになりました。

前回の記事はこちら。

さて今回は、WSL2 のUbuntu にDocker をインストールしていきます。

前提となる動作環境は以下の通りです。

  • Windwos 11 Pro (21H2 ビルド 22000.120)
  • WSL カーネル バージョン: 5.10.16
  • Windows Terminal バージョン: 1.9.1942.0

Docker 公式ドキュメントによると、リポジトリからインストールするのがおすすめの方法ということです。

https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository

上記のページの手順に沿って、作業を進めていきます。

インストール前の準備

とりあえず、パッケージをアップデートして最新の状態にしましょう。

$ sudo apt-get update
$ sudo apt-get upgrade

続いて、リポジトリをHTTPS経由で利用できるようにするためのパッケージをインストールします。

$ sudo apt-get install \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg \
  lsb-release

Docker のリポジトリを利用するために、GPG鍵を追加します。

正直、この辺よくわかっていません。。。セキュリティのための必要事項だ、くらいの雑な理解をしています。

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

前準備の最後の手順です。Docker リポジトリ(安定版、Stable)を追加します。

$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Dockerのインストールと動作確認

追加したリポジトリから、Docker エンジンをインストールします。

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

インストールできたか確認してみます。

$ docker --version
Docker version 20.10.8, build 3967b7d

バージョン情報が表示されれば、パッケージのインストールは成功です。

docker コマンドを実行する前に、Docker デーモンを起動しておきます。

$ sudo service docker start
 * Starting Docker: docker

## 起動確認
$ sudo service docker status
 * Docker is running

ちなみに、サービスを起動し忘れてDockerコマンドを実行すると、以下のようなエラーが出ます。

docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.

Docker デーモンが起動できたら、ようやく動作確認です。hello-world コンテナを動かしてみます。

$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:df5f5184104426b65967e016ff2ac0bfcd44ad7899ca3bbcf8e44e4461491a9e
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

## 本当に実行できたのか、コンテナを確認します
$ sudo docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
f370ebbed892   hello-world   "/hello"   10 seconds ago   Exited (0) 24 seconds ago             goofy_gates

WSL上で、dockerコンテナを動かすことができました!

現在の状態では手動でDocker デーモンを起動する必要があり、最初に動かすときに手間がかかります。

WSLはSystemd が動いていないため、サービスの自動起動などができなくて不便ですね。

このあたりの解決方法はまた別の機会に。

今回の内容は以上です。

あなたのお役に立てればうれしいです。