IT_Server/Web_Server & WAS

[펌][NGINX] NGINX 주요 설정

JJun ™ 2013. 5. 24. 13:40


출처: http://blog.martinfjordvald.com/2010/07/nginx-primer/





Update: 
There is now a follow up to this post which deals with the differences between nginx and Apache, it is recommended reading if you come from Apache:

Nginx is a fairly simple HTTP server, though there are a few gotchas people need to be aware of before they start using this 8th wonder. The most important is that nginx is a reverse proxy first and HTTP server second, it does not necessarily have a concept of file, this will change the way we handle our configuration a bit.

The first thing you need to know is that the nginx configuration file is an inheriting-hierarchy, directives specified in a higher block will filter down to lower blocks as a default value, from this follows that we want to specify things in the top most hierarchy whenever possible. Since directives in top blocks filter down as default values it is still possible to override them in most cases.

There are 3 hierarchies which are usually referred to as blocks. The HTTP-block, the server-block and the location block of which the hierarchy goes like this: http -> server -> location. (I have since gone into more details in a new blog post)

Furthermore there are two special locations, an event block and the root which the event block and the http block reside in. Both of these contain only a minor amount of directives. The majority of your time will be spent in the other three blocks.

The blocks have a semantic meaning of sorts. The server block is what in Apache would be considered a virtual host. The location block usually referrers to the URI.

When using the official wiki the context keyword specifies in which block a directive may be used, as mentioned earlier it is usually recommended to specify the directive in the top most block.

Virtual Hosts

To begin with the most interesting directives are server_name and root. The former instruct nginx to use this server block when the HOST header matches the value and the latter defines what to use as root when looking for files.

This forms the basic of our virtual hosts, an example would be:

  1. server {
  2. listen          80;
  3. server_name     domain.com *.domain.com;
  4. return 301 $scheme://www.domain.com$request_uri;
  5. }
  6.  
  7. server {
  8. listen          80;
  9. server_name     www.domain.com;
  10.  
  11. index index.html;
  12. root /home/domain.com;
  13. }

Here we have two virtual hosts. The first one is hit when domain.com or any subdomain of domain.com except for www is sent as the HOST header by the browser. The reason for this is that nginx will always choose the most specific match, and if visting www.domain.com then this will match the second block precisely.

This also means you can create a default virtual host to catch all domains without a proper match. Thankfully this is as simple as adding the default_server flag to the listen directive. This causes all request without a HOST header or without another vhost matching the HOST header to be sent to this vhost instead. Examples are requests accessing the IP directly or if someone points a random domain at your IP. The server_name _; which you will see mentioned in a lot of guides means nothing and does nothing. It’s just a bogus invalid HOST header that can be used to make sure nothing ever matches it. You should be able to simply not define a server_name.

  1. server {
  2. listen 80 default_server;
  3.  
  4. index index.html;
  5. root /var/www/default;
  6. }

Locations

If you’re changing over from Apache then this is where you want to pay attention. nginx typically does not use complicated rewrites – usually we can accomplish the same using a location block.

The most important things to note are that locations, with the exception of named locations, works on the URI without any query parameters and only one location block will ever be run. This is also why I recommend putting directives in the top most block. A root directive defined in location / will not be available in location /images – unless defined in the server block. I trust you see how defining things in the upper most block will prevent code duplication and headaches.

Another important point about locations is that, as with server_name directive, nginx will use the most specific location block. There are a few rules for how specific various setups will be, the location directive wiki entry explains this very well, so you should read that first.

Let us look at a few examples of how to use a location block. In this example we’ve run a forum on URI /forum/ and have recently moved it to a subdomain. We now need to redirect the old URLs to the new URLs. To do this we use a regex location with a named variable and then issue our redirect.

  1. server {
  2. listen 80 default;
  3. server_name www.domain.com;
  4.  
  5. root /home/domain.com;
  6.  
  7. # This will match any URI beginning with /forum
  8. location ~ ^/forum/(?P.*)$ {
  9. return 301 $scheme://forum.domain.com/$1;
  10. }
  11. }
  12. server {
  13. listen 80;
  14. server_name forum.domain.com;
  15. index index.php;
  16. root /home/domain.com/forum;
  17. }

The requests for /forum are now successfully transferred to our new subdomain while requests to files not in /forum will be served from our normal /home/domain.com root.

Handling PHP

PHP – or any backend really ties in well with locations, namely we can define a location block to catch all PHP files.

  1. server {
  2. listen 80;
  3. server_name forum.domain.com;
  4.  
  5. index index.php;
  6. root /home/domain.com/forum;
  7.  
  8. location ~* \.php$ {
  9. include fastcgi.conf # I include this in http context, it's just here to show it's required for fastcgi!
  10. try_files $uri =404; # This is not needed if you have cgi.fix_pathinfo = 0 in php.ini (you should!)
  11. fastcgi_pass 127.0.0.1:9000;
  12. }
  13. }

