使用 nginx 在同一域上提供反应前端和 php 后端
我有一个 React 前端和一个 Symfony 后端,我正试图在同一个域上提供服务.React 前端需要提供资产(如果存在),否则回退以提供 index.html
.
I have a React frontend and a Symfony backend I'm trying to serve on the same domain. The React frontend needs to serve assets if they exist otherwise fallback to serve index.html
.
当 /api
在请求 uri 中时,我想为 php Symfony 应用程序提供服务.与 React 应用程序类似,我需要所有请求都转到 index.php
文件.
I'd like to serve the php Symfony app when /api
is in the request uri. Similar to the React app, I need all requests to go to the index.php
file.
前端服务正确,但 api 服务不正确.当我在浏览器中点击 /api
时,我从 nginx 得到 404.
The frontend is being served correctly but not the api. I get a 404 from nginx when i hit /api
in the browser.
我觉得我很接近但是由于某种原因nginx没有正确的$document_root
.我正在添加一个标题(X-script
)来测试变量是什么,我得到以下内容:
I feel like i'm close but for some reason nginx doesn't have the correct $document_root
. I'm adding a header(X-script
) to test what the variables are and I'm getting the following:
X-script: /usr/share/nginx/html/index.php
这是我的 nginx 配置.
Here's my nginx config.
server {
listen 80 default_server;
index index.html index.htm;
access_log /var/log/nginx/my-site.com.log;
error_log /var/log/nginx/my-site.com-error.log error;
charset utf-8;
location /api {
root /var/www/my-site.com/backend;
try_files $uri $uri/ /index.php$is_args$args;
}
location / {
root /var/www/my-site.com/frontend;
try_files $uri /index.html;
}
location ~* \.php$ {
add_header X-script "$document_root$fastcgi_script_name" always;
try_files $fastcgi_script_name =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
任何帮助将不胜感激.
在以下 vhost 中,我所做的最重要的更改是:
In the following vhost, the most important changes I made are :
- 在 server 块中注释掉
index
指令:它直接在 location 块中处理 - 在
location/api/
之后添加了一个斜杠,并在同一个 api location 块中删除了不必要的$uri/
- 将 php_fpm 逻辑移动到
index.php
位置块:您希望所有请求都传递到 Symfony 应用程序中的前端控制器 - 出于同样的原因,将 404 逻辑移至通用 php 块,该块将处理任何其他 php 文件请求
- commented out
index
directive in server block : it is handled directly in locations blocks - added a slash after
location /api/
and remove unnecessary$uri/
in the same api location block - moved the php_fpm logic to
index.php
location block : you want all requests to be passed to front controller in Symfony app - For the same reason, moved the 404 logic to a general php block, which will handle any other php file request
server {
listen 80 default_server;
access_log /var/log/nginx/my-site.com.log;
error_log /var/log/nginx/my-site.com-error.log error;
charset utf-8;
location /api/ {
root /var/www/my-site.com/backend;
try_files $uri /index.php$is_args$args;
}
location / {
root /var/www/my-site.com/frontend;
try_files $uri /index.html;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param HTTPS off;
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
最后,我敢打赌你必须将 symfony 公共文件夹添加到 api location block
根指令中.
Last, I bet you'll have to add symfony public folder into api location block
root directive.
这个虚拟主机在我的本地主机上通过以下树进行了良好的测试.
This vhost was tested fine on my localhost with following tree.
api_test
- backend
- index.php
- frontend
- index.html
我可以成功访问
-
backend/index.php
来自 api_test.dv/api -
frontend/index.html
来自 api_test.dv/
-
backend/index.php
from api_test.dv/api -
frontend/index.html
from api_test.dv/