在已有 Hugo + Docker + Nginx 的博客上,通过 Waline 官方 Docker 镜像做独立部署,评论数据自管、国内访问友好。本文记录从零接入到可选个性化的完整步骤,涉及配置均已脱敏。

1. 为什么选 Waline + Docker 自建

  • Waline:轻量评论系统,支持 Markdown、回复、浏览量,与静态站兼容好;官方文档 完善。
  • Docker 独立部署:数据在自家服务器(如 SQLite 存于宿主机卷),不依赖 Vercel/LeanCloud 等第三方;国内云主机上延迟低。
  • 子域名:评论服务单独用 comment.你的域名,与博客、API 同证书、同 Nginx,便于维护和迁移。

2. 架构与数据流

1
2
3
4
5
6
7
8
9
用户浏览器
Nginx (80/443)  ←  blog.你的域名、api.你的域名、comment.你的域名
    ├→ 博客静态文件 (blog/public)
    ├→ API 容器 (:8080)
    └→ Waline 容器 (:8360)  ←  评论 / 注册 / 管理
        SQLite (宿主机 ./waline/data)

评论区的「评论列表、发评论、登录」等请求由前端 JS 发往 https://comment.你的域名,Nginx 反代到 Waline 容器;Waline 将数据写入挂载的 SQLite 目录。

3. 服务端:Docker Compose 增加 Waline

在项目根目录的 docker-compose.yml 中新增服务(示例中博客域名为 www.example.com,评论子域为 comment.example.com,请替换为你的域名):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
services:
  # ... 原有 nginx、api 等 ...

  waline:
    image: lizheming/waline:latest
    container_name: waline
    restart: always
    expose:
      - "8360"
    volumes:
      - ./waline/data:/app/data
    env_file:
      - .env
    environment:
      TZ: Asia/Shanghai
      SQLITE_PATH: /app/data
      SITE_NAME: 你的站点名
      SITE_URL: https://www.example.com
      SECURE_DOMAINS: example.com,www.example.com,comment.example.com
    networks:
      - stack_net

注意:SECURE_DOMAINS 必须包含 comment 子域(如 comment.example.com),否则管理端和评论接口会返回 403。

敏感项(JWT 密钥、博主邮箱等)不要写进仓库,放在服务器上的 .env 中,由 env_file: .env 注入。项目根目录可保留 .env.example 作说明:

1
2
3
# 复制为 .env 后填写,不要提交 .env
JWT_TOKEN=    # 例如: openssl rand -hex 32
AUTHOR_EMAIL= # 可选,接收新评论通知

网关的 depends_on 中加上 waline,保证启动顺序。

4. Nginx:comment 子域反代

nginx/conf.d/ 下新增 waline.conf,风格与现有 blog、api 配置一致:80 做 ACME 与跳 HTTPS,443 用同一套 SSL 证书并反代到 http://waline:8360

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
server {
    listen 80;
    server_name comment.example.com;

    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        root /usr/share/nginx/html;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name comment.example.com;

    ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://waline:8360;
        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;
        proxy_set_header REMOTE-HOST $remote_addr;
    }
}

证书路径按你实际申请结果修改(若多域共用一个证书,可能与 blog 相同)。

5. 博客端:启用评论区并挂载客户端

5.1 站点参数(Hugo config)

blog/config/_default/params.yaml 中开启评论并配置 Waline 客户端地址(与 Nginx 暴露的 comment 域名一致):

1
2
3
4
5
6
7
8
comments: true
waline:
  serverURL: https://comment.example.com
  lang: zh-CN
  dark: 'html[data-theme="dark"]'   # 随主题深色模式
  pageview: true
  emoji: false
  imageUploader: false

更多客户端选项见 Waline 组件属性

5.2 评论区挂载点(partial)

blog/layouts/partials/comments.html 中引入 Waline 官方 CDN 并调用 init(),将 serverURLpath(当前文章 .RelPermalink)、langdarkpageviewemojiimageUploader 等从 site.Params.waline 传入。这样仅在文章单页且配置了 serverURL 时加载评论区。

(具体模板代码与 Waline 快速上手 - HTML 引入 一致,el#walinepath 使用当前页路径以保证每篇文章评论隔离。)

6. 部署与首次运行

  1. DNS:将 comment.example.com 的 A 记录指到当前服务器 IP。
  2. 服务器上:在项目目录执行 cp .env.example .env,编辑 .env 填入 JWT_TOKEN(如 openssl rand -hex 32)和可选 AUTHOR_EMAIL
  3. 启动git pull 后执行 docker compose up -d,确认 gatewayapiwaline 均为 running。
  4. SQLite:若 Waline 日志报缺库/缺表,可从 Waline 仓库 assets 下载 waline.sqlite 到宿主机 ./waline/data/,再 docker compose restart waline
  5. 管理员:浏览器打开 https://comment.example.com/ui/register,首个注册用户即管理员;之后在 https://comment.example.com/ui 管理评论。

7. 常见问题

  • 403 on /api/user 或 /ui:多为 SECURE_DOMAINS 未包含 comment.你的域名,在 compose 的 environment 中补全并重启 waline。
  • 评论区不显示:检查 params.yamlcomments: truewaline.serverURL 与 comment 域名一致;检查主题是否在文章页加载 partial "comments.html"

8. 个性化与配置位置

  • 客户端(外观、表情、上传、排序等):在 blog/config/_default/params.yamlwaline 下增改,并确保 comments.html 中把对应字段传给 init()。参考 组件属性
  • 服务端(等级、审核、频率限制、邮件等):在 docker-compose.ymlwaline.environment 或服务器 .env 中配置;服务端环境变量 更新后需 docker compose up -d waline 生效。

9. 迁移与备份

换机或换云时,评论数据在宿主机 ./waline/data/(SQLite 文件)。将整个 waline/data 目录打包拷贝到新机同路径,保持 JWT_TOKEN 一致(或接受新机重新注册管理员),即可保留历史评论。证书与 CI 按你现有博客迁移流程处理即可。


以上为 Waline Docker 独立部署接入 Hugo 的完整配置思路,涉及域名、证书路径,实际使用时替换为你的域名与路径即可。