As mentioned previously, nginx does not care about files but rather locations and this is why I have a try_files directive inside the php block. This location block matches a URI that ends in .php but it does not care if it’s a file or not. Therefore a request for /forum/avatars/user2.jpg/index.php will be matched and sent to PHP, and if PHP is not configured properly PHP will then execute /forum/avatars/user2.jpg when /forum/avatars/user2.jpg/index.php doesn’t exist. This provides a huge security risk. Do note that this is not a bug in nginx, it’s the intended behaviour and as such will not be “fixed”.

This can also be fixed on the PHP side by setting cgi.fix_pathinfo=0 in the php.ini file.

The end result, though, is that .php files which exist will be passed via fastcgi to our PHP processes running on port 9000.

The Finishing Touch – SEF URLs

This setup works, but all the craze these days is to have search engine friendly URLs for SEO reasons. Usually this involves quite a few rewrites, but with nginx we can do it with just one line, provided the backend script is written in a sane way.

  1. server {
  2. listen 80;
  3. server_name forum.domain.com;
  4.  
  5. index index.php;
  6. root /home/domain.com/forum;
  7.  
  8. location / {
  9.  try_files $uri $uri/ /index.php;
  10. }
  11.  
  12. location ~* \.php$ {
  13. include fastcgi.conf; # I include this in http context, it's just here to show it's required for fastcgi!
  14. try_files $uri =404; # This is not needed if you have cgi.fix_pathinfo = 0 in php.ini (you should!)
  15. fastcgi_pass 127.0.0.1:9000;
  16. }
  17. }

Did you notice the change? It’s minimal really. The one try files line means that it will first try accessing the full URI, which means that a static file request will end here. Secondly it will try the full URI plus a slash, thus looking for a directory. Finally, if none of these are found it will send the request to /index.php and perform a new location match, which will of course hit our PHP location and fastcgi_pass the request. PHP will then have the full URI in $_SERVER['PATH_INFO']. Simple, elegant and easy to understand.

Debugging Requests

Nginx is a complicated server at times, thankfully we have an excellent error log available to us to help figure out where things are going wrong. If you check the error log directive in the wiki you will notice that it takes a second argument. This will let you define how much information is output by nginx. A value of info will give you sufficient info to debug most issues.

Further Reading

The official nginx wiki is an invaluable resource, a good way to expand your knowledge about nginx is to read the directives and variables in the Core module. Also see the full config example to get an idea of a more complex configuration file.






더보기


[출처: http://whiteship.me/?p=13014]


Nginx는 우선 리버스 프록시이고 그 다음이 HTTP 서버라는 점이 중요하다.

Nginx 설정에 있어서 가장 먼저 알아야 할 것은 설정 파일의 계층 구조다. 상위 블럭의 설정이 하위 블럭의 기본값으로 사용된다. 물론 하위 설정에서 재정의 할 수도 있다.

보통 3 블럭으로 나뉜다.

  • HTTP 블럭
  • server 블럭
  • location 블럭

http{

server {

location {

}
}

}

event 블럭과 root 블럭(event 블럭과 HTTP 블럭을 포함하는 블럭)도 있지만 이 둘은 잘 다루지 않는다. 주로 위의 세가지 블럭을 다룬다.

server 블럭은 아파치의 virtual host로 볼 수 있있고, location 블럭은 URI로 볼 수 있다.

Virtual Hosts

가장 눈여겨 볼 설정은 server_name과 root다. HOST 헤더가 server_name에 대응하면 해당 server 블럭을 사용하라고 지시하는것이고, root는 파일을 찾을 루트를 지정한다.

server {
listen 80;
server_name domain.com *.domain.com;
rewrite ^ http://www.domain.com$request_uri permanent;
}

server {
listen 80;
server_name www.domain.com;

index index.html;
root /home/domain.com
}virtual host 두 개를 설정했다. 첫번째 설정은 domain.com또는 www를 제외한 domain.com의 서브 도메인에 해당하는 server 블럭 설정이다. Nginx는 가장 구체적으로 대응하는 것을 선택하기 때문에 www.domain.com은 두번째 블럭에 대응한다.

server {
listen 80 default_server;
server_name _;

index index.html;
root /var/www/default
}

이 설정은 default virtual server를 설정한 것이다. default_server 플래그를 추가하면 HOST 헤더가 없거나 server 블럭 중 대응하는 것이 없을 때 이 곳으로 오게된다. server_name에 설정한 _; 값은 nothing에 해당한다. 아무것도 대응하지 않도록 할 때 사용할 수 있는데 server_name을 아에 정의하지 않을 수도 있다.

Locations

Nginx에서는 보통 복잡한 rewrites 대신 location을 사용한다.

http://wiki.nginx.org/NginxHttpCoreModule#location

server {
listen 80 default;
server_name www.domain.com;

root /home/domain.com

# This will match any URI beginning with /forum
location /forum {
# We capture the URI and redirect it to the subdomain.
rewrite forum(.*) http://forum.domain.com$1 permanent;
}
}

server {
listen 80;
server_name forum.domain.com;

index index.php;
root /home/domain.com/forum;
}

/forum으로 요청이 오면 새로운 서브 도메인으로 보낸다.

나머지 생략