How to serve subfolder as root using Nginx? - nginx

This is my server block at /etc/nginx/sites-enabled/mydomain;
server {
listen 80;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name mydomain.com;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Inside my /var/www/html/ folder I have folder1 and folder2. I can access both of these at mydomain.com/folder1 and mydomain.com/folder2. folder1 is currently being served as mydomain.conf/folder1 so no issues on that one.
However, I want to server folder2 as my main domain. So when I access mydomain.com it should serve whatever insides /var/www/html/folder2.
I literally tried every single answer I could find online (and I'm aware there are dozens of similar questions online) yet none of them worked for me. Sorry I'm a bit rookie and I appreciate your understanding.
EDIT: Both folder1 and folder2 contain PHP apps.

Your first option is to use
root /var/www/html/folder2;
and put folder1 under the /var/www/html/folder2. If you can't do it for some reason, your second option is to use the following config (I omit the try_files directive from your root location since try_files $uri $uri/ =404 is a default behavior):
server {
listen 80;
root /var/www/html/folder2;
index index.php index.html index.htm index.nginx-debian.html;
server_name mydomain.com;
location / {}
location /folder1/ {
root /var/www/html;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
location ~ /\.ht {
deny all;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
If you want the /folder1 URL to be workable too, you either change location /folder1/ { ... } to location /folder1 { ... } or add an explicit redirect (this won't needed if you put your folder1 under the /var/www/html/folder2, in that case this redirect will be issued automatically):
location = /folder1 {
return 301 /folder1/$is_args$args;
}
I prefer the second way since using the first one you made any route started with /folder1 prefix (but different from it, e.g. /folder10) unavailable for your root web app.

Related

Nginx shows 404 error for sub link and paths

I have using nginx for laravel project. When I use the domain name it shows the home page. But When I click any one of the link it does not work. And shows 404 Not Found error.
http://www.myhomepage.com // working
http://www.myhomepage.com/about // not working
I have using the following configuration.
server {
listen 80;
root /var/www/abc-company-website/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name myhomepage.com localhost;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
You probably want to adjust the location / block to pass the query string, as per the documentation:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Laravel 5.8 Docs - Installation - Pretty URLs - Nginx

Nginx separate apps in subdirectories

I am trying to move an app from apache server to nginx. The problem is that there are multiple apps in subdirectories and I can't find a proper way to configure the server.
What I need:
www.example.com serves from /srv/app
www.example.com/sub1 serves from /srv/app/sub1
www.example.com/sub2 serves from /srv/app/sub2
Each of the apps need the same config, so I extracted that in a snippet:
# snippets/app.conf
index index.php index.html index.htm index.nginx-debian.html;
location /system {
return 403;
}
# [a couple of other 403s excluded]
# Pass non-file URI to index.php
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Use PHP
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
# Hide .htaccess
location ~ /\.ht {
deny all;
}
And in the main server file:
# [non-www and http redirects]
server {
# [listen directives]
server_name www.example.com;
root /srv/app;
include snippets/app.conf;
location /sub1 {
root /srv/app/sub1;
include snippets/app.conf;
}
# [other sub-apps included in the same way]
# [ssl stuff]
}
However, this gives me an error:
nginx: [emerg] location "/system" is outside location "/sub1" in /etc/nginx/snippets/app.conf:5
It's obvious from the error that /system is interpreted as being "absolute" www.example.com/system instead of the nested www.example.com/sub1/system. Can I somehow specify that I want the nested locations to be considered relative? Or I just have to repeat the whole near-identical config for every sub-app changing the prefixes?
It turns out that most of the repeating is not necessary in nginx.
The directives to use fastcgi for .php and hide /.ht files were already regexes so they affect everything. It's enough to specify index once and the default there stuff was redundant if I only want to use index.php.
As all the apps are nested on the filesystem in the same way as on web, specifying root was not necessary either.
What surprised me was that location ^~ /(system|data)/ { ... } matches not only www.example.com/system/, but also www.example.com/sub1/system/. I thought that ^~ should match only if the location start matches the regex...
# [non-www and http redirects]
server {
# [listen directives]
server_name www.example.com;
root /srv/app;
index index.php;
location ^~ /(system|data)/ {
return 403;
}
# Use PHP
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
# Pass non-file URI to index.php for all locations
location /sub1/ {
try_files $uri $uri/ /sub1/index.php?$query_string;
}
location /sub2/ {
try_files $uri $uri/ /sub2/index.php?$query_string;
}
# [other sub-apps included in the same way]
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ /\.ht {
deny all;
}
# [ssl stuff]
}
I also tried to replace the separate locations with
location ^~ /(sub1|sub2)/ {
try_files $uri $uri/ /$1/index.php?$query_string;
}`
but didn't succeed with that - this location somehow didn't ever match and everything got passed to the /index.php in base instead.

Server with multiple projects in /var/www?

I have a server that I want to use as a personal server, with all of my projects under /var/www.
I currently have two folders, /var/www/html and /var/www/site.
I want to be able to access these folders by the following URLs (123.123.123.123 is my server IP):
123.123.123.123/html and 123.123.123.123/site
Here is my default virtual host file:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name 123.123.123.123;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
And here is the one I created for /var/www/site, called site:
server {
listen 80;
listen [::]:80;
# Because this site uses Laravel, it needs to point to /public
root /var/www/site/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name 123.123.123.123;
location /site {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
But when I go to 123.123.123.123/site, it says 404 Not Found, so clearly I'm doing something wrong (and yes, I restarted nginx).
Please help!
You only need one server block, as both /html and /site live in the same server.
Use nginx -t to check that nginx really does restart without giving any errors.
As /site uses a complicated directory scheme, you will need to use a nested location block to get the paths correct.
Your first project seems to have a simple arrangement of static and PHP files. You can use a root /var/www; statement to map URIs beginning with /html to the html folder. See this document for more.
Something like this may work for you:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/;
index index.php index.html index.htm index.nginx-debian.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
location ^~ /site {
alias /var/www/site/public;
if (!-e $request_filename) { rewrite ^ /site/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}
}
The default server does not need a server_name.

Block access to files in a directory but allow index.html

I'm hosting a website on /test/ but files can be accessed by going to the url if user knows filename. Ex:
domain.com/test/readmesample.txt
I have it setup like above but now when i go to domain.com/test the index.html file wont load and I get a 403 forbidden.
How can i set it up so when going to /test it allows the html file to load while still blocking files inside that directory? This includes files, folders and .files other than index.html.
location ~ /test {
deny all;
}
Here is my config file
server {
listen 80;
listen 443 ssl default_server;
root /config/www;
index index.html index.htm index.php;
server_name www.domain.com;
ssl_certificate /config/keys/letsencrypt/fullchain.pem;
ssl_certificate_key /config/keys/letsencrypt/privkey.pem;
ssl_dhparam /config/nginx/dhparams.pem;
ssl_ciphers 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
ssl_prefer_server_ciphers on;
client_max_body_size 0;
location / {
try_files $uri $uri/ /index.html /index.php?$args =404;
}
location ~ /new {
deny all;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-cgi alone:
fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
}
Thank you in advance
You can explicitly break out /test/index.html with:
location = /test/index.html {
}
location ^~ /test {
deny all;
}
The exact match location has highest precedence, and the ^~ modifier places the precedence of the prefix location above regular expression locations at the same level.
See this document for more.
I think I figured it out not sure if it's the proper way but it works. Feel free to correct me
location /test {
location ~ \.(txt|gif|jpg|png)$ {
deny all;
}
}
Using that blocks access to all those extensions in /test and inside any sub directory.
I prefer return 444; than deny all;
Deny all show server name
Nginx configuration disallow or allow files access
Richard Smith's answer is correct. Here is another correct answer:
location ^~ /test {
try_files /test/index.html =404
}

nginx rewrite sub url

How can I solve this problem: I want to set up nginx conf file to meet below criteria:
http://www.example.com/site1/article/index.php?q=hello-world -> http://www.example.com/site1/article/hello-world
httb://www.example.com/site2/article/index.php?q=goodbye-world -> httb://www.example.com/site2/article/goodbye-world
httb://www.example.com/site3/article/index.php?q=open-new-world -> httb://www.example.com/site3/article/open-new-world
There are multiple sites after example.com, I want to make the url look clean by using nginx configuration.
But my below configuration doesn't work. Someone help me?
server {
listen 80;
listen [::]:80;
root /var/www/example.com/public_html;
index index.php index.html index.htm;
server_name www.example.com;
location ~ /article/ {
try_files $uri /site1/article/index.php?q=$1;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
}
You would like the client to present a URL like /xxx/article/yyy which is then internally rewritten to /xxx/article/index.php?q=yyy.
You need to capture the components of the source URI in order to use them later. You have a $1 in your question, but you are missing the expression to actually give it a value. With the minimum number of changes, this works:
location ~ ^(.*/article/)(.*)$ {
try_files $uri $1index.php?q=$2;
location ~ \.php$ { ... }
}
However, you do not need to use a nested location for PHP, as long as the PHP regex location appears above the other regex location, it will process all php files. For example:
location ~ \.php$ { ... }
location ~ ^(.*/article/)(.*)$ {
try_files $uri $1index.php?q=$2;
}

Resources