Node.js + Nginx - Apa sekarang?

1003

Saya sudah mengatur Node.js dan Nginx di server saya. Sekarang saya ingin menggunakannya, tetapi, sebelum saya mulai ada 2 pertanyaan:

  1. Bagaimana seharusnya mereka bekerja bersama? Bagaimana saya harus menangani permintaan?
  2. Ada 2 konsep untuk server Node.js, mana yang lebih baik:

    Sebuah. Buat server HTTP terpisah untuk setiap situs web yang membutuhkannya. Kemudian muat semua kode JavaScript pada awal program, sehingga kode ditafsirkan sekali.

    b. Buat satu server Node.js tunggal yang menangani semua permintaan Node.js. Ini membaca file yang diminta dan memeriksa isinya. Jadi file ditafsirkan pada setiap permintaan, tetapi logika server jauh lebih sederhana.

Tidak jelas bagi saya cara menggunakan Node.js dengan benar.

Van Coding
sumber

Jawaban:

1306

Nginx berfungsi sebagai server ujung depan, yang dalam hal ini proksi permintaan ke server node.js. Oleh karena itu Anda perlu mengatur file konfigurasi nginx untuk node.

Inilah yang telah saya lakukan di kotak Ubuntu saya:

Buat file yourdomain.comdi /etc/nginx/sites-available/:

vim /etc/nginx/sites-available/yourdomain.com

Di dalamnya Anda harus memiliki sesuatu seperti:

# the IP(s) on which your node server is running. I chose port 3000.
upstream app_yourdomain {
    server 127.0.0.1:3000;
    keepalive 8;
}

# the nginx server instance
server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com www.yourdomain.com;
    access_log /var/log/nginx/yourdomain.com.log;

    # pass the request to the node.js server with the correct headers
    # and much more can be added, see nginx config options
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;

      proxy_pass http://app_yourdomain/;
      proxy_redirect off;
    }
 }

Jika Anda ingin nginx (> = 1.3.13) juga menangani permintaan websocket, tambahkan baris berikut di location /bagian ini:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Setelah Anda memiliki pengaturan ini, Anda harus mengaktifkan situs yang ditentukan dalam file konfigurasi di atas:

cd /etc/nginx/sites-enabled/ 
ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com

