docker基于本地存储部署outline团队知识库

outline 介绍

Outline 是一个开源的Wiki 知识库和团队协作文档管理工具,美观、实时协作、功能丰富且兼容 Markdown,设计用于帮助团队和组织有效地创建、共享和管理文档。
在这里插入图片描述
注意:官方提供的服务提供30天试用,之后每月10美元或每年100美元。由于outline是开源工具,完全支持自建outline。

官方文档:https://docs.getoutline.com/s/hosting

outline部署规划

部署前置要求:

  • 准备一台云服务器,例如 阿里云ECS服务器 或轻量服务器,本部署示例购买1台阿里云ECS服务器(包年包月购买3年具有2.6折的最低优惠),服务器配置为2核CPU/4G内存/100G磁盘,绑定公网IP,带宽按流量计费;
  • 准备操作系统,本示例使用 Ubuntu 22.04 LTS 操作系统;
  • 准备可用域名,并配置好域名解析,本示例使用阿里云域名
  • SSL证书,由https-portal通过Let's Encrypt自动申请免费证书;
  • 主机上已安装 dockerdocker compose

整体部署架构图:
在这里插入图片描述

部署组件清单:

我们采用 https-portal 作为反向代理和负载均衡器,本地磁盘作为文件存储,Keycloak 作为身份和访问管理工具,并且利用 PostgreSQLRedis 作为数据库和缓存,来支撑 Outline 的运行。

名称说明版本
https-portal基于nginx实现的反向代理和负载均衡器,用于管理和路由 HTTP 请求,提供 SSL 终止和路径路由功能。1.24.1
Keycloak开源的身份和访问管理工具,用于提供单点登录和身份认证功能,支持 OAuth2 和 SAML 协议。25.0.4
Outline开源的知识库和文档管理工具,用于团队协作、文档编辑和知识共享。0.78.0
Redis高性能的内存数据存储,用于缓存和会话管理,提高应用性能。7.4.0
PostgreSQL开源的关系型数据库管理系统,用于存储 Outline 的持久化数据。16.2

Outline文件存储选择

Outline文件存储支持以下两种形式,本示例采用Local file system,以简化部署:

  • Local file system:如果希望将文件上传存储在运行 Outline 的同一服务器上,则可以使用本地文件系统存储选项来实现。
  • AWS S3:由于AWS S3是对象存储的标准,因此不一定使用云上的AWS S3存储,例如可以通过自建minio来实现,完整的支持列表见下表。

Outline 可以与绝大多数 S3 兼容的 API 一起使用,因为使用的是可用 API 接口的一个非常小的子集,以下内容已经过社区成员的测试。

ServiceCompatible
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。

  • Google
  • Microsoft / Azure
  • Slack
  • OIDC
  • Discord
  • GitLab
  • Email magic link
  • SAML
  • Okta
  • OneLogin

注:Outline不支持邮箱+密码认证

前置配置工作

1. 配置域名解析

域名配置清单:

域名地址解析A记录值说明
https://docs.example.com120.79.11.68用于访问 Outline 应用程序的主域名,提供知识库和文档管理功能,供团队成员进行协作和编辑。
https://auth.example.com120.79.11.68用于访问 Keycloak 身份认证服务的域名,提供用户身份验证、授权管理和单点登录服务。

说明:

  • 基本域名为example.com,前缀可自定义,请将example.com域名更改为您自己的域名;
  • 示例公网IP地址 120.79.12.68 为Outline云主机的公网IP地址。

域名解析A记录示例:
在这里插入图片描述

2. 配置安全组规则

安全组规则放通清单:

端口号协议用途说明
80TCPTraefik 代理的 HTTP 端口,用于处理未加密的 Web 流量。
443TCPTraefik 代理的 HTTPS 端口,用于处理加密的 Web 流量(SSL/TLS)。

安全组配置示例
在这里插入图片描述

3. 创建目录结构

创建组件安装目录

mkdir -p /data/{keycloak,outline}

确认目录结构

