前言
半个月前因为某平台服务器打折,本着“有羊毛不薅是混蛋”的原则购入了一台2核4G的 vps 服务器,之后顺理成章地开始部署各种服务,但由于完全是运维小白,频频陷入容器管理和 Nginx 反向代理配置的诸多问题中,尝试在 V2ex 和 nodeseek 论坛上面寻找更优的方案去做应用部署和管理,最终选择拥抱 Coolify !
同时为了优化我的博客使用体验,决定引入开源评论系统 remark42,在各种尝试之后找到最方便可行的配置方案,所以想分享给大家,方便其他人少踩坑。
Coolify
这里简单介绍一下 Coolify :一个超强大的开源 PaaS 平台,支持轻松部署各类数据库和应用,例如 Supabase/n8n/umami/appwrite 等。并可以一键配置 SSL 证书和反向代理。

官网自称是 Heroku/fly.io/Netlify 的完美平替方案。(前提是你得有一台 vps 服务器
安装步骤非常简单,只需要在服务器执行如下命令,并按照提示操作即可。
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
简单来看,Coolify 由如下四个部分组成:
- User Interface: 用户界面,用于配置 Coolify 参数及资源。
- API: Coolify的后端部分,用于与远程资源、数据库、Docker引擎等进行通信。
- HTTP/TCP Proxy: 动态配置Traefik实例以生成反向代理配置,生成SSL证书并将所有传入流量路由到正确的容器。
- SSL certificates are handled by Let’s Encrypt: Coolify 自动生成和存储SSL证书。
基础配置
直接输入 vps 服务器 ip 地址,并加上端口 8000 即可访问。第一个注册用户是 Coolify 实例的 admin 用户,它将可以查看/更改所有部署的资源、访问系统范围的配置、一键更新过程等。其他用户都不会访问系统范围的配置,只能看到他们团队的资源。
如果需要使用域名访问,在完成 DNS 解析之后,可以在左侧的 Settings 中配置域名即可(Coolify会设置反向代理)
如果你使用的是 Cloudflare 的话,建议开启代理,因为 Coolify 会自动把 443 端口请求转发到 8000 端口。

服务搭建
通过 Coolify 支持一键快捷部署应用、数据库、服务。
如下图所示,支持从 git 公共仓库和私有仓库代码部署及 Docker 部署。

同时点击即可创建包括 n8n/appwrite/umami/supabase 等应用。
Remark42 评论系统
之前建站的时候就考虑过接入评论系统,但是由于没有足够多的时间去折腾,所以一直搁置。
最近忙完插件开发的工作之后就开始着手优化博客系统,因为之前在浏览 pseudoyu 的博客时,发现他使用的评论系统主题挺好看,同时该有的功能一样不差,于是考虑接入该评论系统。
首先这里简单介绍一下 Remark42,它是一个轻量且强大的开源评论系统,支持多种 OAuth 包括 Google/Facebook/Github/X 等第三方账号登录。同时使用单文件存储,无需额外配置数据库,方便数据导出和备份。
安装部署
在阅读的其他博客时发现他们使用了 docker-compose 一键构建的方式,但是仍需要花心思和时间去配置 SSL 证书和反向代理,教程复杂且繁琐容易出错,所以这里推荐像我一样使用 Coolify 部署。仅需数分钟即可完成部署上线。
首先第一步需要为 remark42 绑定域名,这里我假设已经把 remark42.demo.com 解析到我的 vps 服务器上。并且我的博客也部署在同一台服务器上面,域名为 blog.demo.com。
这里强烈建议评论系统域名与博客域名应使用相同的顶级域名,如果需要跨域名,则需要额外的参数设置,具体见 Configure Instance on a different domain)
接下来需要在 coolify 中创建一个新服务,并选择 Docker Compose 部署,之后根据如下的 docker-compose 文件配置即可。
version: '2'
services:
remark:
image: 'ghcr.io/umputun/remark42:latest'
container_name: remark42
hostname: remark42
restart: always
logging:
driver: json-file
options:
max-size: 10m
max-file: '5'
environment:
# 这里需要将 REMARK_URL 设置为你配置好的评论系统域名
- REMARK_URL=https://remark42.demo.com
# 该密钥用于服务端生成JWT (仅支持字母和数字
- SECRET=${REMARK_SECRET}
# 评论系统标识。不设置的话默认为remark(后续在博客中嵌入代码时需要用到该标识
- SITE=${SITE_NAME}
- DEBUG=true
# 开启匿名评论。
- AUTH_ANON=true
# 管理员ID。一开始可以不设置,后续可以设置。
- ADMIN_SHARED_ID=${ADMIN_SHARED_ID}
# Google 登录配置。
- AUTH_GOOGLE_CID=${AUTH_GOOGLE_CID}
- AUTH_GOOGLE_CSEC=${AUTH_GOOGLE_CSEC}
# Github 登录配置。
- AUTH_GITHUB_CID=${AUTH_GITHUB_CID}
- AUTH_GITHUB_CSEC=${AUTH_GITHUB_CSEC}
# Telegram 登录配置。
- AUTH_TELEGRAM=true
# 管理员通知配置。
- NOTIFY_ADMINS=telegram
- TELEGRAM_TOKEN=${TELEGRAM_TOKEN}
- NOTIFY_TELEGRAM_CHAN=${NOTIFY_TELEGRAM_CHAN}
# 用户通知配置。
- NOTIFY_USERS=email
# 邮箱登录配置。
- AUTH_EMAIL_ENABLE=true
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_TLS=true
- SMTP_USERNAME=${SMTP_USERNAME}
- SMTP_PASSWORD=${SMTP_PASSWORD}
# 邮箱鉴权地址
- [email protected]
# 邮箱通知地址
- [email protected]
volumes:
- ./var:/srv/var
# 直接使用 Traefik 作为反向代理,coolify 会自动完成 SSL 证书的申请和请求转发。
labels:
- "traefik.enable=true"
# --- 路由器规则 ---
# 规则:当访问的主机是 remark42.demo.com 时,应用此规则
- "traefik.http.routers.remark42.rule=Host(`remark42.demo.com`)"
# 入口点:指定流量从哪个 Traefik 入口点进入 (通常是 https 或 websecure)
- "traefik.http.routers.remark42.entrypoints=https"
# TLS/SSL:为这个域名启用 HTTPS,并使用名为'letsencrypt'的证书解析器
- "traefik.http.routers.remark42.tls.certresolver=letsencrypt"
# --- 服务规则 ---
# 告诉 Traefik,remark42 容器内部的服务监听在 8080 端口
- "traefik.http.services.remark42.loadbalancer.server.port=8080"
这里参数很多,但是第一次填写时只需要填入 REMARK_URL 和 SECRET 即可。其他都是可选的,可以后续再配置。
部署验证
在服务部署完成之后,可以通过访问 https://remark42.demo.com/web 来验证是否部署成功。如果出现如下页面,则说明部署成功。

