





















Twikoo 支持多种部署方式:云函数,Vercel,私有部署、Docker.... 具体参见文档:https://twikoo.js.org/backend.html
最原始的方法,也就是直接在服务器上部署,步骤很简单:安装 node → 安装 tkserver → 启动。
sh
$ npm i -g tkserver
$ ln -s /opt/nodejs/node/bin/tkserver /usr/local/bin/tkserver
$ tkserver然后就可以访问了,地址是:http://服务端IP:8080
Linux 服务器可以用 nohup tkserver >> tkserver.log 2>&1 & 命令后台启动。
提示
可能需要在云服务器上开启 8080 端口的防火墙
还是推荐用 Docker 来部署。我之前是用私有部署,几年后想升级 Twikoo,但是因为 node 版本太老了,导致升级失败... 然后试着升级 node,又是一堆报错...
sh
docker run --name twikoo -e TWIKOO_THROTTLE=1000 -p 8080:8080 -v ${PWD}/data:/app/data -d imaegoo/twikoodocker-compose.yaml 内容:
yaml
version: "3"
services:
twikoo:
image: imaegoo/twikoo
container_name: twikoo
restart: unless-stopped
ports:
- 8080:8080
environment:
TWIKOO_THROTTLE: 1000
volumes:
- ./data:/app/data自己实际部署:😜
twikoo 的 Docker 容器sh
docker run --name twikoo -e TWIKOO_THROTTLE=1000 -p 8426:8080 -v ${PWD}/data:/app/data -d imaegoo/twikoo并在其中生成了一个 docker-compose.yaml 文件
sh
# 创建名为 `twikoo` 的目录
mkdir /root/twikoo
# 创建docker-compose.yaml 文件并添加以下内容
cat >>/root/twikoo/docker-compose.yaml <<EOF
version: '3'
services:
twikoo:
image: imaegoo/twikoo
container_name: twikoo
restart: unless-stopped
ports:
- 8426:8080
environment:
TWIKOO_THROTTLE: 1000
volumes:
- ./data:/app/data
EOF
# 进入该目录
cd /root/twikoo
# 检查 8080 端口是否已经被其他进程占用
netstat -antlp|grep 8080
# 启动twikoo镜像服务
docker-compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 2/2
✔ Network twikoo_default Created 0.0s
✔ Container twikoo Started 0.0s
[root@VM-4-16-centos twikoo]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dc43659872fe imaegoo/twikoo "docker-entrypoint.s…" 56 minutes ago Up 56 minutes 0.0.0.0:8426->8080/tcp, :::8426->8080/tcp twikoo
[root@VM-4-16-centos twikoo]#在私有部署的情况下,在你执行 tkserver 的时候,就会在当前目录创建:
因此,有必要在你自己指定的目录下启动 tkserver,方便后期的数据备份、日志分析等。
如果你使用的是 Docker,在上述命令里其实也用了 ${PWD}/data 来指定数据文件的目录,请自行选择。
sh
[root@VM-4-16-centos twikoo]# ls
data docker-compose.yaml
[root@VM-4-16-centos twikoo]# ls data/
db.json db.json.0 db.json.1 db.json.2
[root@VM-4-16-centos twikoo]#理论上这样部署,就完成后台的部分了,但鉴于我的网站用了 HTTPS,而 Twikoo 本身并不支持,因此还需要做反向代理。
我这里配置 HTTPS 是用到cloudflare

