
先说结论AFFiNE 真的能打而且自部署之后我把 Notion 里最后一篇东西迁出来就顺手卸了。这半年我一直在找 Notion 的替代品前提很硬性——必须支持自部署、必须有白板、必须能处理结构化数据AFFiNE 刚好把这三样捏在一起还提供了一个不折腾的 Docker 镜像。这篇文章会记录我完整的部署过程、踩过的坑以及我对“能不能打”这个问题的最终判断。如果你也在考虑把笔记从 Notion 挪到自部署方案里这篇应该能帮你省不少时间。1. AFFiNE到底是个什么东西1.1 三合一不是噱头而是“反Notion”的设计先把 AFFiNE 拆开看。它想做的是把三种能力收进同一个数据模型里编辑文档类似 Notion 的 page支持标题、引用、代码块、图片、嵌套页面这些常见操作无限白板给用户一块自由画布可以把文档块、图形、手写便签、连接线都拖上去数据库类似 Notion database用表格、看板、日历、列表这些视图管理结构化数据。单看每一项市面上都有独立工具做得比它成熟但 AFFiNE 真正的点在于这三种东西不是三个孤立的模块而是在同一个块编辑器里互通的。文档里可以直接嵌一块白板白板上可以直接挂某个数据库视图白板里的对象和文档里的块是同一套数据模型。这一点是它和“笔记软件加一个画图插件”这种拼凑方案的本质区别。AFFiNE 还有一个很关键的背景它从一开始就把自部署当作一等公民。官方直接提供 Docker 镜像数据落在你自己的机器上。叠加完全开源的代码想要魔改、集成、二次开发理论上都没有什么阻碍。这一点在 Notion 身上基本是看不到的。你可以跑着独立部署的 Notion 替代方案但 Notion 官方始终保持封闭生态。所以对于“数据控制权”有执念的人来说AFFiNE 天然就赢在起跑线上。1.2 为什么应该用Docker而不是去用官方云服务用官方云服务的问题不在于功能而在于你拥有什么。笔记数据是长期积累的数字资产每一次输入都是在制造未来可以被检索、被再加工的信息。如果这些数据只存在于别人家的服务器哪天服务调整、价格变动、使用政策发生变化你就会非常被动。自部署的核心价值是数据控制权具体到 AFFiNE 这个产品上你能得到几个实实在在的好处数据完全在自己的 PostgreSQL 里备份、导出、迁移都自由离线也能用不受服务商网络波动影响可以接自己的域名和证书做成一个私有知识库没有用户数限制给团队用只需要考虑服务器性能。而 Docker 是自部署最主流的载体。它把 AFFiNE 需要的运行时、依赖、环境变量都打包成标准镜像你不需要手动配置 Node.js 环境不需要手工装 PostgreSQL 客户端只需要会用 docker compose 定义服务之间的关系就能在十几分钟内把整个应用跑起来。后续升级也简单拉一个新镜像再启动一次容器就行。不过这里得先纠一个容易混淆的概念。标题里说“笔记白板数据库三合一”很多刚接触的人会把“数据库”理解成部署时要装的那个数据库其实完全是两码事。AFFiNE 自带的数据库视图是应用层用来组织结构化笔记的功能它承载的是表格、看板、日历这些面向使用者的界面而 AFFiNE 真正跑起来依赖的 PostgreSQL 和 Redis是存储层一个放持久化数据一个放缓存和临时状态。前者解决你整理信息的问题后者解决数据放哪里、同步状态怎么维护的问题。这个逻辑先理清了后面部署的时候看见两个数据库服务就不会懵。2. Docker部署AFFiNE前的准备工作2.1 前置条件一台能稳定跑Docker的机器部署 AFFiNE 对硬件的要求不算苛刻但也不能太将就。官方给的建议是 2 核 4G 起步我实际跑下来的感受是如果只给自己用2G 内存也能勉强跑起来但一旦同时打开数据库视图和白板CPU 占用会明显往上跳切页面偶尔会出现延迟。如果你打算存很多笔记、还要做图片和附件管理内存建议往上加。团队使用的话4 核 8G 以上更稳妥。操作系统优先选 Linux。Ubuntu 22.04 或者 Debian 12 这类主流发行版都行。Windows 上也可以用 Docker Desktop 跑但生产环境我个人不建议Docker Desktop 在 Windows 上依赖虚拟机层性能损耗和权限问题都比较麻烦。macOS 用户用 Docker Desktop 没有问题不过 Apple Silicon 上早期部分镜像有过兼容问题建议拉最新的 stable 镜像不要用太老的 tag。Docker 本身的版本也有讲究。最好用 20.10 以上的版本配套的 compose 插件要 V2。老版本的 docker-compose 在解析新的 yaml 语法时有各种坑你完全没必要在环境上浪费时间。装完 Docker 之后可以先检查一下版本docker --version docker compose version确认两个命令都能正常输出再继续往下走。2.2 两种部署方式我推荐用docker compose网上写 AFFiNE 部署的帖子不少常见有两条路线。第一种是最快的单容器方式一条命令拉起来docker run -d -p 3010:3010 ghcr.io/toeverything/affine:stable这种方式适合第一次上手、只想看个界面的情况。但问题也很明显老版本镜像内置了 SQLite数据直接写在容器里如果你不做卷映射容器一删数据就全没了。新版官方其实更推荐把 PostgreSQL 和 Redis 单独拆出来让 AFFiNE 连接外部数据库。这就引出了第二种路线用 docker compose 把 AFFiNE、PostgreSQL、Redis 三个服务编排到一起。两种方式我都试过。如果你只是想在本地体验五分钟那直接 docker run 就好但如果你已经确定要用它来替代 Notion那就别图这个省事。compose 方式虽然多写几行配置但胜在清晰——数据层独立、服务可伸缩、升级时可以控制先后顺序。尤其是数据备份和恢复的时候数据库独立服务带来的好处会非常明显。所以我下面的步骤直接按 compose 来。3. 用Docker Compose把AFFiNE跑起来3.1 目录结构和compose文件先创建工作目录mkdir -p /opt/affine cd /opt/affine touch docker-compose.yml下面这个 compose 文件是我实际部署时用的版本基于官方仓库最新的 stable 镜像调整过。需要注意AFFiNE 的镜像名和端口在不同时期有过调整你部署的时候如果发现镜像拉不下来一定要去官方 GitHub 仓库看一下当前的 compose 示例以那里的最新配置为准。services: affine: image: ghcr.io/toeverything/affine:stable container_name: affine restart: always ports: - 3010:3010 volumes: - ./data:/app/data environment: - AFFINE_SERVER_PORT3010 - AFFINE_SERVER_HOST0.0.0.0 - AFFINE_DB_TYPEpostgres - AFFINE_DB_HOSTaffine-postgres - AFFINE_DB_PORT5432 - AFFINE_DB_USERaffine - AFFINE_DB_PASSWORDyourpassword - AFFINE_DB_DATABASEaffine affine-postgres: image: postgres:16-alpine container_name: affine-postgres restart: always environment: - POSTGRES_USERaffine - POSTGRES_PASSWORDyourpassword - POSTGRES_DBaffine volumes: - ./postgres:/var/lib/postgresql/data这个文件里没有放 Redis因为部分版本的 AFFiNE 默认对 Redis 的依赖不是强制项主要是做缓存和协同消息中间件。如果你的使用场景里有大量实时协同、同一个 workspace 多人在线编辑建议把 Redis 也加上affine-redis: image: redis:7-alpine container_name: affine-redis restart: always volumes: - ./redis:/data然后在 affine 服务的环境变量里补上- AFFINE_REDIS_ENABLEDtrue - AFFINE_REDIS_HOSTaffine-redis - AFFINE_REDIS_PORT6379有三点必须提醒。第一AFFINE_DB_TYPE一定要设成 postgres否则部分镜像默认走 SQLite数据库视图和协同功能会受限。第二restart: always建议保留服务进程异常退出后 Docker 会自动拉起对长期运行的自部署服务来说这是个保底的可靠性措施。第三数据库密码不要用弱口令尤其当你的服务器有公网 IP 时。虽然 PostgreSQL 不直接映射到宿主机端口外部网络默认访问不到但总有人会因为其他需求去改端口映射一旦暴露弱口令就是灾难。3.2 启动、验证和日志排查配置文件写好后在/opt/affine目录下启动docker compose up -d第一次启动会拉镜像PostgreSQL 初始化大概要十几秒到一分钟。看到所有容器都变成 up 状态后打开http://你的服务器IP:3010就能看到注册页面了。如果页面打不开先看日志这是最直接的排查入口docker compose logs -f affine最常见的现象是 affine 容器先起来但 postgres 还没有初始化完导致连接数据库失败、容器不断重启。这种情况不用着急等 postgres 容器完全就绪后重启一次 affine 容器就好docker compose restart affine另外还要提醒一个很多人忽略的问题防火墙。很多云服务器自带安全组系统里也可能开着 ufw 防火墙。Ubuntu 上如果启用了 ufw要记得放行端口sudo ufw allow 3010/tcp这一步不做的话本地 curl 通、外网死活打不开非常容易让人误判成镜像或配置问题。4. 常见问题排查与避坑经验4.1 版本不匹配导致的白屏和登录异常我自己踩的第一个大坑是 web 端和服务端镜像版本不一致。早期 AFFiNE 是单镜像后来官方把服务拆成了affine-web和affine-graphql两个镜像。如果你用旧的前端去连新的后端或者反过来表现往往是页面白屏、登录后一直转圈、创建工作区失败。这类问题很难一眼发现因为容器状态都是正常运行的端口也在监听。排查方法就是看容器日志里有没有版本相关的报错更直接的办法是尽量保持所有镜像的 tag 一致比如都用stable或者都锁定到同一个具体版本号。不要一个用 latest、一个用 stable这种搭配最容易出问题。我的建议是自部署不要追新。等官方发 release 说明之后再统一升级所有镜像。这个项目迭代速度很快稳定运行比“用上最新特性”重要得多。4.2 数据备份与恢复既然要替代 Notion数据就是命根子。我推荐两类备份配合使用。第一类是数据库级备份用 pg_dump 把结构化数据导出来docker exec -it affine-postgres pg_dump -U affine affine affine_backup.sql恢复的时候就反向操作cat affine_backup.sql | docker exec -i affine-postgres psql -U affine affine第二类是文件级备份直接备份 AFFiNE 的数据目录里面包含附件、白板快照等二进制文件tar czvf affine-data-backup.tar.gz /opt/affine/data /opt/affine/postgres实际使用中建议每周做一次数据库备份附件类文件可以低频一点。恢复备份的顺序很重要先恢复数据库再恢复文件最后重启 affine 容器。顺序反了的话AFFiNE 会因为数据不一致出现各种奇怪的同步错误。4.3 内存和性能优化我部署初期那台 4G 内存的服务器上AFFiNE 整个体系包含 PostgreSQL常驻内存大概在 1.2G 到 1.5G 之间。如果只用 SQLite 模式内存会低一些但多端协同和并发能力会明显下降。如果你的服务器内存紧张可以给容器加资源限制deploy: resources: limits: memory: 1G但注意AFFiNE 本身是为协同场景设计的内存限制太小会导致容器被 OOMKilled表现为服务无故消失、重启后数据短暂不可用。个人使用可以给 affine 容器 1G 到 1.5G 的预算团队使用建议不要设上限或者直接把物理内存加到 8G 以上。还有一个小技巧闲置的旧 workspace 不要留着。AFFiNE 每个 workspace 都会维护一套同步状态和索引workspace 多了之后PostgreSQL 的 CPU 占用会明显上升。定期清理不再使用的 workspace对性能帮助很大。4.4 反向代理和HTTPS配置既然做成长期使用的知识库直接用 IP 加端口访问不太体面也容易暴露地址。而且很多浏览器对非 HTTPS 环境的权限限制很严格剪贴板、通知这些 API 会受影响。我建议加一层反向代理。Caddy 是最省事的方案它会自动申请和续期证书配置只需要几行your.domain.com { reverse_proxy :3010 }如果你更习惯 Nginx那要特别注意 WebSocket 的转发。AFFiNE 的实时协同和文档同步依赖 WebSocket如果不把升级头转发过去会看到一个非常诡异的症状页面能打开数据库内容能加载但文档一直同步失败、多端不连通。Nginx 配置里要加上这段location / { proxy_pass http://127.0.0.1:3010; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }5. 数据库能力实测和Notion的差距我实测后的结论5.1 AFFiNE数据库能做什么标题里写“笔记白板数据库三合一”很多人最关心的是数据库能力到底有没有被夸大。我在实际使用中建过表格视图、看板视图、日历视图基本操作体验跟 Notion 的 database 非常接近。核心能力可以归纳成几块创建数据库视图支持表格、看板、日历、列表四种形态自定义字段类型包括文本、数字、下拉选择、日期、成员、附件等多视图同源切换不同视图不会影响原始数据改任何一条记录所有视图同步更新筛选、排序、分组这些轻量项目管理操作都有。对于阅读清单、任务追踪、课程项目记录、团队事项管理这些场景AFFiNE 完全够用。但跟 Notion 对比差距也很明显。AFFiNE 目前缺少更复杂的公式计算、跨数据库的关联视图以及丰富的第三方数据库集成。如果你是重度 Notion 用户靠公式做自动化和复杂计算靠关联数据库搭信息网络那 AFFiNE 现阶段会让你有点施展不开。但如果你只是拿数据库做轻量管理AFFiNE 的体验已经足够顺畅。5.2 迁移Notion数据的实操建议AFFiNE 支持导入 Notion 导出文件这是我敢倒腾的根本原因。实操路径是在 Notion 后台导出 zip 包然后在 AFFiNE 里选择导入。迁移过程中有几个点必须提醒。第一先导出一个小的测试页面验证流程不要一上来就全量导入第一次迁移大概率会碰到格式不完美的情况。第二迁移完成后重点检查附件部分数据库块可能变成纯文本表格字段类型需要手动调整一遍。第三数据库视图配置不会完整保留数据会进来但你已经设置好的排序、筛选、视图布局都要重新建。这不是 bug是不同产品数据模型本身的差异迁移成本不可避免。如果你还在犹豫要不要完全替换 Notion我的建议是先部署一个 AFFiNE 实例把最近一两个月的高频笔记迁进去试用用顺手了再决定要不要全量迁移。不要一上来就走“卸载所有”的极端路线。5.3 谁适合换谁不建议换最后说我的结论。AFFiNE 适合这几类人在意数据主权不愿意把笔记长期放在别人服务器上需要白板和文档结合画架构图、做头脑风暴、做学习项目记录想低成本拥有一个团队知识库不想按人头付订阅费喜欢折腾自部署又不希望折腾得太狠希望有个成熟方案可以直接用。不适合换的情况也很明确你在 Notion 生态里深度依赖公式、自动化、第三方插件这些 AFFiNE 目前还没有完全对应你的团队已经靠 Notion 形成了很固定的协作习惯迁移成本大于收益你需要在移动端高频记录AFFiNE 的移动端目前跟 Notion 差距不小你连一台能长期运行的机器都没有那自部署对你来说就是额外负担。6. 白板场景和AI能力这些额外细节值得知道6.1 白板到底是不是真香我刚开始用 AFFiNE 时对白板是无感的直到有一次我需要在文档里画系统架构图发现以前在 Notion 里得专门把图导成图片再插进去而在 AFFiNE 里直接新建一个白板块画完跟文档内容无缝衔接。这个体验上的差距用过一次就回不去了。白板本身用的是无限画布支持自由放置图形、手绘线条、便签、连接线还能把文档块直接拖到画布上变成对象。最让我意外的是你可以把数据库视图拖进白板里当作一块实时面板白板上的图形可以和数据表关联起来。比如我在做项目规划时左侧放数据库看板右侧放架构图和里程碑节点整体思路非常清晰。这种“文档、数据、图形在一个平面上横向打通”的能力才是 AFFiNE 三合一里最值钱的部分。6.2 把AI能力接上本地模型AFFiNE 内置了一些 AI 功能云版会直接提供模型服务但自部署版本默认没有配好的模型地址。如果你愿意折腾可以配置一个兼容 OpenAI 接口的本地模型服务比如用 Ollama 在服务器上跑一个对话模型然后把 AFFiNE 的 AI 服务地址指向 Ollama 的接口。这样做的意义在于所有 AI 请求不出内网数据不会离开自己的机器和自部署的初衷完全一致。我先说清楚AFFiNE 的 AI 功能目前更多是锦上添花比如摘要、续写、解释文字跟深度智能体那类玩法还有距离。而且配置过程需要你对环境变量、模型名称这些概念有基本了解并不是开箱即用。但如果你本身就在接触本地大模型的部署那把它和 AFFiNE 接起来会是一个很有意思的组合。我实际用下来摘要生成和文本润色这类轻量任务本地模型完全能胜任速度也还可以主要是不需要额外花钱也不会有数据出境的顾虑。结合我自己的体会AFFiNE 目前最大的价值不是“替代 Notion 的每一个功能”而是给你提供了另一个维度上的选择一个数据完全自持、文档白板数据库天然打通、还能DIY接入本地AI能力的工作台。如果你正好有一台空闲服务器花一个下午部署起来试试大概率不会失望。