My folder structure is as follows:
/www
/api.domain.tld
/app.domain.tld
The API contains the system it self and APP implements the API via HTTP.
I want to create an Nginx server for app.domain.tld that also contains an "virtual directory" for API.
You can contact the API likes this: http://api.domain.tld/method/api.json
But it would be great if the API can be contacted like this also: http://app.domain.tld/api/method/api.json without copying something into APP, but keep those two "systems" separated.
What I have for now:
server {
listen 80;
root /var/www/app.domain.tld;
index index.php index.html;
server_name app.domain.tld;
location ^~ /api {
alias /var/www/api.domain.tld;
location ~ \.php$ {
try_files $uri = 404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
rewrite ^/api/([a-z]+)/api.json$ /api.php?method=$1 last;
}
location....
location....
location....
location ~ \.php$ {
try_files $uri = 404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Unfortunately this does now works as expected.
The rewrite does not work at all. I can get api.domain.tld/index.php but when it needs to use the rewrite, it will not work.
I have tried several things. Either I get 404 or 403 with this error:
directory index of [path] is forbidden
Can someone come up with a better solution that actually works?
Regards
You should change SCRIPT_FILENAME path:
server {
listen 80;
root /var/www/app.domain.tld;
index index.php index.html;
location ~ ^/api/(.+\.php)$ {
alias /www/api.domain.tld/public/$1;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
}
Related
lets say I've a path like:
/var/www/myside/
that path contains two folders... let's say
/static and /manage
I'd like to configure nginx to have an access to:
/static folder on / (eg. http://example.org/)
this folder has some .html files.
/manage folder on /manage (eg. http://example.org/manage) in this case this folder contains Slim's PHP framework code - that means the index.php file is in public subfolder (eg. /var/www/mysite/manage/public/index.php)
I've tried a lot of combinations such as
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite;
location /manage {
root $uri/manage/public;
try_files $uri /index.php$is_args$args;
}
location / {
root $uri/static/;
index index.html;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
The / works correctly anyway manage doesn't. Am I doing something wrong? Does anybody know what should I change?
Matthew.
To access a path like /var/www/mysite/manage/public with a URI like /manage, you will need to use alias rather than root. See this document for details.
I am assuming that you need to run PHP from both roots, in which case you will need two location ~ \.php blocks, see example below. If you have no PHP within /var/www/mysite/static, you can delete the unused location block.
For example:
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite/static;
index index.html;
location / {
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location ^~ /manage {
alias /var/www/mysite/manage/public;
index index.php;
if (!-e $request_filename) { rewrite ^ /manage/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
}
The ^~ modifier causes the prefix location to take precedence over regular expression locations at the same level. See this document for details.
The alias and try_files directives are not together due to this long standing bug.
Be aware of this caution in the use of the if directive.
I'm trying to host a symfony app in a virtual folder and using url rewriting with nginx.
Following various examples I found, I'm stuck with something like that:
upstream phpfcgi {
server unix:/var/run/php5-fpm.sock;
}
server {
listen 443;
server_name localhost;
root /realpath/Symfony/web/;
[ssl stuff]
# strip app.php/ prefix if it is present
rewrite ^/app_dev\.php/?(.*)$ /$1 permanent;
location /virtual{
alias /realpath/Symfony/web/;
index app_dev.php;
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^/virtual/(.*)$ /app_dev.php/$1 last;
}
# pass the PHP scripts to FastCGI server from upstream phpfcgi
location ~ ^/(app|app_dev|config)\.php(/|$) {
fastcgi_pass phpfcgi;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
}
}
If I remove the /virtual from the two first locations , it's working fine.
Should I set the SCRIPT_URI on the third location?
Thanks for your help
Here is the solution, see the added line:
location ~ ^/(app|app_dev|config)\.php(/|$) {
fastcgi_pass phpfcgi;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Add this line:
fastcgi_param SCRIPT_NAME /virtual$fastcgi_script_name;
fastcgi_param HTTPS on;
}
I try to make my production server to serve my applications in a same style as phpmyadmin is served. Like example.com/phpmyadmin and what I try to do is example.com/myappname.
My nginx/sites-available/default looks like this:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www;
index index.html index.htm index.php;
server_name _;
location ~ \.php$ {
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location /myapp {
root /var/www/myapp/public/;
index index.php;
}
location /phpmyadmin {
root /usr/share/;
index index.php index.html index.htm;
location ~ ^/phpmyadmin/(.+\.php)$ {
try_files $uri =404;
root /usr/share/;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /usr/share/;
}
}
location /phpMyAdmin {
rewrite ^/* /phpmyadmin last;
}
location ~ /\.ht {
deny all;
}
}
So if someone has a working conf for this, I would like to have it too!
Notice that your /phpmyadmin location has extra configuration to pass the request to PHP-FPM via the fast_cgi configurations.
You'll need to do that for your /myapp location as well.
You may want to change your myapp location to something like this:
location ^/myapp/(.+\.php)$ {
root /var/www/myapp/public/;
index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
}
For comparison, here is my Laravel nginx configuration - however I don't have my app running under a "sub-directory".
Try changing some configuration items to see what you can get to work. Note that I removed fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; from the Laravel app location - I dont believe it is necessary.
Lastly, would this make more sense on ServerFault? You may get better answers there.
Let's say I have a nginx configuration set up for a domain like this:
server {
root /path/to/one;
server_name one.example.org;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Now, if I want to add another domain with different content, is there a way I can re-use equivalent statements from the previous domain, or do I have to duplicate everything for every new domain I want to support?
server {
root /path/to/two; # different
server_name two.example.org; # different
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I tried moving the location directive outside the server closure, but obviously things don't work like that because I got an error "location directive is not allowed here" when restarting nginx.
This is a good example to use nginx Map module. http://wiki.nginx.org/HttpMapModule
Following is what I tried. It works in my devbox. Note
map directive can only be put in the http block.
performance penalty of declaring a map directive is negligible (see above link)
you can have freedom to have different root folder, or port number, etc.
map $subdomain $root_folder {
one /path/to/one;
two /path/to/two;
}
map $subdomain $port_number {
one 9000;
two 9100;
}
server {
listen 80;
server_name ~^(?P<subdomain>.+?)\.mydomain\.com$;
root $root_folder;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:$port_number;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
you can do:
server_name one.example.org two.example.org;
if both are exactly identical except for the domainname
if you have just similar locationblocks you can move those locations to a separate file and then do an
include /etc/nginx/your-filename;
to easily use it in each serverblock
server {
listen 80;
server_name pwta;
root html;
location /test/{
alias html/test/;
autoindex on;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
This configuration works. However, if location /test/ is replaced e.g. location /testpath/ it doesn't work (No input file specified). I assumed base on the explanation of alias directive that the "location" part is dropped and thus /testpath/info.php would result in html/test/info.php.
Thanks for any suggestion.
nginx alias
server {
listen 80;
server_name pwta;
index index.html index.php;
root html;
location /testpath/ {
alias html/test/;
}
location ~ ^/testpath/(.+\.php)$ { ### This location block was the solution
alias html/test/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$1;
include fastcgi_params;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Both the alias and root directives are best used with absolute paths. You can use relative paths, but they are relative to the prefix config option used to compile nginx, and are generally not what you want.
You can see this by executing nginx -V and finding the value following --prefix=.
Prove this to yourself by looking at the log, you will find a "no such file" error.