root@ecs01:~# apt install -y tree
root@ubuntu:~# tree /data/
/data/
├── keycloak
└── outline

2 directories, 0 files

4. 创建docker网络

手动创建docker网络

docker network create stack-network

确认docker网络创建成功

root@ecs01:~# docker network ls
NETWORK ID     NAME               DRIVER    SCOPE
55509fbd4813   bridge             bridge    local
00b8d117c799   host               host      local
a1e5cf67efab   none               null      local
f0f830bcea64   stack-network      bridge    local

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=auth.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=auth.example.com: 指定 Keycloak 服务的主机名,用于通过域名访问 Keycloak,替换为您自己的域名。

创建docker-compose文件

cat >/data/keycloak/docker-compose.yaml<<'EOF'
name: 'keyclock'

networks:
  stack-network:
    external: true

volumes:
  keycloak-postgres:

services:
  postgres-keycloak:
    image: ${KEYCLOAK_POSTGRES_IMAGE_TAG}
    volumes:
      - keycloak-postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: ${KEYCLOAK_DB_NAME}
      POSTGRES_USER: ${KEYCLOAK_DB_USER}
      POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
    networks:
      - stack-network
    healthcheck:
      test: [ "CMD", "pg_isready", "-q", "-d", "${KEYCLOAK_DB_NAME}", "-U", "${KEYCLOAK_DB_USER}" ]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 60s
    restart: unless-stopped

  keycloak:
    image: ${KEYCLOAK_IMAGE_TAG}
    command: start-dev
    environment:
      KC_DB: postgres
      KC_DB_URL_HOST: postgres-keycloak
      KC_DB_URL_DATABASE: ${KEYCLOAK_DB_NAME}
      KC_DB_USERNAME: ${KEYCLOAK_DB_USER}
      KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
      KC_DB_SCHEMA: public
      KEYCLOAK_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:
      - stack-network
    healthcheck:
      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: 10s
      timeout: 5s
      retries: 3
      start_period: 90s
    restart: unless-stopped
    depends_on:
      postgres-keycloak:
        condition: service_healthy

启动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# 

outline部署

参考:官方示例环境变量文件:https://github.com/outline/outline/blob/main/.env.sample

创建环境变量文件

cd /data/outline
cat >/data/outline/docker.env<<EOF
# –––––––––––––––– REQUIRED ––––––––––––––––

NODE_ENV=production

# Generate a hex-encoded 32-byte random key. You should use `openssl rand -hex 32`
# in your terminal to generate a random value.
SECRET_KEY=98ea98adade7b6af8c4252651b195d4083c484b833b8e0e638623ae60cc7d24e

# Generate a unique random key. The format is not important but you could still use
# `openssl rand -hex 32` in your terminal to produce this.
UTILS_SECRET=98ea98adade7b6af8c4252651b195d4083c484b833b8e0e638623ae60cc7d24e

# For production point these at your databases, in development the default
# should work out of the box.
DATABASE_URL=postgres://user:pass@postgres:5432/outline
DATABASE_CONNECTION_POOL_MIN=
DATABASE_CONNECTION_POOL_MAX=
# Uncomment this to disable SSL for connecting to Postgres
PGSSLMODE=disable

# For redis you can either specify an ioredis compatible url like this
REDIS_URL=redis://redis:6379
# or alternatively, if you would like to provide additional connection options,
# use a base64 encoded JSON connection option object. Refer to the ioredis documentation
# for a list of available options.
# Example: Use Redis Sentinel for high availability
# {"sentinels":[{"host":"sentinel-0","port":26379},{"host":"sentinel-1","port":26379}],"name":"mymaster"}
# REDIS_URL=ioredis://eyJzZW50aW5lbHMiOlt7Imhvc3QiOiJzZW50aW5lbC0wIiwicG9ydCI6MjYzNzl9LHsiaG9zdCI6InNlbnRpbmVsLTEiLCJwb3J0IjoyNjM3OX1dLCJuYW1lIjoibXltYXN0ZXIifQ==

