Dockerで作る軽量なPHP 7.4の開発環境

## 環境

以下の環境を仮想マシン(VM)上に作成した．
Docker Desktop for Windowsでも同様の手順で行える．

- Ubuntu 18.04
- Docker 19.03

Docker Hubのアカウント取得と `docker login` を済ませた前提とする．

## 手順

### 1. Dockerfileの作成

今回はベースのDockerイメージとしてAlpine Linuxを使う．
`#`からはじまる行はコメントなので実際には必要ない．

```bash
# alpineを使ったphpのDockerイメージを使用
FROM php:7-alpine3.12

# 外部に開放するポート
EXPOSE 8000

# パケージマネージャapkでパッケージリポジトリ一覧を更新
RUN apk update --no-cache && apk upgrade --no-cache

# composerのインストール
WORKDIR /tmp
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# 開発に必要なパッケージのインストール
RUN apk add --no-cache bash vim jq

# PHPで必要な拡張があればインストール
# パッケージ一覧: https://gist.github.com/chronon/95911d21928cff786e306c23e7d1d3f3
RUN apk add --no-cache oniguruma-dev && \
    docker-php-ext-install -j$(nproc) mbstring pdo_mysql

# 作業用ディレクトリ
WORKDIR /work
CMD ["tail", "-f", "/dev/null"]
```

## 2. Dockerイメージをビルド

```bash
sudo docker build -t my-php:v0.1 .
```

## 3. Docker HubにPush

`<username>` は自分のDocker Hubのユーザ名に変更する．

```bash
sudo docker tag my-php:v0.1 <username>/my-php:v0.1
sudo docker push <username>/my-php:v0.1
```

## 4. 使い方

ポート開放を行う場合は `-p` をつける．`$PWD:/work` はカレントディレクトリをコンテナ内の `/work` にマッピングする．

```bash
sudo docker run -it --rm -v $PWD:/work -p 3000:8000 my-php:v0.1 /bin/bash
```

### 【初回のみ】composerのセットアップ

**初回のみ** 以下のコマンドでcomposerのセットアップを行う．composer.jsonが存在する場合はこの手順は必要ない．

```bash
bash-5.0# composer init

Package name (<vendor>/<name>) [root/work]: tomoyk/php-docker-example
Author [, n to skip]: Tomoyuki KOYAMA <koyama@example.com>
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []:

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? no
Would you like to define your dev dependencies (require-dev) interactively [yes]? no

{
    "name": "tomoyk/php-docker-example",
    "authors": [
        {
            "name": "Tomoyuki KOYAMA",
            "email": "koyama@example.com"
        }
    ],
    "require": {}
}

Do you confirm generation [yes]? yes
Would you like the vendor directory added to your .gitignore [yes]? yes
```

### 【2回目以降】

2回目以降は composer.json が存在するので以下のコマンドでパッケージをまとめてインストールする．

```bash
bash-5.0# composer install
```

### パッケージのインストール(追加)

新たにパッケージを追加したい場合は以下のコマンドを使う．
今回は overtrue/phplint をインストールしている．

```bash
bash-5.0# composer require overtrue/phplint
```

インストールがうまくいくと composer.json の `require` に overtrue/phplint が追加される．
また，vendorディレクトリが作成される．

```bash
bash-5.0# ls
Dockerfile     README.md      composer.json  composer.lock  vendor
```

試しにインストールした phplint を実行してみる．

```bash
bash-5.0# ./vendor/bin/phplint
phplint 2.0.2 by overtrue and contributors.

No config file loaded.

.......................................................    56 / 339 (16%)
........................................................   112 / 339 (33%)
........................................................   168 / 339 (49%)
........................................................   224 / 339 (66%)
........................................................   280 / 339 (82%)
........................................................   336 / 339 (99%)
....

Time: < 1 sec   Memory: 4.0 MiB Cache: No

OK! (Files: 339, Success: 339)
```

パッケージによっては拡張を必要とする場合がある．
その場合はDockerfileの `docker-php-ext-install` でパッケージを追加して再ビルドする．

### PHPファイルの作成/編集

ここでは vim を使う．ホストマシン側からVSCodeをはじめとするエディタや統合開発環境を使ってもよい．

```bash
bash-5.0# ls
Dockerfile     README.md      composer.json  composer.lock  vendor

bash-5.0# vim index.php
### PHPを記述

bash-5.0# cat index.php
<?php

phpinfo();
```

### 開発サーバの起動

以下のコマンドで開発サーバを起動する．

```bash
bash-5.0# php -S 0.0.0.0:8000

[Mon Dec 14 02:45:24 2020] PHP 7.4.13 Development Server (http://0.0.0.0:8000) started
[Mon Dec 14 03:03:26 2020] 172.17.0.1:57906 Accepted
[Mon Dec 14 03:03:26 2020] 172.17.0.1:57906 [200]: GET /
[Mon Dec 14 03:03:26 2020] 172.17.0.1:57906 Closing
[Mon Dec 14 03:03:27 2020] 172.17.0.1:57918 Accepted
[Mon Dec 14 03:03:27 2020] 172.17.0.1:57918 [404]: GET /favicon.ico - No such file or directory
[Mon Dec 14 03:03:27 2020] 172.17.0.1:57918 Closing
[Mon Dec 14 03:03:39 2020] 172.17.0.1:58018 Accepted
[Mon Dec 14 03:03:39 2020] 172.17.0.1:58018 [200]: GET /
[Mon Dec 14 03:03:39 2020] 172.17.0.1:58018 Closing
[Mon Dec 14 03:03:40 2020] 172.17.0.1:58030 Accepted
[Mon Dec 14 03:03:40 2020] 172.17.0.1:58030 [404]: GET /favicon.ico - No such file or directory
[Mon Dec 14 03:03:40 2020] 172.17.0.1:58030 Closing
```

コンテナの外部からアクセスする場合は `docker run -p 3000:8000` のようにdockerコマンドの `-p` オプションをつけておく．

今回は `-p 3000:8000` を付与したのでWebブラウザから http://<dockerが動いているマシンのIPアドレス>:3000/ にアクセスする．index.phpに記述した `phpinfo();` が実行されていることが確認できる．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/ee67907f-02cc-6a4a-6335-91c578cb5783.png)

Composerの使い方は以下の記事が参考になる．

[Composerの使い方 - Qiita](https://qiita.com/sano1202/items/50e5a05227d739302761#%E3%82%AA%E3%83%BC%E3%83%88%E3%83%AD%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0)