如果无法访问该页面,请检查服务是否正常运行及日志中有无报错。
博客接入
以我目前使用的 hugo 博客为例,首先在 layouts/partials/comments.html 中添加如下代码。
<div class="comments">
<div class="title">
<span>Comments</span>
<span class="counter"><span class="remark42__counter" data-url="{{ .Permalink }}"></span></span>
</div>
<div id="remark42">
</div>
</div>
<script>
// 动态获取当前主题状态的函数
function getCurrentTheme() {
// 检查body是否有dark类
if (document.body.classList.contains('dark')) {
return 'dark';
} else {
return 'light';
}
}
var remark_config = {
host: 'https://remark42.demo.com',
site_id: 'remark',
components: ['embed', 'counter'],
max_shown_comments: 20,
simple_view: true,
theme: getCurrentTheme(), // 动态获取主题
}
</script>
<script>
(function () {
const remark42 = window.REMARK42
if (remark42) {
remark42.destroy()
remark42.createInstance(remark_config)
} else {
for (const component of remark_config.components) {
var d = document, s = d.createElement('script');
s.src = `${remark_config.host}/web/${component}.mjs`;
s.type = 'module';
s.defer = true;
// prevent the <script> from loading mutiple times by InstantClick
s.setAttribute('data-no-instant', '')
d.head.appendChild(s);
}
}
})();
</script>
<!-- 监听主题切换并同步更新Remark42主题 -->
<script>
function setupThemeSync() {
if (window.REMARK42 && window.REMARK42.changeTheme) {
const themeToggle = document.getElementById('theme-toggle');
if (themeToggle) {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
const newTheme = getCurrentTheme();
window.REMARK42.changeTheme(newTheme);
}
});
});
observer.observe(document.body, {
attributes: true,
attributeFilter: ['class']
});
}
} else {
setTimeout(setupThemeSync, 500);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', setupThemeSync);
} else {
setupThemeSync();
}
</script>
只需要根据你部署的 remark42 的域名和 site_id 修改对应的参数即可。
之后查看博客主题下面的 theme/PaperMod/layouts/_default/single.html 文件是否存在 comments 部分,如果有的话开启即可,如果没有的话,则需要手动添加上。
管理员配置
在登录 remark42 评论系统之后,可以点击用户头像,并复制右侧的用户 id。