Buat aplikasi server simpul Anda di /var/www/yourdomain/app.jsdan jalankan dilocalhost:3000

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(3000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:3000/');

Tes untuk kesalahan sintaks:

nginx -t

Mulai ulang nginx:

sudo /etc/init.d/nginx restart

Terakhir mulai server simpul:

cd /var/www/yourdomain/ && node app.js

Sekarang Anda akan melihat "Hello World" di yourdomain.com

Satu catatan terakhir berkaitan dengan memulai server simpul: Anda harus menggunakan semacam sistem pemantauan untuk daemon simpul. Ada tutorial mengagumkan tentang simpul dengan pemula dan monit .

Joao Da Silva
sumber
11
Terima kasih untuk posting ini, akan nginx cache tanggapan node.js untuk server di atas, atau jalankan kembali setiap kali.
Lime
79
Apakah ada alasan mengapa Anda tidak bisa begitu saja melakukannya location / { proxy_pass http://127.0.0.1:3000; }? Mengapa Anda membutuhkan seluruh upstreambit konfigurasi?
Robin Winslow
20
+1, jawaban yang sangat mudah dan sederhana untuk pertanyaan umum; bagus untuk orang-orang yang ingin mengatur host virtual menggunakan node dan nginx. Satu-satunya hal yang saya pikir Anda lewatkan adalah jawaban kualitatif mengapa nginx-in-front-of-node terbaik untuk melayani banyak vhosts (pertanyaan kedua penanya).
Paul d'Aoust
34
@Robin Winslow jika Anda ingin menambahkan lebih banyak server untuk server untuk load balancing.
Joao Da Silva
76
Perlu dicatat bahwa jawaban (sangat membantu) ini merujuk pada satu rasa nginx yang, secara default, datang bersama sites-enableddan sites-availabledirektori di dalamnya /etc/nginx. Jika versi Anda datang tanpa dua direktori ini, kemungkinan direktori tersebut memiliki satu conf.ddirektori saja. Dalam hal ini, mengikuti petunjuk ini tidak akan berpengaruh, KECUALI Anda memodifikasi includepernyataan di dalam file nginx.confuntuk menunjuk ke sites-enabledbukan standar conf.d. Harapan itu masuk akal. Itu harus menjadi cukup jelas setelah Anda melihat includepernyataan di dalam nginx.conf.
meetamit
167

Anda juga dapat mengatur beberapa domain dengan nginx, meneruskan ke banyak proses node.js.

Misalnya untuk mencapai ini:

Port-port ini (4000 dan 5000) harus digunakan untuk mendengarkan permintaan aplikasi dalam kode aplikasi Anda.

/ etc / nginx / situs-enabled / domain1

server {
    listen 80;
    listen [::]:80;
    server_name domain1.com;
    access_log /var/log/nginx/domain1.access.log;
    location / {
        proxy_pass    http://127.0.0.1:4000/;
    }
}

Di / etc / nginx / situs-enabled / domain2

server {
    listen 80;
    listen [::]:80;
    server_name domain2.com;
    access_log /var/log/nginx/domain2.access.log;
    location / {
        proxy_pass    http://127.0.0.1:5000/;
    }
}
250R
sumber
5
Saya menggunakan metode proxy_pass Anda, tetapi karena suatu alasan http://example.comotomatis saya akan 302melakukannya http://www.example.com. Mengapa demikian?
Kristian
Apakah Anda memiliki Cloudflare atau yang serupa? Konfigurasi di atas seharusnya tidak mengarahkan sama sekali.
ozzieisaacs
1
@Kristian Anda harus menambahkan proxy_set_header Host $hostuntuk menghindari pengalihan HTTP 302.
Ivan Shatsky
@IvanShatsky - Dapatkah Anda memberikan bantuan cara mengkonfigurasi beberapa port dengan beberapa sub domain dan mencegah port lain berjalan di domain lain?
Nginx
59

Anda juga dapat memiliki url berbeda untuk aplikasi dalam satu konfigurasi server:

Di / etc / nginx / situs-enabled / yourdomain :

server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com;

    location ^~ /app1/{
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass    http://127.0.0.1:3000/;
    }

    location ^~ /app2/{
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass    http://127.0.0.1:4000/;
    }
}

Mulai ulang nginx:

sudo service nginx restart

Memulai aplikasi.

simpul app1.js

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello from app1!\n');
}).listen(3000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:3000/');

simpul app2.js

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello from app2!\n');
}).listen(4000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:4000/');
0x8BADF00D
sumber
3
Versi komunitas open source adalah gratis tetapi mereka memiliki versi dengan fitur lain yang tidak gratis. nginx.com/products/feature-matrix
0x8BADF00D
Maaf atas ketidaktahuan saya. Apa tujuannya, manfaat melayani dengan cara ini? apakah Anda memiliki contoh atau kasus penggunaan? Terima kasih sebelumnya.
Mauro Aguilar
2
@ MauroAguilar Jika Anda membutuhkan aplikasi 2 node.js di satu server, Anda dapat melayani mereka menggunakan cara yang disarankan (menggunakan port yang berbeda). Dalam kasus saya itu adalah dua aplikasi pengujian yang berbeda.
0x8BADF00D
Ok, tapi apa perbedaan antara menjalankan 2 aplikasi dan satu aplikasi? Maksud saya, apa manfaatnya jika dimaksudkan untuk tujuan yang sama?
Mauro Aguilar
2
@ MauroAguilar, Anda dapat menjalankannya dalam satu dan tidak ada manfaatnya jika itu bisa menjadi bagian dari satu proyek dan memiliki tujuan yang sama. Tetapi jika Anda perlu menjalankan 2 proyek yang berbeda dengan tujuan yang berbeda dan dengan konfigurasi yang berbeda pada satu server, maka Anda dapat memanfaatkan konfigurasi ini.
0x8BADF00D
35

Saya proksi aplikasi Node Express independen melalui Nginx.

Dengan demikian aplikasi baru dapat dengan mudah dipasang dan saya juga dapat menjalankan hal-hal lain di server yang sama di lokasi yang berbeda.

Berikut ini rincian lebih lanjut tentang pengaturan saya dengan contoh konfigurasi Nginx:

Menyebarkan beberapa aplikasi Node pada satu server web dalam subfolder dengan Nginx

Hal-hal menjadi rumit dengan Node ketika Anda perlu memindahkan aplikasi Anda dari dari localhost ke internet.

Tidak ada pendekatan umum untuk penyebaran Node.

Google dapat menemukan banyak artikel tentang topik ini, tetapi saya berjuang untuk menemukan solusi yang tepat untuk pengaturan yang saya butuhkan.

Pada dasarnya, saya memiliki server web dan saya ingin aplikasi Node di-mount ke subfolder (yaitu http: // myhost / demo / pet-project / ) tanpa memperkenalkan ketergantungan konfigurasi pada kode aplikasi.

Pada saat yang sama saya ingin hal-hal lain seperti blog dijalankan di server web yang sama.

Kedengarannya sederhana ya? Sepertinya tidak.

Dalam banyak contoh di web, aplikasi Node dijalankan pada port 80 atau diproksikan oleh Nginx ke root.

Meskipun kedua pendekatan ini valid untuk kasus penggunaan tertentu, mereka tidak memenuhi kriteria saya yang sederhana namun sedikit eksotis.

Itulah sebabnya saya membuat konfigurasi Nginx saya sendiri dan ini adalah ekstraknya:

upstream pet_project {
  server localhost:3000;
}

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

  location /demo/pet-project {
    alias /opt/demo/pet-project/public/;
    try_files $uri $uri/ @pet-project;
  }

  location @pet-project {
    rewrite /demo/pet-project(.*) $1 break;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $proxy_host;
    proxy_set_header X-NginX-Proxy true;

    proxy_pass http://pet_project;
    proxy_redirect http://pet_project/ /demo/pet-project/;
  }
}

Dari contoh ini Anda dapat melihat bahwa saya memasang aplikasi Pet Project Node saya yang berjalan pada port 3000 ke http: // myhost / demo / pet-project .

Nginx pertama memeriksa apakah sumber daya yang diminta adalah file statis yang tersedia di / opt / demo / pet-project / public / dan jika demikian itu berfungsi seperti itu yang sangat efisien, jadi kita tidak perlu memiliki lapisan yang berlebihan seperti Connect middleware statis.

Kemudian semua permintaan lainnya ditimpa dan diproksikan ke aplikasi Pet Project Node , sehingga aplikasi Node tidak perlu tahu di mana ia sebenarnya dipasang dan dengan demikian dapat dipindahkan ke mana saja murni dengan konfigurasi.

proxy_redirect adalah keharusan untuk menangani header Lokasi dengan benar. Ini sangat penting jika Anda menggunakan res.redirect () di aplikasi Node Anda.

Anda dapat dengan mudah meniru pengaturan ini untuk beberapa aplikasi Node yang berjalan pada port yang berbeda dan menambahkan lebih banyak penangan lokasi untuk tujuan lain.

Dari: http://skovalyov.blogspot.dk/2012/07/deploy-multiple-node-applications-on.html

skovalyov
sumber
1
Mengapa dan bagaimana Anda harus melakukannya di subdomain: skovalyov.blogspot.dk/2012/10/…
skovalyov
Tautkan hanya jawaban ... bisakah Anda meringkas bagian-bagian yang relevan dalam jawaban Anda jika blog Anda hilang?
kaiser
11

Node.js dengan konfigurasi Nginx.

$ sudo nano /etc/nginx/sites-available/subdomain.your_domain.com

tambahkan konfigurasi berikut sehingga Nginx bertindak sebagai proxy redirect ke port 3000 traffic dari server ketika kita berasal dari “subdomain.your_domain.com”

upstream subdomain.your_domain.com {
  server 127.0.0.1:3000;
}
server {
  listen 80;
  listen [::]:80;
  server_name subdomain.your_domain.com;
  access_log /var/log/nginx/subdomain.your_domain.access.log;
  error_log /var/log/nginx/subdomain.your_domain.error.log debug;
  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarder-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_pass http://subdomain.your_domain.com;
    proxy_redirect off;
  }
}
aquadir
sumber
9

