跳到主要内容

自托管部署

提示

预备条件

  • 一台VPS(以Debian 11为例,推荐大陆地区以外的vps,大陆地区的服务器需备案后,才可以使用80、443端口)

  • 一个域名

1. 视频版

即将到来!

2. 文字版

2.1. 整体架构流程

自部署架构流程

2.2. 具体操作

  • a. 安装curl工具,以Debian为例。
apt install curl -y
  • b. 安装docker和docker compose。
curl -fsSL https://get.docker.com | sh
  • c. 自托管supabase。(用于存储评论数据)

详情见supabase Docker部署文档 或者见此youtube教学视频—Self host Supabase with an Ubuntu Server on Digital Ocean

笔记版本

提示

注:笔记版本中添加了caddy的安装,反向代理supabase、保护supabase studio的流程,建议阅读。

  • d. 使用docker构建并部署
You may ask

Q:为什么不提供dockerhub镜像,直接拉取部署不更好吗?

A:因为Next.js在构建docker镜像时,会将以NEXT_PUBLIC_开头的环境变量内联至docker镜像,这会导致.env文件中自定义的环境变量根本载入不进docker容器。虽然网上有添加entrypoint.sh等解决方案,但是这些方案要么较为繁琐,要么需要牺牲Next.js的性能(将静态生成(ssg)全盘转为服务器端渲染(ssr)),因此自己构建属于自己的docker镜像,并用docker compose部署较为稳妥。

# 克隆git仓库
git clone https://github.com/simple-is-awesome/simple.git
# 进入文件夹
cd simple
# 重命名文件
mv .env.example .env
# 构建一个名为 "blog" 的docker镜像
docker build -t blog .
# 根据 docker-compose.yml 文件中的定义启动并运行docker容器
docker compose up -d
  • e. 更新
# 停止并删除由 docker-compose.yml 文件定义的服务(容器)及其相关资源
docker compose down

# 修改.env或者二次开发(修改过程可见下方解释)

# 重新创建一个名为"blog"的docker镜像
docker build -t blog .
# 根据 docker-compose.yml 文件中的定义启动并运行docker容器
docker compose up -d
# 强制删除所有未被容器引用的镜像
docker image prune -af

.env文件的参数

直接替换xxxxxx即可,不要添加多余的符号。

# Basic config
# 网站的url(如:https://a.exmaple.com)
NEXT_PUBLIC_SITE_URL=xxxxxx
# 网站标题(如:小明的博客)
NEXT_PUBLIC_SITE_TITLE=xxxxxx
# 网站的描述信息(如:记录自己的学习、生活、娱乐)
NEXT_PUBLIC_SITE_DESCRIPTION=xxxxxx
# 网站的关键词(如blog, life, xiaoming)
NEXT_PUBLIC_KEYWORDS=xxxxxx
# 网站的底部信息(如:© 2023 Made with ❤️ By Xiaoming.)
NEXT_PUBLIC_FOOTER=xxxxxx
# 网站每一页的文章数量(如:10)
NEXT_PUBLIC_POSTS_PERPAGE=xxxxxx
# 网站的github仓库地址(如:https://github.com/simple-is-awesome/simple)
NEXT_PUBLIC_GITHUB_REPO=xxxxxx
# 网站是否显示评论(如:true)
NEXT_PUBLIC_SHOW_COMMENT=xxxxxx

# Third-party In Integration
# Inoreader的公开频道的json链接(如:https://www.innoreader.com/stream/user/1005341682/tag/user-broadcasted/view/json)
NEXT_PUBLIC_INOREADER_CHANNEL=xxxxxx
# Raindrop分享集合的rss链接(如:https://bg.raindrop.io/rss/public/32937900)
NEXT_PUBLIC_RAINDROP=xxxxxx

# OpenAI
# OpenAI API是否可以获取(如:true)
NEXT_PUBLIC_OPENAI_API_KEY_AVAILABLE=xxxxxx
# OpenAI的API KEY
OPENAI_API_KEY=xxxxxx
# OpenAI的Organization ID
OPENAI_ORG_ID=xxxxxx

# Cloudflare
# 可通过Cloudflare后台管理面板的Turnstile选项创建获取
# Cloudflare Turnstile的site key
NEXT_PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY=xxxxxx
# Cloudflare Turnstile的secret key
CLOUDFLARE_TURNSTILE_SECRET_KEY=xxxxxx

# Email
# 可用于评论回复邮件通知
# 邮箱用户名(如[email protected]
EMAIL_USERNAME=xxxxxx
# 邮箱授权码(可通过邮箱设置里面开启smtp服务获取)
EMAIL_PASSWORD=xxxxxx
# 邮箱SMTP服务器地址(如:smtp.qq.com)
EMAIL_HOST=xxxxxx
# 邮箱端口(如:465)
EMAIL_PORT=xxxxxx
# 邮箱发邮件时,是否对其进行加密(如:true)
EMAIL_SECURE=xxxxxx

# Supabase
# Supabase 项目的服务角色密钥(可见supabase/docker/.env中的SERVICE_ROLE_KEY)
SUPABASE_SERVICE_ROLE_KEY=xxxxxx
# Supabase 项目的匿名角色密钥(可见supabase/docker/.env中的ANON_KEY)
NEXT_PUBLIC_SUPABASE_ANON_KEY=xxxxxx
# Supabase 项目的 API URL(如:https://api.supabase.exmaple.com,可见自托管supabase中的教程)
NEXT_PUBLIC_SUPABASE_URL=xxxxxx
  • f. 反向代理博客docker容器与宿主机对应的端口

编辑/etc/caddy/Caddyfile

demo.example.com {
reverse_proxy localhost:3001
}

重载caddy

systemctl reload caddy
  • g. 撰写博客

在simple文件夹下的posts文件夹中新建md或mdx文件。

遵循如下所示的frontmatter:

---
title: "GitHub Flavored Markdown语法"
date: "2023-03-30"
tags: ["github","markdown"]
slug: "github-flavored-markdown"
summary: "总结GitHub Flavored Markdown语法"
showtoc: true
---
  • h. 重复更新步骤
# 停止并删除由 docker-compose.yml 文件定义的服务(容器)及其相关资源
docker compose down

# 修改.env或者二次开发(修改过程可见下方解释)

# 重新创建一个名为"blog"的docker镜像
docker build -t blog .
# 根据 docker-compose.yml 文件中的定义启动并运行docker容器
docker compose up -d
# 强制删除所有未被容器引用的镜像
docker image prune -af

执行完此步骤,访问https://demo.exmaple.com,即可访问到包含你最新文章的博客。