I am using nginx and php in a docker-environment, which works fine for a single application. Now I want to develop an application based in yii2/php as backend and angular as frontend, so I need one webserver serving the client, and another one serving the API backend. The directory structure looks as follows:
/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
The frontend application is located in `/var/www/html/client/dist/, the nginx config looks as follows:
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;
}
}
Using this config, the frontend works (URL: /), however the API does not. What I need is:
Request "/": serve the angular app from /var/www/html/client/dist/
Request "/api": use index.php
from /var/www/html/server/api/web/
How to configure this? Thank you.
//Edit: New configuration file:
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$1$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;
}
Calling http://localhost/api/v1/users should be redirected to /var/www/html/server/api/web/index.php with v1/users as parameter (or however Yii2 handles the pretty URLs), but returns a 404 not found instead.
Error Log shows this message, so it looks like the alias directive is not taking effect:
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"
Not exactly sure what you need to rewrite the pretty URIs to, but you need to use the URI of
index.php
which includes the/api
prefix.The
alias
directive works best with a prefixlocation
, otherwise you will need to construct the path with captured variables.For example: