docker-composeで、一つのWebサーバーコンテナ上に複数のLaravelアプリを立ち上げる

同じDBを参照する、2つのLaravelアプリをdocker-composeで立ち上げる方法について書いていきます。一つのWebサーバー上で2つのLaravelアプリが動いていて、それぞれが同じDBを見ている、といった構成です。

ググったらいくらでも出てくるかな？と思ったら、Laradocを使った方法しかなかったので意外でした。

## コンテナの構成

コンテナ関連のディレクトリ構成は、以下の記事を参考にしています。今回やることは、以下の記事のゴールの状態から、立ち上げるLaravelアプリを1つ追加する、みたいなイメージです。

[Laravelの開発環境をDockerを使って構築する](https://qiita.com/ucan-lab/items/17c806973e69792ada99)

## docker-compose.ymlを変更

webサーバーにnginxを使っている場合、docker-compose.ymlは以下のような記述になっているかと思います。

```docker:docker-compose.yml
version: "3"
services:
  app:
    context: ./docker/php
    // アプリコンテナの記述

  web:
    image: nginx:1.17-alpine
    depends_on:
      app
    // portsなどの記述
```

別のLaravelアプリを立ち上げる場合は、起動するアプリコンテナを一つ増やします。記述例としてはこんな感じ。

```docker:docker-compose.yml
version: "3"
services:
  app:
    context: ./docker/php
    // アプリコンテナの記述

  other:
    context: ./docker/php
    // アプリコンテナの記述

  web:
    image: nginx:1.17-alpine
    depends_on:
      app
      other
    ports:
      3500:80
      3501:79
    volumes:
      - ./app:/work/app
      - ./other:/work/other
      - ./logs:/var/log/nginx
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
```

これにより、docker-compose upを実行すると、otherコンテナが立ち上がります。参照するDockerfileは、appと同じものをにするか、新しく定義するかはお好みで。

また、nginxコンテナのdepends_onにotherコンテナを指定し、加えてportsの設定を一つ増やします。これにより、「localhost:3500」でサーバーコンテナの80番ポートに、「localhost:3501」で79番ポートにアクセスできるようになります。

あと、volumesにも変更を加えています。docker-compose.ymlがあるディレクトリの、app/配下がwebサーバーコンテナの/work/appに、other/配下が/work/otherに配置されるようにしています。

## default.confの変更

次に、nginxの設定ファイルを変更しています。変更前はこんな感じになっているはず。

```default.conf
server {
    listen 80;
    root /work/app/public;
    index index.php;
    charset utf-8;

    location / {
        root /work/app/public;
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /work/app/public/index.php;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
```

80番ポートにアクセスが来るとnginxがそれに対応する、みたいな標準的な設定です。80番ポートはapp/に配置されているLaravelアプリに対応するようになっています。

今回、otherコンテナに配置するLaravelアプリは79番ポートで受け付けられるようにするので、以下のように記述を追加します。

```default.conf
server {
  // 80番ポートの設定
}

server {
    listen 79;
    root /work/other/public;
    index index.php;
    charset utf-8;

    location / {
        root /work/other/public;
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass other:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /work/other/public/index.php;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
```

listenを79番に、rootを/work/other/publicに変更しています。docker-compose.ymlのvolumesに対応するようにrootを設定しましょう。（publicはLaravelの公開ディレクトリです）。

webサーバーコンテナの中が、/work/other/(Laravelのディレクトリ群)のような構成になることを想定した記述ですね。

また、「location ~ \.php」の中の記述も少し変更しています。

まず、「fastcgi_pass」がapp:9000から、other:9000になっています。app、otherはアプリコンテナのことで、PHP-FPMとの通信ポートをそれぞれ指定しています。

あと、「fastcgi_param SCRIPT_FILENAME」以下の記述も変更しており、Laravelアプリのpublicフォルダ内のindex.phpを参照するようにしています。ここがズレているとphpファイルが正しく読み込まれず、「File not Found」と表示されて悲しい気持ちになるので忘れずに変更しておいてください。

今回は直接パスを記述していますが、「\$document_root/index.php」みたいな書き方もあります。（$document_rootにはrootで指定したパスが入る）

これで、app/配下、other配下にLaravelをインストールし、.envやディレクトリの権限変更を正しく行えば、localhost:10080、localhost:10079にアクセスするとそれぞれLaravelのWelcomeページが表示されるはずです。

今回は、それぞれのアプリが同じDBを参照するようにしたいので、.envを変更して参照先が同じになるよう設定しておきましょう。

ページが表示されねぇ！みたいなときは、./logs配下のaccess.logやerror.logをヒントに対応してください。

## まとめ

docker-composeでバシッと環境が整うと気持ちいいですよね。nginxの設定は基本的なものだけしか記述していないので、勉強がてらいろいろイジり倒そうと思います。