基于Markdown的多人协作文档Outline项目部署文档,使用OIDC作为认证方式,一键部署

6 阅读4分钟

Outline Wiki + Keycloak OIDC 部署文档

文档为部署后自用写的,适用于内网无HTTPS环境

注意,由于文件内容较多,这篇文章只是概述,相关文件请前往 Github 下载

点我跳转Github地址

image.png

环境信息

项目
Outline 地址http://<服务器IP>:3000
Keycloak 管理后台http://<服务器IP>:3001
Keycloak 管理员admin / admin123
Keycloak Realmoutline
OIDC Client IDoutline

文件结构

<部署目录>/
├── config/
│   ├── redis.conf              # Redis 配置文件
│   └── keycloak-realm.json     # Keycloak realm 预配置(含中文、client secret)
├── data/                       # 所有持久化数据(bind mount,方便备份迁移)
│   ├── postgres/               # PostgreSQL 数据库
│   ├── keycloak/               # Keycloak H2 数据库
│   └── outline/                # Outline 上传文件(图片、附件等)
├── docker-compose.yml          # 一体化部署配置(4 个服务)
├── docker.env                  # Outline 环境变量(含 OIDC 预设值、中文注释)
├── install.sh                  # 一键部署脚本(自动检测/替换 IP)
└── README.md                   # 本文档

快速部署

一键部署

cd <部署目录>

# 自动检测本机 IP 并部署
bash install.sh

# 或手动指定 IP(只是使用这个ip去替换配置文件中的占位符)
bash install.sh 192.168.1.100

install.sh 启动时自动完成:

  1. 检测或接收服务器 IP
  2. 替换所有配置文件中的 IP(docker.env、docker-compose.yml、keycloak-realm.json)
  3. 创建数据目录并设置权限
  4. 启动所有服务(docker-compose up -d)
  5. 等待 Keycloak 就绪(最长 2 分钟)
  6. 应用 StateStore 补丁并重启 Outline

换机器部署

  1. 将整个部署目录复制到新机器
  2. 确认配置文件中 IP 仍为模板值 192.168.1.6(如果之前部署过,Git 回退即可)
  3. 执行 bash install.sh,脚本自动替换为新机器 IP

重新部署(清除所有数据)

docker-compose down -v
rm -rf data
bash install.sh

停止服务(保留数据)

docker-compose down

数据持久化

全部使用 bind mount,无 docker volume,直接映射到 ./data/ 目录:

服务容器路径宿主机路径内容
PostgreSQL/var/lib/postgresql./data/postgres/数据库文件
Keycloak/opt/keycloak/data/h2./data/keycloak/用户、Realm 配置
Outline/var/lib/outline/data./data/outline/上传的图片、附件

备份与迁移

# 停止服务
docker-compose down

# 直接打包整个 data 目录
tar czf backup.tar.gz data/

# 迁移到新服务器
scp backup.tar.gz user@new-server:/path/to/deploy/
tar xzf backup.tar.gz
bash install.sh
# 注意,可能需要替换 docker.env、docker-compose.yml、keycloak-realm.json 这些配置文件中的ip

首次使用 - 创建管理员账户

  1. 访问 Keycloak 管理后台: http://<IP>:3001
  2. 使用 账户密码(compose中查看) 登录
  3. 左上角切换 Realm 到 outline
  4. 进入 Users -> Add user
    • 填写 Username(必填)
    • 点击 Create
  5. 进入用户详情 -> Credentials 标签
    • 点击 Set password
    • 输入密码,将 Temporary 设为 OFF
    • 点击 Save
  6. 访问 Outline: http://<IP>:3000
  7. 点击登录 -> 选择 OpenID Connect
  8. 使用刚创建的用户名密码登录

注意: 第一个通过 OIDC 登录的用户将自动成为 Outline 管理员。

配置文件说明

docker-compose.yml

服务镜像端口数据目录
postgrespostgres:185432(内部)./data/postgres/
redisredis6379(内部)
keycloakquay.io/keycloak/keycloak:latest3001->8080./data/keycloak/
outlineoutlinewiki/outline:1.8.03000:3000./data/outline/

docker.env 关键变量

变量说明
NODE_ENV必须为 production
URLOutline 访问地址(install.sh 自动替换 IP)
FORCE_HTTPS内网 HTTP 设为 false
OIDC_CLIENT_ID / OIDC_CLIENT_SECRET与 keycloak-realm.json 一致

config/keycloak-realm.json

Keycloak 启动时通过 --import-realm 自动导入,包含:

  • Realm 基础设置(中文本地化:zh-CN / en)
  • OIDC Client 配置(含预设 secret、redirect URI)
  • redirect URI 中的 IP 由 install.sh 自动替换

遇到的问题及解决方案

问题 1: NODE_ENV=development 导致 Vite 脚本注入

现象: 浏览器报 CORS 错误,尝试加载 @vite/client 等开发服务器脚本。

解决: 保持 NODE_ENV=production


问题 2: Secure Cookie 导致 OIDC 登录 500 错误

现象: /auth/oidc 返回 500,日志: Cannot send secure cookie over unencrypted connection

原因: production 模式下 StateStore 将 OAuth CSRF cookie 设为 secure: true(代码: secure: _env.default.isProduction), HTTP 连接不允许发送 secure cookie。

解决: install.sh 自动执行 sed 替换为 secure: false


问题 3: bind mount 目录权限导致上传失败

现象: 粘贴图片提示上传失败,容器内 Permission denied

原因: bind mount 目录属主为宿主机用户,容器内以 nodejs(1001) 运行, 无写入权限。

解决: install.sh 创建 data 子目录后执行 chmod 777


问题 4: Keycloak issuer 返回 localhost

现象: well-known 端点 issuer 为 localhost。

解决: docker-compose.yml 中设置 KC_HOSTNAMEKC_HOSTNAME_PORT


问题 5: 配置文件中 IP 硬编码

现象: docker.env、docker-compose.yml、keycloak-realm.json 中 IP 写死为 192.168.1.6,换机器需手动修改。

解决: install.sh 启动时自动检测或接收 IP,使用 sed 替换所有配置文件。

日常维护

查看日志

docker logs outline_outline_1 --tail 50
docker logs outline_keycloak_1 --tail 20

备份

docker-compose down
tar czf backup_$(date +%Y%m%d).tar.gz data/
docker-compose up -d

Keycloak 用户管理

访问 Keycloak 管理后台 -> 选 outline realm -> Users 管理用户。