Skip to content

Commit bb9c2f0

Browse files
committed
add post self host affine
1 parent 5d22351 commit bb9c2f0

1 file changed

Lines changed: 257 additions & 0 deletions

File tree

content/posts/self-host-affine.md

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
---
2+
title: 私有知识库和笔记工具 Affine 搭建, 修复导入 Markdown 图片丢失的问题
3+
date: 2025-11-12
4+
description: "私有知识库和笔记工具 Affine 搭建, 修复导入 Markdown 图片丢失的问题"
5+
layout: post
6+
7+
tags:
8+
- Wiki
9+
- Notion
10+
- Affine
11+
categories:
12+
- SelfHost
13+
lightgallery: true
14+
15+
toc:
16+
auto: true
17+
---
18+
19+
# 私有知识库和笔记工具 Affine 搭建, 修复导入 Markdown 图片丢失的问题
20+
21+
## 前言
22+
23+
一直以来我使用 Obsidian 作为我的知识库管理和编辑工具,配合自建的图床和 Nextcloud 的同步,我几乎可以在任何地方随意维护我的知识库,后面因为 Obsidian 的 Vim 模式用起来不顺手,在中文之间移动有卡顿的感觉,所以索性编辑器直接就用了 `Vim` ,但我一直苦恼一个问题,就是我的知识库一直以 Markdown 源文件的方式在 Nextcloud 的同步下,我虽然可以随时打开 Obsidian 查看,但是在移动端查看不方便,以及每次想查询的时候还得打开客户端,我本人是很不喜欢客户端的,我希望能在 web 上就可以查看,当然 Nextcloud 也能在网页端查看渲染的 Markdown 文件,但是效果也差强人意,正好刷 Koala 聊编程的时候看到了 Affine,其主打的 Notion 替代品的概念吸引了我,虽然我也用 Notion, 但用的并不多,而且 Notion 无法迁移我的本地知识库,导入的 Markdown 格式各种问题,抱着试试看的心态部署了一下,虽说官方提供了完整的 `docker-compose`配置文件,但实际配置下来还是遇到了一些问题,在此权当记录一下。
24+
25+
## 安装 affine 服务端
26+
27+
### Docker compose 安装服务端
28+
29+
还是使用 `dokcer compose`部署,下载最新版本 `docker-compose.yaml`文件。
30+
31+
```shellscript
32+
wget -O docker-compose.yml https://github.com/toeverything/affine/releases/latest/download/docker-compose.yml
33+
```
34+
35+
  下载配置模板修改配置