menjawab pertanyaan Anda 2:

Saya akan menggunakan opsi bhanya karena mengkonsumsi sumber daya yang jauh lebih sedikit. dengan opsi 'a', setiap klien akan menyebabkan server mengkonsumsi banyak memori, memuat semua file yang Anda butuhkan (walaupun saya suka php, ini adalah salah satu masalah dengan itu). Dengan opsi 'b' Anda dapat memuat perpustakaan Anda (kode yang dapat digunakan kembali) dan membaginya di antara semua permintaan klien.

Tetapi perlu diketahui bahwa jika Anda memiliki banyak core, Anda harus men-tweak node.js untuk menggunakan semuanya.

Hugo Mota
sumber
2
Ikuti saran ini jika sumber daya adalah masalah Anda yang paling penting (tidak mungkin). Ada beberapa kompromi yang berbeda antara (a) dan (b). Opsi (a) mungkin lebih baik jika Anda ingin situs menjadi lebih mandiri misalnya memulai kembali atau pemeliharaan situs, koneksi db, basis kode, dependensi perpustakaan, memindahkan situs antar server, dll.
robocat
8

Saya membuat repositori di Github yang bisa Anda tiru, vagrant-node-nginx-boilerplate

pada dasarnya aplikasi node.js di /var/www/nodeappis

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(4570, '127.0.0.1');

