使用Nginx在同一域上服务React前端和PHP后端

时间:2018-09-23 23:49:01

标签: symfony nginx nginx-location

我有一个React前端和一个Symfony后端,我想在同一域中提供服务。如果有资产,React前端需要服务资产,否则会退回以服务index.html

/api在请求uri中时,我想提供php Symfony应用程序。与React应用类似,我需要所有请求才能转到index.php文件。

可以正确提供前端,但不能正确提供api。在浏览器中点击/api时,我从Nginx收到404。

我觉得我已经接近了,但是由于某种原因,nginx没有正确的$document_root。我正在添加标头(X-script)来测试变量是什么,并且得到以下信息:

X-script: /usr/share/nginx/html/index.php

这是我的Nginx配置。

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;
    }
}

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

Symfony 4项目的Web根目录必须包含public子文件夹。我没有使用NGINX,但我认为这是正确的配置:

location /api {
    root /var/www/my-site.com/backend/public;

答案 1 :(得分:0)

在以下虚拟主机中,我所做的最重要的更改是:

  • 在服务器块中注释了index指令:直接在位置块中处理
  • location /api/之后添加斜杠,并在同一 api位置块
  • 中删除不必要的$uri/
  • 将php_fpm逻辑移至index.php位置块:您希望将所有请求都传递到Symfony应用程序中的前端控制器
  • 出于相同的原因,将404逻辑移到了一个通用的php块,该块将处理任何其他php文件请求

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根指令中。

此虚拟主机在我的本地主机上使用以下树进行了很好的测试。

api_test
  - backend
    - index.php
  - frontend
    - index.html

我可以成功访问

    api_test.dv / api中的
  • backend/index.php
  • frontend/index.html来自api_test.dv /

答案 2 :(得分:0)

以上答案非常好,但是要使其完全起作用,需要在服务器下添加一个根指令,否则将出现错误消息“ primary script unknown”。这几乎总是与nginx fastcgi_param指令中错误设置的SCRIPT_FILENAME有关。

# Nginx configuration
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name ${NGINX_HOST};

    root /var/www/html/backend/public;

    access_log /var/log/nginx/access_log.log;
    error_log /var/log/nginx/error.log error;

    charset utf-8;

    location / {
        root /var/www/html/frontend/build;
        try_files $uri /index.html;
    }

    location /api {
        alias /var/www/html/backend/public;
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass php-fpm:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;

        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;
    }
}