On my Nginx webserver i have several virtual hosts like this:
- api.example.com
- www.example.com
- cv.example.com
But when i am visiting www.example.com/example and this is not an valid path its giving me 404 page of my api.example.com. But why ?
This is my current nginx configuration of www.example.com :
server {
listen 443 ssl;
listen [::]:443 ssl;
access_log /var/log/nginx/www.example.com-access.log timed;
error_log /var/log/nginx/www.example.com-error.log;
root /var/www/wwwexamplecom/html/_site;
server_name example.com www.example.com;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
location / {
index index.html index.php;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME /var/www/example/html/public/index.php;
include fastcgi_params;
}
location ~ /.well-known {
allow all;
}
}
This is the configuration of my api.example.com :
server {
listen 443 ssl;
listen [::]:443 ssl;
access_log /var/log/nginx/api.example.com-access.log timed;
error_log /var/log/nginx/api.example.com-error.log;
root /var/www/apiexamplecom/html/public;
server_name api.example.com;
include snippets/ssl-api.example.com.conf;
include snippets/ssl-params.conf;
location / {
index index.html index.php;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME /var/www/apiexamplecom/html/public/index.php;
include fastcgi_params;
}
location ~ /.well-known {
allow all;
}
}
I think self its in the / location part but i am not really how i can fix this issue. This is also happening on other virtualhost.
You have to explicitly let nginx know that you want to throw a 404 error if it can't find anything in the location block. Otherwise it will try matching your 'default' server block (which in this case seems to be the api.example.com one because you haven't specified the default). It can't find anything in that server either, THEN it tries the 404.
To explicitly tell nginx to throw a 404 if it can't find anything in your location block, add =404 to the end of your try_files line. This means that if it can't find any files for $uri, $uri/ or any php files, then throw the 404 without trying anything else.
try_files $uri $uri/ /index.php?q=$uri&$args =404;
Related
Hi there!
I'am trying to configure Nginx for 2 yii projects, frontend for users and admin for admins with only one domain (no sub domain). I need to configure it in a way such that mydomain.com should refer to frontend and mydomain.com/admin to admin. The problem is I'am being able to configure only one of them at a time, meaning I can use frontend or admin not both of them.
What I have tried
front.conf
server {
listen 80;
server_name api.maim.experiments.uz;
return 301 https://$server_name$request_uri;
}
server {
charset utf-8;
client_max_body_size 128M;
listen 443 ssl;
ssl_certificate_key privkey.pem;
ssl_certificate fullchain.pem;
ssl_protocols TLSv1.2;
set $host_path "/home/itschool/inha_dev/frontend";
server_name api.maim.experiments.uz;
root $host_path/web;
set $yii_bootstrap "index.php";
access_log /var/log/nginx/itschool-access.log;
error_log /var/log/nginx/itschool-error.log;
location / {
index index.html $yii_bootstrap;
try_files $uri $uri/ /index.php;
}
location ~ ^/(protected|framework|themes/\w+/views) {
deny all;
}
location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
try_files $uri =404;
}
location ~ \.php$ {
set $fsn /index.php;
if (-f $document_root$fastcgi_script_name){
set $fsn $fastcgi_script_name;
}
fastcgi_pass 127.0.0.1:9002;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fsn;
}
location ~ /\.(ht|svn|git) {
deny all;
}
location ~* /\. {
deny all;
access_log off;
log_not_found off;
}
}
back.conf
server {
listen 80;
server_name api.maim.experiments.uz;
return 301 https://$server_name$request_uri;
}
server {
charset utf-8;
client_max_body_size 128M;
listen 443 ssl;
ssl_certificate_key privkey.pem;
ssl_certificate fullchain.pem;
ssl_protocols TLSv1.2;
set $host_path "/home/itschool/inha_dev/backend";
server_name api.maim.experiments.uz;
root $host_path/web;
set $yii_bootstrap "index.php";
access_log /var/log/nginx/itschool-access.log;
error_log /var/log/nginx/itschool-error.log;
location ^~ /admin {
alias /home/itschool/inha_dev/backend/web;
if (!-e $request_filename) { rewrite ^ /admin/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass 127.0.0.1:9002;
}
}
location ~ /\.(ht|svn|git) {
deny all;
}
location ~* /\. {
deny all;
access_log off;
log_not_found off;
}
}
I found some questions with answers but they didn't work for me, please help.
I have recently use similar configuration to support web application / mobile application and admin panel on single domain
I hope this could help you out. Below is the configuration
server {
listen 80;
set $root /var/www/html/application;
#here we go
#if backend not found in url then set root url
if ($uri !~ "^(.*)/(backend)(.*)") {
set $root /var/www/html/application/frontend/web;
}
# when request is coming from mobile then display mobile site
# you don't need this one, I just written in order to explain the mobile application navigation.
if ($http_user_agent ~* "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos") {
set $root /var/www/html/application/mobile/web;
}
root $root;
index index.php index.html index.htm index.nginx-debian.html;
server_name your_domain;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}
location / {
index index.html index.php;
if (!-e $request_filename){
rewrite ^/(.*) /index.php?r=$1 last;
}
}
location ~ /\.ht {
deny all;
}
}
Also have a look in official document of Yii2 to setup yii2-app-advanced on single domain (Apache, Nginx).
CLICK HERE
One more thing that you need to know is if you want to change backend/web to admin then you also have to made some changes in Yii2 application.
One domain will lead all requests to one IP (server). Nginx will use the first server block matching server_name https://nginx.org/en/docs/http/request_processing.html so you need to put all configuration on one file and use location to separate them.
You can move location ^~ /admin at the beginning of the front.conf locations and play with roots;
Or you can create a proxying config file that will contain just a little.
Something like that
location /admin {
proxy_pass http://localhost:8001;
}
location / {
proxy_pass http://localhost:8002;
}
Using the latter one you should change front & back configs to listen to other ports. Also, an SSL certificate was given for a domain, not URL. So you can use it only in the proxying config.
If you follow some of the key instructions from option 1 of Yii2 Single Domain Apache and Nginx you should be able to accomplish what you want.
Per the referenced link, Option 1:
Assuming Linux OS
cd /path/to/project/frontend/web
ln -s ../../backend/web backend
and set your nginx file
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name api.maim.experiments.uz;
root /home/itschool/inha_dev/frontend/web;
index index.php;
access_log /var/log/nginx/itschool-access.log;
error_log /var/log/nginx/itschool-error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}
Not: See below link for the Option-2, if the above does not work:
Yii2 Single Domain Apache and Nginx
Is it possible to optimize/minimize the config posted below?
I feel that it should be possible to merge all the redirects into something more simple.
http:// & http://www & https://www > https://
Though I've had issues and settled.
I understand variables are not supported in NGINX config, so I have to manually define the log locations for example. Would there be a way to set a default location for all vhosts?
I use the same ssl-params.conf file for all vhosts. Can this be defaulted and disabled on a per-vhost basis?
# Redirect http:// & http://www to https://
server {
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
# Redirect https://www to https://
server {
listen 443 ssl;
server_name www.example.com;
return 301 https://example.com/$request_uri;
}
# Main config
server {
listen 443 ssl;
server_name example.com;
# SSL config
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
# Error logs
access_log /srv/logs/nginx.access.example.com.log;
error_log srv/logs/nginx.error.example.com.log;
# Root dir
location / {
root /srv/example.com/_site/;
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}
# Caching
location ~ .php$ {
root /srv/example.com/_site/;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
root /srv/example.com/_site/;
expires 365d;
}
location ~* \.(pdf)$ {
root /srv/example.com/_site/;
expires 30d;
}
# SSL
location /.well-known {
allow all;
}
}
I understand variables are not supported in NGINX config, so I have to manually define the log locations for example. Would there be a way to set a default location for all vhosts?
Yes, just define it in the http context of your config or stick with the default of your distro (e.g. /var/log/nginx/access.log).
I use the same ssl-params.conf file for all vhosts. Can this be defaulted and disabled on a per-vhost basis?
It works the other way around you enable it where you need it through the include directive.
Here is a shorter config (untested):
http {
error_log /srv/logs/nginx.error.example.com.log;
access_log /srv/logs/nginx.access.example.com.log;
index index.php index.html index.htm;
server {
listen 80;
listen 443 ssl;
server_name .example.com;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
root /srv/example.com/_site/;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
location / {
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files $uri =404;
}
location ~* \.(jpe?g|png|gif|ico|css|js)$ {
expires 365d;
}
location ~* \.(pdf)$ {
expires 30d;
}
try_files $uri $uri/ /index.php?$args;
}
location /.well-known {
allow all;
}
}
}
I have a problem with Nginx server as it only shows default page. Virtual host and host file seem to be ok. I don't get where is the problem.
Here is my virtual host configuration:
server {
listen 80;
listen [::]:80;
listen 443 default ssl;
server_name marketplace_unirgy;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
root /var/www/html/marketplace_unirgy/;
index index.php;
#location / {
# index index.html index.php;
# autoindex on;
# #If missing pass the URI to Magento's front handler
# try_files $uri $uri/ #handler;
# expires max;
#}
#need it to execute php
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
include fastcgi.conf;
}
## Magento uses a common front handler
location #handler {
rewrite / /index.php;
}
}
And my host:
127.0.0.1 marketplace_unirgy localhost
My website is in /var/www/html/marketplace_unirgy
You seem to have the default location commented out for some reason. Try enabling it with:
location / {
try_files $uri $uri/ /index.php;
}
See this and this for more.
I upgraded my nginx package via apt-upgrade (running ubuntu 14.04) and now, when I've tried to connect to my website, it only shows a blank page (no error message).
This is what my nginx configuration file looks like:
server {
listen 80;
server_name www.example.com;
root /home/forge/example.com/public;
# FORGE SSL (DO NOT REMOVE!)
# ssl on;
# ssl_certificate;
# ssl_certificate_key;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
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/example.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
Also, the error.log shows this message: conflicting server name "www.example.com" on 0.0.0.0:80, ignored
Second time today I'm seeing the use of fastcgi_split_pathinfo without setting a document root and path info setting. Where does that come from? In addition the match is on \.php$, so it won't ever match on path info requests.
I'm guessing there lies the root of your problem as fastcgi_params has been upgraded.
My company is running a webserver with nginx. The configuration is set so that every request on a certain server block are forcefully rewritten to https, using a location block. This is the full configuration for a specific domain:
# HTTP server
server {
listen 80;
server_name www.mydomain.it mydomain.it admin.mydomain.it;
rewrite ^(.*) https://$host$1 permanent;
}
# HTTPS server
server {
listen 443;
server_name www.mydomain.it mydomain.it admin.mydomain.it;
root /usr/share/nginx/html/mydomain_server;
ssl on;
ssl_certificate /etc/certs/mydomain-bundle.crt;
ssl_certificate_key /etc/certs/mydomain.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/mydomain.ssl.access.log main;
error_log /var/log/nginx/mydomain.ssl.error.log error;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404-mydomain.html;
error_page 500 502 503 504 /50x.html;
location ~ \.php$ {
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
This domain serves several implementations of the same software to different customers, and works like this:
Customer John: www.domain.com/John
Customer Ada: www.domain.com/Ada
etc...
Obviously, as you can see, all accesses to such URLS are redirected to HTTPS.
Now, there is a particular need for a single customer not this to happen.
I've been reading the official doc here about locations, which tells I can't non-match a particular expression (as stated here too), and I can't find a way to have it work.
I've tried to add another location block matching the customer path before the default one, like this:
server {
listen 80;
server_name www.mydomain.it mydomain.it admin.mydomain.it;
root /usr/share/nginx/html/mydomain_server;
location ^~ /Mole/ {
try_files $uri $uri/ =404;
}
location / {
rewrite ^(.*) https://$host$1 permanent;
try_files $uri $uri/ =404;
}
}
which is not working, as Mole is still being redirected to HTTPS. I've tried using "~", "=" and even simply "location /Mole/", without success. Not a browser cache problem as I've tried already flushing it. What am I missing?
You could try using the map directive to identify customers who prefer to use http:
map $uri $use_https {
default 1;
~^/Mole/ 0; # add other exceptions as needed
}
server {
listen 80;
server_name www.mydomain.it mydomain.it admin.mydomain.it;
root /usr/share/nginx/html/mydomain_server;
location / {
if ($use_https) { # consider using 302 for testing
return 301 https://$host$request_uri;
}
try_files $uri $uri/ =404;
}
}