console.log('Node Server running at 127.0.0.1:4570/');

dan konfigurasi nginx at /etc/nginx/sites-available/adalah

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

        root /var/www/nodeapp;
        index index.html index.htm;

        server_name localhost;

        location / {
          proxy_pass http://127.0.0.1:4570;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection 'upgrade';
          proxy_set_header Host $host;
          proxy_cache_bypass $http_upgrade;
        }
}
svnm
sumber
5

Anda juga bisa menggunakan node.js untuk menghasilkan file statis ke direktori yang dilayani oleh nginx. Tentu saja, beberapa bagian dinamis situs Anda dapat dilayani oleh simpul, dan sebagian oleh nginx (statis).

Memiliki beberapa dari mereka dilayani oleh nginx meningkatkan kinerja Anda ..

Matej
sumber
5

Kita dapat dengan mudah mengatur aplikasi Nodejs dengan Nginx bertindak sebagai proxy terbalik.
Konfigurasi berikut menganggap aplikasi NodeJS berjalan pada 127.0.0.1:8080,

  server{
     server_name domain.com sub.domain.com; # multiple domains

     location /{ 
      proxy_pass http://127.0.0.1:8080;  
      proxy_set_header Host $host;
      proxy_pass_request_headers on;  
     }

     location /static/{
       alias /absolute/path/to/static/files; # nginx will handle js/css
     }
   } 

dalam pengaturan di atas aplikasi Nodejs Anda akan,

  • dapatkan HTTP_HOSTtajuk tempat Anda dapat menerapkan logika khusus domain untuk melayani respons. '
  • Aplikasi Anda harus dikelola oleh manajer proses seperti pm2 atau penyelia untuk menangani situasi / penggunaan kembali soket atau sumber daya dll.

  • Siapkan layanan pelaporan kesalahan untuk mendapatkan kesalahan produksi seperti sentry atau rollbar

