Aplikasi Node bisa melayani HTTP sendirian. Sebaiknya jangan: ia harus menuntaskan TLS, menyajikan berkas statis, selamat dari kejatuhan, dan mengikat porta 443 sebagai root. Nginx di depan mengerjakan keempatnya, dan aplikasi itu tinggal menjadi sebuah aplikasi.

Proksinya

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name app.example.com;

    ssl_certificate     /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        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;
    }
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Pasangan Upgrade dan Connection itulah yang membuat WebSocket bekerja. Tanpa keduanya, sambungan diteruskan lalu dijatuhkan, dan itu tampak seperti aplikasi yang rusak.

Ikat Node ke localhost saja

app.listen(3000, '127.0.0.1');
Mengikat ke 0.0.0.0 membiarkan porta 3000 terjangkau dari internet, melewati setiap aturan yang Anda tulis di Nginx. Inilah kesalahan paling umum pada susunan ini.

Jaga ia tetap hidup dengan systemd, bukan dengan sebuah terminal

# /etc/systemd/system/app.service
[Unit]
Description=Node app
After=network.target

[Service]
Type=simple
User=app
WorkingDirectory=/var/www/app
EnvironmentFile=/etc/app.env
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now app
journalctl -u app -f

Percayai proksinya - di dalam aplikasi

Di belakang Nginx, alamat yang dilihat aplikasi Anda adalah 127.0.0.1 pada setiap permintaan. Suruh kerangkanya membaca tajuk yang diteruskan - di Express, app.set('trust proxy', 1) - kalau tidak, setiap catatan dan setiap batas laju jadi tak bermakna.

Sajikan berkas statis dari Nginx dengan sebuah blok location, bukan lewat Node. Itu lebih cepat, dan membiarkan gelung peristiwanya luang untuk pekerjaan yang hanya bisa dikerjakan kode Anda.