# URL should point to the fully qualified, publicly accessible URL. If using a
# proxy the port in URL and PORT may be different.
URL=https://docs.example.com
PORT=3000

# See [documentation](docs/SERVICES.md) on running a separate collaboration
# server, for normal operation this does not need to be set.
COLLABORATION_URL=

# Specify what storage system to use. Possible value is one of "s3" or "local".
# For "local", the avatar images and document attachments will be saved on local disk. 
FILE_STORAGE=local

# If "local" is configured for FILE_STORAGE above, then this sets the parent directory under
# which all attachments/images go. Make sure that the process has permissions to create
# this path and also to write files to it.
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data

# Maximum allowed size for the uploaded attachment.
FILE_STORAGE_UPLOAD_MAX_SIZE=262144000

# Override the maximum size of document imports, generally this should be lower
# than the document attachment maximum size.
FILE_STORAGE_IMPORT_MAX_SIZE=

# Override the maximum size of workspace imports, these can be especially large
# and the files are temporary being automatically deleted after a period of time.
FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE=

# To support uploading of images for avatars and document attachments in a distributed 
# architecture an s3-compatible storage can be configured if FILE_STORAGE=s3 above.
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

# –––––––––––––– AUTHENTICATION ––––––––––––––

# Third party signin credentials, at least ONE OF EITHER Google, Slack,
# or Microsoft is required for a working installation or you'll have no sign-in
# options.

# To configure Slack auth, you'll need to create an Application at
# => https://api.slack.com/apps
#
# When configuring the Client ID, add a redirect URL under "OAuth & Permissions":
# https://<URL>/auth/slack.callback
SLACK_CLIENT_ID=get_a_key_from_slack
SLACK_CLIENT_SECRET=get_the_secret_of_above_key

# To configure Google auth, you'll need to create an OAuth Client ID at
# => https://console.cloud.google.com/apis/credentials
#
# When configuring the Client ID, add an Authorized redirect URI:
# https://<URL>/auth/google.callback
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

# To configure Microsoft/Azure auth, you'll need to create an OAuth Client. See
# the guide for details on setting up your Azure App:
# => https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4
AZURE_CLIENT_ID=
AZURE_CLIENT_SECRET=
AZURE_RESOURCE_APP_ID=

# To configure generic OIDC auth, you'll need some kind of identity provider.
# See documentation for whichever IdP you use to acquire the following info:
# Redirect URI is https://<URL>/auth/oidc.callback
OIDC_CLIENT_ID=outline
OIDC_CLIENT_SECRET=Bz8GjPI9E7QqAZcGoQRaktEsW155V5u2
OIDC_AUTH_URI=https://auth.example.com/realms/outline/protocol/openid-connect/auth
OIDC_TOKEN_URI=https://auth.example.com/realms/outline/protocol/openid-connect/token
OIDC_USERINFO_URI=https://auth.example.com/realms/outline/protocol/openid-connect/userinfo
OIDC_LOGOUT_URI=

# Specify which claims to derive user information from
# Supports any valid JSON path with the JWT payload
OIDC_USERNAME_CLAIM=preferred_username

# Display name for OIDC authentication
OIDC_DISPLAY_NAME=OpenID Connect

# Space separated auth scopes.
OIDC_SCOPES=openid profile email

# To configure the GitHub integration, you'll need to create a GitHub App at
# => https://github.com/settings/apps
#
# When configuring the Client ID, add a redirect URL under "Permissions & events":
# https://<URL>/api/github.callback
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_APP_NAME=
GITHUB_APP_ID=
GITHUB_APP_PRIVATE_KEY=

# To configure Discord auth, you'll need to create a Discord Application at
# => https://discord.com/developers/applications/
#
# When configuring the Client ID, add a redirect URL under "OAuth2":
# https://<URL>/auth/discord.callback
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=