CATATAN: Anda dapat mengatur logika untuk menyerahkan rute permintaan khusus domain, membuat middleware untuk aplikasi expressjs

Renjith Thankachan
sumber
1
Alasan lain untuk menggunakan PM2 adalah agar Anda dapat menjalankan aplikasi 'selamanya' setelah keluar dari shell, dan secara otomatis memulai jika Anda perlu me-reboot server Anda, lihat: pm2.keymetrics.io/docs/usage/startup
SeanQuinn781
3

Nginx dapat bertindak sebagai server proxy terbalik yang berfungsi seperti manajer proyek. Ketika mendapat permintaan, itu menganalisis dan meneruskan permintaan ke hulu (anggota proyek) atau menangani sendiri. Nginx memiliki dua cara untuk menangani permintaan berdasarkan cara konfigurasi.

  • melayani permintaan
  • meneruskan permintaan ke server lain

    server{
     server_name mydomain.com sub.mydomain.com;
    
     location /{ 
      proxy_pass http://127.0.0.1:8000;  
      proxy_set_header Host $host;
      proxy_pass_request_headers on;  
     }
    
     location /static/{
       alias /my/static/files/path;
     }

    }

Server permintaan

Dengan konfigurasi ini, ketika URL permintaan mydomain.com/static/myjs.jsmengembalikan myjs.jsfile dalam /my/static/files/pathfolder. Saat Anda mengkonfigurasi nginx untuk menyajikan file statis, itu menangani permintaan itu sendiri.

meneruskan permintaan ke server lain

Ketika url permintaan adalah mydomain.com/dothisnginx akan meneruskan permintaan ke http://127.0.0.1:8000 . Layanan yang berjalan pada port localhost 8000 akan menerima permintaan dan mengembalikan respons ke nginx dan nginx mengembalikan respons ke klien.

Ketika Anda menjalankan server node.js pada port 8000 nginx akan meneruskan permintaan ke node.js. Tulis logika node.js dan tangani permintaan tersebut. Itu saja Anda memiliki server nodejs Anda berjalan di belakang server nginx.

Jika Anda ingin menjalankan layanan lain selain nodejs, jalankan saja layanan lain seperti Django, flask, php pada port yang berbeda dan konfigurasikan dalam nginx.

Vkreddy Komatireddy
sumber
1

Anda dapat menjalankan nodejs menggunakan PM2 jika Anda ingin mengelola setiap sarana microservice dan menjalankannya. Node akan berjalan di port yang benar, cukup konfigurasikan port itu di nginx (/etc/nginx/sites-enabled/domain.com)

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

  location / {
     return 403;
  }
    location /url {
        proxy_pass http://localhost:51967/info;
    }
}

Periksa apakah localhost sedang berjalan atau tidak dengan menggunakan ping.

Dan

Create one single Node.js server which handles all Node.js requests. This reads the requested files and evals their contents. So the files are interpreted on each request, but the server logic is much simpler.

Ini yang terbaik dan seperti yang Anda katakan lebih mudah juga

gokul kandasamy
sumber
1

Setup terbaik dan sederhana dengan Nginx dan Nodejs adalah menggunakan Nginx sebagai penyeimbang beban HTTP dan TCP dengan proxy_protocol diaktifkan. Dalam konteks ini, Nginx akan dapat mem-proxy permintaan masuk ke nodejs, dan juga mengakhiri koneksi SSL ke server Nginx backend, dan tidak ke server proxy itu sendiri. (SSL-Lewati)

Menurut pendapat saya, tidak ada gunanya memberikan contoh non-SSL, karena semua aplikasi web (atau seharusnya) menggunakan lingkungan yang aman.

