Outline
Outline is a self-hosted knowledge base and documentation platform that allows you to build and manage your own knowledge base applications.
Configuration
services:
outline:
image: outlinewiki/outline:0.82.0
restart: always
depends_on:
- postgres
- redis
- dex
ports:
- 3000
environment:
NODE_ENV: production
URL: ${URL}
FORCE_HTTPS: 'false'
PROXY_HEADERS_TRUSTED: 'true'
SECRET_KEY: ${SECRET_KEY}
UTILS_SECRET: ${UTILS_SECRET}
DATABASE_URL: postgres://outline:${POSTGRES_PASSWORD}@postgres:5432/outline
PGSSLMODE: disable
REDIS_URL: redis://redis:6379
FILE_STORAGE: local
FILE_STORAGE_LOCAL_ROOT_DIR: /var/lib/outline/data
OIDC_CLIENT_ID: outline
OIDC_CLIENT_SECRET: ${CLIENT_SECRET}
OIDC_AUTH_URI: ${DEX_URL}/auth
OIDC_TOKEN_URI: ${DEX_URL}/token
OIDC_USERINFO_URI: ${DEX_URL}/userinfo
OIDC_USERNAME_CLAIM: preferred_username
OIDC_DISPLAY_NAME: OpenID Connect
OIDC_SCOPES: openid profile email
volumes:
- outline_data-test-outline-khufpx:/var/lib/outline/data
dex:
image: nginx:1.27-alpine
restart: always
depends_on:
- dex-server
volumes:
- ../files/etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
ports:
- 5556
dex-server:
image: ghcr.io/dexidp/dex:v2.37.0
restart: always
volumes:
- ../files/etc/dex/config.yaml:/etc/dex/config.yaml
command:
- dex
- serve
- /etc/dex/config.yaml
postgres:
image: postgres:15
restart: always
environment:
POSTGRES_DB: outline
POSTGRES_USER: outline
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data-test-outline-khufpx:/var/lib/postgresql/data
redis:
image: redis:latest
restart: always
command: redis-server --appendonly yes
volumes:
- redis_data-test-outline-khufpx:/data
volumes:
outline_data-test-outline-khufpx:
postgres_data-test-outline-khufpx:
redis_data-test-outline-khufpx:[variables]
main_domain = "${domain}"
dex_domain = "dex-${domain}"
secret_key = "${hash:64}"
utils_secret = "${base64:32}"
client_secret = "${base64:32}"
postgres_password = "${password}"
[[config.domains]]
serviceName = "outline"
port = 3_000
host = "${main_domain}"
[[config.domains]]
serviceName = "dex"
port = 5_556
host = "${dex_domain}"
[config.env]
URL = "https://${main_domain}"
DEX_URL = "https://${dex_domain}"
DOMAIN_NAME = "${main_domain}"
POSTGRES_PASSWORD = "${postgres_password}"
SECRET_KEY = "${secret_key}"
UTILS_SECRET = "${utils_secret}"
CLIENT_SECRET = "${client_secret}"
[[config.mounts]]
filePath = "/etc/dex/config.yaml"
content = """
issuer: https://${dex_domain}
web:
http: 0.0.0.0:5556
storage:
type: memory
enablePasswordDB: true
frontend:
issuer: Outline
logger:
level: debug
staticPasswords:
- email: "[email protected]"
# bcrypt hash of the string "password": $(echo password | htpasswd -BinC 10 admin | cut -d: -f2)
hash: "$2y$10$jsRWHw54uxTUIfhjgUrB9u8HSzPk7TUuQri9sXZrKzRXcScvwYor."
username: "admin"
userID: "1"
oauth2:
skipApprovalScreen: true
alwaysShowLoginScreen: false
passwordConnector: local
staticClients:
- id: "outline"
redirectURIs:
- https://${main_domain}/auth/oidc.callback
name: "Outline"
secret: "${client_secret}"
"""
[[config.mounts]]
filePath = "/etc/nginx/conf.d/default.conf"
content = """
server {
listen 5556;
location = / {
add_header Content-Type text/plain;
return 200 "Dex ready\n";
}
location / {
proxy_pass http://dex-server:5556;
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;
}
}
"""Base64
To import this template in Dokploy: create a Compose service → Advanced → Base64 import and paste the content below:
ewogICJjb21wb3NlIjogInNlcnZpY2VzOlxuICBvdXRsaW5lOlxuICAgIGltYWdlOiBvdXRsaW5ld2lraS9vdXRsaW5lOjAuODIuMFxuICAgIHJlc3RhcnQ6IGFsd2F5c1xuICAgIGRlcGVuZHNfb246XG4gICAgICAtIHBvc3RncmVzXG4gICAgICAtIHJlZGlzXG4gICAgICAtIGRleFxuICAgIHBvcnRzOlxuICAgICAgLSAzMDAwXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICBOT0RFX0VOVjogcHJvZHVjdGlvblxuICAgICAgVVJMOiAke1VSTH1cbiAgICAgIEZPUkNFX0hUVFBTOiAnZmFsc2UnXG4gICAgICBQUk9YWV9IRUFERVJTX1RSVVNURUQ6ICd0cnVlJ1xuICAgICAgU0VDUkVUX0tFWTogJHtTRUNSRVRfS0VZfVxuICAgICAgVVRJTFNfU0VDUkVUOiAke1VUSUxTX1NFQ1JFVH1cbiAgICAgIERBVEFCQVNFX1VSTDogcG9zdGdyZXM6Ly9vdXRsaW5lOiR7UE9TVEdSRVNfUEFTU1dPUkR9QHBvc3RncmVzOjU0MzIvb3V0bGluZVxuICAgICAgUEdTU0xNT0RFOiBkaXNhYmxlXG4gICAgICBSRURJU19VUkw6IHJlZGlzOi8vcmVkaXM6NjM3OVxuICAgICAgRklMRV9TVE9SQUdFOiBsb2NhbFxuICAgICAgRklMRV9TVE9SQUdFX0xPQ0FMX1JPT1RfRElSOiAvdmFyL2xpYi9vdXRsaW5lL2RhdGFcbiAgICAgIE9JRENfQ0xJRU5UX0lEOiBvdXRsaW5lXG4gICAgICBPSURDX0NMSUVOVF9TRUNSRVQ6ICR7Q0xJRU5UX1NFQ1JFVH1cbiAgICAgIE9JRENfQVVUSF9VUkk6ICR7REVYX1VSTH0vYXV0aFxuICAgICAgT0lEQ19UT0tFTl9VUkk6ICR7REVYX1VSTH0vdG9rZW5cbiAgICAgIE9JRENfVVNFUklORk9fVVJJOiAke0RFWF9VUkx9L3VzZXJpbmZvXG4gICAgICBPSURDX1VTRVJOQU1FX0NMQUlNOiBwcmVmZXJyZWRfdXNlcm5hbWVcbiAgICAgIE9JRENfRElTUExBWV9OQU1FOiBPcGVuSUQgQ29ubmVjdFxuICAgICAgT0lEQ19TQ09QRVM6IG9wZW5pZCBwcm9maWxlIGVtYWlsXG4gICAgdm9sdW1lczpcbiAgICAgIC0gb3V0bGluZV9kYXRhLXRlc3Qtb3V0bGluZS1raHVmcHg6L3Zhci9saWIvb3V0bGluZS9kYXRhXG5cbiAgZGV4OlxuICAgIGltYWdlOiBuZ2lueDoxLjI3LWFscGluZVxuICAgIHJlc3RhcnQ6IGFsd2F5c1xuICAgIGRlcGVuZHNfb246XG4gICAgICAtIGRleC1zZXJ2ZXJcbiAgICB2b2x1bWVzOlxuICAgICAgLSAuLi9maWxlcy9ldGMvbmdpbngvY29uZi5kL2RlZmF1bHQuY29uZjovZXRjL25naW54L2NvbmYuZC9kZWZhdWx0LmNvbmZcbiAgICBwb3J0czpcbiAgICAgIC0gNTU1NlxuXG4gIGRleC1zZXJ2ZXI6XG4gICAgaW1hZ2U6IGdoY3IuaW8vZGV4aWRwL2RleDp2Mi4zNy4wXG4gICAgcmVzdGFydDogYWx3YXlzXG4gICAgdm9sdW1lczpcbiAgICAgIC0gLi4vZmlsZXMvZXRjL2RleC9jb25maWcueWFtbDovZXRjL2RleC9jb25maWcueWFtbFxuICAgIGNvbW1hbmQ6XG4gICAgICAtIGRleFxuICAgICAgLSBzZXJ2ZVxuICAgICAgLSAvZXRjL2RleC9jb25maWcueWFtbFxuXG4gIHBvc3RncmVzOlxuICAgIGltYWdlOiBwb3N0Z3JlczoxNVxuICAgIHJlc3RhcnQ6IGFsd2F5c1xuICAgIGVudmlyb25tZW50OlxuICAgICAgUE9TVEdSRVNfREI6IG91dGxpbmVcbiAgICAgIFBPU1RHUkVTX1VTRVI6IG91dGxpbmVcbiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAke1BPU1RHUkVTX1BBU1NXT1JEfVxuICAgIHZvbHVtZXM6XG4gICAgICAtIHBvc3RncmVzX2RhdGEtdGVzdC1vdXRsaW5lLWtodWZweDovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGFcblxuICByZWRpczpcbiAgICBpbWFnZTogcmVkaXM6bGF0ZXN0XG4gICAgcmVzdGFydDogYWx3YXlzXG4gICAgY29tbWFuZDogcmVkaXMtc2VydmVyIC0tYXBwZW5kb25seSB5ZXNcbiAgICB2b2x1bWVzOlxuICAgICAgLSByZWRpc19kYXRhLXRlc3Qtb3V0bGluZS1raHVmcHg6L2RhdGFcbiAgICBcbnZvbHVtZXM6XG4gIG91dGxpbmVfZGF0YS10ZXN0LW91dGxpbmUta2h1ZnB4OlxuICBwb3N0Z3Jlc19kYXRhLXRlc3Qtb3V0bGluZS1raHVmcHg6XG4gIHJlZGlzX2RhdGEtdGVzdC1vdXRsaW5lLWtodWZweDpcbiIsCiAgImNvbmZpZyI6ICJbdmFyaWFibGVzXVxubWFpbl9kb21haW4gPSBcIiR7ZG9tYWlufVwiXG5kZXhfZG9tYWluID0gXCJkZXgtJHtkb21haW59XCJcbnNlY3JldF9rZXkgPSBcIiR7aGFzaDo2NH1cIlxudXRpbHNfc2VjcmV0ID0gXCIke2Jhc2U2NDozMn1cIlxuY2xpZW50X3NlY3JldCA9IFwiJHtiYXNlNjQ6MzJ9XCJcbnBvc3RncmVzX3Bhc3N3b3JkID0gXCIke3Bhc3N3b3JkfVwiXG5cbltbY29uZmlnLmRvbWFpbnNdXVxuc2VydmljZU5hbWUgPSBcIm91dGxpbmVcIlxucG9ydCA9IDNfMDAwXG5ob3N0ID0gXCIke21haW5fZG9tYWlufVwiXG5cbltbY29uZmlnLmRvbWFpbnNdXVxuc2VydmljZU5hbWUgPSBcImRleFwiXG5wb3J0ID0gNV81NTZcbmhvc3QgPSBcIiR7ZGV4X2RvbWFpbn1cIlxuXG5bY29uZmlnLmVudl1cblVSTCA9IFwiaHR0cHM6Ly8ke21haW5fZG9tYWlufVwiXG5ERVhfVVJMID0gXCJodHRwczovLyR7ZGV4X2RvbWFpbn1cIlxuRE9NQUlOX05BTUUgPSBcIiR7bWFpbl9kb21haW59XCJcblBPU1RHUkVTX1BBU1NXT1JEID0gXCIke3Bvc3RncmVzX3Bhc3N3b3JkfVwiXG5TRUNSRVRfS0VZID0gXCIke3NlY3JldF9rZXl9XCJcblVUSUxTX1NFQ1JFVCA9IFwiJHt1dGlsc19zZWNyZXR9XCJcbkNMSUVOVF9TRUNSRVQgPSBcIiR7Y2xpZW50X3NlY3JldH1cIlxuXG5bW2NvbmZpZy5tb3VudHNdXVxuZmlsZVBhdGggPSBcIi9ldGMvZGV4L2NvbmZpZy55YW1sXCJcbmNvbnRlbnQgPSBcIlwiXCJcbmlzc3VlcjogaHR0cHM6Ly8ke2RleF9kb21haW59XG5cbndlYjpcbiAgaHR0cDogMC4wLjAuMDo1NTU2XG5cbnN0b3JhZ2U6XG4gIHR5cGU6IG1lbW9yeVxuXG5lbmFibGVQYXNzd29yZERCOiB0cnVlXG5cbmZyb250ZW5kOlxuICAgaXNzdWVyOiBPdXRsaW5lXG5cbmxvZ2dlcjpcbiAgbGV2ZWw6IGRlYnVnXG5cbnN0YXRpY1Bhc3N3b3JkczpcbiAgLSBlbWFpbDogXCJhZG1pbkBleGFtcGxlLmNvbVwiXG4gICAgIyBiY3J5cHQgaGFzaCBvZiB0aGUgc3RyaW5nIFwicGFzc3dvcmRcIjogJChlY2hvIHBhc3N3b3JkIHwgaHRwYXNzd2QgLUJpbkMgMTAgYWRtaW4gfCBjdXQgLWQ6IC1mMilcbiAgICBoYXNoOiBcIiQyeSQxMCRqc1JXSHc1NHV4VFVJZmhqZ1VyQjl1OEhTelBrN1RVdVFyaTlzWFpyS3pSWGNTY3Z3WW9yLlwiXG4gICAgdXNlcm5hbWU6IFwiYWRtaW5cIlxuICAgIHVzZXJJRDogXCIxXCJcblxuXG5vYXV0aDI6XG4gIHNraXBBcHByb3ZhbFNjcmVlbjogdHJ1ZVxuICBhbHdheXNTaG93TG9naW5TY3JlZW46IGZhbHNlXG4gIHBhc3N3b3JkQ29ubmVjdG9yOiBsb2NhbFxuXG5zdGF0aWNDbGllbnRzOlxuICAtIGlkOiBcIm91dGxpbmVcIlxuICAgIHJlZGlyZWN0VVJJczpcbiAgICAgIC0gaHR0cHM6Ly8ke21haW5fZG9tYWlufS9hdXRoL29pZGMuY2FsbGJhY2tcbiAgICBuYW1lOiBcIk91dGxpbmVcIlxuICAgIHNlY3JldDogXCIke2NsaWVudF9zZWNyZXR9XCIgXG5cIlwiXCJcblxuW1tjb25maWcubW91bnRzXV1cbmZpbGVQYXRoID0gXCIvZXRjL25naW54L2NvbmYuZC9kZWZhdWx0LmNvbmZcIlxuY29udGVudCA9IFwiXCJcIlxuc2VydmVyIHtcbiAgbGlzdGVuIDU1NTY7XG5cbiAgbG9jYXRpb24gPSAvIHtcbiAgICBhZGRfaGVhZGVyIENvbnRlbnQtVHlwZSB0ZXh0L3BsYWluO1xuICAgIHJldHVybiAyMDAgXCJEZXggcmVhZHlcXG5cIjtcbiAgfVxuXG4gIGxvY2F0aW9uIC8ge1xuICAgIHByb3h5X3Bhc3MgaHR0cDovL2RleC1zZXJ2ZXI6NTU1NjtcbiAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgJGhvc3Q7XG4gICAgcHJveHlfc2V0X2hlYWRlciBYLVJlYWwtSVAgJHJlbW90ZV9hZGRyO1xuICAgIHByb3h5X3NldF9oZWFkZXIgWC1Gb3J3YXJkZWQtRm9yICRwcm94eV9hZGRfeF9mb3J3YXJkZWRfZm9yO1xuICAgIHByb3h5X3NldF9oZWFkZXIgWC1Gb3J3YXJkZWQtUHJvdG8gJHNjaGVtZTtcbiAgfVxufVxuXCJcIlwiXG4iCn0=Links
Tags
documentation, knowledge-base, self-hosted
Version: 0.82.0
Otter Wiki
An Otter Wiki is a simple, lightweight, and fast wiki engine built with Python and Flask. It provides a user-friendly interface for creating and managing wiki content with markdown support.
Owncast
Owncast is a self-hosted live video streaming and chat server for use with existing broadcasting software.