location /social {
index index.php;
try_files $uri /social/index.php;
}
When a user hits up a directory, it needs to run the local ./index.php
So far, when people hit up /social/ it runs index.php
When the user visits all unknown URLs, they get /social/index.php
However, when a user vists /social/subdir/ and there is a /social/subdir/index.php, it still runs /social/index.php. I need it to run /social/subdir/index.php
if I change the config to:
location /social {
index index.php;
try_files $uri $uri/index.php /social/index.php;
}
Then nginx serves up the CONTENT of social/subdir/index.php as content-type: octet/stream.
I thought index index.php would look for the paths index file.
php rendering block:
location ~ .php$ { ## Execute PHP scripts
if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss
expires off; ## Do not cache dynamic content
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
I think your main issue is that you didn't use http:// before 127.0.0.1:9000 , also make sure that your php uses port 9000 not a sock file, otherwise you change the fastcgi_pass to unix socket.
Here's my simplified config.
Remove the index index.php from the /social block if it's the same value in the server block.
location /social {
# index index.php; # remove if not needed
try_files $uri $uri/ /social/index.php;
}
location ~* \.php$ {
include fastcgi_params;
fastcgi_pass http://127.0.0.1:9000;
}
First remove the index.php from the try_files directive so it will look like this
location /social {
index index.php;
try_files $uri $uri/ /social/index.php =404;
}
Also make sure that no other location block catches the /social/subdir/ request.
Lastly (irrelevant to your question, but very important) remove this line
if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss
It is totally redundant and evil. try_files does not miss 404s. Have a look at this for more info IfIsEvil
Related
I'm currently trying to set up multiple projects of React Apps using Nginx. So far, whenever I had static files conflicting, I'd just copy everything from a folder into the other (yes, it's an awful solution, but it was working so far). The problem is that now I have multiple projects on the same server, and although the previous solution would still work, it wouldn't be long before it's a complete mess. I've looked up Stack Overflow and many websites, and I've come to a configuration that looks like what I want to do, but it's not working properly.
This is my nginx.conf file:
#user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
server_names_hash_bucket_size 64;
#gzip on;
index index.html index.htm;
map $http_referer $webroot {
"/project1/main" "/home/username/project1main/build";
"/project1/admin" "/home/username/project1admin/build";
"/project2/main" "/home/username/project2main/build";
"/project2/admin" "/home/username/project2admin/build";
}
include /etc/nginx/conf.d/*.conf;
}
This is my server.conf file:
server {
listen 80;
server_name gcloud-server;
location /project1/main {
alias /home/username/project1main/build;
try_files $uri $uri/ /index.html =404;
}
location /project1/admin {
alias /home/username/project1admin/build;
try_files $uri $uri/ /index.html =404;
}
location /project2/main {
alias /home/username/project2main/build;
try_files $uri $uri/ /index.html =404;
}
location /project2/admin {
alias /home/username/project2admin/build;
try_files $uri $uri/ /index.html =404;
}
location /static {
root $webroot;
}
}
Is there a way to solve this problem like this? Or am I stuck into setting one /static location in which I'll have to copy every single projects' static files?
Thanks in advance.
As far a I can remember how an alias directive worked, you came into the following problem. Lets assume you've got a /project1/main/some/path/file request:
location /project1/main {
alias /home/username/project1main/build;
# here our internal variables are:
# $document_root = "/home/username/project1main/build"
# $uri = "/project1/main/some/path/file"
try_files $uri $uri/ /index.html =404;
# 1) try_files checks the existence of $document_root$uri physical file
# this is "/home/username/project1main/build/project1/main/some/path/file"
# which is absent
# 2) try_files checks the existence of $document_root$uri/ directory
# this is "/home/username/project1main/build/project1/main/some/path/file/"
# which is absent
# 3) you've got a 404 HTTP error
}
This problem didn't happen when you are using a root directive, but alias works this way. What you can do is
# use regex location match and capture URI suffix in a $1 variable
location ~ /project1/main(.*) {
alias /home/username/project1main/build;
# here our internal variables are:
# $document_root = "/home/username/project1main/build"
# $uri = "/project1/main/some/path/file"
# $1 = "/some/path/file"
try_files $1 $1/index.html =404;
# checked file is $document_root$1
# this is "/home/username/project1main/build/some/path/file"
# request would be served if this file exists
}
I'm trying to add on cakephp on to an existing server, but the location / block is being used. I'm following the pretty url on nginx section on the cakephp cookbook. On my test environment, I have the server block looking like
server {
listen 80;
server_name localhost;
access_log /var/www/html/log/access.log;
error_log /var/www/html/log/error.log;
location / {
root /var/www/html/cakephp/app/webroot/;
index index.php;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
root /var/www/html/cakephp/app/webroot/;
index index.php;
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
From this, I'm able to run my testsController through the url localhost/tests
However, the server that I'm trying to add cakephp to, there is already another application installed at the domain root.
location / {
proxy_pass https://localhost/somepage;
}
I tried setting up a location block like
location /cakephp {
root /var/www/html/cakephp/app/webroot/;
index index.php;
try_files $uri $uri/ /index.php?args;
}
I understand that this wouldn't work because it's looking for cakephp in the url, which it wouldn't be there. Since root is set to be /var/www/html/cakephp/app/webroot, when I access the url localhost/cakephp, is it looking for /var/www/html/cakephp/app/webroot/cakephp?
I'm getting confused about how to set this up. I read about url rewriting and cakephp running in some subdirectory, but I'm not sure if that's what I am looking for. Right now, the application runs with http://localhost/someController. I would like to have the the application run with the url http://localhost/cakephp/someController. How should I setup my nginx config?
Fix static files first
With the config in the question, what you'll find is that nothing really works - not even requests for static files.
Consider:
server {
...
root /wherever/;
error_log /tmp/cakephp.err.log debug; # <- add this
location /cakephp {
root /var/www/html/cakephp/app/webroot/;
index index.php;
try_files $uri $uri/ /index.php?args;
}
}
This will produce:
$ curl -I http://cakephp.dev/cakephp/favicon.ico
HTTP/1.1 404 Not Found
The debug log will help to clarify why this occurs:
-> cat /tmp/cakephp.err.log
...
2015/08/23 10:53:43 [debug] 9754#0: *87 http script var: "/cakephp/favicon.ico"
2015/08/23 10:53:43 [debug] 9754#0: *87 trying to use file: "/cakephp/favicon.ico" "/var/www/html/cakephp/app/webroot/cakephp/favicon.ico"
Nginx is using the whole url as the path to a file, not just the bit after the location prefix. This is where understanding the difference between the root directive and the alias directive is important, and is also a common question (random result, there are many).
So, fixing that first:
server {
...
error_log /tmp/cakephp.err.log debug;
location /cakephp {
alias /var/www/html/cakephp/app/webroot/; # <- alias, not root
index index.php;
try_files $uri $uri/ /index.php?args;
}
}
Will produce:
$ curl -I http://cakephp.dev/cakephp/favicon.ico
HTTP/1.1 200 OK
Then fix php requests
The problem with php requests is more or less the same thing; though the request finds the right php file it's configured such that CakePHP will assume it's installed in the root. There are various solutions to this - here's one:
server {
...
error_log /tmp/cakephp.err.log debug;
location /cakephp {
alias /var/www/html/cakephp/app/webroot/;
index index.php;
try_files $uri $uri/ /cakephp/index.php; # <- redirect to the actual equivalent request
}
location /cakephp/index.php {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
# Explicit script filename
fastcgi_param SCRIPT_FILENAME /var/www/html/cakephp/app/webroot/index.php;
}
}
In this way static files and dynamic requests both work - and the environment variables that CakePHP receives are such that it understands the root of the application to be /cakephp/.
I have two backbone applications and one API on the same subdomain but i am having trouble making pushStates work for the applications with correct location regex.
This is the paths im trying to accomplish
subdomain.domain.org/admin
subdomain.domain.org/client
subdomain.domain.org/api
I have tried to configure rewrite rules for client and admin but it always fail with 404 or 500 error. What would be the correct way to do this?
Here is just one example of all the combinations i have tried:
location ~ ^/admin.*$ {
alias /var/www/project/admin/public
rewrite ^(.+)$ /index.html last;
}
I figured it out after reading this https://serverfault.com/questions/361159/nginx-multiple-location-issues#361426
and ended up with this:
location ^~ /admin {
access_log /var/log/nginx/admin.access.log;
error_log /var/log/nginx/admin.error.log notice;
alias /var/www/project/admin/public/;
try_files $uri $uri/ /index.html;
rewrite ^/admin/(.+/)$ /admin/index.html last;
}
location ^~ /client {
access_log /var/log/nginx/client.access.log;
error_log /var/log/nginx/client.error.log notice;
alias /var/www/project/client/public/;
try_files $uri $uri/ /index.html;
rewrite ^/client/(.+/)$ /client/index.html last;
}
Currently i am working on cakephp with nginx. I setup a cakephp environment on a Centos server running Nginx with Fact CGI. The problem is that I cannot get the rewrite rules to setup correct in my vhost so that cake renders pages correctly i.e. with styling and so on.
My .conf file is as -
#The default server
server {
listen 80 default_server;
server_name 1 23.123.123.123;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
Luchomolina's answer below got me started in the right direction. However, CSS and JS files stopped working on URLs that were not top-level URLs, e.g. /posts worked but /posts/title123 didn't.
This is what ended up working for me:
location / {
if (-f $request_filename) {
break;
}
if (!-f $request_filename) {
rewrite ^/(.+)$ /index.php?url=$1 last;
break;
}
set $new_uri $uri;
}
use the blow code
location / {
if (-f $request_filename) {
break;
}
if (!-f $request_filename) {
rewrite ^/(.+)$ /index.php?url=$1 last;
break;
}
set $new_uri $uri;
}
This works for me:
server {
listen 80 ;
server_name example.com;
root /www/example.com/app/webroot;
index index.html index.php;
location / {
try_files $uri $uri/ /index.php?$uri&$args;
set $new_uri $uri;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PATH_INFO $new_uri;
}
location ~ /(\.ht|\.git|\.svn) {
deny all;
}
}
The $new_uri rules were added to make some special routes work on my site, maybe that won't apply to you, but note that CakePHP assumes PATH_INFO is set, so those rules won't harm leaving it there.
Hope it helps.
I managed to get this to work a while back, but on returning to the cakephp project I had started it seems that whatever changes I've made to nginx recently (or perhaps a recent update) have broken my rewrite rules.
Currently I have:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.php index.html index.htm;
}
location /basic_cake/ {
index index.php;
if (-f $request_filename) {
break;
}
if (!-f $request_filename) {
rewrite ^/basic_cake/(.+)$ /basic_cake/index.php?url=$1 last;
break;
}
}
location /cake_test/ {
index index.php;
if (-f $request_filename) {
break;
}
if (!-f $request_filename) {
rewrite ^/cake_test/(.+)$ /cake_test/index.php?url=$1 last;
break;
}
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
server {
listen 8081;
server_name localhost;
root /srv/http/html/xsp;
location / {
index index.html index.htm index.aspx default.aspx;
}
location ~ \.(aspx|asmx|ashx|asax|ascx|soap|rem|axd|cs|config|dll)$ {
fastcgi_pass 127.0.0.1:9001;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
The problem that I have is that the css and images will not load from the webroot. Instead if I visit http://localhost/basic_cake/css/cake.generic.css, I get a page which tells me:
CakePHP: the rapid development php
framework Missing Controller
Error: CssController could not be
found.
Error: Create the class CssController
below in file:
app/controllers/css_controller.php
Notice: If you want to customize this
error message, create
app/views/errors/missing_controller.ctp
CakePHP: the rapid development php
framework
Does anybody have any ideas on how to fix this?
(I posted this on ServerFault, but I have this feeling that not many people check that site in comparison to this one, so I probably shouldn't have bothered...)
There is a much easier way to do this using alias and try_files directives. I've started with a simple configuration with working PHP and added a Cake project in the path /cakeproject on the server:
root /var/www;
index index.php;
location /cakeproject {
alias /var/www/cakeproject/app/webroot;
try_files $uri $uri/ /cakeproject/app/webroot/index.php;
}
location ~ \.htaccess {
deny all;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
The cake project now works perfectly from http://thedomain.com/cakeproject/
I've managed to solve this by adding App.base parameter to the cakephp configuration instead of using the App.baseUrl (looked the code in dispatcher.php).
So let's say I have the cakephp copy located in /var/www/html/cakeprj and my WWWROOT is /var/www/html:
nginx host configuration
# that's for all other content on the web host
location / {
root /var/www/html;
autoindex off;
index index.php index.html index.htm;
...
}
# that's for cakephp
location /cakeprj {
rewrite ^/cakeprj$ /cakeprj/ permanent;
rewrite ^/cakeprj/(.+)$ /$1 break;
root /var/www/html/cakeprj/app/webroot;
try_files $uri /$uri/ #cakephp;
}
# that's for all other php scripts on the web host
location ~ \.php$ {
root /var/www/html;
fastcgi_pass unix:/var/lib/fcgi/php-fcgi.socket;
...
include /etc/nginx/fastcgi_params;
}
# that's for cakephp execution
location #cakephp {
set $q $request_uri;
if ($request_uri ~ "^/cakeprj(.+)$") {
set $q $1;
}
fastcgi_param SCRIPT_FILENAME /var/www/html/cakeprj/app/webroot/index.php;
fastcgi_param QUERY_STRING url=$q;
fastcgi_pass unix:/var/lib/fcgi/php-fcgi.socket;
include /etc/nginx/fastcgi_params;
}
cakephp configuration in app/config/core.php
Configure::write('App.base', '/cakeprj');
Configure::write('App.baseUrl', '/cakeprj/'); // seems like it doesn't matter anymore
...and voila - you get nginx serving cakephp static files correctly, url passing to the cakephp dispatcher correctly and cakephp generating urls correctly as well.
P.S. if your nginx doesn't support try_files I believe its configuration can be rewritten with if condition and another rewrite.
In my case, what I did was the following:
location /cakeproj {
rewrite_log on;
error_log /var/log/nginx/notice.log notice; # just for debuggin
if (-f $request_filename) {
break;
}
# Avoid recursivity
if ($request_uri ~ /webroot/index.php) {
break;
}
rewrite ^/cakeproj$ /cakeproj/ permanent;
rewrite ^/cakeproj/app/webroot/(.*) /cakeproj/app/webroot/index.php?url=$1 last;
rewrite ^/cakeproj/(.*)$ /cakeproj/app/webroot/$1 last;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_pass unix:/var/run/php5-fpm.sock;
# Edit listen directive in /etc/php5/fpm/pool.d/www.conf
fastcgi_index index.php;
include fastcgi_params;
}
And it worked!!!
Right now I'm experiencing slowness, but I think is PHP and not nginx related
Cheers
Found a solution:
location /cakeprj {
rewrite ^/cakeprj(.+)$ /cakeprj/app/webroot$1 break;
try_files $uri $uri/ /cakeprj/index.php?$args;
}
where cakeprj is a cakephp directory.
Ref: http://jamesmcdonald.id.au/it-tips/cakephp-in-a-subdirectory-nginx