Contoh konfigurasi untuk server proxy, di /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
  upstream webserver-http {
    server 192.168.1.4; #use a host port instead if using docker
    server 192.168.1.5; #use a host port instead if using docker
  }
  upstream nodejs-http {
    server 192.168.1.4:8080; #nodejs listening port
    server 192.168.1.5:8080; #nodejs listening port
  }
  server {
    server_name example.com;
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_set_header Connection "";
      add_header       X-Upstream $upstream_addr;
      proxy_redirect     off;
      proxy_connect_timeout  300;
      proxy_http_version 1.1;
      proxy_buffers 16 16k;
      proxy_buffer_size 16k;
      proxy_cache_background_update on;
      proxy_pass http://webserver-http$request_uri;
    }
  }
  server {
    server_name node.example.com;
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";
      add_header       X-Upstream $upstream_addr;
      proxy_redirect     off;
      proxy_connect_timeout  300;
      proxy_http_version 1.1;
      proxy_buffers 16 16k;
      proxy_buffer_size 16k;
      proxy_cache_background_update on;
      proxy_pass http://nodejs-http$request_uri;
    }
  }
}
stream {
  upstream webserver-https {
    server 192.168.1.4:443; #use a host port instead if using docker
    server 192.168.1.5:443; #use a host port instead if using docker
  }

  server {
    proxy_protocol on;
    tcp_nodelay on;
    listen 443;
    proxy_pass webserver-https;
  }
  log_format proxy 'Protocol: $protocol - $status $bytes_sent $bytes_received $session_time';
  access_log  /var/log/nginx/access.log proxy;
  error_log /var/log/nginx/error.log debug;
}

Sekarang, mari kita menangani server web backend. /etc/nginx/nginx.conf :

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
load_module /etc/nginx/modules/ngx_http_geoip2_module.so; # GeoIP2
events {
    worker_connections  1024;
}
http {
    variables_hash_bucket_size 64;
    variables_hash_max_size 2048;
    server_tokens off;
    sendfile    on;
    tcp_nopush  on;
    tcp_nodelay on;
    autoindex off;
    keepalive_timeout  30;
    types_hash_bucket_size 256;
    client_max_body_size 100m;
    server_names_hash_bucket_size 256;
    include         mime.types;
    default_type    application/octet-stream;
    index  index.php index.html index.htm;
    # GeoIP2
    log_format  main    'Proxy Protocol Address: [$proxy_protocol_addr] '
                        '"$request" $remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';

    # GeoIP2
    log_format  main_geo    'Original Client Address: [$realip_remote_addr]- Proxy Protocol Address: [$proxy_protocol_addr] '
                            'Proxy Protocol Server Address:$proxy_protocol_server_addr - '
                            '"$request" $remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '$geoip2_data_country_iso $geoip2_data_country_name';

    access_log  /var/log/nginx/access.log  main_geo; # GeoIP2
#===================== GEOIP2 =====================#
    geoip2 /usr/share/geoip/GeoLite2-Country.mmdb {
        $geoip2_metadata_country_build  metadata build_epoch;
        $geoip2_data_country_geonameid  country geoname_id;
        $geoip2_data_country_iso        country iso_code;
        $geoip2_data_country_name       country names en;
        $geoip2_data_country_is_eu      country is_in_european_union;
    }
    #geoip2 /usr/share/geoip/GeoLite2-City.mmdb {
    #   $geoip2_data_city_name city names en;
    #   $geoip2_data_city_geonameid city geoname_id;
    #   $geoip2_data_continent_code continent code;
    #   $geoip2_data_continent_geonameid continent geoname_id;
    #   $geoip2_data_continent_name continent names en;
    #   $geoip2_data_location_accuracyradius location accuracy_radius;
    #   $geoip2_data_location_latitude location latitude;
    #   $geoip2_data_location_longitude location longitude;
    #   $geoip2_data_location_metrocode location metro_code;
    #   $geoip2_data_location_timezone location time_zone;
    #   $geoip2_data_postal_code postal code;
    #   $geoip2_data_rcountry_geonameid registered_country geoname_id;
    #   $geoip2_data_rcountry_iso registered_country iso_code;
    #   $geoip2_data_rcountry_name registered_country names en;
    #   $geoip2_data_rcountry_is_eu registered_country is_in_european_union;
    #   $geoip2_data_region_geonameid subdivisions 0 geoname_id;
    #   $geoip2_data_region_iso subdivisions 0 iso_code;
    #   $geoip2_data_region_name subdivisions 0 names en;
   #}

#=================Basic Compression=================#
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/css text/xml text/plain application/javascript image/jpeg image/png image/gif image/x-icon image/svg+xml image/webp application/font-woff application/json application/vnd.ms-fontobject application/vnd.ms-powerpoint;
    gzip_static on;

    include /etc/nginx/sites-enabled/example.com-https.conf;
}

