Outline 极速部署
看到了糖喵的前端速成教程用了 outline,确实好看,又有点想自己搞一个出来,不由得回忆起以前刚开始看 outline 部署的时候。
当时傻不拉叽没想到直接配 SMTP, 也没想到 gitea(forgejo) 是个 OpenID Provider, 可以对接 OIDC. 这些都是后来配熟了才意识到的。
除此之外,最难的就是 S3 了。当时是指定要求使用 S3 存储,但是也没有我能负担得起的 S3 服务商,真的难倒我。当时再加上一些人发的劝退言论,令我很是绝望,就几乎忘记了这玩意的存在。不过这次看到文档说 0.72 以后他们支持了本地文件存储^1,就省事很多了。那我觉得还是有些能做出来的希望的。
最近看 notion 替代品的时候,经常有人提到 outline. 虽然肯定不及 notion 和飞书那么强大,但我觉得它姑且算开源,而且我正好缺一个好用的在线 WYSIWYG markdown 编辑器当作草稿箱,而它正好合适,看起来比 standard notes 和 joplin 顺手多了,虽然没有 e2ee. 哦对了,似乎占用也不大,刚起来的时候加起来吃掉 1GB RAM 吧。
添加 OAuth App
要拿 forgejo 当作 OpenID Provider, 就要在 forgejo 里面添加一个 application, 然后拿走 client id 和 client secret.
Callback URL 文档里没写,是等到第一次调用 OIDC 进到授权界面的时候,看到地址栏里有个 redirect 然后得知的,path 是 /auth/oidc.callback
,太奇妙了。
部署
按照文档,看起来就是一个 docker compose 的事情,那再把 TLS 部分交给 nginx 就行,并不困难。
上 compose file
文档中提供了 compose 配置的示例。看到暴露端口的时候就绷不住了,拿下来加以修改。
添加
container_name
作为内部通信用的 hostname,无需再对外暴露端口。将 volume 改为直接 bind mount 文件夹。
注意:需要随后将
storage-data
文件夹的所有权改为1001:65533
,否则无法正常上传文件或导出(可使用docker exec -it outline_app sh
进入容器内,执行id -u
和id -g
自行验证)将 image tag 的版本锁定住。
不需要使用单独的反代了,我自己有 nginx.
把 forgejo 的地址解析到它容器所在的网关,那个地址有一个 nginx 监听,不必绕一圈公网了。
# docker-compose.yml
version: "3.2"
services:
outline:
image: docker.getoutline.com/outlinewiki/outline:0.74.0
env_file: ./docker.env
container_name: outline_app
ports:
- "127.0.0.1:3000:3000"
volumes:
- ./storage-data:/var/lib/outline/data
depends_on:
- postgres
- redis
extra_hosts:
- "forgejo.example.com:172.30.0.1"
redis:
image: redis:7.0-alpine
env_file: ./docker.env
container_name: outline_redis
# ports:
# - "6379:6379"
volumes:
- ./redis.conf:/redis.conf
command: ["redis-server", "/redis.conf"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 30s
retries: 3
postgres:
image: postgres:13-alpine
env_file: ./docker.env
container_name: outline_postgres
# ports:
# - "5432:5432"
volumes:
- ./database-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready"]
interval: 30s
timeout: 20s
retries: 3
environment:
POSTGRES_USER: 'user'
POSTGRES_PASSWORD: 'pass'
POSTGRES_DB: 'outline'
改环境变量
文档里提及了 github 上面托管的示例,拿下来重命名为 docker.env
提供给 docker compose 用。
按照自己的需求修改。
Line | Comment |
---|---|
7, 11 | 自己生成去 |
15, 16, 23 | 更改 postgres 和 redis 的地址,就可以在内部 bridge 通信,不用对容器外暴露端口。 |
20 | 内部通信,postgres 不开 SSL 了。 |
33 | 改成你自己拿来暴露到公网的地址 |
48-55, 59 | 使用本地存储 |
71-96 | 删去不使用的外部认证配置 |
101-106 | 照 forgejo 文档的 OIDC Endpoints 猛抄一遍 |
134 | 顺便禁用一些奇妙的 TLS 配置 |
138 | 禁用遥测(虽然感觉自欺欺人) |
142 | 进程数我开了 4, 看个人需求。 |
160-162 | 删去 slack 集成 |
175-182 | 考虑到我那个域名邮箱可怜的 quota, 就不配 SMTP 了(后来一看那个邮件通知设置,一堆开关,真能把 quota 用爆,然后塞满我的收件箱。) |
7c7
-SECRET_KEY=generate_a_new_key
+SECRET_KEY=<GENERATED_SECRET_1>
11c11
-UTILS_SECRET=generate_a_new_key
+UTILS_SECRET=<GENERATED_SECRET_2>
15,16c15,16
-DATABASE_URL=postgres://user:pass@localhost:5432/outline
-DATABASE_URL_TEST=postgres://user:pass@localhost:5432/outline-test
+DATABASE_URL=postgres://user:pass@outline_postgres:5432/outline
+DATABASE_URL_TEST=postgres://user:pass@outline_postgres:5432/outline-test
20c20
-# PGSSLMODE=disable
+PGSSLMODE=disable
23c23
-REDIS_URL=redis://localhost:6379
+REDIS_URL=redis://outline_redis:6379
33c33
-URL=https://app.outline.dev:3000
+URL=https://outline.example.com
48,55c48,55
-AWS_ACCESS_KEY_ID=get_a_key_from_aws
-AWS_SECRET_ACCESS_KEY=get_the_secret_of_above_key
-AWS_REGION=xx-xxxx-x
-AWS_S3_ACCELERATE_URL=
-AWS_S3_UPLOAD_BUCKET_URL=http://s3:4569
-AWS_S3_UPLOAD_BUCKET_NAME=bucket_name_here
-AWS_S3_FORCE_PATH_STYLE=true
-AWS_S3_ACL=private
+# AWS_ACCESS_KEY_ID=get_a_key_from_aws
+# AWS_SECRET_ACCESS_KEY=get_the_secret_of_above_key
+# AWS_REGION=xx-xxxx-x
+# AWS_S3_ACCELERATE_URL=
+# AWS_S3_UPLOAD_BUCKET_URL=http://s3:4569
+# AWS_S3_UPLOAD_BUCKET_NAME=bucket_name_here
+# AWS_S3_FORCE_PATH_STYLE=true
+# AWS_S3_ACL=private
80,81c80,81
-SLACK_CLIENT_ID=get_a_key_from_slack
-SLACK_CLIENT_SECRET=get_the_secret_of_above_key
+# SLACK_CLIENT_ID=get_a_key_from_slack
+# SLACK_CLIENT_SECRET=get_the_secret_of_above_key
88,89c88,89
-GOOGLE_CLIENT_ID=
-GOOGLE_CLIENT_SECRET=
+# GOOGLE_CLIENT_ID=
+# GOOGLE_CLIENT_SECRET=
94,96c94,96
-AZURE_CLIENT_ID=
-AZURE_CLIENT_SECRET=
-AZURE_RESOURCE_APP_ID=
+# AZURE_CLIENT_ID=
+# AZURE_CLIENT_SECRET=
+# AZURE_RESOURCE_APP_ID=
101,105c101,105
-OIDC_CLIENT_ID=
-OIDC_CLIENT_SECRET=
-OIDC_AUTH_URI=
-OIDC_TOKEN_URI=
-OIDC_USERINFO_URI=
+OIDC_CLIENT_ID=<YOUR_CLIENT_ID>
+OIDC_CLIENT_SECRET=<YOUR_CLIENT_SECRET>
+OIDC_AUTH_URI=https://forgejo.example.com/login/oauth/authorize
+OIDC_TOKEN_URI=https://forgejo.example.com/login/oauth/access_token
+OIDC_USERINFO_URI=https://forgejo.example.com/login/oauth/userinfo
134c134
-FORCE_HTTPS=true
+FORCE_HTTPS=false
138c138
-ENABLE_UPDATES=true
+ENABLE_UPDATES=false
142c142
-WEB_CONCURRENCY=1
+WEB_CONCURRENCY=4
160,162c160,162
-SLACK_VERIFICATION_TOKEN=your_token
-SLACK_APP_ID=A0XXXXXXX
-SLACK_MESSAGE_ACTIONS=true
+# SLACK_VERIFICATION_TOKEN=your_token
+# SLACK_APP_ID=A0XXXXXXX
+# SLACK_MESSAGE_ACTIONS=true
165c165
-GOOGLE_ANALYTICS_ID=
+# GOOGLE_ANALYTICS_ID=
170,171c170,171
-SENTRY_DSN=
-SENTRY_TUNNEL=
+# SENTRY_DSN=
+# SENTRY_TUNNEL=
175,182c175,182
-SMTP_HOST=
-SMTP_PORT=
-SMTP_USERNAME=
-SMTP_PASSWORD=
-SMTP_FROM_EMAIL=hello@example.com
-SMTP_REPLY_EMAIL=hello@example.com
-SMTP_TLS_CIPHERS=
-SMTP_SECURE=true
+# SMTP_HOST=
+# SMTP_PORT=
+# SMTP_USERNAME=
+# SMTP_PASSWORD=
+# SMTP_FROM_EMAIL=hello@example.com
+# SMTP_REPLY_EMAIL=hello@example.com
+# SMTP_TLS_CIPHERS=
+# SMTP_SECURE=true
添加 nginx 配置
server stream 都少不了
stream {
map $ssl_preread_server_name $name {
...
+ outline.example.com outline;
}
...
...
+ upstream outline {
+ server 127.0.0.3001;
+ }
顺便要加 TLS 配置,不要忘记。我用了 wildcard, 复用分离出来的 TLS 配置文件就行了。
server {
listen 127.0.0.1:3001 ssl; http2 on;
server_name outline.example.com;
# TLS settings
include /etc/nginx/conf.d/xx-tls.conf;
# enforce authenticated pull
include /etc/nginx/conf.d/xx-verify-client.conf;
location / {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
其他的一些就不再提了。有坑慢慢填。
初次启动
nginx -t
检查一下配置,然后 systemctl reload nginx
重启 nginx.
容器部分,先启动 redis 和 postgres, 再启动 app 本体。
docker compose up redis postgres
然后另外开个 tty(用 tmux/screen 更快)
docker compose up outline
观察一下启动好了以后,访问 outline 实例,用 OIDC 登录。
跳转到授权界面,权限要得属实有些多了,forgejo 什么时候修
然后就能进来了,尽情玩耍吧。