自托管部署
提示
预备条件
一台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
,即可访问到包含你最新文章的博客。