Sekarang, mari konfigurasikan host virtual dengan konfigurasi yang diaktifkan SSL dan proxy_protocol ini di /etc/nginx/sites-available/example.com-https.conf :

server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name 192.168.1.4; #Your current server ip address. It will redirect to the domain name.
    listen 80;
    listen 443 ssl http2;
    listen [::]:80;
    listen [::]:443 ssl http2;
    ssl_certificate     /etc/nginx/certs/example.com.crt;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    return 301 https://example.com$request_uri;
}
server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name  example.com;
    listen       *:80;
    return 301   https://example.com$request_uri;
}
server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name www.example.com;
    listen 80;
    listen 443 http2;
    listen [::]:80;
    listen [::]:443 ssl http2 ;
    ssl_certificate     /etc/nginx/certs/example.com.crt;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    return 301 https://example.com$request_uri;
}
server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name example.com;
    listen 443 proxy_protocol ssl http2;
    listen [::]:443 proxy_protocol ssl http2;
    root /var/www/html;
    charset UTF-8;
    add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Referrer-Policy no-referrer;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
    keepalive_timeout   70;
    ssl_buffer_size 1400;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=86400;
    resolver_timeout 10;
    ssl_certificate     /etc/nginx/certs/example.com.crt;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
    ssl_trusted_certificate /etc/nginx/certs/example.com.crt;
location ~* \.(jpg|jpe?g|gif|png|ico|cur|gz|svgz|mp4|ogg|ogv|webm|htc|css|js|otf|eot|svg|ttf|woff|woff2)(\?ver=[0-9.]+)?$ {
    expires modified 1M;
    add_header Access-Control-Allow-Origin '*';
    add_header Pragma public;
    add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    access_log off;
    }
    location ~ /.well-known { #For issuing LetsEncrypt Certificates
        allow all;
    }
location / {
    index index.php;
    try_files $uri $uri/ /index.php?$args;
    }
error_page  404    /404.php;

location ~ \.php$ {
    try_files       $uri =404;
    fastcgi_index   index.php;
    fastcgi_pass    unix:/tmp/php7-fpm.sock;
    #fastcgi_pass    php-container-hostname:9000; (if using docker)
    fastcgi_pass_request_headers on;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_intercept_errors on;
    fastcgi_ignore_client_abort off;
    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 180;
    fastcgi_request_buffering on;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    include fastcgi_params;
}
location = /robots.txt {
    access_log off;
    log_not_found off;
    }
location ~ /\. {
    deny  all;
    access_log off;
    log_not_found off;
    }
}

Dan terakhir, sampel dari 2 nodejs webservers : Server pertama:

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello From Nodejs\n');
}).listen(8080, "192.168.1.4");
console.log('Server running at http://192.168.1.4:8080/');

Server kedua:

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello From Nodejs\n');
}).listen(8080, "192.168.1.5");
console.log('Server running at http://192.168.1.5:8080/');

Sekarang semuanya harus bekerja dengan sempurna dan seimbang.

Beberapa waktu lalu saya menulis tentang Cara mengatur Nginx sebagai penyeimbang beban TCP di Docker . Periksa apakah Anda menggunakan Docker.

Skeptis
sumber