php - 502 Bad Gateway - Google Cloud 在冷启动时使用 php-fpm(未找到套接字)运行
问题描述
我正在处理一个问题,即对我的 Google Cloud Run 容器的第一个请求导致 502 Bad Gateway 错误。在日志中可以看到以下内容:
[crit] 23#23: *3 connect() to unix:/run/php/php7.4-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 169.254.8.129, server: domain.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:", host: "my.domain.com"
但是,在第二个请求上它工作正常。
我将 supervisord 与 php-fpm 和 nginx 一起使用。
Dockerfile
FROM php:7.4-fpm
ENV COMPOSER_MEMORY_LIMIT='-1'
RUN apt-get update && \
apt-get install -y --force-yes --no-install-recommends \
nginx \
supervisor \
libmemcached-dev \
libzip-dev \
libz-dev \
libzip-dev \
libpq-dev \
libjpeg-dev \
libpng-dev \
libfreetype6-dev \
libssl-dev \
openssh-server \
libmagickwand-dev \
git \
cron \
nano \
libxml2-dev \
libreadline-dev \
libgmp-dev \
mariadb-client \
unzip
RUN docker-php-ext-install exif zip pdo_mysql intl
#####################################
# PHPRedis:
#####################################
RUN pecl install redis && docker-php-ext-enable redis
#####################################
# Imagick:
#####################################
RUN pecl install imagick && \
docker-php-ext-enable imagick
#####################################
# PHP Memcached:
#####################################
# Install the php memcached extension
RUN pecl install memcached && docker-php-ext-enable memcached
#####################################
# Composer:
#####################################
# Install composer and add its bin to the PATH.
RUN curl -s http://getcomposer.org/installer | php && \
echo "export PATH=${PATH}:/var/www/vendor/bin" >> ~/.bashrc && \
mv composer.phar /usr/local/bin/composer
# Source the bash
RUN . ~/.bashrc
#####################################
# Laravel Schedule Cron Job:
#####################################
# RUN echo "* * * * * www-data /usr/local/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1" >> /etc/cron.d/laravel-scheduler
# RUN chmod 0644 /etc/cron.d/laravel-scheduler
#
#--------------------------------------------------------------------------
# NGINX
#--------------------------------------------------------------------------
#
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
ADD infrastructure/nginx/nginx.conf /etc/nginx/sites-available/default
ADD infrastructure/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
#
#--------------------------------------------------------------------------
# Move config files
#--------------------------------------------------------------------------
#
ADD ./infrastructure/php/php.ini /usr/local/etc/php/conf.d/php.ini
ADD ./infrastructure/php/php-fpm.conf /usr/local/etc/php-fpm.d/zz-docker.conf
#
#--------------------------------------------------------------------------
# Ensure fpm socket folder is present
#--------------------------------------------------------------------------
#
RUN mkdir -p /run/php/
RUN rm -r /var/lib/apt/lists/*
RUN usermod -u 1000 www-data
COPY ./infrastructure/entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
RUN ln -s /usr/local/bin/entrypoint.sh /
ENTRYPOINT ["entrypoint.sh"]
WORKDIR /var/www
COPY . .
RUN chown -R www-data:www-data /var/www
RUN composer install
EXPOSE 8000
入口点.sh
#!/bin/bash
# Start the cron service.
service cron start
##
# Run artisan migrate
##
php artisan migrate
##
# Run a command or start supervisord
##
if [ $# -gt 0 ];then
# If we passed a command, run it
exec "$@"
else
# Otherwise start supervisord
/usr/bin/supervisord
fi
Nginx.conf
server {
listen 8000 default_server;
root /var/www/public;
index index.html index.htm index.php;
server_name my.domain.com;
charset utf-8;
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; }
# Remove index.php$
if ($request_uri ~* "^(.*/)index\.php/*(.*)") {
return 301 $1$2;
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_buffering off;
fastcgi_index index.php;
include fastcgi_params;
}
error_page 404 /index.php;
}
phpfpm 自定义配置
[global]
daemonize = no
[www]
listen = /run/php/php7.4-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
监督者
[supervisord]
nodaemon=true
user=root
[program:nginx]
command=nginx -g "daemon off;"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:php-fpm]
command=php-fpm
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
解决方案
冷启动的 Cloud Run 容器需要执行多项任务,然后才能根据文档处理请求。这可能是第一个请求失败的原因,而后续请求得到了正确处理:
启动例程包括:启动服务、启动容器、运行 entrypoint 命令启动服务器、检查开放的服务端口
同一文档页面提供了一些技巧来避免冷启动和提高容器启动性能,特别是设置一些始终处于空闲状态的最小实例。由于 Cloud Run 可以缩减到 0 个实例,这将在没有活动实例时创建冷启动。
nginx.conf
至于日志中的具体错误消息,根据此相关线程,您的文件中的路径似乎可能是错误的。根据线程,路径fpm
应该是:
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; //with your specific fpm version
推荐阅读
- javascript - 使用js中的.parentElement方法返回未定义
- java - 无论如何要修复android 4.x上的ssl握手错误,SSL库协议错误失败
- c - 执行此程序时,char 函数会返回变量。我不知道为什么?
- node.js - 如何使用 Express 设置我的 sitemap.xml 的“X-Robots-Tag”
- c# - 在 Visual Studio (.NET Core) 的输出窗口中从堆栈跟踪转到行
- javascript - 在 vue cli3 项目中包含我自己的 js 和 css 文件
- javascript - eslint+ 流:道具验证中缺少“属性”(带有标识符的对象)
- python-3.x - 从数千张图片中快速检索exif数据——优化功能
- zend-framework - 有没有办法将zend日志的时间戳更改为unix
- arduino - 如何在 UART 上接收多条消息?