Skip to content

Instantly share code, notes, and snippets.

@tpai
Last active September 6, 2017 07:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tpai/a907aa08c296b2e69369 to your computer and use it in GitHub Desktop.
Save tpai/a907aa08c296b2e69369 to your computer and use it in GitHub Desktop.
nginx related note

前端優化

  • Server 設置:啟用 gzip 壓縮、靜態內容設置 max-age/expires 或使用 CDN、動態內容設置 cache control。(樣板參考)
  • 減少 HTTP Requests:善用 CSS Sprite 解決大量載入圖片的問題,盡量以水平排列圖片,相較於垂直排列圖片大小較小。
  • favicon.ico:存在且小於 1KB 加上較長的 expires。
  • 預載:頁面加載完成後隨即加載用於其他頁面的資源。

CORS

config

SSL/TLS

Install Nginx Module

sudo apt-get install nginx-extras

/etc/nginx/nginx.conf

http {
    more_set_headers 'Access-Control-Allow-Origin: $http_origin';
    more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD';
    more_set_headers 'Access-Control-Allow-Credentials: true';
    more_set_headers 'Access-Control-Allow-Headers: auth,Origin,Content-Type,Accept,Authorization';
}

/etc/nginx/sites-enabled/default

location / {
    if ($request_method = 'OPTIONS') {
        more_set_headers 'Access-Control-Allow-Origin: $http_origin';
        more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD';
        more_set_headers 'Access-Control-Max-Age: 1728000';
        more_set_headers 'Access-Control-Allow-Credentials: true';
        more_set_headers 'Access-Control-Allow-Headers: auth,Origin,Content-Type,Accept,Authorization';
        more_set_headers 'Content-Type: text/plain; charset=UTF-8';
        more_set_headers 'Content-Length: 0';
        return 204;
    }
}

Ref: handling-cors-with-nginx

fetch snippets

// GET With Custom Header
fetch('/api', {
    method: 'GET',
    headers: {
        auth: token
    }
})

// GET With URL Parameters
const body = param({
    key1: 1,
    key2: [2, 3]
});
// /api?key1=1&key2[]=2&key2[]=3
fetch(`/api?${body}`, {
    method: 'GET'
})

// POST JSON
fetch('/api', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({...})
})

// POST Form Data
fetch('/api', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: param({
        ...
    })
})

Ref: param()

nginx.conf

server {
    listen      80;
    server_name localhost;

    gzip_http_version 1.0; # add this line for really enable gzip in official nginx docker image
    gzip on;
    gzip_types text/plain text/css application/json text/javascript application/javascript application/x-javascript text/xml application/xml application/xml+rss;

    # directly return HTTP 200 OK
    location = / {
        return 200 'OK';
        add_header Content-Type text/plain;
    }

    # resolve custom path
    location /custom {
        try_files $uri /index.html =404;
        alias   /usr/share/nginx/html; # 
        index   index.html index.htm;
    }
}
www.example.com/custom                =nginx=> /usr/share/nginx/html/index.html
www.example.com/custom/static/main.js =nginx=> /usr/share/nginx/html/static/main.js

Ref:

Step By Step Compile HTTP/2 NGINX

Run a container based on phusion/baseimage

docker run -p 80:80 -p 443:443 -it phusion/baseimage:0.9.18 /sbin/my_init -- bash -l

Update package list & install related packages

apt-get -y update
apt-get -y install openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev build-essential wget

Download nginx source and compile

wget http://nginx.org/download/nginx-1.9.14.tar.gz

tar zxvf nginx-1.9.14.tar.gz

cd nginx-1.9.14.tar.gz

./configure \
--user=nginx                          \
--group=nginx                         \
--prefix=/etc/nginx                   \
--sbin-path=/usr/sbin/nginx           \
--conf-path=/etc/nginx/nginx.conf     \
--pid-path=/var/run/nginx.pid         \
--lock-path=/var/run/nginx.lock       \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module        \
--with-http_stub_status_module        \
--with-http_ssl_module                \
--with-pcre                           \
--with-file-aio                       \
--with-http_realip_module             \
--with-http_v2_module                 \
--without-http_scgi_module            \
--without-http_uwsgi_module           \
--without-http_fastcgi_module

make && make install

Create SSL/TLS certification

cd /etc/nginx
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout cert.key -out cert.crt

Add nginx user

useradd -r nginx

Set configuration

        listen       443 ssl http2;

        ssl_certificate      cert.crt;
        ssl_certificate_key  cert.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !eNULL !LOW !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED';
        ssl_prefer_server_ciphers  on;

Run

nginx -c nginx.conf

Test

npm i -g is-http2-cli
brew update
brew upgrade openssl
brew link --force openssl
which openssl
mv /usr/bin/openssl /usr/bin/openssl_OLD
ln -s /usr/local/Cellar/openssl/1.0.2g/bin/openssl /usr/bin/openssl
is-http2 [ip-address]

Ref:

/etc/hosts

127.0.0.1 www.domain1.com
127.0.0.1 www.domain2.com
127.0.0.1 www.domain3.com

/etc/nginx/site-available/default

server {
        listen 80;
        listen [::]:80;

        server_name www.domain1.com;

        root /usr/share/nginx/html;

        location = / {
                try_files /another.html /404.html;
        }
        include /etc/nginx/allow-assets.conf;
}

/etc/nginx/valid-sites.conf

valid_referers blocked www.domain1.com www.domain2.com www.domain3.com;
if ($invalid_referer) {
        return 403;
}

/etc/nginx/allow-assets.conf

location ^~ /url/ {
        include /etc/nginx/valid-sites.conf;
        proxy_pass http://127.0.0.1:3000;
}
location ~* \/(images|dist|bin)\/ {
        include /etc/nginx/valid-sites.conf;
        if ($document_uri ~* \/images\/) {
                expires 30d;
                access_log off;
                add_header Pragma public;
                add_header Cache-Control "public";
        }
        try_files /$uri /404.html;
}
location = /standalone.html {
        try_files /$uri /404.html;
}
location / {
        return 404;
}

Ref:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment