I am new to nginx environment and trying to host my first app using nginx.
But I am not being able start the first steps with nginx.
I have seen and read thousands of tutorials on basic nginx setup and have set up basic nginx server block as anyone would have.
Here is my sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm ;
error_log /var/log/nginx/error.log debug;
error_page 400 401 402 403 404 40x.html;
server_name mydomain.com;
location / {
root /var/www/html;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
# fastcgi_pass unix:/run/php/php7.0-fpm.sock;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
And i have done several deployments with apache but with nginx, i am experiencing peculiar behaviour.
This is how it goes.
It serves the default nginx welcome page successfully from /var/www/htmlon mydomain.com
Now, if i create a new html file say test.html inside /var/www/html and try to open mydomain.com/test.html, it shows internal server error with no logs in error log or access log.
Now in my server block, if i add test.html to the index directive as the first option, the same /var/www/html/test.html file is served and seen without any error on mydomain.com (So that it is clear that there are no problems in file permissions).
Also, if say i have index as the default index page only, if i add a hyperlink in the default index page, say Test Page , and on the default home page served on mydomain.com if i click on that hyperlink, test.html file is served, but the url in my browser does not change.
I am banging my head on this from last two days and i have tried several things.
Increased the verbosity of error logs to debug, still nothing shows up in logs
Tried a hundred other logically same but syntactically different server configurations.
I am pretty experienced with server configurations and have done number of deployments with apache and have never experienced something like this on apache.
Maybe, I am skipping some of the basic concepts of nginx as i do not know much about nginx but felt it would be similar to apache.
Please help me with this issue.
Thanks in advance
Related
I just installed ngninx on my dev machine.
It automatically migrated my vhosts from lighttpd (very comfy!), I only had to adjust the TLDs (it only took \.dev, I changed that to \.(dev|test|local).
and bound itself to port 81; after removing lighttpd, I changed the ports in /etc/nginx/sites-available to 80.
But when I call http://<ip-adress>/ in the browser, I get the index page of one of my vhosts instead of the default DOCUMENT_ROOT (/var/www/).
I touched /etc/nginx/sites-available/default, changed the port number and uncommented the PHP block.
current contents (comments stripped):
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www;
index.php index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}
Half of the vhosts had self-references in /etc/nginx/sites-enabled, I replaced them with symlinks to /etc/nginx/sites-available and added a symlink for default; all my vhosts can now be accessed, but calling the IP address still routes to the same vhost instead of /var/www.
That vhost file is neither alphabetically first nor considering the mtime, but it is when I list the directory unsorted (ls -f), it even comes before ...
How do I get nginx to deliver /var/www/ instead of /var/www/vhost/?
update: After a few clicks on my primary vhost, switching to https and back, it changed:
http://www.vhost1.test now routes to /var/www, but the other vhosts seem to work correctly.
update: I tried to solve the problem by uncommenting the server block in nginx.conv (pointing to /var/www) and linking sites-enabled/default to sites-available/vhost1. The latter resulted in both the ip-address and vhost1 getting routed to another vhost. The other vhosts are still working fine.
I got it:
sites-available/vhost1 only had listen 443 ssl;; listen 80; was missing
(because listen 80 default_server caused a "duplicate default server" error),
so calling the domain via port 80 fell back to the default server.
The basic installation is working, on linux mint OS. resolving the domain on 'localhost' confirms that nginx is running.
however, the issue i am running into stems from the generation of my own server block. its very basic:
server {
listen 80;
listen [::]:80;
root /usr/share/nginx/html;
index index.html index.htm;
# Make site accessible from alias.
server_name tokum.com www.tokum.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
}
as you can see, i have created an alias for www.tokum.com in this server block. attempting to resolve this url in a browser, i am greeted with the lovely 'server not found' message.
my feeling is that it surrounds the 'try_files' functionality, but i cannot be sure why.
No other resources have been created on the server other than my tokum.com server block file, which is located at the path /etc/nginx/sites-available/tokum.com. Any help is most appreciated.
I have configured nginx with fastcgi_mono_server4.
In my nginx config I have 2 hostnames :
server {
listen 80;
server_name dev.example.org
location / {
root /var/www/dev.example.org/;
fastcgi_index Default.aspx;
fastcgi_pass 127.0.0.1:9001;
include /etc/nginx/fastcgi_params;
}
}
server {
listen 80;
server_name *.example.org
location / {
root /var/www/example.org/;
fastcgi_index Default.aspx;
fastcgi_pass 127.0.0.1:9000;
include /etc/nginx/fastcgi_params;
}
}
nginx is OK with this configuration. dev goes to one and all other to another one .
I've already tried this :
fastcgi-mono-server4 /applications=*.example.org:/:/var/www/example.org/ /socket=tcp:127.0.0.1:9000
but it throws an error (Uri parse exception)
Update :
I need to get the full host name in my application, for example if the request was abc.example.org, I need to get "abc".
Unfortunately, HttpContext.Current.Request.Url does not contains "abc" but "*" which causes the parse error
If nginx is going to take care of routing the appropriate sub-domains to each fastcgi port (9000 or 9001) then can you get away with a wildcard domain when you start the mono server process e.g. just use a * instead of '*.example.org'
fastcgi-mono-server4 /applications=*:/:/var/www/example.org/ /socket=tcp:127.0.0.1:9000
Update: The above works to get two Mono server apps listening via nginx, but, using the nginx config from the original question will lead to an exception if you call HttpContext.Request.Url on the catch-all server. This is due to it not liking the * in *.example.org.
There are two possible solutions, depending what you'd like to see returned from HttpContext.Request.Url when a client browses foo.example.org, bar.example.org etc.
Option 1: If you don't care about the sub-domain and want to see example.org
Configure the second (*.example.org) nginx server to be the 'default_server' and have it assign a server-name without the wildcard e.g.
server {
listen 80 default_server;
server_name example.org;
access_log ... }
With these settings, browsing to foo.example.org/Default.aspx loads the page and HttpContext.Request.Url returns example.org/Default.aspx
Option 2: If you want to see the actual sub-domain e.g. foo.example.org
Removing the server_name from the second server definition works.
server {
listen 80 default_server;
access_log ... }
With these settings, browsing to foo.example.org/Default.aspx loads the page and HttpContext.Request.Url returns foo.example.org/Default.aspx
#stephen's answer is more simple and does not need fastcgi config modification.
I tried previous answer (before update), but it did not work.
Nginx take care of routing, as #stephen said, and the routing part worked.
to start fastcgi I used this command to match all routes (and server names)
fastcgi-mono-server4 /applications=/:/var/www/example.org/ /socket=tcp:127.0.0.1:9000
The problem was that HttpContext.Request.Url contains the $server_name value in my case it was "*.example.org" and when I try to parse URI there was an error.
To handle this I changed nginx fastcgi_params and replaced thi line
fastcgi_param SERVER_NAME $server_name;
by
fastcgi_param SERVER_NAME $http_host;
and add in site-available conf
proxy_set_header Host $host;
I think it is set by default.
reload nginx
nginx -t && service nginx reload
reload fastcgi-mono-server to test
fastcgi-mono-server4 /applications=/://var/www/example.org/ /socket=tcp:127.0.0.1:9000 /printlog=True /loglevels=Debug
in the log SERVER_NAME contains the real (not *) subomain.
I set up my domain on my server using nginx. So far so good my homepage works. But now I wanna add some locations for later test of programming. My plan is to call diffrent projects like mydomain.com/php/myprogramm.php
So I add some folder in /var/www/mydomain.com/php (my side index is in /var/www/mydomain.com/html)
Entering www.mydomain.com/php/ leads to an 403 error and mydomain.com/php/myprogramm.php says File not found...
this is my nginx file:
server {
listen 80 default_server;
#listen [::]:80 default_server ipv6only=on;
# Make site accessible from http://localhost/
server_name mydomain.com www.mydomain.com;
location / {
root /var/www/mydomain.com/html;
index index.html index.htm;
}
location /php/ {
root /var/www/mydomain.com;
}
location /js/ {
root /var/www/mydomain.com;
}
location /node/ {
root /var/www/mydomain.com;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
#
# # 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 fastcgi_params;
}
}
Of course when I set up my domain I also set sudo chown -R www-data:www-data /var/www/mydomain.com/html and sudo chmod 755 /var/www
Some ideas someone? :/
Problems analysis
The first golden rule is:
nginx always serves request from a single location only. (Re-)read http://nginx.org/en/docs/http/request_processing.html.
Based on your configuration:
Requests to (www.)mydomain.com/php/<whatever> for files not ending with .php will be served by location /php/ from /var/www/mydomain.com/php/<whatever>
Requests to (www.)mydomain.com/<whatever>.php will be served by location ~\.php$ from <default root ('html' by default)>/<whatever>.php
The first problem here is that you are not serving .php files from where you think you are. Learn from location documentation how the location block serving a request is chosen.
You will note that the 'File not found' error was not an nginx error, but a message generated by PHP. That helps to know whether the problem comes from (frontend or backend).
Now about that 403: it seems nginx has trouble accessing the location where it is supposed to serve content from. Check /var/www/mydomain.com/php/ (directory + contents) rights.
Proposed pieces of advice
Your configuration looks suboptimal.
If you use the same root in lots of location blocks, why not moving it one level upper so it becomes the default (which yo ucan override in specific locations where needed)?
You can used nested locations, ie to solve you PHP files serving problem. Note that it is always a good idea to enclose regex locations inside prefix locations (What is the difference? Read location documentation). The reason is regex locations are order-sensitive, which is bad for maintenance. Prefix locations are not since only the longest match with a request URI will be chosen.
Here is a propsed updated version of part of your configuration:
root /var/www/mydomain.com;
location / {
root /var/www/mydomain.com/html;
index index.html index.htm;
}
location /php/ {
location ~ \.php$ {
# Useless without use of $fastcgi_script_name and $fastcgi_path_info
# Moreover, requests ending up here always end with .php...
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# You seem to have copy-pasted this section without understanding it.
# Good understanding of what happens here is mandatory for security.
}
}
I suggest you read the documentation about fastcgi_split_path_info, $fastcgi_script_name and $fastcgi_path_info.
For my testing right now I fixed the issue quite simply.
I forogt to check my php.ini and change the cgi.fix_pathinfo to 0
Also I changed the group for my folders (still had root inside) to www-data.
At the end I updated my configuration: I set root /var/www/mydomain.com; in my server block (server{})
That's all I did.
But I will keep your advice in mind for later issues.
Thanks for your help I appreciate it.
After seeing this post http://www.ewanleith.com/blog/900/10-million-hits-a-day-with-wordpress-using-a-15-server I changed my server from apache2 to nginx. I am no computer geek just, savvy. I followed the steps. After that, the site was perfect, except for one thing: non-www to www thing. I searched all over the net on how to do this. I tried the modrewrite thing they said but just getting worst. For now, it is directed to www because I use wordpress and set it in general settings http://www.pageantly.com. Yet, I have static directories and it is in plain non-www. Please take a look on my default.conf in /etc/nginx/conf.d/ as well as the tutorial with link above:
server {
server_name pageantly.com www.pageantly.com;
root /var/www/;
listen 8080;
## This should be in your http block and if it is, it's not needed here.
index index.html index.htm index.php;
include conf.d/drop;
location / {
# This is cool because no php is touched for static content
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
fastcgi_buffers 8 256k;
fastcgi_buffer_size 128k;
fastcgi_intercept_errors on;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/dev/shm/php-fpm-www.sock;
}
# BEGIN W3TC Page Cache cache
location ~ /wp-content/w3tc/pgcache.*html$ {
add_header Vary "Accept-Encoding, Cookie";
}
[...]
}
# END W3TC Page Cache core
}
Ideally, each domain (sub-domains included) should have a separate server block. Going by that, your configuration would look like:
# Following block redirects all traffic coming to pageantly.com to www.pageantly.com
server {
server_name pageantly.com;
listen 8080;
# Send a 301 permanent redirect to any request which comes on this domain
return 301 http://www.pageantly.com$request_uri;
}
# Following block handles requests for www.pageantly.com
server {
server_name www.pageantly.com;
listen 8080;
root /var/www;
[...] # all your default configuration for the website
}
Another unclean and inefficient way to achieve this would be to introduce an if statement which reads domain value and branches flow accordingly either to redirect traffic (in case of pageantly.com) or to process requests (in case of www.pageantly.com) but I would recommend you avoid going by that route.
Hope this helps.
If you are using Route 53 on AWS; then you do NOT have to do any such thing. On Route53 itself we can create an alias and configure so that non-www is redirected to www.