从零搭建企业级AFFiNE私有部署方案:解决团队协作数据孤岛问题
引言:当Notion替代方案遇上数据安全需求
你是否正面临这样的困境:团队使用的在线协作工具虽功能强大,却因数据存储在第三方服务器而引发合规风险?AFFiNE(全称为All-in-One Flexible Framework for Information Engineering,一体化灵活信息工程框架)作为Notion和Miro的开源替代方案,提供了本地部署能力,让企业数据主权回归掌控。本文将通过12个实操步骤,带领你完成从环境准备到高可用集群部署的全流程,最终实现一个支持50人团队协作的私有AFFiNE工作区。
读完本文你将掌握:
- 企业级AFFiNE部署的硬件配置标准
- 容器化部署架构的设计与实现
- 数据备份与监控告警体系搭建
- 多环境隔离与CI/CD流程整合
- 性能优化与常见问题排查方案
一、部署架构设计与环境准备
1.1 系统架构概览
AFFiNE私有部署采用微服务架构,主要包含以下组件:
1.2 硬件配置建议
根据团队规模选择合适的部署规格:
| 团队规模 | CPU核心数 | 内存容量 | 存储空间 | 部署模式 |
|---|---|---|---|---|
| 10人以下 | 4核 | 8GB | 100GB | 单机部署 |
| 10-50人 | 8核 | 16GB | 500GB | 容器化部署 |
| 50-200人 | 16核 | 32GB | 1TB | 集群部署 |
| 200人以上 | 32核+ | 64GB+ | 2TB+ | 分布式集群 |
1.3 操作系统要求
- 推荐使用Ubuntu 22.04 LTS或CentOS Stream 9
- 确保系统已安装Docker和Docker Compose:
# Ubuntu系统安装Docker
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y docker-ce docker-compose-plugin
sudo usermod -aG docker $USER
1.4 网络端口规划
| 服务 | 端口号 | 用途 | 是否对外暴露 |
|---|---|---|---|
| HTTP | 80 | Web访问 | 是 |
| HTTPS | 443 | 安全Web访问 | 是 |
| PostgreSQL | 5432 | 数据库服务 | 否 |
| Redis | 6379 | 缓存服务 | 否 |
| MinIO | 9000 | 对象存储API | 否 |
| MinIO控制台 | 9001 | 对象存储管理 | 否 |
| 监控系统 | 9090 | Prometheus | 否 |
| 监控面板 | 3000 | Grafana | 否 |
二、基础服务部署(Docker Compose)
2.1 创建Docker Compose配置文件
创建docker-compose.yml文件,定义基础服务:
version: '3.8'
services:
postgres:
image: pgvector/pgvector:pg16
container_name: affine-postgres
restart: always
environment:
POSTGRES_USER: affine
POSTGRES_PASSWORD: affine_password
POSTGRES_DB: affine
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U affine -d affine"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: affine-redis
restart: always
volumes:
- redis_data:/data
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
minio:
image: minio/minio:latest
container_name: affine-minio
restart: always
environment:
MINIO_ROOT_USER: minio_access_key
MINIO_ROOT_PASSWORD: minio_secret_key
volumes:
- minio_data:/data
ports:
- "9000:9000"
- "9001:9001"
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
redis_data:
minio_data:
2.2 启动基础服务
# 创建数据目录
mkdir -p /data/affine/{postgres,redis,minio}
# 启动服务
docker-compose up -d
# 检查服务状态
docker-compose ps
2.3 初始化对象存储
# 进入MinIO容器
docker exec -it affine-minio /bin/sh
# 创建存储桶
mc alias set local http://localhost:9000 minio_access_key minio_secret_key
mc mb local/affine-attachments
mc mb local/affine-backups
mc mb local/affine-user-uploads
# 设置存储桶策略
mc policy set public local/affine-attachments
mc policy set public local/affine-user-uploads
exit
三、AFFiNE服务部署
3.1 获取AFFiNE源码
# 创建工作目录
mkdir -p /opt/affine && cd /opt/affine
# 克隆代码仓库
git clone https://gitcode.com/GitHub_Trending/af/AFFiNE.git .
# 检查当前分支
git branch
3.2 配置环境变量
# 创建环境变量文件
cp ./.docker/dev/.env.example ./.docker/dev/.env
cp packages/backend/server/.env.example packages/backend/server/.env
# 编辑环境变量文件
vim packages/backend/server/.env
关键环境变量配置:
# 数据库配置
DATABASE_URL="postgresql://affine:affine_password@postgres:5432/affine"
# Redis配置
REDIS_URL="redis://redis:6379"
# 对象存储配置
STORAGE_TYPE="s3"
S3_ENDPOINT="http://minio:9000"
S3_ACCESS_KEY_ID="minio_access_key"
S3_SECRET_ACCESS_KEY="minio_secret_key"
S3_BUCKET="affine-attachments"
S3_REGION="us-east-1"
S3_FORCE_PATH_STYLE="true"
# 服务器配置
PORT=3000
NODE_ENV="production"
DOMAIN="affine.example.com"
PROTOCOL="https"
# 安全配置
JWT_SECRET="your_secure_jwt_secret_key_here"
JWT_EXPIRES_IN="7d"
# 邮件配置
EMAIL_FROM="AFFiNE <no-reply@affine.example.com>"
SMTP_HOST="mailhog"
SMTP_PORT="1025"
SMTP_USER=""
SMTP_PASSWORD=""
3.3 安装依赖并构建项目
# 安装Node.js环境
curl -fsSL https://fnm.vercel.app/install | bash
source ~/.bashrc
fnm install 20
fnm use 20
# 配置Yarn
corepack enable
corepack prepare yarn@stable --activate
# 安装依赖
yarn install
# 构建原生模块
yarn affine @affine/native build
yarn affine @affine/server-native build
# 构建Reader包
yarn affine @affine/reader build
# 初始化数据库
yarn affine server init
3.4 构建前端应用
# 构建Web前端
BUILD_TYPE=production yarn build
# 构建桌面应用资源(可选)
BUILD_TYPE=production yarn affine @affine/electron generate-assets
3.5 创建系统服务
# 创建systemd服务文件
sudo vim /etc/systemd/system/affine.service
服务文件内容:
[Unit]
Description=AFFiNE Service
After=network.target docker.service
Requires=docker.service
[Service]
User=root
Group=root
WorkingDirectory=/opt/affine
Environment="PATH=/root/.local/share/fnm_multishells/xxx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
ExecStart=/usr/bin/yarn affine server start
Restart=always
RestartSec=5s
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
启动服务:
# 重新加载systemd配置
sudo systemctl daemon-reload
# 启动AFFiNE服务
sudo systemctl start affine
# 设置开机自启
sudo systemctl enable affine
# 检查服务状态
sudo systemctl status affine
四、Web服务器配置(Nginx)
4.1 安装并配置Nginx
# 安装Nginx
sudo apt install -y nginx
# 创建Nginx配置文件
sudo vim /etc/nginx/sites-available/affine
配置文件内容:
server {
listen 80;
server_name affine.example.com;
# 重定向到HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name affine.example.com;
# SSL配置
ssl_certificate /etc/letsencrypt/live/affine.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/affine.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# 前端应用
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $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_connect_timeout 300s;
proxy_read_timeout 300s;
}
# API请求
location /api {
proxy_pass http://localhost:3000;
proxy_set_header Host $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_connect_timeout 300s;
proxy_read_timeout 300s;
}
# WebSocket连接
location /ws {
proxy_pass http://localhost:3000;
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;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
# 上传文件大小限制
client_max_body_size 100M;
}
4.2 启用站点配置并测试Nginx
# 启用站点
sudo ln -s /etc/nginx/sites-available/affine /etc/nginx/sites-enabled/
# 测试配置
sudo nginx -t
# 重启Nginx
sudo systemctl restart nginx
4.3 配置SSL证书(Let's Encrypt)
# 安装Certbot
sudo apt install -y certbot python3-certbot-nginx
# 获取SSL证书
sudo certbot --nginx -d affine.example.com
# 设置自动续期
sudo certbot renew --dry-run
四、初始化与用户管理
4.1 数据库初始化
# 进入项目目录
cd /opt/affine
# 执行数据库迁移
yarn affine server prisma migrate deploy
# 初始化管理员账户
yarn affine server seed-admin
4.2 创建初始用户
系统默认创建以下测试用户:
| 用户类型 | 邮箱 | 密码 | 工作空间成员上限 |
|---|---|---|---|
| 普通用户 | dev@affine.pro | dev | 3人 |
| 专业用户 | pro@affine.pro | pro | 10人 |
| 团队用户 | team@affine.pro | team | 10人(含团队工作区) |
4.3 访问AFFiNE Web界面
打开浏览器访问:https://affine.example.com
使用默认管理员账户登录后,应立即修改密码并创建新的用户账户。
五、监控与维护
5.1 部署监控系统
# 创建监控目录
mkdir -p /opt/affine/monitoring && cd /opt/affine/monitoring
# 创建docker-compose.yml
cat > docker-compose.yml << EOF
version: '3.8'
services:
prometheus:
image: prom/prometheus:v2.45.0
container_name: affine-prometheus
restart: always
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
grafana:
image: grafana/grafana:10.1.0
container_name: affine-grafana
restart: always
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=grafana_admin_password
depends_on:
- prometheus
volumes:
prometheus_data:
grafana_data:
EOF
# 创建Prometheus配置
cat > prometheus.yml << EOF
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'affine-backend'
static_configs:
- targets: ['host.docker.internal:3000']
- job_name: 'affine-db'
static_configs:
- targets: ['host.docker.internal:5432']
- job_name: 'affine-redis'
static_configs:
- targets: ['host.docker.internal:6379']
EOF
# 启动监控服务
docker-compose up -d
5.2 数据备份策略
创建备份脚本:
# 创建备份目录
mkdir -p /opt/affine/backups/scripts
# 创建备份脚本
cat > /opt/affine/backups/scripts/backup.sh << 'EOF'
#!/bin/bash
# AFFiNE数据备份脚本
# 配置
BACKUP_DIR="/opt/affine/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DB_CONTAINER="affine-postgres"
REDIS_CONTAINER="affine-redis"
MINIO_CONTAINER="affine-minio"
RETENTION_DAYS=30
# 创建备份目录
mkdir -p $BACKUP_DIR/{db,redis,config}
# 数据库备份
echo "Creating database backup..."
docker exec $DB_CONTAINER pg_dump -U affine affine > $BACKUP_DIR/db/affine_db_$TIMESTAMP.sql
gzip $BACKUP_DIR/db/affine_db_$TIMESTAMP.sql
# Redis备份
echo "Creating Redis backup..."
docker exec $REDIS_CONTAINER redis-cli save
docker cp $REDIS_CONTAINER:/data/dump.rdb $BACKUP_DIR/redis/affine_redis_$TIMESTAMP.rdb
gzip $BACKUP_DIR/redis/affine_redis_$TIMESTAMP.rdb
# 配置文件备份
echo "Backing up configuration files..."
tar -czf $BACKUP_DIR/config/affine_config_$TIMESTAMP.tar.gz \
/opt/affine/packages/backend/server/.env \
/opt/affine/.docker/dev/.env \
/etc/nginx/sites-available/affine
# 对象存储备份
echo "Backing up object storage..."
docker exec $MINIO_CONTAINER mc mirror local/affine-attachments local/affine-backups/attachments_$TIMESTAMP
docker exec $MINIO_CONTAINER mc mirror local/affine-user-uploads local/affine-backups/user_uploads_$TIMESTAMP
# 清理旧备份
echo "Cleaning up old backups..."
find $BACKUP_DIR/db -name "affine_db_*.sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR/redis -name "affine_redis_*.rdb.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR/config -name "affine_config_*.tar.gz" -mtime +$RETENTION_DAYS -delete
find $MINIO_CONTAINER:/data/affine-backups -name "*" -mtime +$RETENTION_DAYS -delete
echo "Backup completed successfully!"
echo "Backup files saved to $BACKUP_DIR"
EOF
# 添加执行权限
chmod +x /opt/affine/backups/scripts/backup.sh
设置定时任务:
# 编辑crontab
crontab -e
# 添加以下行(每天凌晨3点执行备份)
0 3 * * * /opt/affine/backups/scripts/backup.sh >> /opt/affine/backups/backup_log.txt 2>&1
5.3 日志管理
配置日志轮转:
# 创建日志轮转配置
sudo cat > /etc/logrotate.d/affine << 'EOF'
/opt/affine/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 root root
}
EOF
六、性能优化与扩展
6.1 数据库优化
PostgreSQL性能优化配置:
# 创建自定义配置文件
cat > /opt/affine/postgres.conf << 'EOF'
# PostgreSQL性能优化配置
max_connections = 100
shared_buffers = 2GB
effective_cache_size = 6GB
maintenance_work_mem = 512MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 20971kB
min_wal_size = 1GB
max_wal_size = 4GB
EOF
# 应用配置
docker cp /opt/affine/postgres.conf affine-postgres:/var/lib/postgresql/data/postgresql.auto.conf
docker restart affine-postgres
6.2 水平扩展方案
当团队规模增长时,可以考虑以下扩展策略:
- 应用服务扩展:部署多个AFFiNE后端实例,通过负载均衡器分发请求
- 数据库扩展:配置PostgreSQL主从复制,实现读写分离
- 缓存优化:增加Redis集群,提高缓存命中率
- 对象存储:迁移到专业对象存储服务(如AWS S3或阿里云OSS)
七、常见问题排查与解决方案
7.1 服务无法启动
# 检查服务状态
sudo systemctl status affine
# 查看日志
journalctl -u affine -f
# 检查依赖服务
docker-compose ps
7.2 数据库连接问题
# 检查数据库连接
docker exec -it affine-postgres psql -U affine -d affine -c "SELECT NOW();"
# 检查数据库日志
docker logs affine-postgres
7.3 性能问题排查
# 查看系统资源使用情况
top
# 检查Nginx连接数
netstat -an | grep :443 | wc -l
# 检查数据库连接数
docker exec -it affine-postgres psql -U affine -d affine -c "SELECT count(*) FROM pg_stat_activity;"
八、总结与展望
通过本文的步骤,你已经成功部署了一个企业级的AFFiNE私有部署环境,包括完整的Web服务、数据库、缓存、对象存储和监控系统。这一部署方案提供了安全、可靠、可扩展的协作平台,满足中小团队的知识管理需求。
未来可以考虑以下改进方向:
- 多区域部署:实现跨地域高可用架构
- 自动化运维:通过Kubernetes实现容器编排和自动扩缩容
- 高级安全特性:集成IAM系统和多因素认证
- 数据分析:增加用户行为分析和内容洞察功能
附录:常用命令速查表
| 任务 | 命令 |
|---|---|
| 启动所有服务 | docker-compose up -d |
| 停止所有服务 | docker-compose down |
| 查看应用日志 | journalctl -u affine -f |
| 数据库备份 | /opt/affine/backups/scripts/backup.sh |
| 重启AFFiNE服务 | sudo systemctl restart affine |
| 查看系统状态 | sudo systemctl status affine |
| 执行数据库迁移 | yarn affine server prisma migrate deploy |
| 构建前端应用 | BUILD_TYPE=production yarn build |
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