将该 id 填入 ADMIN_SHARED_ID 中,并重启服务。
可以看到评论区出现的 setting 选择,可以选择删除和拉黑评论。

通知推送
首先通知类型分为两种,管理员通知和用户通知,具体的区别可以看官网的文档说明,简单理解就是:
- 管理员通知:所有新评论都发送给管理员(例如发邮箱或 Telegram 频道)。
- 用户通知:允许用户订阅他们自己评论的回复通知,但需要手动开启。
目前前者支持 Slack, email, 和 Telegram 推送管理员通知。后者仅支持 email 推送用户通知。
管理通知配置
这里以 Telegram 为例,首先需要填写的多个参数。
NOTIFY_ADMINS=telegram
NOTIFY_TELEGRAM_CHAN=-100**********
NOTIFY_TELEGRAM_TOKEN=62*****253:AA***********************************
首先 NOTIFY_TELEGRAM_TOKEN 是 Telegram 机器人的 token,可以通过 @BotFather 获取后获取(具体步骤请参考这篇教程
之后需要创建一个 channel 并获取 channel 的 ID,创建的方式如下在 chat 中点击右上角的编辑,选择 New Channel

之后需要登录 网页版 Telegram ,并选择 channel 中,复制以 -xxxx 开头的 channel ID 填入 NOTIFY_TELEGRAM_CHAN 中。(必须带上负号

配置完成后重启服务,发送一条评论可以在 channel 里面收到通知。

用户订阅通知配置
目前仅支持 email 推送用户通知,配置方式如下:
- 首先配置邮箱 STMP 服务:
- SMTP_HOST:SMTP 服务器地址
- SMTP_PORT:SMTP 服务器端口
- SMTP_TLS:是否启用 TLS
- SMTP_USERNAME:SMTP 用户名
- SMTP_PASSWORD:SMTP 密码
- 配置邮箱通知:
- NOTIFY_USERS:通知用户的方式,我选择了了 email, 即邮件通知,则需要配置下文的 SMTP
- NOTIFY_EMAIL_FROM:邮箱通知的发送地址
Github/X/Google 登录配置
这里推荐参考 官方文档 进行配置。
踩坑点
注意如果博客中使用的标题或者文字渲染出了一个 <div id="remark42"></div> 标签,会导入前端 embed 组件嵌入失败,从而无法正常显示。