Docker環境でcomposerのimageつかってupdateしてみる

docker環境で、composerを使用する場合、phpのDockerfile内でcomposerコマンドをインストールして、composer installや、composer updateしてる人多いと思いますが（僕もそうでした。。）、composerのイメージが存在するので、今回はcomposer updateだけをするコンテナ作って動かしてみました。

https://hub.docker.com/_/composer

# 構成
mac OS Mojave
php:7.3-apache
composer:1.9.0


# まずは、完成したものからみてみる

### ディレクトリ構成
docker/php/Dockerfile これ、正直docker-compose.ymlだけで表現できる内容なのですが、実際の現場だとDockerfile内にいろいろ記述するケースが多いので、わざわざファイル作ってます。

```
$ tree
.
├── app
│   └── composer.json
├── docker
│   └── php
│       └── Dockerfile
└── docker-compose.yml
```

### docker-compose.yml
```docker-compose.yml
version: "3.3"

services:
  php:
    build: ./docker/php
    volumes:
      - ./app:/var/www/html/
    ports:
      - "8010:80"
  composer:
    image: composer:1.9.0
    command: 'composer update'
    volumes: 
      - ./app:/app
    links:
      - php
```

### docker/php/Dockerfile
```Dockerfile
FROM php:7.3-apache

CMD ["apache2-foreground"]
```


# 実際に動かしてみる
上記のdocker composeファイルを使って実際に起動してみましょう。

## composer.jsonをつくる
appフォルダにcdして、composer.jsonを作成しましょう。
composer initすると対話形式でいろいろ聞かれますが、今回は基本デフォルトのままで作成します。

```console
$ cd app
$ composer init

                                            
  Welcome to the Composer config generator  
                                            


This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [yuya.sega/app]: php-composer/docker
Description []: composerをdockerイメージ使ってupdateする
Author [yuya.sega <sega@sorich.jp>, n to skip]: 
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]? 
Search for a package: 
Would you like to define your dev dependencies (require-dev) interactively [yes]? 
Search for a package: 

{
    "name": "php-composer/docker",
    "description": "composerをdockerイメージ使ってupdateする",
    "authors": [
        {
            "name": "yuya.sega",
            "email": "sega@sorich.jp"
        }
    ],
    "require": {}
}

Do you confirm generation [yes]? 
```

そうすると、app/composer.jsonが作成されます。

## composerでおとしてくるライブラリをかく

試しに、laravelフレームワークをcomposerでおとしてくるようにcomposer.jsonを書き換えます。
実際に書き換えたのは、requireの`laravel/framework": "6.0.*`としている部分だけです。

```json
{
    "name": "php-composer/docker",
    "description": "composerをdockerイメージ使ってupdateする",
    "authors": [
        {
            "name": "yuya.sega",
            "email": "sega@sorich.jp"
        }
    ],
    "require": {
        "laravel/framework": "6.0.*"
    }
}
```

## よし、upする。

```console
$ docker-compose build && docker-compose up
Building php
Step 1/2 : FROM php:7.3-apache
 ---> 406c73effb13
Step 2/2 : CMD ["apache2-foreground"]
 ---> Using cache
 ---> 832fb1c3e525

Successfully built 832fb1c3e525
Successfully tagged php-composer_php:latest
Creating network "php-composer_default" with the default driver
Creating php-composer_php_1 ... done
Creating php-composer_composer_1 ... done
Attaching to php-composer_php_1, php-composer_composer_1
php_1       | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.176.2. Set the 'ServerName' directive globally to suppress this message
php_1       | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.176.2. Set the 'ServerName' directive globally to suppress this message
php_1       | [Tue Sep 24 02:52:09.788930 2019] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Debian) PHP/7.3.3 configured -- resuming normal operations
php_1       | [Tue Sep 24 02:52:09.789086 2019] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
composer_1  | Loading composer repositories with package information
composer_1  | Updating dependencies (including require-dev)
composer_1  | Package operations: 40 installs, 0 updates, 0 removals
composer_1  |   - Installing symfony/polyfill-ctype (v1.12.0): Downloading (100%)  

~~ 略 ~~

composer_1  | Writing lock file
composer_1  | Generating autoload files
php-composer_composer_1 exited with code 0
```

exit codeが0で正常終了しましたね。

立ち上がったコンテナをpsしてみると、たしかにcomposerのコンテナは終了してますので、以後の動作が遅くなったり重くなったりしなくていいですね

```console
$ docker-compose ps
         Name                        Command               State           Ports        
----------------------------------------------------------------------------------------
php-composer_composer_1   /bin/sh /docker-entrypoint ...   Exit 0                       
php-composer_php_1        docker-php-entrypoint apac ...   Up       0.0.0.0:8010->80/tcp
```


# 少し解説

### docker-compose.yml#composer:
実際にcomposerでしたいことをdocker-compose.yml内のcommandに記述してます。
もちろんupdateだけでなくinstallや、他のコマンドも指定できます。

```console
command: 'composer update'
```

# さいごに
いままで、phpコンテナのDockerfileにcomposerコマンドのインストール等を行ってました。
ですがcomposer専用のコンテナを用意し、実行することで、Dockerfileもスッキリして気持ちいいし、buildも実際早くなってると思うので、みなさんも是非やってみて欲しいです。