当 NGINX 无法访问应用程序文件时的 NGINX 配置,以及 php-fpm 和 docker
NGINX configuration when NGINX does not have access to the application files, along with php-fpm and docker
所以我的 docker 设置如下:我有一个接受 HTTP 请求的 Nginx 容器,我有另一个容器(我的自定义容器),其中有 php-fpm,我的应用程序代码。应用代码不在宿主机上,只在web容器中。
我想将 Nginx 配置为代理,以获取请求并将它们路由到 php-fpm。
我的 nginx 确认如下(我删除了一些不重要的部分):
upstream phpserver {
server web:9000;
}
server {
listen 443 ssl http2;
server_name app;
root /app/web;
ssl_certificate /ssl.crt;
ssl_certificate_key /ssl.key;
location ~ ^/index\.php(/|$) {
fastcgi_pass phpserver;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_read_timeout 160;
internal;
http2_push_preload on;
}
}
还有我的 docker 配置(同样,我删除了一些不重要的部分)
nginx:
ports:
- 443:443/tcp
- 80:80/tcp
image: nginx
links:
- web:web
web:
image: custom_image
container_name: web
使用此配置我得到以下 Nginx 错误:"open() "/app/web" failed (2: No such file or directory)", 因为 Nginx 无权访问该文件夹(该文件夹在 Web 容器中是 php-fpm 是)。
有没有一种方法可以配置 Nginx 来路由 HTTP 请求,即使它无权访问应用程序代码?
我知道解决此问题的方法之一是将应用程序代码挂载到 Nginx 容器,但我想尽可能避免这种情况。原因是在 swarm 模式下,如果两个容器不共享主机,那将无法工作。
我设法解决了这个问题,所以我在下面发布了我自己的解决方案,供有类似问题的人使用。
解决方案是在 nginx 配置中使用 'alias' 指令而不使用 'root' 指令(我已经删除了一些不重要的部分):
upstream phpserver {
server web:9000;
}
server {
listen 443 http2;
ssl on;
server_name app;
ssl_certificate /ssl.crt;
ssl_certificate_key /ssl.key;
location ~ ^/index\.php(/|$) {
alias /app/web;
fastcgi_pass phpserver;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
internal;
http2_push_preload on;
}
}
现在请求已正确路由到端口 9000 上的 php 服务器,并由 php fpm 在那里处理。 Php fpm 通过查看 'alias' 指令知道要执行哪个脚本。
现在的问题是如何提供静态文件。一种解决方案是也通过 php fpm 为它们提供服务,但根据我在网上阅读的内容,不推荐这样做,因为开销会更大。所以我的解决方案是与 nginx docker 容器共享所有静态文件,以便 ngnix 可以访问它们并可以直接为它们提供服务。如果有人对如何在这种情况下提供静态文件有更好的解决方案,请告诉我。
# Cache Control for Static Files
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
#access_log on;
#log_not_found off;
expires 360d;
}
所以我的 docker 设置如下:我有一个接受 HTTP 请求的 Nginx 容器,我有另一个容器(我的自定义容器),其中有 php-fpm,我的应用程序代码。应用代码不在宿主机上,只在web容器中。
我想将 Nginx 配置为代理,以获取请求并将它们路由到 php-fpm。
我的 nginx 确认如下(我删除了一些不重要的部分):
upstream phpserver {
server web:9000;
}
server {
listen 443 ssl http2;
server_name app;
root /app/web;
ssl_certificate /ssl.crt;
ssl_certificate_key /ssl.key;
location ~ ^/index\.php(/|$) {
fastcgi_pass phpserver;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_read_timeout 160;
internal;
http2_push_preload on;
}
}
还有我的 docker 配置(同样,我删除了一些不重要的部分)
nginx:
ports:
- 443:443/tcp
- 80:80/tcp
image: nginx
links:
- web:web
web:
image: custom_image
container_name: web
使用此配置我得到以下 Nginx 错误:"open() "/app/web" failed (2: No such file or directory)", 因为 Nginx 无权访问该文件夹(该文件夹在 Web 容器中是 php-fpm 是)。
有没有一种方法可以配置 Nginx 来路由 HTTP 请求,即使它无权访问应用程序代码?
我知道解决此问题的方法之一是将应用程序代码挂载到 Nginx 容器,但我想尽可能避免这种情况。原因是在 swarm 模式下,如果两个容器不共享主机,那将无法工作。
我设法解决了这个问题,所以我在下面发布了我自己的解决方案,供有类似问题的人使用。
解决方案是在 nginx 配置中使用 'alias' 指令而不使用 'root' 指令(我已经删除了一些不重要的部分):
upstream phpserver {
server web:9000;
}
server {
listen 443 http2;
ssl on;
server_name app;
ssl_certificate /ssl.crt;
ssl_certificate_key /ssl.key;
location ~ ^/index\.php(/|$) {
alias /app/web;
fastcgi_pass phpserver;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
internal;
http2_push_preload on;
}
}
现在请求已正确路由到端口 9000 上的 php 服务器,并由 php fpm 在那里处理。 Php fpm 通过查看 'alias' 指令知道要执行哪个脚本。
现在的问题是如何提供静态文件。一种解决方案是也通过 php fpm 为它们提供服务,但根据我在网上阅读的内容,不推荐这样做,因为开销会更大。所以我的解决方案是与 nginx docker 容器共享所有静态文件,以便 ngnix 可以访问它们并可以直接为它们提供服务。如果有人对如何在这种情况下提供静态文件有更好的解决方案,请告诉我。
# Cache Control for Static Files
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
#access_log on;
#log_not_found off;
expires 360d;
}