香港服务器搭建Outline团队Wiki:替代Notion/Confluence的私有知识库完整方案

香港服务器搭建Outline团队Wiki:替代Notion/Confluence的私有知识库完整方案

Notion 需要科学上网、数据在美国服务器、团队版按座位收费($16/人/月);Confluence 更贵且重。Outline 是目前最接近 Notion 体验的开源 Wiki,界面现代、支持 Markdown 和富文本混用、有完整的权限管理和搜索功能。自托管在香港服务器后,国内外团队成员均可流畅访问,数据完全自主可控。


一、Outline vs 竞品对比

维度Outline(自托管)NotionConfluence
月费(20人团队)服务器费用(¥80)$160/月$100/月
大陆访问✅(香港服务器,30ms)需翻墙需翻墙
数据自主✅ 完全自主在 Notion 服务器在 Atlassian
Markdown 支持有限
全文搜索✅(内置 Postgres)
权限管理集合级别页面级别空间级别
API

二、环境准备与 Docker Compose 部署

<code"># Outline 依赖:PostgreSQL + Redis + S3 兼容存储(我们用 MinIO)
# 建议服务器配置:2核4G,20GB SSD

mkdir -p /opt/outline
cd /opt/outline

# 生成必要的密钥
# SECRET_KEY(64位随机十六进制)
openssl rand -hex 32
# UTILS_SECRET(同上)
openssl rand -hex 32
<code"># /opt/outline/docker-compose.yml
version: '3.8'

services:
  outline:
    image: outlinewiki/outline:latest
    container_name: outline
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    env_file: .env
    depends_on:
      - postgres
      - redis
      - storage
    volumes:
      - /opt/outline/data:/var/lib/outline/data

  postgres:
    image: postgres:16-alpine
    container_name: outline-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: outline
      POSTGRES_USER: outline
      POSTGRES_PASSWORD: outline_db_pass
    volumes:
      - /opt/outline/postgres:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    container_name: outline-redis
    restart: unless-stopped
    command: redis-server --maxmemory 256mb

  storage:
    image: minio/minio:latest
    container_name: outline-minio
    restart: unless-stopped
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: outline_minio_key
      MINIO_ROOT_PASSWORD: outline_minio_secret
    volumes:
      - /opt/outline/minio:/data
    ports:
      - "127.0.0.1:9000:9000"
      - "127.0.0.1:9001:9001"
<code"># /opt/outline/.env
# 基础配置
NODE_ENV=production
SECRET_KEY=在上面生成的64位十六进制key
UTILS_SECRET=在上面生成的另一个key

# 访问 URL
URL=https://wiki.yourdomain.com
PORT=3000

# 数据库
DATABASE_URL=postgres://outline:outline_db_pass@postgres:5432/outline

# Redis
REDIS_URL=redis://redis:6379

# 文件存储(MinIO,兼容 S3)
AWS_ACCESS_KEY_ID=outline_minio_key
AWS_SECRET_ACCESS_KEY=outline_minio_secret
AWS_REGION=us-east-1
AWS_S3_UPLOAD_BUCKET_NAME=outline
AWS_S3_UPLOAD_BUCKET_URL=http://storage:9000
AWS_S3_FORCE_PATH_STYLE=true
AWS_S3_ACL=private

# 身份验证(选择一种)
# 方式1:Slack SSO(推荐,团队已有 Slack 时)
SLACK_CLIENT_ID=your_slack_client_id
SLACK_CLIENT_SECRET=your_slack_client_secret

# 方式2:Google OAuth
# GOOGLE_CLIENT_ID=xxx
# GOOGLE_CLIENT_SECRET=xxx

# 方式3:邮件(OTP 验证码登录)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=outline@yourdomain.com
SMTP_PASSWORD=your_app_password
SMTP_FROM_EMAIL=outline@yourdomain.com
SMTP_REPLY_EMAIL=support@yourdomain.com

# 功能配置
DEFAULT_LANGUAGE=zh_CN
FORCE_HTTPS=true
TEAM_LOGO=
ALLOWED_DOMAINS=yourdomain.com   # 限制只有此域名邮箱可以注册
<code"># 初始化数据库
docker compose up -d postgres redis
sleep 10
docker compose run --rm outline yarn db:migrate

# 在 MinIO 中创建 bucket
docker exec outline-minio mc alias set local http://localhost:9000 outline_minio_key outline_minio_secret
docker exec outline-minio mc mb local/outline

