本文主要是介绍docker基于minio部署outline团队知识库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
outline 介绍
Outline 是一个开源的Wiki 知识库和团队协作文档管理工具,美观、实时协作、功能丰富且兼容 Markdown,设计用于帮助团队和组织有效地创建、共享和管理文档。
Outline 具有简单易用的界面和强大的功能,可以替代传统的文档管理系统,如 Google Docs 或 Confluence。Outline 提供了一种结构化的方式来组织信息,使团队成员可以快速访问和协作内容。
主要特性:
- ✏️ 直观的编辑体验:一个极快的编辑器,支持 Markdown、斜杠命令、交互式嵌入等等
- 👥 多人协作:与团队成员实时协作处理文档。评论和话题让对话井井有条。
- 🔍 强大的搜索和问答功能:立即在您的工作空间中进行搜索,并提出有关文档的问题以获得直接的 AI 答案。
- 💬 与 Slack 集成:无需离开聊天即可搜索、共享文档并提出问题。文档更新时向频道发布通知。
- 🌐 公开分享:通过链接公开共享文档,或与团队私下共享文档。使用您自己的品牌颜色、徽标和域名。**
其他特性:
- ⚡ 速度极快:Outline 速度很快,真的很快。努力确保毫秒级响应时间 - 文档立即加载、搜索快速、用户界面导航快捷。
- 🤝 协作性:Outline 经过精心设计,功能强大、实时且易于使用。阅读和编写文档应该是一件令人愉快的事情。
- 🌙 深色模式:对于夜猫子来说,我们已经为您提供了帮助。 Outline 具有漂亮的深色模式,既养眼又美观。
- 🔒 安全和权限:通过读写权限、用户组、来宾用户、公共共享等管理知识库。
- 🛠️ 20+ 集成:简单集成到您日常使用的工具中,例如 Slack、Figma、Loom 等。找不到您需要的集成?还有一个开放的 API 。
- 🌍 用您的语言:Outline 支持 RTL,包括 17 种语言的翻译,包括 🇫🇷 法语、🇪🇸 西班牙语、🇩🇪 德语、🇰🇷 韩语和 🇨🇳 中文。
- 🚀 建于公共场所:Outline 会定期更新新功能和修复,请查看我们的公共变更日志以了解进展情况!
- 🛠️ 开源:Outline 的源代码是公开的,开发是公开完成的。更喜欢托管在您自己的基础设施上?没问题。
- 🖌️ 可定制:自定义域允许您拥有 docs.yourteam.com 。带有您自己的品牌和颜色的白色标签。
官方网站:https://www.getoutline.com/
项目地址:https://github.com/outline/outline
outline 部署规划
我们将采用分步部署的方式,依次通过docker-compose安装traefik、minio、keyclock及outline组件,主要涉及docker-compose .env
环境变量文件的定义及docker-compose.yaml
文件的创建。
部署前置要求:
- 准备一台云服务器,例如 阿里云ECS服务器 或轻量服务器,本部署示例购买1台阿里云ECS服务器(包年包月购买3年具有2.6折的最低优惠),服务器配置为2核CPU/4G内存/100G磁盘,绑定公网IP,带宽按流量计费;
- 准备操作系统,本示例使用
Ubuntu 22.04 LTS
操作系统; - 准备可用域名,并配置好域名解析,本示例使用阿里云域名;
- -SSL证书,由
traefik
通过Let's Encrypt
自动申请免费证书; - 主机上已安装
docker
和docker compose
。
整体部署架构图:
部署服务组件清单:
我们采用 Traefik
作为反向代理和负载均衡器,MinIO
作为对象存储,Keycloak
作为身份和访问管理工具,并且利用 PostgreSQL
和 Redis
作为数据库和缓存,来支撑 Outline
的运行。
名称 | 说明 | 版本 |
---|---|---|
Traefik | 现代的反向代理和负载均衡器,用于管理和路由 HTTP 请求,提供 SSL 终止和路径路由功能。 | v3.1 |
MinIO | 高性能的对象存储服务,兼容 AWS S3 API,Outline 用于存储文件和附件。 | RELEASE.2024-08-26T15-33-07Z |
Keycloak | 开源的身份和访问管理工具,用于提供单点登录和身份认证功能,支持 OAuth2 和 SAML 协议。 | 25.0.4 |
Outline | 开源的知识库和文档管理工具,用于团队协作、文档编辑和知识共享。 | 0.78.0 |
Redis | 高性能的内存数据存储,用于缓存和会话管理,提高应用性能。 | 7.4.0 |
PostgreSQL | 开源的关系型数据库管理系统,用于存储 Outline 的持久化数据。 | 16.2 |
Outline文件存储选择
Outline文件存储支持以下两种形式,本示例采用minio S3存储
:
Local file system
:如果希望将文件上传存储在运行 Outline 的同一服务器上,则可以使用本地文件系统存储选项来实现。AWS S3
:由于AWS S3是对象存储的标准,因此不一定使用云上的AWS S3存储,例如可以通过自建minio来实现,完整的支持列表见下表。
Outline 可以与绝大多数 S3 兼容的 API 一起使用,因为使用的是可用 API 接口的一个非常小的子集,以下内容已经过社区成员的测试。
Service | Compatible |
---|---|
Amazon S3 | ✅ |
Minio | ✅ |
DigitalOcean Object Storage | ✅ |
Alibaba Cloud / Aliyun OSS | ✅ (discussion) |
Scaleway | ✅ (discussion) |
Cloudflare R2 | ❌ (discussion) |
Backblaze | ❌ (discussion) |
OVH Object Storage | ❌ |
身份验证提供程序选择
Outline 可以配置为接受各种 SSO、OIDC 和 SAML 身份验证选项,具体取决于所使用的版本,本部署示例使用支持OIDC的keycloak
。
- Microsoft / Azure
- Slack
- OIDC
- Discord
- GitLab
- Email magic link
- SAML
- Okta
- OneLogin
注:Outline不支持邮箱+密码认证
前置配置工作
1. 配置域名解析
域名配置清单:
域名地址 | 解析A记录值 | 说明 |
---|---|---|
https://outline.example.com | 120.79.11.68 | 用于访问 Outline 应用程序的主域名,提供知识库和文档管理功能,供团队成员进行协作和编辑。 |
https://keycloak.example.com | 120.79.11.68 | 用于访问 Keycloak 身份认证服务的域名,提供用户身份验证、授权管理和单点登录服务。 |
https://minio.example.com | 120.79.11.68 | 用于Outline访问 MinIO 对象存储服务的域名,存储 Outline 中的文件、文档和附件,支持 S3 兼容 API 操作。 |
https://console.minio.example.com | 120.79.11.68 | 用于访问 MinIO 管理控制台的域名,提供对 MinIO 对象存储服务的管理界面,包括用户和权限管理功能。 |
说明:
- 基本域名为
example.com
,前缀可自定义,请将example.com
域名更改为您自己的域名; - 示例公网IP地址
120.79.11.68
为Outline云主机的公网IP地址。
域名解析A记录示例:
2. 配置安全组规则
安全组规则放通清单:
端口号 | 协议 | 用途说明 |
---|---|---|
80 | TCP | Traefik 代理的 HTTP 端口,用于处理未加密的 Web 流量。 |
443 | TCP | Traefik 代理的 HTTPS 端口,用于处理加密的 Web 流量(SSL/TLS)。 |
安全组配置示例
3. 创建目录结构
创建组件安装目录
mkdir -p /data/{traefik,minio,keycloak,outline}
确认目录结构
root@ecs01:~# apt install -y tree
root@ubuntu:~# tree /data/
/data/
├── keycloak
├── minio
├── outline
└── traefik4 directories, 0 files
4. 创建docker网络
手动创建docker网络
docker network create traefik-network
docker network create outline-network
docker network create keycloak-network
docker network create minio-network
确认docker网络创建成功
root@ecs01:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
55509fbd4813 bridge bridge local
00b8d117c799 host host local
b1c5d0f0cd6d keycloak-network bridge local
3af149dcc797 minio-network bridge local
a1e5cf67efab none null local
f0f830bcea64 outline-network bridge local
ba512776a14a traefik-network bridge local
Traefik 部署
使用以下方式生成traefikadmin
密码,替换TRAEFIK_BASIC_AUTH
中的值。
root@ecs01:~# apt install -y apache2-utils
root@ecs01:~# echo $(htpasswd -nbB traefikadmin "mypassword") | sed -e s/\\$/\\$\\$/g
traefikadmin:$$2y$$05$$AKU6mkLPs1EB4t3Hh5QdB.nUJgLYFqZySUpFVyJw4XSFeG.dPXveS
创建环境变量文件
cd /data/traefik
cat >/data/traefik/.env<<EOF
# Traefik Variables
TRAEFIK_IMAGE_TAG=traefik:v3.1
TRAEFIK_LOG_LEVEL=WARN
TRAEFIK_ACME_EMAIL=example@outlook.com
TRAEFIK_HOSTNAME=traefik.example.com
# Basic Authentication for Traefik Dashboard
# Username: traefikadmin
# Passwords must be encoded using MD5, SHA1, or BCrypt https://hostingcanada.org/htpasswd-generator/
TRAEFIK_BASIC_AUTH=traefikadmin:$$2y$$05$$AKU6csLPs1EB4t3Hh5QdF.nUJgLYFqasdfwerqweJw4XSFeG.dPXveS
EOF
参数说明
TRAEFIK_IMAGE_TAG=traefik:v3.1
: 指定 Traefik 镜像的版本标签。TRAEFIK_LOG_LEVEL=WARN
: 设置 Traefik 的日志级别(DEBUG, INFO, WARN, ERROR)。TRAEFIK_ACME_EMAIL=example@outlook.com
: 用于 ACME 协议的电子邮件地址,管理 SSL 证书。TRAEFIK_HOSTNAME=traefik.example.com
: 指定 Traefik 仪表板的访问域名,替换为您自己的域名。TRAEFIK_BASIC_AUTH
: 用于保护 Traefik 仪表板的基本认证信息,格式为用户名:加密后的密码
。
创建docker-compose文件
cat >/data/traefik/docker-compose.yaml<<'EOF'
name: traefiknetworks:traefik-network:external: truevolumes:traefik-certificates:services:traefik:image: ${TRAEFIK_IMAGE_TAG}command:- "--log.level=${TRAEFIK_LOG_LEVEL}"- "--accesslog=true"- "--api.dashboard=true"- "--api.insecure=true"# Docker Provider- "--providers.docker=true"- "--providers.docker.endpoint=unix:///var/run/docker.sock"- "--providers.docker.exposedByDefault=false"# health check- "--ping=true"- "--ping.entrypoint=ping"- "--entryPoints.ping.address=:8082"# letsencrypt- "--entryPoints.websecure.address=:443"- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"- "--certificatesresolvers.letsencrypt.acme.email=${TRAEFIK_ACME_EMAIL}"- "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/acme.json"# dashboard-redirect-https- "--entryPoints.web.address=:80"- "--entrypoints.web.http.redirections.entryPoint.to=websecure"- "--entrypoints.web.http.redirections.entryPoint.scheme=https"- "--entrypoints.web.http.redirections.entrypoint.permanent=true"# prometheus - "--metrics.prometheus=true"- "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0"- "--global.checkNewVersion=true"- "--global.sendAnonymousUsage=false"volumes:- /var/run/docker.sock:/var/run/docker.sock- traefik-certificates:/etc/traefik/acmenetworks:- traefik-networkports:- "80:80"- "443:443"healthcheck:test: ["CMD", "wget", "http://localhost:8082/ping","--spider"]interval: 10stimeout: 5sretries: 3start_period: 5slabels:- "traefik.enable=true"# dashboard with https- "traefik.http.routers.dashboard.rule=Host(`${TRAEFIK_HOSTNAME}`)"- "traefik.http.routers.dashboard.service=api@internal"- "traefik.http.routers.dashboard.entrypoints=websecure"- "traefik.http.services.dashboard.loadbalancer.server.port=8080"- "traefik.http.routers.dashboard.tls=true"- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"- "traefik.http.services.dashboard.loadbalancer.passhostheader=true"# basic auth- "traefik.http.routers.dashboard.middlewares=authtraefik"- "traefik.http.middlewares.authtraefik.basicauth.users=${TRAEFIK_BASIC_AUTH}"# service-redirect-https - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"- "traefik.http.routers.http-catchall.entrypoints=web"- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"restart: unless-stopped
EOF
启动traefik容器
docker compose up -d
确认容器运行状态
root@ecs01:/data/traefik# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
traefik-traefik-1 traefik:v3.1 "/entrypoint.sh --lo…" traefik 3 minutes ago Up 2 minutes (healthy) 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp
root@ecs01:/data/traefik#
浏览器访问traefik dashboard: https://traefik.example.com
,输入traefik登录账号traefikadmin及设置的密码。
正常登录后如下:
Minio部署
创建环境变量文件
cd /data/minio
cat >/data/minio/.env<<EOF
# Minio Variables
MINIO_IMAGE_TAG=minio/minio:RELEASE.2024-08-26T15-33-07Z
MINIO_ADMIN=minioadmin
MINIO_ADMIN_PASSWORD=minioadmin
# MiniIO API hostname
MINIO_HOSTNAME=minio.example.com
MINIO_CONSOLE_URL=https://console.minio.example.com
MINIO_CONSOLE_HOSTNAME=console.minio.example.com
# Minio for Outline
OUTLINE_MINIO_BUCKET_NAME=outline
OUTLINE_MINIO_USER=bucket.outline
OUTLINE_MINIO_USER_PASSWORD=outlinepass
EOF
参数说明
-
MINIO_IMAGE_TAG
: 指定 MinIO 镜像的版本标签,表示使用的 MinIO 版本。 -
MINIO_ADMIN=minioadmin
: MinIO 的管理员用户名,示例值为minioadmin
。 -
MINIO_ADMIN_PASSWORD=minioadmin
: MinIO 的管理员密码,示例值为minioadmin
。 -
MINIO_HOSTNAME=minio.example.com
: 指定 MinIO 服务的主机名,用于通过域名访问 MinIO API,替换为您自己的域名。 -
MINIO_CONSOLE_URL=https://console.minio.example.com
: 指定 MinIO 控制台的完整 URL,用于访问 MinIO Web 管理界面,替换为您自己的域名。 -
MINIO_CONSOLE_HOSTNAME=console.minio.example.com
: 指定 MinIO 控制台的主机名,用于配置 Traefik 代理的路由或域名解析,替换为您自己的域名。 -
OUTLINE_MINIO_BUCKET_NAME=outline
:指定 Outline 在 MinIO 中使用的存储桶名称。这个存储桶用于存储 Outline 的文件、文档和附件,是一个用于组织和管理所有 Outline 相关数据的存储容器。 -
OUTLINE_MINIO_USER=bucket.outline
:设置访问 MinIO 存储桶的用户名。通常以“bucket.”作为前缀,表示该用户对OUTLINE_MINIO_BUCKET_NAME
中指定的存储桶具有特定的访问权限。 -
OUTLINE_MINIO_USER_PASSWORD=outlinepass
:这是与 MinIO 用户 (bucket.outline
) 关联的密码,用于认证和授权访问 Outline 指定的 MinIO 存储桶。
创建docker-compose文件
cat >/data/minio/docker-compose.yaml<<'EOF'
name: minionetworks:minio-network:external: truetraefik-network:external: truevolumes:minio-data:services:minio:image: ${MINIO_IMAGE_TAG}command: minio server /data --console-address ":9001"volumes:- minio-data:/dataenvironment:MINIO_ROOT_USER: ${MINIO_ADMIN}MINIO_ROOT_PASSWORD: ${MINIO_ADMIN_PASSWORD}MINIO_BROWSER_REDIRECT_URL: ${MINIO_CONSOLE_URL}networks:- minio-network- traefik-networkhealthcheck:test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]interval: 10stimeout: 5sretries: 3start_period: 60slabels:- "traefik.enable=true"# Minio API- "traefik.http.routers.minio-api.rule=Host(`${MINIO_HOSTNAME}`)"- "traefik.http.routers.minio-api.service=minio-api"- "traefik.http.routers.minio-api.entrypoints=websecure"- "traefik.http.services.minio-api.loadbalancer.server.port=9000"- "traefik.http.routers.minio-api.tls=true"- "traefik.http.routers.minio-api.tls.certresolver=letsencrypt"- "traefik.http.services.minio-api.loadbalancer.passhostheader=true"- "traefik.http.routers.minio-api.middlewares=compresstraefik"# Minio Console- "traefik.http.routers.minio-console.rule=Host(`${MINIO_CONSOLE_HOSTNAME}`)"- "traefik.http.routers.minio-console.service=minio-console"- "traefik.http.routers.minio-console.entrypoints=websecure"- "traefik.http.services.minio-console.loadbalancer.server.port=9001"- "traefik.http.routers.minio-console.tls=true"- "traefik.http.routers.minio-console.tls.certresolver=letsencrypt"- "traefik.http.services.minio-console.loadbalancer.passhostheader=true"- "traefik.http.routers.minio-console.middlewares=compresstraefik"- "traefik.http.middlewares.compresstraefik.compress=true"- "traefik.docker.network=traefik-network"restart: unless-stopped
EOF
启动minio容器
docker compose up -d
确认容器运行状态
root@ecs01:/data/minio# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
minio-minio-1 minio/minio:RELEASE.2024-08-26T15-33-07Z "/usr/bin/docker-ent…" minio 4 hours ago Up 4 hours (healthy) 9000/tcp
浏览器访问minio console控制台: https://console.minio.example.com
,输入minio登录账号minioadmin
及设置的密码。
登录后示例如下:
Minio配置
安装minio客户端,可以从官网下载或从容器取出客户端文件
root@ecs01:/data/minio# docker cp minio-minio-1:/usr/bin/mc /usr/local/bin/
为outline创建存储桶及minio用户
定义minio配置变量,在当前shell执行以下命令
cd /data/minio
source .env
配置 minio 本地访问
mc config host add minio https://${MINIO_HOSTNAME} ${MINIO_ADMIN} ${MINIO_ADMIN_PASSWORD}
为outline创建单独的minio存储桶及用户
mc mb minio/${OUTLINE_MINIO_BUCKET_NAME}
mc admin user add minio ${OUTLINE_MINIO_USER} ${OUTLINE_MINIO_USER_PASSWORD}
为outline创建单独的minio访问策略
mkdir -p /data/minio/outline_policys
cd /data/minio/outline_policys
cat > outline-policy.json <<-EOF{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": ["s3:GetBucketLocation","s3:ListBucket","s3:ListBucketMultipartUploads"],"Resource": ["arn:aws:s3:::${OUTLINE_MINIO_BUCKET_NAME}"]},{"Action": ["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject","s3:GetObject"],"Effect": "Allow","Resource": ["arn:aws:s3:::${OUTLINE_MINIO_BUCKET_NAME}/*"],"Sid": ""}]}
EOF
cat > outline-public.json <<-EOF{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"AWS": ["*"]},"Action": ["s3:GetObject","s3:ListMultipartUploadParts"],"Resource": ["arn:aws:s3:::${OUTLINE_MINIO_BUCKET_NAME}/public/*"]}]}
EOF
应用策略
mc anonymous set-json outline-public.json minio/${OUTLINE_MINIO_BUCKET_NAME}
mc admin policy create minio OutlineAppFullAccess outline-policy.json
mc admin policy attach minio OutlineAppFullAccess --user=${OUTLINE_MINIO_USER}
确认存储桶已创建
keycloak部署
创建环境变量文件
cd /data/keycloak
cat >/data/keycloak/.env<<EOF
# Keycloak Variables
KEYCLOAK_POSTGRES_IMAGE_TAG=docker.io/library/postgres:16.2
KEYCLOAK_IMAGE_TAG=docker.io/keycloak/keycloak:25.0.4
KEYCLOAK_DB_NAME=keycloakdb
KEYCLOAK_DB_USER=keycloakdbuser
KEYCLOAK_DB_PASSWORD=keycloakdbpass
KEYCLOAK_ADMIN_USERNAME=keycloakadmin
KEYCLOAK_ADMIN_PASSWORD=keycloakadminpass
KEYCLOAK_HOSTNAME=keycloak.example.com
EOF
参数说明
KEYCLOAK_POSTGRES_IMAGE_TAG=docker.io/library/postgres:16.2
: 指定用于 Keycloak 数据库的 PostgreSQL 镜像版本标签。KEYCLOAK_IMAGE_TAG=docker.io/keycloak/keycloak:25.0.4
: 指定 Keycloak 服务的镜像版本标签。KEYCLOAK_DB_NAME=keycloakdb
: Keycloak 使用的数据库名称。KEYCLOAK_DB_USER=keycloakdbuser
: 连接 Keycloak 数据库的用户名。KEYCLOAK_DB_PASSWORD=keycloakdbpass
: 连接 Keycloak 数据库的用户密码。KEYCLOAK_ADMIN_USERNAME=keycloakadmin
: Keycloak 管理员账户的用户名,用于登录 Keycloak 管理控制台。KEYCLOAK_ADMIN_PASSWORD=keycloakadminpass
: Keycloak 管理员账户的密码,用于登录 Keycloak 管理控制台。KEYCLOAK_HOSTNAME=keycloak.example.com
: 指定 Keycloak 服务的主机名,用于通过域名访问 Keycloak,替换为您自己的域名。
创建docker-compose文件
cat >/data/keycloak/docker-compose.yaml<<'EOF'
name: 'keyclock'networks:keycloak-network:external: truetraefik-network:external: truevolumes:keycloak-postgres:services:postgres-keycloak:image: ${KEYCLOAK_POSTGRES_IMAGE_TAG}volumes:- keycloak-postgres:/var/lib/postgresql/dataenvironment:POSTGRES_DB: ${KEYCLOAK_DB_NAME}POSTGRES_USER: ${KEYCLOAK_DB_USER}POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD}networks:- keycloak-networkhealthcheck:test: [ "CMD", "pg_isready", "-q", "-d", "${KEYCLOAK_DB_NAME}", "-U", "${KEYCLOAK_DB_USER}" ]interval: 10stimeout: 5sretries: 3start_period: 60srestart: unless-stoppedkeycloak:image: ${KEYCLOAK_IMAGE_TAG}command: start-devenvironment:KC_DB: postgresKC_DB_URL_HOST: postgres-keycloakKC_DB_URL_DATABASE: ${KEYCLOAK_DB_NAME}KC_DB_USERNAME: ${KEYCLOAK_DB_USER}KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD}KC_DB_SCHEMA: publicKEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN_USERNAME}KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}KC_HEALTH_ENABLED: 'true'KC_HOSTNAME: ${KEYCLOAK_HOSTNAME}KC_HTTP_ENABLED: 'true'KC_PROXY_HEADERS: 'xforwarded'PROXY_ADDRESS_FORWARDING: 'true'networks:- keycloak-network- traefik-networkhealthcheck:test:- "CMD-SHELL"- |exec 3<>/dev/tcp/localhost/9000 &&echo -e 'GET /health/ready HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' >&3 &&cat <&3 | tee /tmp/healthcheck.log | grep -q '200 OK'interval: 10stimeout: 5sretries: 3start_period: 90slabels:- "traefik.enable=true"- "traefik.http.routers.keycloak.rule=Host(`${KEYCLOAK_HOSTNAME}`)"- "traefik.http.routers.keycloak.service=keycloak"- "traefik.http.routers.keycloak.entrypoints=websecure"- "traefik.http.services.keycloak.loadbalancer.server.port=8080"- "traefik.http.routers.keycloak.tls=true"- "traefik.http.routers.keycloak.tls.certresolver=letsencrypt"- "traefik.http.services.keycloak.loadbalancer.passhostheader=true"- "traefik.http.routers.keycloak.middlewares=compresstraefik"- "traefik.http.middlewares.compresstraefik.compress=true"- "traefik.docker.network=traefik-network"restart: unless-stoppeddepends_on:postgres-keycloak:condition: service_healthy
EOF
启动keycloak容器
docker compose up -d
确认容器运行状态
root@ecs01:/data/keycloak# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
keyclock-keycloak-1 docker.io/keycloak/keycloak:25.0.4 "/opt/keycloak/bin/k…" keycloak 4 hours ago Up 4 hours (healthy) 8080/tcp, 8443/tcp, 9000/tcp
keyclock-postgres-keycloak-1 docker.io/library/postgres:16.2 "docker-entrypoint.s…" postgres-keycloak 4 hours ago Up 4 hours (healthy) 5432/tcp
root@ecs01:/data/keycloak#
keycloak配置
浏览器访问keycloak控制台: https://keycloak.example.com
,输入keycloak登录账号keycloakadmin
及设置的密码。
登录后下拉选择Create realm,新建realm
指定Realm name名称为outline
接下来,在“Manage”部分中选择“Clients”,然后单击“Create client”按钮。
在“Client type”字段中,选择“OpenID Connect”。
在“Client ID”字段中,输入“outline”(小写),然后单击“下一步”按钮。
接下来,您需要启用“Client authentication”并在“Authentication flow”部分中选择“Standard flow”。应禁用所有其他值。
单击“下一步”按钮。
设置登录选项
# Root URL
https://outline.example.com/
# Home URL
https://outline.example.com/
# Valid redirect URIs
https://outline.example.com/
请注意,outline.example.com
是我服务的域名。因此,需要指定你自己的域名,该域名指向安装了 Traefik 服务的服务器的 IP 地址,这会将请求重定向到 Outline。
单击“保存”按钮。
导航到“Credentials”选项卡并复制“Client Secret”字段的内容。
后续将“客户端密钥”字段的复制内容粘贴到outline .env
文件中的OUTLINE_OIDC_CLIENT_SECRET
变量中。
Bz8GjPI9E7QqAZcGoQRaktEsW155V5u2
现在让我们创建一个能够使用 Keycloak 登录 Outline 的用户。
在“Manage”部分中选择“Users”,然后单击“Create new user”按钮。
在下一步中,您需要指定:用户名、电子邮件地址、名字、姓氏和密码。
请注意,如果您提供电子邮件地址,用户不仅可以使用用户名还可以使用电子邮件登录 Outline。
单击“创建”按钮。
接下来,您需要为新用户设置密码。
转到“Credentials”选项卡,然后单击“Set password”按钮。
输入强密码并单击“保存”按钮。
单击“保存密码”按钮确认为用户分配新密码。新密码已成功设置。后续,您可以启动 Outline 及其附带服务,并使用之前创建的用户登录 Outline。
outline部署
创建环境变量文件
cd /data/outline
cat >/data/outline/.env<<EOF
# Outline Variables
OUTLINE_POSTGRES_IMAGE_TAG=postgres:16.2
OUTLINE_IMAGE_TAG=outlinewiki/outline:0.78.0
OUTLINE_REDIS_IMAGE_TAG=redis:7.4.0
OUTLINE_DB_NAME=outlinedb
OUTLINE_DB_USER=outlinedbuser
OUTLINE_DB_PASSWORD=outlinedbpass
OUTLINE_URL=https://outline.example.com
OUTLINE_HOSTNAME=outline.example.com# MiniIO Variables
OUTLINE_MINIO_USER=bucket.outline
OUTLINE_MINIO_USER_PASSWORD=outlinepass
OUTLINE_MINIO_BUCKET_NAME=outline
OUTLINE_AWS_S3_UPLOAD_BUCKET_URL=https://minio.example.com/outline
OUTLINE_FILE_STORAGE_UPLOAD_MAX_SIZE=104857600000
OUTLINE_FILE_STORAGE_IMPORT_MAX_SIZE=104857600000# Secret key
# It can be generated with the command:
# openssl rand -hex 32
OUTLINE_SECRET_KEY=00703eaa1fedbb92c903c439feac11e4268c76f6eecc097ba6cc714431b5cb08
# Utils secret
# It can be generated with the command:
# openssl rand -hex 32
OUTLINE_UTILS_SECRET=7eee2571836979c3724f9900a55b1291aa3cdfbc32c42056aacfaaa5b9978649
# Keycloak realm secret
# You need to specify it before starting the Outline container
# It can be found in your realm manage section. Clients/YourClient/Credentials.
OUTLINE_OIDC_CLIENT_SECRET=Bz8GjPI9E7QqAZcGoQRaktEsW155V5u2
# Authentication endpoints
# It can be found in your realm configure section. Realm Settings/General/Endpoints.
OUTLINE_OIDC_AUTH_URI=https://keycloak.example.com/realms/outline/protocol/openid-connect/auth
# It can be found in your realm configure section. Realm Settings/General/Endpoints.
OUTLINE_OIDC_TOKEN_URI=https://keycloak.example.com/realms/outline/protocol/openid-connect/token
# It can be found in your realm configure section. Realm Settings/General/Endpoints.
OUTLINE_OIDC_USERINFO_URI=https://keycloak.example.com/realms/outline/protocol/openid-connect/userinfo
OUTLINE_OIDC_DISPLAY_NAME=Keycloak
OUTLINE_OIDC_USERNAME_CLAIM=email
OUTLINE_OIDC_SCOPES=openid profile email
EOF
outline参数说明:
OUTLINE_POSTGRES_IMAGE_TAG=postgres:16.2
: 指定用于 Outline 数据库的 PostgreSQL 镜像版本标签。OUTLINE_IMAGE_TAG=outlinewiki/outline:0.78.0
: 指定 Outline 应用的镜像版本标签。OUTLINE_REDIS_IMAGE_TAG=redis:7.4.0
: 指定用于 Outline 缓存的 Redis 镜像版本标签。OUTLINE_DB_NAME=outlinedb
: Outline 使用的数据库名称。OUTLINE_DB_USER=outlinedbuser
: 连接 Outline 数据库的用户名。OUTLINE_DB_PASSWORD=outlinedbpass
: 连接 Outline 数据库的用户密码。OUTLINE_URL=https://outline.example.com
: Outline 应用的公共 URL,用于访问应用。OUTLINE_HOSTNAME=outline.example.com
: 指定 Outline 服务的主机名,用于通过域名访问 Outline。
MinIO 相关参数
OUTLINE_MINIO_USER=bucket.outline
: 用于连接 MinIO 服务的 Outline 用户名,示例格式为bucket.<bucketname>
。OUTLINE_MINIO_USER_PASSWORD=outlinepass
: 用于连接 MinIO 服务的 Outline 用户密码。OUTLINE_MINIO_BUCKET_NAME=outline
: MinIO 中用于存储 Outline 文件的存储桶名称。OUTLINE_AWS_S3_UPLOAD_BUCKET_URL=https://minio.example.com/outline
: Outline 使用的 MinIO 存储桶的完整 URL。OUTLINE_FILE_STORAGE_UPLOAD_MAX_SIZE=104857600
: Outline 允许的最大文件上传大小100M,以字节为单位。OUTLINE_FILE_STORAGE_IMPORT_MAX_SIZE=104857600
: Outline 允许的最大导入文件大小100M,以字节为单位。
安全密钥相关参数
OUTLINE_SECRET_KEY=
: Outline 的应用程序密钥,用于加密数据。OUTLINE_UTILS_SECRET=
: 用于实用工具(Utils)的秘密密钥。
Keycloak 相关参数
OUTLINE_OIDC_CLIENT_SECRET=
: 用于 Keycloak OIDC(OpenID Connect)客户端的秘密密钥。OUTLINE_OIDC_AUTH_URI=
: Keycloak 身份验证端点的 URI。OUTLINE_OIDC_TOKEN_URI=
: Keycloak 令牌端点的 URI。OUTLINE_OIDC_USERINFO_URI=
: Keycloak 用户信息端点的 URI。OUTLINE_OIDC_DISPLAY_NAME=Keycloak
: 用于在 Outline 中显示的 OIDC 提供程序名称。OUTLINE_OIDC_USERNAME_CLAIM=email
: 指定用于用户名的 OIDC 声明,通常是电子邮件。OUTLINE_OIDC_SCOPES=openid profile email
: 指定 OIDC 请求的权限范围,包括基本信息和电子邮件。
创建docker-compose文件
cat >/data/outline/docker-compose.yaml<<'EOF'
name: 'outline'
networks:outline-network:external: truetraefik-network:external: truevolumes:outline-postgres:services:postgres-outline:image: ${OUTLINE_POSTGRES_IMAGE_TAG}volumes:- outline-postgres:/var/lib/postgresql/dataenvironment:POSTGRES_DB: ${OUTLINE_DB_NAME}POSTGRES_USER: ${OUTLINE_DB_USER}POSTGRES_PASSWORD: ${OUTLINE_DB_PASSWORD}networks:- outline-networkhealthcheck:test: [ "CMD", "pg_isready", "-q", "-d", "${OUTLINE_DB_NAME}", "-U", "${OUTLINE_DB_USER}" ]interval: 10stimeout: 5sretries: 3start_period: 60srestart: unless-stoppedredis:image: ${OUTLINE_REDIS_IMAGE_TAG}networks:- outline-networkhealthcheck:test: ["CMD", "redis-cli", "ping"]interval: 10stimeout: 5sretries: 3start_period: 60srestart: unless-stoppedoutline:image: ${OUTLINE_IMAGE_TAG}environment:DATABASE_URL: postgres://${OUTLINE_DB_USER}:${OUTLINE_DB_PASSWORD}@postgres-outline:5432/${OUTLINE_DB_NAME}?sslmode=disable&connect_timeout=10PGSSLMODE: disableREDIS_URL: redis://redis:6379URL: ${OUTLINE_URL}PORT: 3000SECRET_KEY: ${OUTLINE_SECRET_KEY}UTILS_SECRET: ${OUTLINE_UTILS_SECRET}FORCE_HTTPS: 'false'ENABLE_UPDATES: 'true'AWS_REGION: eu-east-1AWS_ACCESS_KEY_ID: ${OUTLINE_MINIO_USER}AWS_SECRET_ACCESS_KEY: ${OUTLINE_MINIO_USER_PASSWORD}AWS_S3_UPLOAD_BUCKET_URL: ${OUTLINE_AWS_S3_UPLOAD_BUCKET_URL}AWS_S3_ACCELERATE_URL: ${OUTLINE_AWS_S3_UPLOAD_BUCKET_URL}AWS_S3_UPLOAD_BUCKET_NAME: ${OUTLINE_MINIO_BUCKET_NAME}AWS_S3_FORCE_PATH_STYLE: 'false'AWS_S3_ACL: privateFILE_STORAGE_UPLOAD_MAX_SIZE: ${OUTLINE_FILE_STORAGE_UPLOAD_MAX_SIZE}FILE_STORAGE_IMPORT_MAX_SIZE: ${OUTLINE_FILE_STORAGE_IMPORT_MAX_SIZE}OIDC_CLIENT_ID: outlineOIDC_CLIENT_SECRET: ${OUTLINE_OIDC_CLIENT_SECRET}OIDC_AUTH_URI: ${OUTLINE_OIDC_AUTH_URI}OIDC_TOKEN_URI: ${OUTLINE_OIDC_TOKEN_URI}OIDC_USERINFO_URI: ${OUTLINE_OIDC_USERINFO_URI}OIDC_DISPLAY_NAME: ${OUTLINE_OIDC_DISPLAY_NAME}OIDC_USERNAME_CLAIM: ${OUTLINE_OIDC_USERNAME_CLAIM}OIDC_SCOPES: ${OUTLINE_OIDC_SCOPES}networks:- outline-network- traefik-networkhealthcheck:test: timeout 10s bash -c ':> /dev/tcp/127.0.0.1/3000' || exit 1interval: 10stimeout: 5sretries: 3start_period: 90slabels:- "traefik.enable=true"- "traefik.http.routers.outline.rule=Host(`${OUTLINE_HOSTNAME}`)"- "traefik.http.routers.outline.service=outline"- "traefik.http.routers.outline.entrypoints=websecure"- "traefik.http.services.outline.loadbalancer.server.port=3000"- "traefik.http.routers.outline.tls=true"- "traefik.http.routers.outline.tls.certresolver=letsencrypt"- "traefik.http.services.outline.loadbalancer.passhostheader=true"- "traefik.http.routers.outline.middlewares=compresstraefik"- "traefik.http.middlewares.compresstraefik.compress=true"- "traefik.docker.network=traefik-network"restart: unless-stoppeddepends_on:postgres-outline:condition: service_healthyredis:condition: service_healthy
EOF
启动outline容器
docker compose up -d
确认容器运行状态
root@ecs01:/data/outline# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
outline-outline-1 outlinewiki/outline:0.78.0 "docker-entrypoint.s…" outline 4 hours ago Up 4 hours (healthy) 3000/tcp
outline-postgres-outline-1 postgres:16.2 "docker-entrypoint.s…" postgres-outline 4 hours ago Up 4 hours (healthy) 5432/tcp
outline-redis-1 redis:7.4.0 "docker-entrypoint.s…" redis 4 hours ago Up 4 hours (healthy) 6379/tcp
root@ecs01:/data/outline#
outline访问
浏览器访问outline控制台: https://outline.example.com
,输入outline登录账号admin
及设置的密码。
首先会跳转到keycloak进行认证:
Outline 登录后如下
新建文档集及文档
查看对象存储中上传的数据:
至此,我们在一台云服务器上,通过docker-compose方式完成了outline的部署。
参考:
https://www.heyvaldemar.com/install-outline-and-keycloak-using-docker-compose/
https://github.com/heyvaldemar/outline-keycloak-traefik-letsencrypt-docker-compose
这篇关于docker基于minio部署outline团队知识库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!