Can't serve two static websites with Nginx - nginx

I have two React build folders and I want to access them like this :
https://example.com/ -> /var/www/web_client/
https://example.com/videochat/ -> /var/www/videochat/
Here is my nginx configuration file :
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
location / {
root /var/www/web_client;
try_files $uri /index.html;
}
location /videochat/ {
root /var/www/videochat;
try_files $uri /index.html;
}
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
The location block / works perfectly but /videochat/ redirects me to the 404 page of /var/www/web_client and not the index.html of /var/www/videochat.
How can I fix this error and get nginx to serve both static websites on the same server ?
I tried to reverse the two like this to make sure the error is coming from nginx:
location / {
root /var/www/videochat;
try_files $uri /index.html;
}
location /web_client/ {
root /var/www/web_client;
try_files $uri /index.html;
}
Now it's the other way around, the location block / redirects me to the index.html of /var/www/videochat as expected but /web_client/ redirects me to /var/www/videochat and not the index.html of /var/www/web_client.

I think you can try having /videochat location block first and then then the / location block.
Because location /, will be the block that gets used for both / as well /videochat.
Only if we specify '=' in the location match, it will be a exact match, if not requested URI will be matched against the beginning of the mentioned URI in the location block.
For many location blocks it will be better to use regex.
You can refer to article like this for more info:
https://www.digitalocean.com/community/tutorials/nginx-location-directive

Related

If I try to delete wave slash from URL, /index answers 404 Not Found

I'm working on a docker Nginx server on local, this is my conf.d/default.conf configuration:
server {
listen 80;
listen [::]:80;
server_name localhost;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/ssl/certs/localhost.pem;
ssl_certificate_key /etc/ssl/private/localhost.key;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html;
}
location ~ ^/~(.+?)(/.*)?$ {
alias /home/$1/public_html$2;
index index.html index.htm;
autoindex on;
}
}
This configuration works perfectly, but for last "location" block, which works as an "userDir" directive, I have to type an URL like this: https://localhost/~user1/
In order to remove that trailing slash, I tried:
location ~ ^/(.+?)(/.*)?$ {
alias /home/$1/public_html$2;
index index.html index.htm;
autoindex on;
}
This solution works fine and answers with the index.html content in "/home/user1/public_html" by using the URL https:/localhost/user1 which is how I want it to work, but then, root content (https:/localhost/) becomes 404 Not Found.
Hope I did explain it well and someone has a solution! Thank you in advance!!

nginx path based routing

I would like to to route requests based on a path to two different Angular applications. So when i request http://example.com/admin is routes to one app http://example.com/client routes to the second app. I have the following config but all requests are always sent to the nginx default page. Configuration is as follows:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /admin {
root /home/ubuntu/apps/admin/;
index index.html;
try_files $uri $uri/ /index.html?$args;
}
location /client {
root /home/ubuntu/apps/client;
index index.html;
try_files $uri $uri/ /index.html?$args;
}
}
No other confs are in /etc/nginx/sites-enabled and nginx.conf is default post install on Ubuntu. Any help is appreciated.
You were using the wrong value for the root directive. In both locations the correct value for the root directive is /home/ubuntu/apps, which means you can simplify the configuration by using just one root directive by moving it into the server block.
Of course you can use the alias directive - but as the manual states :
When location matches the last part of the directive’s value ... it is better to use the root directive instead.
The other problem is that your try_files statements are pointing to the wrong index.html file.
For example:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /home/ubuntu/apps;
location /admin {
try_files $uri $uri/ /admin/index.html;
}
location /client {
try_files $uri $uri/ /client/index.html;
}
}
Note that server_name _; is not necessary - see the Server Names document.
Also, index index.html; is not necessary being the default value for the index directive.
It appears that you cannot use multiple root directives but instead need to use alias (Configure nginx with multiple locations with different root folders on subdomain). With that, I would still get 404s until I took off $args from the index.html. After that everything worked fine (don't ask how long it took to figure that out). Working config:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
index index.html;
location /admin {
alias /home/ubuntu/apps/admin;
try_files $uri /index.html =404;
}
location /client {
alias /home/ubuntu/apps/client;
try_files $uri /index.html =404;
}
}

How to serve multiple web servers using nginx?

