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が動くようにしたぐらいで変哲はない
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
だけいじった
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のコンテナのポート指定して接続していた
# ~省略~
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で動かす設定ファイルコピーして内容書き込み、最後に起動しているだけです。
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の起動をするようにしました
色々対応方法あるっぽいけど、Laravelのキューでsupervisor使うのでまあ良いかって感じです
もっと良い対処法あれば知りたいです
[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