用Nginx把Hugo部署到云服务器上

一、安装 Nginx

卸载安装 Nginx

Copy
sudo apt-get purge nginx nginx-common # 卸载nginx，包括删除配置文件。
apt install nginx

nginx 的常用命令

Copy
nginx -s stop 快速关闭Nginx，可能不保存相关信息，并迅速终止web服务。
nginx -s quit 平稳关闭Nginx，保存相关信息，有安排的结束web服务。
nginx -s reload 因改变了Nginx相关配置，需要重新加载配置而重载。
nginx -s reopen 重新打开日志文件。
nginx -c filename 为 Nginx 指定一个配置文件，来代替缺省的。
nginx -t 不运行，仅仅测试配置文件。nginx 将检查配置文件的语法的正确性，并尝试打开配置文件中所引用到的文件。
nginx -v 显示 nginx 的版本。
nginx -V 显示 nginx 的版本，编译器版本和配置参数。

如果不想每次都敲命令，可以在 nginx 安装目录下新添一个启动批处理文件 startup.bat，双击即可运行。内容如下：

Copy
@echo off
rem 如果启动前已经启动nginx并记录下pid文件，会kill指定进程
nginx.exe -s stop

rem 测试配置文件语法正确性
nginx.exe -t -c conf/nginx.conf

rem 显示版本信息
nginx.exe -v

rem 按照指定配置去启动nginx
nginx.exe -c conf/nginx.conf

如果是 Linux 的话，我猜测是这么写的，不知道对不对，未验证

Copy
#!/bin/sh

#如果启动前已经启动nginx并记录下pid文件，会kill指定进程
nginx -s stop

#测试配置文件语法正确性
nginx -t -c conf/nginx.conf

#显示版本信息
nginx -v

#按照指定配置去启动nginx
nginx -c conf/nginx.conf

二、用 rsync 上传public文件夹到服务器上

Copy
rsync -avuz --progress --delete public/ root@ip地址:/home/public/

前提 Vps 上也需要安装 rsync; 已知 Mac 自带工具，win 平台用 Fz 客户端同步文件

Copy
apt install rsync

三、申请 ssl 证书

获取 CerBot 客户端

Copy
install certbot

获取证书

Copy
certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com

这个命令会为 example.com 和 www.example.com 这两个域名生成一个证书，使用 --webroot 模式会在 /var/www/example 中创建 .well-known 文件夹，这个文件夹里面包含了一些验证文件，certbot 会通过访问 example.com/.well-known/acme-challenge 来验证你的域名是否绑定的这个服务器。这个命令在大多数情况下都可以满足需求，
满足需求，

但是有些时候我们的一些服务并没有根目录，例如一些微服务，这时候使用 --webroot 就走不通了。certbot 还有另外一种模式 --standalone ， 这种模式不需要指定网站根目录，他会自动启用服务器的 443 端口，来验证域名的归属。我们有其他服务（例如 nginx）占用了 443 端口，就必须先停止这些服务，在证书生成完毕后，再启用。

Copy
certbot certonly --standalone -d example.com -d www.example.com

证书生成完毕后，我们可以在 /etc/letsencrypt/live/ 目录下看到对应域名的文件夹，里面存放了指向证书的一些快捷方式。

这时候我们的第一生成证书已经完成了，接下来就是配置我们的 web 服务器，启用 HTTPS。

四、配置 nginx 的 nginx.conf 文件

/etc/nginx 目录下

Copy
# 要配置的第一个地方，这里的用户要改成root，不然可能会没有权限
user root;

worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

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;

include /etc/nginx/mime.types;
default_type application/octet-stream;

include /etc/nginx/conf.d/*.conf;

# 配置http
server {
# 要配置的第二个地方，80访问端口
listen 80 default_server;
listen [::]:80 default_server;

# 要配置的第三个地方，域名
server_name blog.ryujinx.top;
rewrite ^(.*) https://$server_name$1 permanent; #自动从http跳转到https
# 要配置的第四个地方，这里指向public文件夹
root /home/public;

include /etc/nginx/default.d/*.conf;

# 要配置的第五个地方
location / {
root /home/public;
index index.html index.htm;
}

# 要配置的第六个地方
error_page 404 /404.html;
location = /40x.html {
root /home/public;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

# 配置https
server {
listen 443 ssl;
# 要配置的第七个地方
server_name blog.ryujinx.top;
root /home/public;

# 要配置的第八个地方
ssl_certificate /etc/letsencrypt/live/blog.ryujinx.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.ryujinx.top/privkey.pem;

# 要配置的第九个地方，可以按照我的写法
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

# 要配置的第十个地方
error_page 404 /404.html;
location = /404.html {
root /home/public;
}

include /etc/nginx/default.d/*.conf;
}

}

其中端口 80 用于配置 http 服务，端口 443 用于配置 https 服务，这样就完成了 nginx 的配置

修改完成后重加载配置文件

Copy
sudo nginx -s reload

检查 nginx 服务的运行情况

Copy
sudo systemctl status nginx

重启 nginx 服务

Copy
sudo systemctl restart nginx

后续文章发布

直接用 rsync 同步public文件夹即可

注意事项

1. 自动更新 SSL 证书

SSL 存活时间 90 天，到期用下述命令刷新

Copy
certbot renew --dry-run

如果生成证书的时候使用的是 --standalone 模式，验证域名的时候，需要启用443端口，这个错误的意思就是要启用的端口已经被占用了。 这时候我必须把nginx先关掉，才可以成功。果然，我先运行 service nginx stop 运行这个命令，就没有报错了，所有的证书都刷新成功。

Copy
# 搞个cron脚本
touch certbot-auto-renew-cron
#向文件里添加下面内容
15 2 * */2 * certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"

--pre-hook 这个参数表示执行更新操作之前要做的事情，因为我有 --standalone 模式的证书，所以需要 停止 nginx 服务，解除端口占用。 --post-hook 这个参数表示执行更新操作完成后要做的事情，这里就恢复 nginx 服务的启用

最后我们用 crontab 来启动这个定时任务

Copy
crontab certbot-auto-renew-cron

省力方案：使用 npm 可视化界面配置

Docker-Compose 安装 npm

Create a docker-compose.yml file similar to this:

Copy
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt

Bring up your stack by running

Copy
docker-compose up -d
# If using docker-compose-plugin
docker compose up -d

Log in to the Admin UI
http://localhost:81

Default Admin User:

Copy
Email: admin@example.com
Password: changeme

配置

detail 页面填写正确的 ip，代理博客端口填写 80，填入自己已经解析好的域名

ssl 标签栏申请证书

advanced 填写路径

Copy
location / {
root /data/xxxx.github.io;
}

/data/xxxx.github.io 实在 npm 安装的根目录下开始计算的，在相应的文件夹下上传好 html 文件夹
具体用法参考 nginx location [PATTERN]

Reference

hugo 博客部署到腾讯云轻量级服务器

Let's Encrypt 使用教程，免费的 SSL 证书，让你的网站拥抱 HTTPS

Nginx 极简教程