nginx
upstream twi {
server peterjxl.com:8080; #你的域名+加端口
}
server {
listen 443 ssl;
server_name twikoo.peterjxl.com; #子域名
ssl_certificate /opt/nginxrun/conf/cert/8852603_twikoo.peterjxl.com.pem;
ssl_certificate_key /opt/nginxrun/conf/cert/8852603_twikoo.peterjxl.com.key;
# ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!ADH:!EXPORT56:RC4+RSA:+MEDIUM;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://twi;
}
}nginx
# 进入该目录
cd /etc/nginx/conf.d/
# 创建文件
vim twikoo.seasir.top.conf
[root@VM-4-16-centos conf.d]# cat twikoo.seasir.top.conf
server {
listen 80;
server_name twikoo.seasir.top;
#配置https重定向
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name twikoo.seasir.top;
location / {
proxy_pass http://云服务器ip:8080/; # 实际的后台路径
client_max_body_size 100M;
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;
}
access_log /var/log/nginx/photo.onedayxyy.cn.https.log;
}
# 用于测试 Nginx 配置文件的语法是否正确
nginx -t
docs\.vitepress\config.ts文件或者前往查看博主Config配置,修改为如下代码:ts
comment: {
// provider: "giscus",
provider: "twikoo",
options: {
// twikoo 配置,官网:https://twikoo.js.org/
envId: "填写您自己的twikoo域名",
jsUrl: "https://cdn.staticfile.org/twikoo/1.6.42/twikoo.all.min.js",
},
},Twikoo 评论,需要部署前后端,包括数据库,操作略有复杂,但是不限制代码托管和服务托管,自定义程度更高。官方文档 https://twikoo.js.org/ ,非常详细,部署步骤如下:
MongoDB AtLas 是 MongoDB Inc 提供的 MongoDB 数据库托管服务。免费账户可以永久使用 500 MiB 的数据库,足够存储 Twikoo 评论使用。
申请 MongoDB AtLas 账号
创建免费 MongoDB 数据库,区域推荐选择离 Twikoo 后端(Vercel / Netlify / AWS Lambda / VPS)地理位置较近的数据中心以获得更低的数据库连接延迟。如果不清楚自己的后端在哪个云服务器和地区,可选择 AWS / Oregon (us-west-2)和香港地区,该数据中心基建成熟,故障率低,且使用 Oregon 州的清洁能源,较为环保
在 Database Access 页面点击 Add New Database User 创建数据库用户,Authentication Method 选 Password,在 Password Authentication 下设置数据库用户名和密码,建议点击 Auto Generate 自动生成一个不含特殊符号的强壮密码并妥善保存。点击 Database User Privileges 下方的 Add Built In Role,Select Role 选择 Atlas Admin,最后点击 Add User

Network Access 页面点击 Add IP Address 添加网络白名单。因为 Vercel / Netlify / Lambda 的出口地址不固定,因此 Access List Entry 输入 0.0.0.0/0(允许所有 IP 地址的连接)即可。如果 Twikoo 部署在自己的服务器上,这里可以填入固定 IP 地址。点击 Confirm 保存
Overview 页面点击 Connect,连接方式选择 Drivers,并记录数据库连接字符串,请将连接字符串中的 <username>:<password> 修改为刚刚创建的数据库 用户名:密码,复制Mongodb连接字符串并妥善保管,后面部署需要用到!然后点击 Done示例
mongodb+srv://数据库用户名:数据库密码@cluster0.d1vvzs3.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0

Vercel DeploySettings - Environment Variables,添加环境变量 MONGODB_URI,值为前面记录的数据库连接字符串
Settings - Deployment Protection,设置 Vercel Authentication 为 Disabled,并 Save
进入 Deployments , 然后在任意一项后面点击更多(三个点) , 然后点击 Redeploy , 最后点击下面的 Redeploy 等待部署完成,部署完成即可
进入 Overview,点击 Domains 下方的链接,如果环境配置正确,可以看到 “Twikoo 云函数运行正常” 的提示,说明部署成功!


