一.更新日志
因为AppFlowy-Cloud还在频繁的迭代,文章的教程也会跟着随之变动。大家可看记录的日期来参考部署。这里只列出部署层面相关的改动。
20240501-0.3.32
1.部署的.env配置文件可以指定minio、postgres、redis的地址了。部署更加友好可以复用已有的服务。
2.新增了appflowy_ai的服务 具体作用未知
二.了解介绍
首先介绍一下appflowy,这款软件是我在23年10月份的时候想找oneNote平替软件注意到的,我的主要需求是自托管,那会看官网介绍还没自托管的部署,在12月底的时候想看下appflowy的安卓端是否出来了(咕咕咕);安卓端没找到,倒是看到了自托管的Appflowy Cloud出来了,当即决定部署,经过两天摸索,将安装的步骤整理如下。
自托管的Appflowy Cloud采用Docker compose进行部署,一共有12个容器服务,其中5个服务是可选部署;12个服务如下:
- nginx:代理服务,用于代理各个服务的地址
- minio:一个开源的对象存储服务器,它兼容Amazon S3服务接口。用于数据存储。
- postgres:数据库服务
- redis:缓存中间件
- gotrue:身份验证服务器
- appflowy_cloud:appflowy的核心业务服务
- appflowy_ai:AI服务
- admin_frontend(可选):管理登陆授权的web页面服务,官方建议是安装,便于新增用户和登陆。因为不使用第三方的oauth的时候,只能通过web页面登陆然后跳转到appflowy。没看明白的话建议先安装,后续使用就明白了。
- tunnel(可选):提供将 appflowy 连接到 Cloudflare 的安全方式,无需公共可路由 IP 地址。
- portainer、portainer_init(可选):两个服务是便于Docker管理的WEB UI。
- pgadmin(可选):管理postgres 数据库的WEB UI。
部署的服务架构图如下:
📌
可以看到有很多的服务非Appflowy本身的,可以与其他的共用;但是因为docker-compose的配置内容都是默认的,如果使用自己部署的minio、postgres、redis的话注意需要修改docker-compose.yml文件里面的地址并注释掉对应的服务,其中postgres还需要手工打脚本。经过折腾后还是强烈建议不要使用自己部署的minio、postgres、redis,可以省了很多麻烦。
三.部署准备
本着最小化原则,本次部署的教程去除了tunnel、portainer、portainer_init、pgadmin的部署。如果都需部署可以跳过我修改的配置信息。
- 端口 80/443 可用,这点很重要!!!因为哪怕服务改了端口,但是Appflowy客户端在websocket访问的时候默认的80端口会导致数据无法同步,🥴疯狂踩坑。
- 运行内存最低2GB,建议4GB
- 本次教程部署的服务器系统为Debian 11
四.程序部署
1.部署Docker
官网教程地址:https://docs.docker.com/engine/install/debian/
a.运行一下命令卸载相关可能导致冲突的包
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
b.设置Docker apt存储库
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
c.安装Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
d.通过运行hello-world镜像验证运行是否成功
sudo docker run hello-world
2.部署AppFlowy-Cloud
a.登陆服务器拉取最新代码
mkdir appflowy && cd appflowy
git clone https://github.com/AppFlowy-IO/AppFlowy-Cloud
cd AppFlowy-Cloud
b.修改.env配置文件
首先复制一份模板命名为.env
cp deploy.env .env
修改.env的配置信息
## 连接到gotrue docker容器的URL 一般默认即可
APPFLOWY_GOTRUE_BASE_URL=http://gotrue:9999
## 连接到postgres docker容器的URL 如果单独部署数据库的需要更改配置
APPFLOWY_DATABASE_URL=postgres://postgres:password@postgres:5432/postgres
APPFLOWY_ACCESS_CONTROL=true
# admin frontend
## 连接到redis docker容器的URL 如果使用单独部署的redis需要更改配置
ADMIN_FRONTEND_REDIS_URL=redis://redis:6379
## 连接到gotrue docker容器的URL 一般默认即可
ADMIN_FRONTEND_GOTRUE_URL=http://gotrue:9999
# 设置一个加密的密码 任意都可
GOTRUE_JWT_SECRET=benzhu666
# JWT令牌的过期时间(秒)默认即可
GOTRUE_JWT_EXP=7200
#如果设置为true,将自动确认用户注册。
#如果设置了OAuth2或配置了smtp,则可以将其设置为false
#以强制执行电子邮件确认或OAuth2登录。
#如果设置为false,则需要设置SMTP
GOTRUE_MAILER_AUTOCONFIRM=false
# 每分钟可以发送的电子邮件数 默认即可
GOTRUE_RATE_LIMIT_EMAIL_SENT=100
# 设置邮箱的stmp
GOTRUE_SMTP_HOST=smtp.exmail.qq.com
GOTRUE_SMTP_PORT=465
GOTRUE_SMTP_USER=
GOTRUE_SMTP_PASS=
GOTRUE_SMTP_ADMIN_EMAIL=
# gotrue管理员账号
GOTRUE_ADMIN_EMAIL=my@benzhu.xyz
GOTRUE_ADMIN_PASSWORD=6666666
# 应用的地址
API_EXTERNAL_URL=http://127.0.0.1
# 设置oathu2登录 建议可以设置一个github的 也很方便 参考链接如下:
# https://github.com/AppFlowy-IO/AppFlowy-Cloud/blob/main/doc/AUTHENTICATION.md#github
# Google OAuth2
GOTRUE_EXTERNAL_GOOGLE_ENABLED=false
GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID=
GOTRUE_EXTERNAL_GOOGLE_SECRET=
GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI=http://your-host/gotrue/callback
# GitHub OAuth2
GOTRUE_EXTERNAL_GITHUB_ENABLED=true
GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=
GOTRUE_EXTERNAL_GITHUB_SECRET=
GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=http://127.0.0.1/gotrue/callback
# Discord OAuth2
GOTRUE_EXTERNAL_DISCORD_ENABLED=false
GOTRUE_EXTERNAL_DISCORD_CLIENT_ID=
GOTRUE_EXTERNAL_DISCORD_SECRET=
GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI=http://your-host/gotrue/callback
# File Storage
# 这是存储图像、文件等存储的地方
# 默认情况下,Minio用作默认文件存储,该存储使用主机的文件系统
# 单独部署的Minio的话需要修改配置 不是的话默认即可
APPFLOWY_S3_USE_MINIO=true
APPFLOWY_S3_MINIO_URL=http://minio:9000 # 如果你使用不同的Minio地址,请更改此项
APPFLOWY_S3_ACCESS_KEY=minioadmin
APPFLOWY_S3_SECRET_KEY=minioadmin
APPFLOWY_S3_BUCKET=appflowy
#APPFLOWY_S3_REGION=us-east-1
# 作用不详 我和上面smtp的配置保持一致
APPFLOWY_MAILER_SMTP_HOST=smtp.exmail.qq.com
APPFLOWY_MAILER_SMTP_USERNAME=
APPFLOWY_MAILER_SMTP_PASSWORD=
RUST_LOG=info
# AppFlowy AI服务
# 这里看了下代码应该是封装openapi的请求服务 api_key填的应该是openai的key
# 实际作用不明 待研究
APPFLOWY_AI_OPENAI_API_KEY=
APPFLOWY_AI_SERVER_HOST=appflowy_ai
APPFLOWY_AI_SERVER_PORT=5001
# AppFlowy History服务
# 理解是历史数据备份用的 但是当前的版本不会创建这个服务 后期迭代应该会加上
APPFLOWY_HISTORY_URL=http://history:50051
APPFLOWY_HISTORY_REDIS_URL=redis://redis:6379
APPFLOWY_HISTORY_DATABASE_URL=postgres://postgres:password@postgres:5432/postgres
# 下面这些服务我都没有部署 直接注释掉
# PgAdmin
#PGADMIN_DEFAULT_EMAIL=admin@example.com
#PGADMIN_DEFAULT_PASSWORD=password
# Portainer (username: admin)
#PORTAINER_PASSWORD=password1234
# Grafana Dashboard
#GF_SECURITY_ADMIN_USER=admin
#GF_SECURITY_ADMIN_PASSWORD=password
# Cloudflare tunnel token
#CLOUDFLARE_TUNNEL_TOKEN=
c.修改docker-compose.yml
新版本的扩展服务单独到了docker-compose-extras.yml,所以docker-compose.yml文件夹无需修改。
但是如果使用了自己单独部署的minio、postgres、redis的话记得还是需要修改docker-compose.yml注释掉对应服务的创建。
d.修改nginx配置
主要是注释可选的服务的代理配置,路径nginx/nginx.conf。
注意果使用了自己单独部署的minio、postgres、redis的话,记得修改对应的代理地址。
# Minimal nginx configuration for AppFlowy-Cloud
# Self Hosted AppFlowy Cloud user should alter this file to suit their needs
events {
worker_connections 1024;
}
http {
# docker dns resolver
resolver 127.0.0.11 valid=10s;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 8080;
# https://github.com/nginxinc/nginx-prometheus-exporter
location = /stub_status {
stub_status;
}
}
server {
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/private_key.key;
listen 80;
listen 443 ssl;
client_max_body_size 10M;
underscores_in_headers on;
# GoTrue
location /gotrue/ {
set $gotrue gotrue;
proxy_pass http://$gotrue:9999;
rewrite ^/gotrue(/.*)$ $1 break;
# Allow headers like redirect_to to be handed over to the gotrue
# for correct redirecting
proxy_set_header Host $http_host;
proxy_pass_request_headers on;
}
# WebSocket
location /ws {
set $appflowy_cloud appflowy_cloud;
proxy_pass http://$appflowy_cloud:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
# AppFlowy-Cloud
# created a separate location block for handling CORS preflight (OPTIONS) requests specifically for the /api endpoint.
location = /api/options {
if ($http_origin ~* (http://127.0.0.1:8000)) {
add_header 'Access-Control-Allow-Origin' $http_origin;
}
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, PATCH';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, Client-Version';
add_header 'Access-Control-Max-Age' 3600;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
location /api {
set $appflowy_cloud appflowy_cloud;
proxy_pass http://$appflowy_cloud:8000;
proxy_set_header X-Request-Id $request_id;
proxy_set_header Host $http_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;
# Set CORS headers for other requests
if ($http_origin ~* (http://127.0.0.1:8000)) {
add_header 'Access-Control-Allow-Origin' $http_origin always;
}
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, Client-Version' always;
add_header 'Access-Control-Max-Age' 3600 always;
}
# AppFlowy AI
location /appflowy_ai/ {
proxy_pass http://appflowy_ai:5001;
proxy_set_header Host $http_host;
proxy_pass_request_headers on;
}
# Minio Web UI
# Derive from: https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html
# Optional Module, comment this section if you are did not deploy minio in docker-compose.yml
location /minio/ {
set $minio minio;
proxy_pass http://$minio:9001;
rewrite ^/minio/(.*) /$1 break;
proxy_set_header Host $http_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;
proxy_set_header X-NginX-Proxy true;
## This is necessary to pass the correct IP to be hashed
real_ip_header X-Real-IP;
proxy_connect_timeout 300;
## To support websockets in MinIO versions released after January 2023
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)
# Uncomment the following line to set the Origin request to an empty string
# proxy_set_header Origin '';
chunked_transfer_encoding off;
}
# PgAdmin 可选的服务 注释掉
# Optional Module, comment this section if you are did not deploy pgadmin in docker-compose.yml
#location /pgadmin/ {
# set $pgadmin pgadmin;
# proxy_pass http://$pgadmin:80;
# proxy_set_header X-Script-Name /pgadmin;
# proxy_set_header X-Scheme $scheme;
# proxy_set_header Host $host;
# proxy_redirect off;
#}
# Portainer 可选的服务 注释掉
# Optional Module, comment this section if you are did not deploy portainer in docker-compose.yml
#location /portainer/ {
# set $portainer portainer;
# proxy_pass http://$portainer:9000;
#rewrite ^/portainer/(.*) /$1 break;
#}
# Admin Frontend
# Optional Module, comment this section if you are did not deploy admin_frontend in docker-compose.yml
location / {
set $admin_frontend admin_frontend;
proxy_pass http://$admin_frontend:3000;
proxy_set_header X-Scheme $scheme;
proxy_set_header Host $host;
}
}
}
e.启动服务
docker compose up -d
f.检查服务是否正常
docker ps -a
g.重新配置和重新部署
重新配置和重新启动是很常见的。只需编辑并再次.env执行docker compose up -d
五.客户端安装
1.客户端下载
直接下载appflowy的最新版本即可。
https://github.com/AppFlowy-IO/AppFlowy/tags
2.客户端设置
a.安装点击快速进入,然后进入设置
b.在cloud settings里面开启同步后点击重启,重启后进入填入appflowy cloud的地址,默认的是80端口,无需带后缀,比如http://127.0.0.1。
c.登录账号
因为目前应用端是没法直接输入账号密码登录的,要么通过othau2登录,要么通过web管理台登录。
othau2没啥好说,直接唤起登录即可,通过管理台登录的话先打开地址:http://127.0.0.1/web/login,将127.0.0.1修改为自己服务的地址,用配置的账号密码进行登录,然后单击open appflowy:
六.相关问题
1.如何自编译admin_frontend
如果我们采用的自己单独部署的redis和postgrep数据库之类的话需要修改,这里提供一下参考。
下载了appflowy cloud源码后进入admin_frontend目录。将内容修改完毕后执行命令编译自己的镜像:
docker compose up -d --no-deps --build admin_frontend
赞,哥们更新下内容?部署运行都没问题,就是经常同步报错囧,但是如果两部pc同时操作一个页面,则可以同步囧
code: RecordNotFound
msg: Record not found:Can’t find the row for query: QueryCollab { object_id: “a792dc99-75af-4ba3-8e23-40bd0abfa9cb”, collab_type: Document }
我2核 2G的机子,勉强能带动。我也是卸下来了。等什么时候appflowy修复能自定义端口吧ヾ(≧∇≦*)ゝ
这个自托管部署真麻烦,默认占用80端口
目前有没有魔改版本的
目前看没有 我觉得可以等一手官方支持 现在更新很频繁
脑洞大开试试,不知道有没有用zerotier的思路能实现的,让zerotier给appflowy-cloud分配一个ip,每次都打开zerotier-one就能自动同步了。
哈哈 老哥脑洞我没太理解 zerotier是组网工具 和应用没啥关系呀 能部署appflowy-cloud当然也能部署zerotier、WireGuard这类组网vpn进行数据同步呀
请问是否可以修改默认的80和443接口呢?因为我服务器是多个容器公用的,不知道哪个用了443,尝试在nginx.conf中修改了默认的443但是并未生效,不知道为啥
改端口服务启动是ok的,nginx.conf的配置不需要改,把docker-compose.yml的nginx服务的端口映射进行更换。因为之前客户端的websocket的请求默认写死了80(不知道新版是否有变动),所以必须要80端口,没有443应该可行。可以尝试下。
感谢博主深夜回复,我继续尝试下|´・ω・)ノ
兄弟你成功了吗。。我发现怎么弄都没有办法修改端口都是nginx说80和443端口被占用。
写的非常好,可惜我是小白,只会有群晖这类简单的部署,这个对我来说太复杂了,谢谢。
😊不太建议安装,目前部署方式不太友好,使用起来也挺多bug;版本还在不断迭代,可以关注后续变化稳定后再安装。
谢谢提醒,那我暂时用Joplin过渡下,随时关注。
我就是先用群晖测试的,这个服务端基于ubuntu,安装过程会大量报错,而且对cpu资源占用奇高,如果是白群不建议用,黑群自己配一台高性能的话倒是可以试试
我想通过volume 把docker里面的数据挂载到外边,但是不知道数据的存储路径在哪里。怎么实现
数据是存储在minio里面,可以通过指定minio镜像挂载的路径来实现。
redis跟postgre用来做什么的
官方文档我没有找到有关postgre和redis有关详细说明;postgre是个数据库,正常来说会存储用户的信息,minio里面的数据通过postgre与用户关联起来等等;redis一般充当缓存中间件和用于多服务数据共享的。