# DISCORD_SERVER_ID should be the ID of the Discord server that Outline is
# integrated with. 
# Used to verify that the user is a member of the server as well as server
# metadata such as nicknames, server icon and name.
DISCORD_SERVER_ID=

# DISCORD_SERVER_ROLES should be a comma separated list of role IDs that are
# allowed to access Outline. If this is not set, all members of the server
# will be allowed to access Outline.
# DISCORD_SERVER_ID and DISCORD_SERVER_ROLES must be set together.
DISCORD_SERVER_ROLES=

# –––––––––––––––– OPTIONAL ––––––––––––––––

# Base64 encoded private key and certificate for HTTPS termination. This is only
# required if you do not use an external reverse proxy. See documentation:
# https://wiki.generaloutline.com/share/1c922644-40d8-41fe-98f9-df2b67239d45
SSL_KEY=
SSL_CERT=

# If using a Cloudfront/Cloudflare distribution or similar it can be set below.
# This will cause paths to javascript, stylesheets, and images to be updated to
# the hostname defined in CDN_URL. In your CDN configuration the origin server
# should be set to the same as URL.
CDN_URL=

# Auto-redirect to https in production. The default is true but you may set to
# false if you can be sure that SSL is terminated at an external loadbalancer.
FORCE_HTTPS=true

# Have the installation check for updates by sending anonymized statistics to
# the maintainers
ENABLE_UPDATES=true

# How many processes should be spawned. As a reasonable rule divide your servers
# available memory by 512 for a rough estimate
WEB_CONCURRENCY=1

# You can remove this line if your reverse proxy already logs incoming http
# requests and this ends up being duplicative
DEBUG=http

# Configure lowest severity level for server logs. Should be one of
# error, warn, info, http, verbose, debug and silly
LOG_LEVEL=info

# For a complete Slack integration with search and posting to channels the
# following configs are also needed, some more details
# => https://wiki.generaloutline.com/share/be25efd1-b3ef-4450-b8e5-c4a4fc11e02a
#
SLACK_VERIFICATION_TOKEN=your_token
SLACK_APP_ID=A0XXXXXXX
SLACK_MESSAGE_ACTIONS=true

# For Dropbox integration, follow these instructions to get the key https://www.dropbox.com/developers/embedder#setup
# and do not forget to whitelist your domain name in the app settings
DROPBOX_APP_KEY=

# Optionally enable Sentry (sentry.io) to track errors and performance,
# and optionally add a Sentry proxy tunnel for bypassing ad blockers in the UI:
# https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option)
SENTRY_DSN=
SENTRY_TUNNEL=

# To support sending outgoing transactional emails such as "document updated" or
# "you've been invited" you'll need to provide authentication for an SMTP server
SMTP_HOST=
SMTP_PORT=
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_FROM_EMAIL=
SMTP_REPLY_EMAIL=
SMTP_TLS_CIPHERS=
SMTP_SECURE=true

# The default interface language. See translate.getoutline.com for a list of
# available language codes and their rough percentage translated.
DEFAULT_LANGUAGE=en_US

# Optionally enable rate limiter at application web server
RATE_LIMITER_ENABLED=true

# Configure default throttling parameters for rate limiter
RATE_LIMITER_REQUESTS=1000
RATE_LIMITER_DURATION_WINDOW=60

# Iframely API config
#IFRAMELY_URL=
#IFRAMELY_API_KEY=
EOF

参数说明

  • FILE_STORAGE=local:使用本地存储
  • FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data 指定本地存储路径
  • 1IFRAMELY_URL=:注释该行,避免启动报错
  • OIDC_CLIENT_SECRET:在部署keycloak后再进行配置

参考:官方示例docker-compose文件:https://docs.getoutline.com/s/hosting/doc/docker-7pfeLP5a8t

创建docker-compose文件

cat >/data/outline/docker-compose.yaml<<'EOF'
name: "outline"

networks:
  stack-network:
    external: true

