Nginx 的安装比 PHP 容易得多,所以你应该更容易将 Nginx 安装到一个现成的官方 PHP 映像中。下面是一个 Dockerfile 示例,展示了如何通过安装一些 PHP 扩展的示例来实现您的目标:
FROM php:7.2-fpm
RUN apt-get update -y \
&& apt-get install -y nginx
# PHP_CPPFLAGS are used by the docker-php-ext-* scripts
ENV PHP_CPPFLAGS="$PHP_CPPFLAGS -std=c++11"
RUN docker-php-ext-install pdo_mysql \
&& docker-php-ext-install opcache \
&& apt-get install libicu-dev -y \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl \
&& apt-get remove libicu-dev icu-devtools -y
RUN { \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
echo 'opcache.enable_cli=1'; \
} > /usr/local/etc/php/conf.d/php-opocache-cfg.ini
COPY nginx-site.conf /etc/nginx/sites-enabled/default
COPY entrypoint.sh /etc/entrypoint.sh
COPY --chown=www-data:www-data . /var/www/mysite
WORKDIR /var/www/mysite
EXPOSE 80 443
ENTRYPOINT ["/etc/entrypoint.sh"]
nginx-site.conf 文件包含您的 Nginx http 主机配置。以下示例适用于 Symfony 应用程序:
server {
root /var/www/mysite/web;
include /etc/nginx/default.d/*.conf;
index app.php index.php index.html index.htm;
client_max_body_size 30m;
location / {
try_files $uri $uri/ /app.php$is_args$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_index app.php;
include fastcgi.conf;
}
}
entrypoint.sh 会在容器启动时运行 Nginx 和 php-fpm(否则只会启动 php-fpm 作为官方 PHP 镜像的默认操作):
#!/usr/bin/env bash
service nginx start
php-fpm
当然,从最佳实践的角度来看,这不是最好的方法,但我希望这是您问题的答案。
更新:
如果您在 entrypoint.sh 文件上收到权限被拒绝错误,如果您是在 Linux 下构建,请检查此文件是否具有可执行权限,或者如果您在 Windows 下,请将 RUN chmod +x /etc/entrypoint.sh 添加到 Dockerfile ( Windows 下的所有文件都在没有容器可执行权限的情况下复制。
如果您在 Google Cloud Run 下运行,请记住 Nginx 在 PHP 之前启动,它比 PHP 快得多。这就导致了Cloud Run发送第一个请求的时候,Nginx已经初始化了,但是PHP-FPM还没有,Cloud Run请求失败。要解决这个问题,您应该将入口点更改为在 Nginx 之前启动 PHP-FPM:
#!/usr/bin/env sh
set -e
php-fpm -D
nginx -g 'daemon off;'
此脚本仅在 Alpine Linux 下进行测试。我想它也应该适用于其他图像。该脚本首先在后台运行 php-fpm,然后在不退出的情况下运行 Nginx。这样,Nginx 总是在 PHP-FPM 初始化后开始监听端口。