I have installed nginx and I want to serve two different web applications under the same user on the same server.
This is the config I already use:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
return 301 https://www.example.com$request_uri;
}
# HTTPS — proxy all requests to the Node app
server {
# Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires 30d;
add_header Vary Accept-Encoding;
access_log off;
}
root /home/myuser/main/dist;
# Use the Let’s Encrypt certificates
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
# Include the SSL configuration from cipherli.st
include snippets/ssl-params.conf;
}
As you can see, I have under /home/myuser directory a directory called main and a dist directory in it. There there are static files that are successfully served using nginx.
I want to add another directory under the myuser directory, called for example, test.
So I will have /myuser/test and there to server another web application. Using the very same nginx server.
I have tried to write many variants in the config file I mentioned above but it couldn't work.
The config file located in: /etc/nginx/sites-enabled/example.com.conf
I edit it using sudo.
If you want to host different static files from local directories a configuration could look like this:
Notice: Your location uri (/, /one) will be appended to the root directory path if using the root directive.
The root directive can be used in every location block to set the document root.
http://nginx.org/en/docs/http/ngx_http_core_module.html#root
This is the reason why alias exists. With alias the location will not become a part of the directory path. Check this out:
http://nginx.org/en/docs/http/ngx_http_core_module.html#alias
1. One Domain - Multi-Location
server {
server_name example.com;
listen 443 ssl;
.....
root /home/user/main/dist;
location / {
index index.html;
# If you have some sort of React or Angular App you might want to use this
# try_files $uri $uri/ /index.html;
# If you just host a local files (css, js, html, png)...
# try_files $uri $uri/ =404;
}
location /two {
alias /home/main/example;
index index.html;
.....
}
}
2. Two Domains - Single Location
server {
server_name example.com;
listen 443 ssl;
.....
root /home/user/main/dist;
location / {
index index.html;
# If you have some sort of React or Angular App you might want to use this
# try_files $uri $uri/ /index.html;
# If you just host a local files (css, js, html, png)...
# try_files $uri $uri/ =404;
}
}
server {
server_name example1.com;
listen 443 ssl;
.....
root /home/user/main/test;
location / {
index index.html;
# If you have some sort of React or Angular App you might want to use this
# try_files $uri $uri/ /index.html;
# If you just host a local files (css, js, html, png)...
# try_files $uri $uri/ =404;
}
}

Nginx configuration causing too many redirects

I have a conf file with example.com as the root. In the example.com directory, there is an html, css, img, and js folder. I understand this deviates from the traditional html directory as root. I have tried many different configurations (using regex based on filetypes, variables, etc.) but I always get too many redirect errors. Can anyone help on a good conf file for this type of directory structure? Here is my conf file currently.
server {
listen 80 default_server;
listen [::]:80 default_server;
# return 301 https://$server_name$request_uri;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
server_name www.example.com example.com;
root /var/www/www.example.com/;
index index.php index.html;
client_max_body_size 100m;
error_page 404 = error.html?error=404;
location ~ /.well-known {
allow all;
}
location / {
location ~* \.(html|php)$ {
root html/;
}
location ~* \.css$ {
root css/;
}
location ~* \.js$ {
root js/;
}
location ~* \.(png|jpeg|gif)$ {
root img/;
}
try_files $uri =404;
}
}
Thanks in advance for any help!
Here is the configuration I ended up using:
server {
listen 80 default_server;
listen [::]:80 default_server;
# return 301 https://$server_name$request_uri;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
server_name www.example.com example.com;
root /var/www/www.example.com/;
index index.php index.html;
client_max_body_size 100m;
error_page 404 = /html/error.html?error=404;
location ~ /.well-known {
allow all;
}
location = / {
try_files /html/index.html =404;
}
location / {
location ~* \.(html|php)$ {
try_files $uri /html/$uri =404;
}
location ~* \.css$ {
try_files $uri /css/$uri =404;
}
location ~* \.js$ {
try_files $uri /js/$uri =404;
}
location ~* \.(png|jpeg|gif)$ {
try_files $uri /img/$uri =404;
}
try_files $uri =404;
}
}
My problem was that all of my redirects were using relative pathing (such as try_files html/$uri) instead of absolute pathing from the site root (/html/$uri). This lead to redirects like /html/html/html/...
I thought that if I used an absolute path, it would be absolute to the root of the server, and not the site.
My only issue now is that my parameter on my error page redirect (?error=404) doesn't work with absolute pathing, but that not a huge deal.

Nginx route with single page app

I'm starting to go nuts at this. For some reason, routing wont work on my single page application. So www.example.com works, but not www.example.com/service. I read a lot of posts on how to fix it, but nothing seems to work.
This is my config file at /etc/nginx/conf.d/App.conf
server {
listen 80;
server_name example.com *.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /path/to/certificate/;
ssl_certificate_key /path/to/certificate/key;
root /var/www/App/public;
index index.html;
location / {
try_files $uri /index.html;
}
ssl_session_timeout 5;
}
I have tried all kind of different "location" routes, and nothing seems to work. I do also restart the service with "sudo service nginx restart" everytime I change.
Any clues?
In the comments you said there's a small fixed set of possible routes. In that case you can add a location block for each route, with an alias to the top-level, for example,
location / {
try_files $uri $uri/ =404;
}
location /services {
alias /var/www/App/public;
try_files $uri $uri/ =404;
}
Edit: Or, if you want to serve the top-level index.html in response to any request at all,
location / {
try_files /index.html =404;
}

Resources