services:

  outline:
    image: docker.getoutline.com/outlinewiki/outline:0.78.0
    env_file: ./docker.env
    networks:
      - stack-network
    ports:
      - "3000:3000"
    volumes:
      - storage-data:/var/lib/outline/data
    depends_on:
      - postgres
      - redis

  redis:
    image: redis:7.4.0
    env_file: ./docker.env
    networks:
      - stack-network
    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:16.2
    env_file: ./docker.env
    networks:
      - stack-network
    ports:
      - "5432:5432"
    volumes:
      - database-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-d", "outline", "-U", "user"]
      interval: 30s
      timeout: 20s
      retries: 3
    environment:
      POSTGRES_USER: 'user'
      POSTGRES_PASSWORD: 'pass'
      POSTGRES_DB: 'outline'

  https-portal:
    image: steveltn/https-portal:1.24.1
    env_file: ./docker.env
    networks:
      - stack-network
    ports:
      - '80:80'
      - '443:443'
    #links:
    #  - outline
    restart: always
    volumes:
      - https-portal-data:/var/lib/https-portal
    healthcheck:
      test: ["CMD", "service", "nginx", "status"]
      interval: 30s
      timeout: 20s
      retries: 3
    environment:
      DOMAINS: 'docs.example.com -> http://outline:3000, auth.example.com -> http://keycloak:8080'
      STAGE: 'production'
      WEBSOCKET: 'true'
      CLIENT_MAX_BODY_SIZE: '0'

volumes:
  https-portal-data:
  storage-data:
  database-data:

启动outline容器

docker compose up -d

确认容器运行状态

root@ecs01:/data/outline# docker compose ps
NAME                         IMAGE                        COMMAND                  SERVICE            CREATED       STATUS                 PORTS
outline-https-portal-1       steveltn/https-portal:1.24.1 "/init"                  https-portal   50 seconds ago   Up 3 seconds (healthy)   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp
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# 

keycloak配置

浏览器访问keycloak控制台: https://auth.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://docs.example.com/
# Home URL
https://docs.example.com/
# Valid redirect URIs
https://docs.example.com/*

请注意,docs.example.com 是我服务的域名。因此,您需要指定您的域名,该域名指向安装了 https-portals 服务的服务器的 IP 地址,这会将请求重定向到 Outline。

单击“保存”按钮。
在这里插入图片描述

导航到“Credentials”选项卡并复制“Client Secret”字段的内容。
在这里插入图片描述

后续将“客户端密钥”字段的复制内容粘贴到outline docker.env文件中的OIDC_CLIENT_SECRET变量中。

Bz8GjPI9E7QqAZcGoQRaktEsW155V5u2

现在让我们创建一个能够使用 Keycloak 登录 Outline 的用户。

在“Manage”部分中选择“Users”,然后单击“Create new user”按钮。
在这里插入图片描述

在下一步中,您需要指定:用户名、电子邮件地址、名字、姓氏和密码。

请注意,如果您提供电子邮件地址,用户不仅可以使用用户名还可以使用电子邮件登录 Outline。

单击“创建”按钮。
在这里插入图片描述

接下来,您需要为新用户设置密码。

转到“Credentials”选项卡,然后单击“Set password”按钮。
在这里插入图片描述

输入强密码并单击“保存”按钮。
在这里插入图片描述

单击“保存密码”按钮确认为用户分配新密码。新密码已成功设置。

现在,可以修改 Outline docker.env配置文件中的OIDC_CLIENT_SECRET参数。

$ cd /data/outline
$ vim /data/outline/docker.env
......
OIDC_CLIENT_SECRET=Bz8GjPI9E7QqAZcGoQRaktEsW155V5u2
......

重新启动outline容器

cd /data/outline
docker compose up -d

outline访问

浏览器访问outline控制台: https://docs.example.com,输入outline登录账号admin及设置的密码。

首先会跳转到keycloak进行认证:
在这里插入图片描述

Outline 登录后如下
在这里插入图片描述

新建文档集及文档

在这里插入图片描述
至此,我们在一台云服务器上,通过docker-compose方式完成了outline的部署。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值