Nginx部署Hugo站点

1 安装软件
- Git: https://git-scm.com/downloads
- Hugo: https://github.com/gohugoio/hugo/releases/latest, 推荐使用
extended
版本 - Nginx: https://nginx.org/en/linux_packages.html
- acme.sh: https://github.com/acmesh-official/acme.sh/wiki/说明
2 配置仓库
2.1 服务器中的Remote仓库
以下是在云服务器中的操作。
由于SSH方式连接Git仓库, 参数格式是这样的: ssh://<UserName>@<domain|ip>:[port]/xxx.git
, 所以:
- 如果新建名为
git
的用户, 那么之后Git仓库地址是git@<domain|ip>:[port]/xxx.git
, 符合习惯, 比如常用的[email protected]
。 - 直接使用现有的普通用户, 比如
senzyo
, 之后Git仓库地址则是ssh://senzyo@<domain|ip>:[port]/xxx.git
。
初始化裸仓库:
cd /home/senzyo/git-repos/blog git init --bare .git
编辑Git Hooks:
vim .git/hooks/post-receive
粘贴以下内容后保存退出:
#!/bin/bash BRANCH="master" GIT_DIR="/home/senzyo/project/blog/.git" TARGET="/home/senzyo/project/blog" read oldrev newrev ref if [ "$ref" == "refs/heads/$BRANCH" ]; then echo "$ref已成功接收, 正在部署$BRANCH分支" git --work-tree="$TARGET" --git-dir="$GIT_DIR" pull cd $TARGET rm -rf public hugo --gc --minify else echo "$ref已成功接收, 但只有$BRANCH分支更改时才进行部署" fi git push -f github git push -f gitee
赋予
post-receive
可执行权限:chmod +x .git/hooks/post-receive
2.2 服务器中的生产环境仓库
以下是在云服务器中的操作。
为了方便搞事, 比如自动更新twikoo、同步到多个Git Repo源等, 所以服务器上有两个Git仓库, 一个是Remote, 一个是生产环境, nginx.conf
中location
的root
路径指向的正是生产环境。
如果只需要在本地push
到Remote后, 自动构建Hugo博客, 可以从Remote的.git
中checkout
出仓库文件到.git
的父目录中, 然后配置nginx.conf
中location
的root
路径指向.git
的父目录。
#!/bin/bash
BRANCH="master"
GIT_DIR="/home/senzyo/git-repos/blog/.git"
TARGET="/home/senzyo/git-repos/blog"
read oldrev newrev ref
if [ "$ref" == "refs/heads/$BRANCH" ]; then
echo "$ref已成功接收, 正在部署$BRANCH分支"
git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f "$BRANCH"
cd $TARGET
rm -rf public
hugo --gc --minify
else
echo "$ref已成功接收, 但只有$BRANCH分支更改时才进行部署"
fi
参考Git Config为当前用户进行设置。
复制当前用户的公钥, 粘贴到
/home/senzyo/.ssh/authorized_keys
文件里, 如果有多个公钥, 则一行一个。将
/home/senzyo/git-repos/blog/.git
这个仓库克隆到/home/senzyo/project
:cd /home/senzyo/project/ git clone ssh://senzyo@localhost:[port]/home/senzyo/git-repos/blog/.git
配置仓库:
git remote add github [email protected]:senzyo/blog.git git remote add gitee [email protected]:senzyo/blog.git
git remote -v
, Remote应该包括GitHub、Gitee和服务器中的Remote仓库:gitee [email protected]:senzyo/blog.git (fetch) gitee [email protected]:senzyo/blog.git (push) github [email protected]:senzyo/blog.git (fetch) github [email protected]:senzyo/blog.git (push) origin ssh://senzyo@localhost:[port]/home/senzyo/git-repos/blog/.git (fetch) origin ssh://senzyo@localhost:[port]/home/senzyo/git-repos/blog/.git (push)
注意权限:
chmod 700 /home/senzyo/.ssh chmod 600 /home/senzyo/.ssh/*
2.3 本地电脑中的Git仓库
以下是在本地电脑中的操作。
克隆, 并设置仓库:
git clone ssh://senzyo@<domain|ip>:[port]/home/senzyo/git-repos/blog/.git
存储、提交和推送:
git add -A && git commit -m "测试" && git push -uf origin master
3 配置Nginx
不同系统中, Nginx配置文件的路径不同, 在Debian中的路径是/etc/nginx/nginx.conf
。
备份
/etc/nginx/nginx.conf
文件:sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
编辑
/etc/nginx/nginx.conf
文件:sudo vim /etc/nginx/nginx.conf
编辑
/etc/nginx/nginx.conf
, 以下简单设置仅供参考, 推荐使用 DigitalOcean 的 nginxconfig.io 来生成 Nginx 配置文件:# Generated by nginxconfig.io # See nginxconfig.txt for the configuration share link user www-data; pid /run/nginx.pid; worker_processes auto; worker_rlimit_nofile 65535; # Load modules include /etc/nginx/modules-enabled/*.conf; events { multi_accept on; worker_connections 65535; } http { charset utf-8; sendfile on; tcp_nopush on; tcp_nodelay on; server_tokens off; log_not_found off; types_hash_max_size 2048; types_hash_bucket_size 64; client_max_body_size 16M; # MIME include mime.types; default_type application/octet-stream; # Logging log_format main '[$time_iso8601] $remote_addr ' '"$request" $status ' '"$http_referer" "$http_user_agent"'; access_log off; error_log /var/log/nginx/error.log warn; # SSL ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE ciphersuites ssl_dhparam /etc/nginx/dhparam.pem; # Mozilla Intermediate configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 64.6.64.6 64.6.65.6 valid=60s; resolver_timeout 2s; # Load configs include /etc/nginx/conf.d/*.conf; # www.example.com server { listen 443 ssl; http2 on; server_name www.example.com; root /var/www/example.com/public; # SSL ssl_certificate /etc/nginx/ssl/example.com/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/example.com/example.com.key; # security headers add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always; add_header Permissions-Policy "interest-cohort=()" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # . files location ~ /\.(?!well-known) { deny all; } # logging access_log /var/log/nginx/www.example.com/access.log main buffer=512k flush=1m; error_log /var/log/nginx/www.example.com/error.log warn; # favicon.ico location = /favicon.ico { log_not_found off; } # robots.txt location = /robots.txt { log_not_found off; } # assets, media location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ { expires 7d; } # svg, fonts location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ { add_header Access-Control-Allow-Origin "*"; expires 7d; } # gzip gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; error_page 404 /404.html; } # non-www, subdomains redirect server { listen 443 ssl; http2 on; server_name .example.com; # SSL ssl_certificate /etc/nginx/ssl/example.com/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/example.com/example.com.key; return 301 https://www.example.com$request_uri; } # HTTP redirect server { listen 80; server_name .example.com; return 301 https://www.example.com$request_uri; } }
运行命令
sudo mkdir -p /var/log/nginx/www.example.com
创建存放日志的文件夹。运行命令
sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
生成 Diffie-Hellman keys。更改Nginx服务器的配置文件后, 重新启动或重新加载服务之前测试配置是否存在任何语法或系统错误:
sudo nginx -t
强制重载Nginx配置:
sudo service nginx force-reload
据测试
sudo service nginx reload
并不会重新加载证书。或者重启Nginx服务:
sudo systemctl restart nginx.service
设置Nginx服务开机自启动:
sudo systemctl enable nginx.service
查看Nginx服务状态:
sudo systemctl status nginx.service
至此, 网站能够正常访问, 且访问http://example.com/
、http://www.example.com/
、https://example.com/
, 都会跳转到https://www.example.com/
。