LoginSignup
21
15

More than 3 years have passed since last update.

Docker Composeでdocker multi stage buildをつかってみた

Posted at

少し前に、Docker環境でcomposerのimageつかってupdateしてみるの記事を書かせていただきましたが、この構成だと、docker-compose upの際に毎回composer updateが実行されて、時間かかって嫌だなぁと思ってました。。

その問題を解消するために、今回はDocker multi stage buildを使ってcomposer updateの起動タイミングを制御してみようと思います。

一式をGitHubに公開してますので、是非。
https://github.com/yuya-sega/docker-multi-stage-build-sample

まず、できたものみてみる

docker/php/Dockerfile

今回作成したDockerfileはこちらです。
FROMが2つありますが、devとしてaliasつけているのが普段、開発で使用することを想定してるステージです。
composerとしてaliasつけているのが、composer updateを実行したいときに使用するステージです。

FROM php:7.3-apache AS dev

CMD ["apache2-foreground"]

FROM dev AS composer

RUN apt-get update && apt-get install -y zip unzip
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer

CMD ["composer", "update", "--no-plugins", "--no-scripts"]
docker-compose.yml

Docker Composeファイルで主に注目すべきは、target: ${PHP_CONTAINER_BUILD_TARGET}の部分です。targetに、先程Dockerfile内で命名したalias名を指定することによって、ビルド時のステージを切り替えることが可能となります。

version: "3.7"

services:
  php:
    build: 
      context: .
      dockerfile: ./docker/php/Dockerfile
      target: ${PHP_CONTAINER_BUILD_TARGET}
    volumes:
      - ./app:/var/www/html/
    ports:
      - "8010:80"
.env

docker-compose.ymlで参照している変数は、envファイルに定義してあります。

PHP_CONTAINER_BUILD_TARGET=composer

実際に動かしてみる

PHP_CONTAINER_BUILD_TARGET=composerで動かす

composerを実行して動かす場合、up後コンテナは正常終了します。
するとapp配下にvenderフォルダなどが生成され、必要なライブラリがダウンロード完了した状態となります。

$ docker-compose build && docker-compose up
Building php
Step 1/7 : FROM php:7.3-apache AS dev
 ---> 406c73effb13
Step 2/7 : CMD ["apache2-foreground"]
 ---> Running in 68f88f2b3ab8
Removing intermediate container 68f88f2b3ab8
 ---> f55426e4e3d8

Step 3/7 : FROM dev AS composer
 ---> f55426e4e3d8
Step 4/7 : RUN apt-get update && apt-get install -y zip unzip
 ---> Running in 1b2252f6568b
Get:1 http://security-cdn.debian.org/debian-security stretch/updates InRelease [94.3 kB]

~~ 略 ~~

php_1  | Writing lock file
php_1  | Generating autoload files
docker-multi-stage-build-sample_php_1 exited with code 0
$

PHP_CONTAINER_BUILD_TARGET=devで動かす

次に、.envファイルのPHP_CONTAINER_BUILD_TARGETcomposerからdevに書き換えます。
起動する際は、再度docker-compose buildを実行する必要がありますのでご注意ください。

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

Successfully built f55426e4e3d8
Successfully tagged docker-multi-stage-build-sample_php:latest
Recreating docker-multi-stage-build-sample_php_1 ... done
Attaching to docker-multi-stage-build-sample_php_1
php_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.16.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.16.2. Set the 'ServerName' directive globally to suppress this message
php_1  | [Thu Sep 26 05:44:39.139258 2019] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Debian) PHP/7.3.3 configured -- resuming normal operations
php_1  | [Thu Sep 26 05:44:39.139583 2019] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

実行すると、コンテナは起動状態を維持したまま作業が進められます!
これで、何度コンテナをupしても、composer updateが実行されず、up時間を短縮することができました

少し解説

FROM dev AS composer

ここでは、エイリアス名devで作成したステージをベースに、別のステージをつくるような指定となっています。
今回はわざわざcomposerのイメージを落としてくる必要もないと考え、このようにしてますが、以下のようにしてDockerfileをシンプルに書くことも可能です。

FROM php:7.3-apache AS dev

CMD ["apache2-foreground"]

FROM composer:1.9.0 AS composer
WORKDIR /var/www/html
CMD ["composer", "update"]

composerステージbuildしたあと、devステージでもbuildしなきゃいけない

PHP_CONTAINER_BUILD_TARGET=composerdocker-compose build && docker-compose upした後、
PHP_CONTAINER_BUILD_TARGET=devdocker-compose build && docker-compose upしなければならない手順なのですが、devのビルド時は、composerでのビルドの際にできたキャッシュを利用したビルドとなるので、ビルドに時間がかからないため、今回はよしとしました。

Building php
Step 1/2 : FROM php:7.3-apache AS dev
 ---> 406c73effb13
Step 2/2 : CMD ["apache2-foreground"]
 ---> Using cache  ← キャッシュ使ってますね!
 ---> f55426e4e3d8

課題

いくつか課題残ってると思うので、以下に箇条書きしてきます。

  • 必要なときにcomposer updateしわすれるんじゃないか。。
  • .envをいちいち書き換えるのがめんどくさい

さいごに

multi stage buildは触ってみて全然難しいものでないと感じたので、今後はどんどん活用していきたいです。

21
15
1

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
21
15