路径
(推荐)config.tsTwikoo.vuetwikoo.scssTeekLayoutProvider.vue
ts
comment: {
// provider: "giscus",
provider: "twikoo",
options: {
// twikoo 配置,官网:https://twikoo.js.org/
envId: "填写您自己的twikoo域名",
//jsUrl: "https://cdn.staticfile.org/twikoo/1.6.42/twikoo.all.min.js",
version: "1.6.44",
},
},vue
代码请在源码自行获取:https://gitee.com/SeasirHyde/teek-hyde/blob/main/docs/.vitepress/theme/components/Twikoo/twikoo.scssscss
代码请在源码自行获取:https://gitee.com/SeasirHyde/teek-hyde/blob/main/docs/.vitepress/theme/components/Twikoo/twikoo.scssvue
<script setup lang="ts">
import Twikoo from './Twikoo.vue'
</script>
<template>
<Teek.Layout>
<template #teek-doc-after-appreciation-before>
<!-- 评论组件 -->
<Twikoo />
</template>
</Teek.Layout>
</template>前后端都处理好后,界面就能正常展示了,但是我们还要处理下邮件功能。进入您的文章底部,找到评论区的设置,首次打开设置按钮后,会有设置密码框,设置一个复杂密码并记住。然后进入配置管理,选择邮件通知
按照提示输入你的邮箱,邮箱授权码等即可。最后有个邮件测试,测试后,你能收到一封邮件,说明功能可用了
twikoo 配置面板里的插件页签,选择代码高亮主题 coy,代码复制插件 copyButton。
自定义 css
.vitepress/theme/style/comment.scss
scss
.twikoo {
.el-input-group__append,
.el-input-group__prepend,
.el-textarea__inner {
border: 1px solid #dcdfe6;
box-shadow: none;
}
.el-input-group__prepend {
border-right: none;
}
.el-button--small {
height: auto;
}
.el-textarea > .el-textarea__inner {
min-height: 117px !important;
border-radius: 8px;
margin-top: 16px;
}
.tk-preview-container {
border-radius: 8px;
}
.tk-comments-count {
font-size: 14px;
color: #666;
}
.tk-nick,
.tk-replies .tk-nick-link {
font-size: 15px;
margin-right: 8px;
color: #409eff;
}
.tk-tag {
margin-right: 8px;
}
.tk-comments-container > .tk-comment {
border: solid 1px #f3f4f6;
border-radius: 1rem;
padding: 24px;
margin-top: 0;
margin-bottom: 24px;
transition: all 0.3s ease;
}
.tk-comments-container > .tk-comment:hover {
box-shadow: 0 4px 12px var(--vp-c-brand-1);
}
.tk-replies-expand > .tk-comment {
border-top: solid 1px #f7f7f7;
padding-top: 24px;
}
.tk-content p {
line-height: 1.6;
}
a:not(.tk-ruser):not(.tk-nick-link) {
color: #3072b3;
font-weight: 500;
text-underline-offset: 2px;
}
a:not(.tk-ruser):not(.tk-nick-link):hover {
color: #409eff;
}
/* 代码块 */
div.code-toolbar {
border-radius: 8px !important;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
div.code-toolbar :not(pre) > code[class*="language-"],
div.code-toolbar pre[class*="language-"] {
background: #f5f5f5;
border-radius: 8px;
}
div.code-toolbar pre[class*="language-"] {
border-radius: 8px;
}
div.code-toolbar pre[class*="language-"]::before,
div.code-toolbar pre[class*="language-"]::after {
content: none;
}
div.code-toolbar pre[class*="language-"] > code {
padding: 1em;
border-left: 4px solid #409eff;
border-radius: 8px;
}
div.code-toolbar > div.toolbar {
z-index: 1;
top: 8px;
right: 8px;
}
div.code-toolbar > div.toolbar > .toolbar-item > button {
display: none;
padding: 0 6px;
font-size: 12px;
color: black;
}
div.code-toolbar:hover > div.toolbar > .toolbar-item > button {
display: block;
}
.tk-admin-container {
z-index: 1;
}
}
.tk-avatar {
background-color: #ffffff00;
}
.tk-avatar .tk-avatar-img {
height: 41px !important;
}
.dark .twikoo {
.tk-comments-container > .tk-comment {
border-color: #454545;
}
.tk-comments-container > .tk-comment:hover {
box-shadow: 0 4px 12px var(--vp-c-brand-1);
}
.tk-replies-expand > .tk-comment {
border-color: #343434;
}
/* 代码块 */
div.code-toolbar pre[class*="language-"] > code {
filter: brightness(0.8);
}
}在docs\.vitepress\theme\styles\index.scss中添加配置
docs\.vitepress\theme\styles\index.scss
scss
@use "./comment.scss" as *; // 评论样式此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。