# 启动所有服务
docker compose up -d

# 查看日志
docker compose logs -f outline | grep -E "started|error|listening"

三、Nginx 反向代理配置

<code"># /etc/nginx/sites-available/wiki.yourdomain.com
server {
    listen 443 ssl http2;
    server_name wiki.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/wiki.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/wiki.yourdomain.com/privkey.pem;

    client_max_body_size 100M;    # 允许上传大文件附件

    location / {
        proxy_pass http://127.0.0.1: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;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

四、配置 Google OAuth 登录(推荐)

<code">
1. 访问 Google Cloud Console → APIs & Services → Credentials
2. 创建 OAuth 2.0 Client ID
   - Application type: Web application
   - Authorized redirect URIs: https://wiki.yourdomain.com/auth/google.callback
3. 复制 Client ID 和 Client Secret 到 .env:
   GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
   GOOGLE_CLIENT_SECRET=GOCSPX-xxxxx

4. 重启 Outline:
   docker compose restart outline

5. 访问 https://wiki.yourdomain.com
   点击「Continue with Google」即可用 Google 账号登录

五、Outline 使用指南

<code">
知识库结构规划(建议):

├── 公司手册
│   ├── 入职指南
│   ├── 考勤制度
│   └── 报销流程
├── 技术文档
│   ├── 系统架构
│   ├── API 文档
│   ├── 部署手册
│   └── 故障排查
├── 产品
│   ├── 产品需求文档
│   ├── 功能规划
│   └── 竞品分析
├── 运营
│   ├── 营销素材
│   └── 活动记录
└── 会议记录
    ├── 周会
    └── 项目会议

权限设置建议:
- 公司手册:全员可读,HR 可编辑
- 技术文档:研发团队可读写,其他只读
- 产品文档:产品+研发可读写

六、API 集成(批量导入文档)

<code">import requests

OUTLINE_API = "https://wiki.yourdomain.com/api"
API_TOKEN = "从用户设置中获取的API Token"

headers = {
    "Authorization": f"Bearer {API_TOKEN}",
    "Content-Type": "application/json"
}

def create_document(title: str, text: str, collection_id: str) -> dict:
    """创建文档"""
    response = requests.post(
        f"{OUTLINE_API}/documents.create",
        headers=headers,
        json={
            "title": title,
            "text": text,
            "collectionId": collection_id,
            "publish": True
        }
    )
    return response.json()

def search_documents(query: str) -> list:
    """全文搜索"""
    response = requests.post(
        f"{OUTLINE_API}/documents.search",
        headers=headers,
        json={"query": query, "limit": 10}
    )
    return response.json().get("data", [])

# 批量导入 Markdown 文件
import os
for filename in os.listdir("/path/to/docs"):
    if filename.endswith(".md"):
        with open(f"/path/to/docs/{filename}") as f:
            content = f.read()
        title = filename.replace(".md", "").replace("-", " ")
        create_document(title, content, "your_collection_id")
        print(f"导入: {title}")

七、自动备份

<code"># 备份脚本(数据库 + MinIO 文件)
cat > /opt/outline/backup.sh << 'EOF' #!/bin/bash DATE=$(date +%Y%m%d_%H%M) mkdir -p /backup/outline # 备份数据库 docker exec outline-postgres pg_dump -U outline outline \ | gzip > /backup/outline/db-$DATE.sql.gz

# 备份 MinIO 文件
docker exec outline-minio mc mirror local/outline /backup/outline/files-$DATE/

# 清理30天前的备份
find /backup/outline -name "*.sql.gz" -mtime +30 -delete
find /backup/outline -type d -name "files-*" -mtime +30 -exec rm -rf {} +

echo "[$DATE] Outline 备份完成"
EOF
chmod +x /opt/outline/backup.sh
echo "0 2 * * * /opt/outline/backup.sh >> /var/log/outline-backup.log 2>&1" >> /etc/crontab

八、总结

Outline 自托管在香港服务器,彻底解决了国内外团队协作的两大痛点:国内访问 Notion 需要翻墙,以及数据不愿意放在境外服务商。20 人团队用 2核4G 香港 VPS(¥120/月)运行 Outline,对比 Notion Team($160/月)每月节省约 ¥1000,且知识库数据完全自主可控。

Telegram