Nginx Configuration

As a web developer, nginx is often used in deployment architecture. Write down the useful nginx configuration examples here.

Intall nginx is very easy and not describe here. Configuration good reference here

底下的設定值是用最基本的nginx install, 沒有額外的module

Basic configuration

/etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 最基本的設定,不詳述
user  nginx;
worker_processes  1;
pid        /var/run/nginx.pid;

events {
  worker_connections  1024;
}

http {
  # 載入支援的mime type
  include       /etc/nginx/mime.types;

  # 當有不認識的mime type時就用octet-stream當一般binary檔案處理
  default_type  application/octet-stream;

  # 定義自己的log format
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

  # access log存放位置並且使用 main 這個log format,也就是上述定義的格式
  # buffer=8k 表示不會一直寫log到disk,等到buffer滿了才寫,避免I/O過重
  access_log  /var/log/nginx/access.log main buffer=8k;


  ## Size Limits
  # 當request body超過這個body size時會被先寫進暫存檔處理
  client_body_buffer_size   8k;

  # 限制http header的大小
  client_header_buffer_size 1k;

  # 限制request body大小,超過server會回傳413(Request Entity Too Large)
  client_max_body_size      1m;

  ## Timeouts, do not keep connections open longer then necessary to reduce
  # 讀取request body timeout時間,超過時間會回傳408(Request time out)
  client_body_timeout     4s;

  # 讀取request header timeout時間(e.g GET HTTP/1.1),超過時間回傳408(Request time out)
  client_header_timeout   2s;

  # HTTP 1.1 keepalive的timeout時間, 各家browser各有不同時間.
  keepalive_timeout       65s;

  # 送資料給client的timeout時間(指得是兩次資料讀取時間), 降低這個值可以避免Slowloris DoS attack
  send_timeout            5s;

  ## General Options
  # 設定值 >=1 的話讓NGINX支持下載部份檔。 如果你的server有要讓人下載大檔續傳的話..
  max_ranges 0;

  # keepalive的連線最大數量
  keepalive_requests        5;

  # Browder cache 失效時間, 負值的話表示不要有任何cache.
  expires 1d;

  # Request limits
  # 限制一個IP在1秒內只處理5個requests
  # myzone是自行定義的名稱,用來存放IP, 2m表示最大不超過2M記憶體
  limit_req_zone  $binary_remote_addr  zone=myzone:2m  rate=5r/s;


  # 載入其它設定檔
  include /etc/nginx/conf.d/*.conf;

}

How to reverse proxy?

Separate the config from nginx.conf is good practice. I move server defination into default.conf

/etc/nginx/conf.d/default.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 定義在後端的servers
upstream backend_web_servers {
  server 192.168.0.102:3000 max_fails=250 fail_timeout=180s;
  server 192.168.0.103:3000 max_fails=250 fail_timeout=180s;

  # 設了backup後只有當上面102,103 server都掛點時才會導request到底下100
  server 192.168.0.100 backup;
}

server {
  # listening on 80 port. 額外設定socket receive和send buffer size
  listen 80 rcvbuf=8k sndbuf=8k;

  # server名稱
  server_name www.myserver.io

  # 文件根目錄
  root /usr/share/nginx/html;

  # 限制一個IP不能超過10個open connections. nodelay會讓超過限制的connection直接回傳503不等待
  limit_req zone=myzone burst=10 nodelay;

  # location 怎麼用可以參考http://cssor.com/nginx-location-configuration.html
  location / {
    try_files $uri @backend_web_servers;
  }

  location @backend_web_servers {
    # 允許proxies server cache網頁,看個人需求。如果你的網頁有太多個人資訊就不建議public
    add_header  Cache-Control "public";

    # 不允許網頁內容被放進iframe
    add_header  X-Frame-Options "DENY";

    # header設定. 將real ip傳進backend servers
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    # 將request proxy到後端server
    proxy_pass http://backend_web_servers;
  }

}

Redirect domain name.

For instance: redirect http://myserver.io to http://www.myserver.io. The official document suggest us using return not rewrite.

/etc/nginx/conf.d/redirect_server.conf
1
2
3
4
5
server {
  listen 80;
  server_name myserver.io;
  return 301 $scheme://www.myserver.io$request_uri;
}

Enable/Disable Maintenance mode

If the maintenance.html exists, it shows maintenance page first. And disable the cache(set expires -1) to prevent browser cache maintenance.html.

/etc/nginx/conf.d/default.conf
1
2
3
4
5
6
7
location / {
  try_files /maintenance.html $uri @backend_web_servers;
}

location /maintenance.html {
  expires -1; # prevent maintenance.html cached
}

Serve static resources for RAILS

All requests to assets folder like http://127.0.0.1/assets/applicatoin-xxxxx.js will be served by Nginx.

/etc/nginx/conf.d/default.conf
1
2
3
location ^~ /assets/ {
  root /home/rails/myrail/public/;
}

Comments