PHPコンテナのDockerファイルでCMDを書くとnginxコンテナと接続できなくなった

Laravel、cron、nginx、nodeの環境を作ったら詰みかけた。

# 先に結論

`php:7.4-fpm-alpine`をベースイメージにして、`CMD`を書くと
`php-fpm`が起動されなくなる

作ったものはこちら
https://github.com/natsume0718/Docker_Laravel

# なにがおきたか
cronとphpを同一コンテナにいれたものと、nginxを接続しようとしたらできなかった。

nginx側で
`[emerg] host not found in upstream “app:9000”`と出てた。


##1.alpineでphp-fpmのDockerファイルをこんな感じで作った

Laravelが動くようにしたぐらいで変哲はない

```docker

FROM php:7.4-fpm-alpine

# 基本的なあれこれとgd,node,npm
RUN apk upgrade --update && \
    apk --no-cache --update add \
    icu-dev autoconf make g++ gcc bash git zip unzip vim\
    coreutils \
    freetype-dev \
    libjpeg-turbo-dev \
    libltdl \
    libmcrypt-dev \
    libpng-dev \
    oniguruma-dev \
    nodejs npm

# php extension
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd \
    bcmath opcache sockets pdo_mysql 

# install Composer
RUN curl -sS https://getcomposer.org/installer | php && \
    mv composer.phar /usr/local/bin/composer && \
    chmod +x /usr/local/bin/composer

# php ini
COPY ./php.ini /usr/local/etc/php/php.ini
```

##2.nginxはベースイメージをそのままつかって.`default.conf`だけいじった

```yaml

services:
  nginx:
    image: nginx:stable-alpine
    container_name: nginx
    ports:
      - ${APP_PORT:-80}:80
    volumes:
      - ./src:/var/www/html:cached
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    networks:
      - laravel

  app:
    container_name: app
    build:
      context: ./app
      dockerfile: Dockerfile
    volumes:
      - ./src:/var/www/html:cached
    environment:
      TZ: "Asia/Tokyo"
    networks:
      - laravel
```

下記の様にphpのコンテナのポート指定して接続していた

```conf:default.conf
# ~省略~
    location ~ \.php$ {
        fastcgi_pass app:9000; # php-fpm側のコンテナ:9000 
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
# ~省略~
```


**この時点まではnginxは問題なくPHPを表示できていました。**

# cronを入れたとたんうごかなくなるnginx

cronいれるというか最初から入ってるので、cronで動かす設定ファイルコピーして内容書き込み、最後に起動しているだけです。

```dockerfile
FROM php:7.4-fpm-alpine

# 基本的なあれこれとgd,node,npm,supervisor
RUN apk upgrade --update && \
    apk --no-cache --update add \
    icu-dev autoconf make g++ gcc bash git zip unzip vim\
    coreutils \
    freetype-dev \
    libjpeg-turbo-dev \
    libltdl \
    libmcrypt-dev \
    libpng-dev \
    oniguruma-dev \
    nodejs npm

# php extension
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd \
    bcmath opcache sockets pdo_mysql 

# install Composer
RUN curl -sS https://getcomposer.org/installer | php && \
    mv composer.phar /usr/local/bin/composer && \
    chmod +x /usr/local/bin/composer

# php ini
COPY ./php.ini /usr/local/etc/php/php.ini

# cronファイルコピーして、内容を書き込む
COPY ./laravel-crontab /var/spool/cron/crontabs/
RUN cat /var/spool/cron/crontabs/laravel-crontab >> /var/spool/cron/crontabs/root

CMD ["/usr/sbin/crond"]
```

が、nginxでPHPが動作しているページを開くと

`502 Bad Gateway`

エラーログを調べると

`[emerg] host not found in upstream “app:9000”`

# 原因を探す

ググってると似たような状態にいる人を発見する

cronを追加した途端動かなくなったとのこと。
https://stackoverflow.com/questions/62752220/laravel-docker-cron-nginx-502-bad-gateway-issue-111-connection-refused-while

`CMD cron && docker-php-entrypoint php-fpm`で解決しましたとある。

`docker-php-entrypoint`コマンドは何者...?という疑問になり調べると

下記のようなのが見つかり、もともと知らぬ間に`docker-php-entrypoint php-fpm`というのを実行していたとのこと。
https://qiita.com/shim-hiko/items/653059fab63af962a21f

んでこのコマンドはphp-fpmをデーモン化してくれていたらしい...

# どう対処したか

supervisor入れて、cronとphpをデーモン化して、CMDではsupervisorの起動をするようにしました
[色々対応方法](https://qiita.com/YuukiMiyoshi/items/bb7f14436d60d4bd8a8b)あるっぽいけど、Laravelのキューでsupervisor使うのでまあ良いかって感じです

もっと良い対処法あれば知りたいです

```conf

[supervisord]
nodaemon=true
logfile=/var/log/jobschedule/supervisord.log
pidfile=/var/log/jobschedule/supervisord.pid

[program:php-fpm]
command = /usr/local/bin/docker-php-entrypoint php-fpm -D
autostart = true

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work database --tries=1 --sleep=3
autostart=true
autorestart=true
user=root
numprocs=8
redirect_stderr=true
stdout_logfile=/var/log/jobschedule/worker.log
stopwaitsecs=3600

[program:crond]
command = /usr/sbin/crond
user = root
autostart = true
stdout_logfile=/var/log/jobschedule/cron.log
```