36+
37+
```shellscript
38+
wget -O .env https://github.com/toeverything/affine/releases/latest/download/default.env.example
39+
```
40+
41+
下面是我的配置
42+
43+
```
44+
# 数据库挂载目录
45+
DB_DATA_LOCATION=./postgres
46+
# 上传的附件目录
47+
UPLOAD_LOCATION=/mnt/media/affine
48+
# 配置文件目录
49+
CONFIG_LOCATION=./config
50+
# 数据库配置
51+
DB_USERNAME=affine
52+
DB_PASSWORD=****
53+
DB_DATABASE=affine
54+
# select a revision to deploy, available values: stable, beta, canary
55+
# 部署的版本:稳定版
56+
AFFINE_REVISION=stable
57+
58+
# set the host for the server for outgoing links
59+
# AFFINE_SERVER_HTTPS=true
60+
# AFFINE_SERVER_HOST=affine.yourdomain.com
61+
# or
62+
# 这里是我的自定义的内网域名,如果放到公网改成你自己的域名,如果内网IP访问则去掉这行
63+
AFFINE_SERVER_EXTERNAL_URL=https://wiki.linkzz.hm
64+
```
65+
66+
运行
67+
68+
```shellscript
69+
docker compose up -d
70+
```
71+
72+
正常运行之后打开 http://{youip}:3010 进行管理员配置
73+
74+
### 反向代理
75+
76+
内网部署服务众多,我不想记忆每个服务的端口,所以我选择使用内网域名来进行反代,下面是 `Nginx` 反代的配置:
77+
78+
```nginx
79+
map $http_upgrade $connection_upgrade {
80+
default upgrade;
81+
'' close;
82+
}
83+
upstream wiki-server {
84+
server 192.168.5.128:3010;
85+
}
86+
server {
87+
listen 443 ssl;
88+
server_name wiki.linkzz.hm;
89+
ssl_certificate ssl/linkzz.hm/_wildcard.linkzz.hm.pem;
90+
ssl_certificate_key ssl/linkzz.hm/_wildcard.linkzz.hm-key.pem;
91+
92+
ssl_session_timeout 5m;
93+
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
94+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
95+
ssl_prefer_server_ciphers on;
96+
97+
location / {
98+
proxy_pass http://wiki-server;
99+
proxy_set_header Host $host:$server_port;
100+
proxy_set_header X-Real-IP $remote_addr;
101+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
102+
proxy_set_header X-Forwarded-Proto https;
103+
proxy_set_header Upgrade $http_upgrade;
104+
proxy_set_header Connection $connection_upgrade;
105+
proxy_cache_bypass $http_upgrade;
106+
proxy_http_version 1.1;
107+
}
108+
109+
error_page 404 /404.html;
110+
location = /40x.html {
111+
}
112+
113+
error_page 500 502 503 504 /50x.html;
114+
location = /50x.html {
115+
}
116+
}
117+
118+
server {
119+
listen 80;
120+
server_name wiki.linkzz.hm;
121+
rewrite ^(.*)$ https://${server_name}$1 permanent;
122+
}
123+
```
124+
125+
## 解决导入时图片跨域问题
126+
127+
我部署的版本是 `0.25.0` 这个版本导入 Markdown 文件时其他格式都能很好保留,唯独图片存在跨域的问题,看了下控制台,Markdown 中的外链图片会通过官方的 Cloudflare worker 处理,这个worker 默认只处理官方host 的 Referer, 即 <https://app.affine.pro/> ,而我们部署的版本浏览器会自动加上这个域名的Referer,所以图片导入是无法使用的。
128+
129+
### 部署自己的图片处理 worker
130+
131+
好在官方已经开源了这个 worker
132+
133+
[GitHub - toeverything/affine-workers](https://github.com/toeverything/affine-workers)
134+
135+
我们可以自己部署自己的版本来解决这个问题,Fork 一下官方源码,修改以下地方
136+
137+
```diff
138+
modified packages/utils/src/headers.ts
139+
@@ -5,6 +5,7 @@ const ALLOW_ORIGIN: OriginRule[] = [
140+
'https://app.affine.pro',
141+
'https://insider.affine.pro',
142+
'https://affine.fail',
143+
+ 'https://wiki.linkzz.hm',
144+
'https://try-blocksuite.vercel.app',
145+
/https?:\/\/localhost(:\d+)/,
146+
/https:\/\/.*?-toeverything\.vercel\.app$/,
147+
modified packages/worker/src/index.ts
148+
@@ -2,7 +2,7 @@ import { DomainRouterBuilder, domainRoutersHandler, type Env } from '@affine/uti
149+
150+
import { AFFiNEWorker } from './affine.js';
151+
152+
-const WORKER_DOMAIN = 'affine-worker.toeverything.workers.dev';
153+
# 这个地址需要改为你的worker 访问地址
154+
+const WORKER_DOMAIN = 'affine-worker.***.workers.dev';
155+
156+
const affine = AFFiNEWorker();
157+
158+
modified packages/worker/wrangler.toml
159+
@@ -4,5 +4,19 @@ compatibility_date = "2023-11-21"
160+
workers_dev = true
161+
minify = true
162+
163+
-[limits]
164+
-cpu_ms = 500
165+
+# [limits]
166+
+# cpu_ms = 500
167+
+[observability]
168+
+enabled = false
169+
+head_sampling_rate = 1
170+
+
171+
+[observability.logs]
172+
+enabled = true
173+
+head_sampling_rate = 1
174+
+persist = true
175+
+invocation_logs = true
176+
+
177+
+[observability.traces]
178+
+enabled = false
179+
+persist = true
180+
+head_sampling_rate = 1
181+
```
182+
183+
observability 相关的配置是记录worker日志的,可以去掉
184+
185+
使用 `wrangler`或者在 Cloudflare 控制台关联仓库部署一下,下面是 wrangler 的部署步骤:
186+
187+
安装 [wrangler](https://developers.cloudflare.com/workers/wrangler/)
188+
189+
```shellscript
190+
npm install -g wrangler
191+
```
192+
193+
安装 [pnpm](https://pnpm.io/installation)
194+
195+
```shellscript
196+
npm install -g pnpm
197+
```
198+
199+
安装依赖
200+
201+
```shellscript
202+
pnpm install
203+
```
204+
205+
登录授权 wrangler
206+
207+
```shellscript
208+
wrangler login
209+
```
210+
211+
部署 worker
212+
213+
```shellscript
214+
pnpm run deploy
215+
```
216+
217+
###
218+
219+
### 应用自己的worker
220+
221+
目前使用的这个版本 worker 的地址是硬编码在前端的,无法使用配置项替换,改官方源码还要编译构建,只能自己改下镜像替换一下制品,目前 `0.25.0`使用这个方法是可行的。
222+
223+
创建 Dockerfile 文件, 下面的地址需要替换为你部署好的 worker 访问地址。
224+
225+
```docker
226+
FROM ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}
227+
228+
RUN sed -i 's|https://affine-worker.toeverything.workers.dev|https://affine-worker.***.workers.dev|g' /app/static/js/index.*.js
229+
```
230+
231+
然后修改 `docker-compose.yml` 文件
232+
233+
```yaml
234+
name: affine
235+
services:
236+
affine:
237+
# 使用 Local Dockerfile 构建镜像
238+
#image: ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}
239+
build: .
240+
container_name: affine_server
241+
```
242+
243+
最后重启之后运行容器
244+
245+
```shellscript
246+
docker compose down && docker compose up -d --build
247+
```
248+
249+
没问题的话就可以试试效果了
250+
251+
![image.png](https://img.linkzz.eu.org/main/images/2025/11/281d097b9eeace3cf204b83f0b3305a9.png)
252+
253+
以上是我的博客的一篇文章导入的效果,可以看到他成功下载了我图床里面的图片并导入到了内置的存储之中。
254+
255+
## 结语
256+
257+
目前使用下来,Affine 还是比较丝滑的,目前这个还不是完整版的 Affine,因为AI 功能尚未配置,不过用作个人知识库倒是足够了,我先深度使用一段时间来看看,后续等 AI 功能稳定了再考虑配置。

0 commit comments

Comments
 (0)