背景

手头有一台 4核4G 的轻量云服务器(Debian 13),想搭一个纯静态的技术博客。要求很简单:低资源占用、HTTPS、自动续期证书、页脚挂备案号。

方案选型

服务器上已经装了 1Panel 面板和 Docker 版 OpenResty,所以不再额外安装 Nginx,直接复用现有的 OpenResty 容器做反向代理和静态文件服务。静态博客不需要数据库、不需要 PHP,资源占用几乎为零。

  • Web 服务:复用 1Panel 的 OpenResty(Docker 容器,宿主机目录挂载进容器)
  • 证书:acme.sh 申请 Let’s Encrypt 证书,HTTP-01 验证,自动续期
  • 站点文件:纯 HTML/CSS,放 /opt/1panel/www/sites/域名/index/

关键配置

站点配置放在 /opt/1panel/www/conf.d/ 下,这个目录被挂载到容器内 /usr/local/openresty/nginx/conf/conf.d/,主配置会自动 include 它:

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

    # 保留 ACME 验证路径,续期时要用
    location ~ /.well-known/acme-challenge {
        allow all;
        root /www/sites/example.com/index;
    }

    # 其余请求全部跳转 HTTPS
    location / {
        return 301 https://example.com$request_uri;
    }
}

server {
    listen 443 ssl;
    http2 on;
    server_name example.com www.example.com;
    root /www/sites/example.com/index;

    ssl_certificate     /usr/local/openresty/nginx/conf/ssl/example/fullchain.pem;
    ssl_certificate_key /usr/local/openresty/nginx/conf/ssl/example/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
}

证书自动续期

acme.sh 安装证书时通过 --reloadcmd 指定续期后的重载命令,之后完全无需人工干预:

~/.acme.sh/acme.sh --install-cert -d example.com --ecc \
  --fullchain-file .../fullchain.pem \
  --key-file .../privkey.pem \
  --reloadcmd "docker exec openresty容器名 nginx -s reload"

踩过的坑

  • Fish shell:Debian 默认 shell 是 fish,不支持 bash 的命令替换语法,SSH 执行命令要显式包一层 bash -c。
  • SSL session cache:ssl_session_cache shared:SSL:10m 里 zone 名不能带空格,写错直接 nginx -t 报错。
  • DNS 缓存:域名换解析后,本机代理软件(TUN 模式)的 DNS 缓存还指向旧 IP,表现为"服务器上一切正常但本地 404"。ipconfig /flushdns 解决。

总结:复用现有设施 > 重新造轮子。整站资源占用接近零,证书自动续期,备案号挂在页脚,一次配置长期免维护。