Hiện tại có rất nhiều dịch vụ hỗ trợ deploy tự động cho NextJS như Vercel, Netlify, AWS... Tuy nhiên Vercel không thể deploy nếu NextJS dùng custom server. Netlify không có basic auth. AWS thì mất phí.
Nhằm mục đích phục vụ kiểm thử sản phẩm trước khi phát hành, bài viết này sẽ hướng dẫn bạn cách deploy NextJS lên server riêng của mình.
A. Static HTML Export => Apache
Nếu build bằng next export, hãy copy tất cả các file bên trong thư mục out vào /var/www/html.
Tuy nhiên, next export sẽ hạn chế khá nhiều tính năng mà NextJS mang lại.
Vì vậy, tôi sẽ hướng dẫn bạn cấu hình Nginx để chạy bản build của NextJS.
B. Server-side rendering runtime => Nginx
Đăng nhập qua SSH:
> ssh <USER>@<IP> -p<PORT>1. Cấu hình Nginx
Để thêm repository CentOS EPEL, mở terminal và sử dụng lệnh sau:
> sudo yum install epel-releaseCài đặt Nginx bằng lệnh yum:
> sudo yum install nginxNginx không tự khởi động. Để chạy Nginx, gõ lệnh:
> sudo systemctl start nginxCài đặt Node.js:
> sudo yum install nodejsXử lý lỗi khi khởi động Nginx
Lỗi này về cơ bản có nghĩa là một ứng dụng khác đang sử dụng các port mặc định đó. Bạn có thể kiểm tra bằng:
> sudo netstat -tulpnLấy PID của process đang sử dụng port đó và gửi tín hiệu bằng lệnh kill:
> sudo kill -2 <PID>Lưu ý nếu tắt nhầm PID của SSH, bạn có thể bật lại bằng lệnh sau:
Khởi động lại SSH Service:
> sudo systemctl start sshd2. Tùy chỉnh cài đặt Firewall
> sudo yum install ufw
> sudo ufw app list
> sudo ufw allow 'Nginx HTTP'Xử lý lỗi: ERROR: Could not find a profile matching 'Nginx Full'
> vi /etc/ufw/applications.d/nginx.iniDán nội dung này vào trong file:
[Nginx HTTP]
title=Web Server
description=Enable NGINX HTTP traffic
ports=80/tcp
[Nginx HTTPS] \
title=Web Server (HTTPS) \
description=Enable NGINX HTTPS traffic
ports=443/tcp
[Nginx Full]
title=Web Server (HTTP,HTTPS)
description=Enable NGINX HTTP and HTTPS traffic
ports=80,443/tcpSau đó chạy lệnh sau để cập nhật:
> ufw app update nginx
> ufw app info 'Nginx HTTP'
> sudo ufw allow 'Nginx HTTP'Cho phép lưu lượng HTTP và HTTPS:
> sudo firewall-cmd --permanent --zone=public --add-service=http
> sudo firewall-cmd --permanent --zone=public --add-service=https
> sudo firewall-cmd --reloadXử lý lỗi firewall-cmd: command not found
> sudo yum install firewalld
> sudo systemctl start firewalld
> sudo systemctl enable firewalld
> sudo systemctl status firewalldXử lý lỗi firewall không hoạt động
> sudo systemctl restart dbus
> sudo systemctl restart firewalldXử lý ERROR: initcaps [Errno 2] ip6tables v1.4.21: can't initialize ip6tables table `filter': Table does not exist (do you need to insmod?) Perhaps ip6tables or your kernel needs to be upgraded.
Lỗi này bạn có thể bỏ qua. Mặc dù báo lỗi nhưng ứng dụng vẫn chạy bình thường.
> sudo yum update3. Cấu hình Nginx làm Reverse Proxy
Chỉnh sửa /etc/nginx/nginx.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
# server_name _;
# root /usr/share/nginx/html;
# Load configuration files for the default server block.
#include /etc/nginx/default.d/*.conf;
location / {
# reverse proxy for next server
proxy_pass http://localhost:3000;
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;
# we need to remove this 404 handling
# because next's _next folder and own handling
# try_files $uri $uri/ =404;
}
# error_page 404 /404.html;
# location = /404.html {
# }
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
}> sudo systemctl restart nginx4. Giữ ứng dụng luôn hoạt động (Keep Alive)
Cài đặt PM2:
> sudo npm install -g pm2Bây giờ hãy khởi chạy ứng dụng Next.js bằng PM2.
Đảm bảo bạn đã di chuyển vào thư mục dự án /website:
> cd website
> pm2 start --name=renew npm -- starthoặc chạy với script tùy chỉnh trong package.json:
> pm2 start npm --name=renew -- run "script-name"Cập nhật bản build mới:
> pm2 restart renew5. Nginx: Bật Basic Auth
> yum -y install httpd-tools
> Chỉnh sửa /etc/nginx/nginx.confserver_names_hash_bucket_size 512;
location / {
auth_basic "Basic Auth";
auth_basic_user_file "/etc/nginx/.htpasswd";
...
}> htpasswd -c /etc/nginx/.htpasswd username
> systemctl restart nginxFile nginx.conf hoàn chỉnh không yêu cầu Basic Auth cho danh sách IP whitelist
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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 /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 512;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
geo $authentication {
default "Authentication required";
192.168.1.56 "off";
....[whitelist IP]
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# server_name _;
# root /usr/share/nginx/html;
# Load configuration files for the default server block.
#include /etc/nginx/default.d/*.conf;
location / {
auth_basic $authentication;
auth_basic_user_file "/etc/nginx/.htpasswd";
# reverse proxy for next server
proxy_pass http://localhost:3000;
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;
# we need to remove this 404 handling
# because next's _next folder and own handling
# try_files $uri $uri/ =404;
}
# error_page 404 /404.html;
# location = /404.html {
# }
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
}
}Mẹo: Làm thế nào để thực hiện git pull mà không cần nhập lại mật khẩu?
> git config credential.helper store