nginx 和 fastcgi 的两个文档根目录

Two document roots with nginx and fastcgi

我在 docker 环境中使用 nginx 和 php,它适用于单个应用程序。现在我想开发一个基于 yii2/php 作为后端和 angular 作为前端的应用程序,所以我需要一个为客户端服务的网络服务器,另一个为 API 后端服务。目录结构如下:

/var/www/html/ $ tree -L 3
.
├── client
│   ├── dist
│   │   ├── 0.chunk.js
│   │   ├── 0.chunk.js.map
│   │   ├── assets
│   │   ├── index.html
│   │   ├── ...
│   ├── e2e
│   │   ├── ...
│   ├── node_modules
│   │   ├── ...
├── docker
│   ├── mysql
│   │   ├── Dockerfile
│   │   └── my.cnf
│   ├── nginx
│   │   ├── Dockerfile
│   │   └── default.conf
│   └── php7
│       └── Dockerfile
├── docker-compose.yml
└── server
    ├── api
    │   ├── common
    │   ├── config
    │   ├── modules
    │   └── web
    │   │   └── index.php 
    ├── common
    ├── composer.json
    ├── console
    └── vendor

前端应用程序位于`/var/www/html/client/dist/,nginx 配置如下:

server {
    listen 80 default_server;
    root /var/www/html/client/dist/;
    index index.html index.php;

    charset utf-8;

    location / {
            # Redirect everything that isn't a real file to index.php
            try_files $uri $uri/ /index.php$is_args$args;
        }

    location /api {
        root /var/www/html/server/api/web/;
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    sendfile off;

    client_max_body_size 100m;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_read_timeout 300s;
    }

    location ~ /\.ht {
        deny all;
    }
}

使用此配置,前端工作 (URL: /),但 API 不工作。我需要的是:

请求“/”:从 /var/www/html/client/dist/ 提供 angular 应用程序 请求“/api”:使用 index.php from /var/www/html/server/api/web/

如何配置?谢谢。

//编辑:新配置文件:

server {
    listen 80 default_server;
    root /var/www/html/client/dist/;
    index index.html;

    charset utf-8;

    location ~ ^/api(.*) {
        alias /var/www/html/server/api/web/;

        # Redirect everything that isn't a real file to index.php
        try_files $uri $uri/ /index.php$args;
        index index.php;

        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass php:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_intercept_errors off;
            fastcgi_buffer_size 16k;
            fastcgi_buffers 4 16k;
            fastcgi_read_timeout 300s;
        }

        location ~ /\.ht {
            deny all;
        }
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

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

    sendfile off;

    client_max_body_size 100m;
}

调用 http://localhost/api/v1/users 应该被重定向到 /var/www/html/server/api/web/index.php 以 v1/users 作为参数(或者 Yii2 处理漂亮的 URLs),但是returns 未找到 404。

错误日志显示此消息,因此看起来别名指令未生效:

2017/07/11 16:51:57 [error] 5#5: *1 open() "/var/www/html/client/dist/index.php" failed (2: No such file or directory), client: 172.17.0.1, server: , request: "GET /api/v1/users HTTP/1.1", host: "localhost"

不确定您需要将漂亮的 URI 重写成什么,但您需要使用包含 /api 前缀的 index.php 的 URI。

alias directive works best with a prefix location,否则需要用捕获的变量构造路径

例如:

location ^~ /api/ {
    alias /var/www/html/server/api/web/;

    index index.php;

    if (!-e $request_filename) { 
        rewrite ^/api(.*) /api/index.php?uri= last;
    }

    location ~ \.php$ {
        if (!-f $request_filename) { return 404; }

        fastcgi_pass php:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_read_timeout 300s;
    }

    location ~ /\.ht {
        deny all;
    }
}