docker.recipes

Outline Wiki Knowledge Base

intermediate

Modern team wiki and knowledge base with real-time collaboration.

Overview

Outline is a modern, open-source wiki and knowledge base platform designed for teams that need real-time collaborative documentation. Built with a focus on beautiful UI and excellent writing experience, Outline supports structured documents with rich formatting, linking between pages, and powerful search capabilities. Unlike traditional wikis, Outline emphasizes a more document-centric approach similar to Notion or Confluence but with better performance and team collaboration features. This production stack combines Outline with PostgreSQL for robust document storage and full-text search, Redis for session management and real-time collaboration features, MinIO for file uploads and media storage, and NGINX for high-performance reverse proxying. The architecture provides enterprise-grade reliability while maintaining the flexibility of self-hosted deployment. This configuration is ideal for organizations wanting complete control over their knowledge base without vendor lock-in, development teams needing technical documentation with code syntax highlighting, and companies requiring compliance with data sovereignty requirements where cloud-hosted solutions aren't suitable.

Key Features

  • Real-time collaborative editing with conflict resolution powered by Redis pub/sub messaging
  • Full-text search across all documents using PostgreSQL's advanced search capabilities with ranking
  • S3-compatible file storage through MinIO for document attachments, images, and media assets
  • Structured document organization with collections, nested pages, and automatic table of contents
  • OAuth integration support for Slack, Google Workspace, and custom OIDC providers
  • Document versioning and revision history stored in PostgreSQL with efficient diff tracking
  • Public document sharing with customizable permissions and link-based access controls
  • High-performance static asset delivery through NGINX with caching and compression

Common Use Cases

  • 1Engineering teams building technical documentation with code examples and API references
  • 2Startups creating company handbooks, processes, and knowledge repositories
  • 3Educational institutions managing course materials and collaborative research documentation
  • 4Healthcare organizations maintaining compliant documentation with audit trails
  • 5Remote teams centralizing meeting notes, project documentation, and decision records
  • 6Software companies creating user-facing documentation and help centers
  • 7Consulting firms organizing client deliverables and internal methodology guides

Prerequisites

  • Minimum 4GB RAM (2GB for Outline + PostgreSQL, 512MB for Redis, 512MB for MinIO, 256MB for NGINX)
  • Docker Engine 20.10+ and Docker Compose v2 for health check and depends_on support
  • OAuth provider configured (Slack, Google, or OIDC) as Outline requires external authentication
  • Domain name and SSL certificates if deploying for production team access
  • Basic understanding of PostgreSQL administration for backup and maintenance procedures
  • Ports 80, 443, 3000, 9000, and 9001 available for web access and MinIO console

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 outline:
3 image: outlinewiki/outline:latest
4 ports:
5 - "3000:3000"
6 environment:
7 SECRET_KEY: ${SECRET_KEY}
8 UTILS_SECRET: ${UTILS_SECRET}
9 DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
10 REDIS_URL: redis://redis:6379
11 URL: http://localhost:3000
12 PORT: 3000
13 AWS_ACCESS_KEY_ID: ${MINIO_ACCESS_KEY}
14 AWS_SECRET_ACCESS_KEY: ${MINIO_SECRET_KEY}
15 AWS_S3_UPLOAD_BUCKET_URL: http://minio:9000
16 AWS_S3_UPLOAD_BUCKET_NAME: outline
17 AWS_S3_FORCE_PATH_STYLE: "true"
18 AWS_S3_ACL: private
19 SLACK_CLIENT_ID: ${SLACK_CLIENT_ID}
20 SLACK_CLIENT_SECRET: ${SLACK_CLIENT_SECRET}
21 depends_on:
22 postgres:
23 condition: service_healthy
24 redis:
25 condition: service_started
26 minio:
27 condition: service_started
28 networks:
29 - outline-net
30 restart: unless-stopped
31
32 postgres:
33 image: postgres:16-alpine
34 environment:
35 POSTGRES_USER: ${POSTGRES_USER}
36 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
37 POSTGRES_DB: ${POSTGRES_DB}
38 volumes:
39 - postgres_data:/var/lib/postgresql/data
40 healthcheck:
41 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
42 interval: 10s
43 timeout: 5s
44 retries: 5
45 networks:
46 - outline-net
47 restart: unless-stopped
48
49 redis:
50 image: redis:7-alpine
51 volumes:
52 - redis_data:/data
53 networks:
54 - outline-net
55 restart: unless-stopped
56
57 minio:
58 image: minio/minio:latest
59 ports:
60 - "9000:9000"
61 - "9001:9001"
62 environment:
63 MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
64 MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
65 volumes:
66 - minio_data:/data
67 command: server /data --console-address ":9001"
68 networks:
69 - outline-net
70 restart: unless-stopped
71
72 nginx:
73 image: nginx:alpine
74 ports:
75 - "80:80"
76 - "443:443"
77 volumes:
78 - ./nginx.conf:/etc/nginx/nginx.conf:ro
79 depends_on:
80 - outline
81 networks:
82 - outline-net
83 restart: unless-stopped
84
85volumes:
86 postgres_data:
87 redis_data:
88 minio_data:
89
90networks:
91 outline-net:
92 driver: bridge

.env Template

.env
1# Outline Secrets
2SECRET_KEY=$(openssl rand -hex 32)
3UTILS_SECRET=$(openssl rand -hex 32)
4
5# PostgreSQL
6POSTGRES_USER=outline
7POSTGRES_PASSWORD=secure_postgres_password
8POSTGRES_DB=outline
9
10# MinIO
11MINIO_ACCESS_KEY=minioadmin
12MINIO_SECRET_KEY=secure_minio_password
13
14# Slack OAuth (required)
15SLACK_CLIENT_ID=xxx
16SLACK_CLIENT_SECRET=xxx

Usage Notes

  1. 1Outline at http://localhost:3000
  2. 2Requires Slack, Google, or OIDC for authentication
  3. 3MinIO Console at http://localhost:9001
  4. 4Create MinIO bucket 'outline' before starting

Individual Services(5 services)

Copy individual services to mix and match with your existing compose files.

outline
outline:
  image: outlinewiki/outline:latest
  ports:
    - "3000:3000"
  environment:
    SECRET_KEY: ${SECRET_KEY}
    UTILS_SECRET: ${UTILS_SECRET}
    DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
    REDIS_URL: redis://redis:6379
    URL: http://localhost:3000
    PORT: 3000
    AWS_ACCESS_KEY_ID: ${MINIO_ACCESS_KEY}
    AWS_SECRET_ACCESS_KEY: ${MINIO_SECRET_KEY}
    AWS_S3_UPLOAD_BUCKET_URL: http://minio:9000
    AWS_S3_UPLOAD_BUCKET_NAME: outline
    AWS_S3_FORCE_PATH_STYLE: "true"
    AWS_S3_ACL: private
    SLACK_CLIENT_ID: ${SLACK_CLIENT_ID}
    SLACK_CLIENT_SECRET: ${SLACK_CLIENT_SECRET}
  depends_on:
    postgres:
      condition: service_healthy
    redis:
      condition: service_started
    minio:
      condition: service_started
  networks:
    - outline-net
  restart: unless-stopped
postgres
postgres:
  image: postgres:16-alpine
  environment:
    POSTGRES_USER: ${POSTGRES_USER}
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    POSTGRES_DB: ${POSTGRES_DB}
  volumes:
    - postgres_data:/var/lib/postgresql/data
  healthcheck:
    test:
      - CMD-SHELL
      - pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}
    interval: 10s
    timeout: 5s
    retries: 5
  networks:
    - outline-net
  restart: unless-stopped
redis
redis:
  image: redis:7-alpine
  volumes:
    - redis_data:/data
  networks:
    - outline-net
  restart: unless-stopped
minio
minio:
  image: minio/minio:latest
  ports:
    - "9000:9000"
    - "9001:9001"
  environment:
    MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
    MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
  volumes:
    - minio_data:/data
  command: server /data --console-address ":9001"
  networks:
    - outline-net
  restart: unless-stopped
nginx
nginx:
  image: nginx:alpine
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf:ro
  depends_on:
    - outline
  networks:
    - outline-net
  restart: unless-stopped

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 outline:
5 image: outlinewiki/outline:latest
6 ports:
7 - "3000:3000"
8 environment:
9 SECRET_KEY: ${SECRET_KEY}
10 UTILS_SECRET: ${UTILS_SECRET}
11 DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
12 REDIS_URL: redis://redis:6379
13 URL: http://localhost:3000
14 PORT: 3000
15 AWS_ACCESS_KEY_ID: ${MINIO_ACCESS_KEY}
16 AWS_SECRET_ACCESS_KEY: ${MINIO_SECRET_KEY}
17 AWS_S3_UPLOAD_BUCKET_URL: http://minio:9000
18 AWS_S3_UPLOAD_BUCKET_NAME: outline
19 AWS_S3_FORCE_PATH_STYLE: "true"
20 AWS_S3_ACL: private
21 SLACK_CLIENT_ID: ${SLACK_CLIENT_ID}
22 SLACK_CLIENT_SECRET: ${SLACK_CLIENT_SECRET}
23 depends_on:
24 postgres:
25 condition: service_healthy
26 redis:
27 condition: service_started
28 minio:
29 condition: service_started
30 networks:
31 - outline-net
32 restart: unless-stopped
33
34 postgres:
35 image: postgres:16-alpine
36 environment:
37 POSTGRES_USER: ${POSTGRES_USER}
38 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
39 POSTGRES_DB: ${POSTGRES_DB}
40 volumes:
41 - postgres_data:/var/lib/postgresql/data
42 healthcheck:
43 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
44 interval: 10s
45 timeout: 5s
46 retries: 5
47 networks:
48 - outline-net
49 restart: unless-stopped
50
51 redis:
52 image: redis:7-alpine
53 volumes:
54 - redis_data:/data
55 networks:
56 - outline-net
57 restart: unless-stopped
58
59 minio:
60 image: minio/minio:latest
61 ports:
62 - "9000:9000"
63 - "9001:9001"
64 environment:
65 MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
66 MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
67 volumes:
68 - minio_data:/data
69 command: server /data --console-address ":9001"
70 networks:
71 - outline-net
72 restart: unless-stopped
73
74 nginx:
75 image: nginx:alpine
76 ports:
77 - "80:80"
78 - "443:443"
79 volumes:
80 - ./nginx.conf:/etc/nginx/nginx.conf:ro
81 depends_on:
82 - outline
83 networks:
84 - outline-net
85 restart: unless-stopped
86
87volumes:
88 postgres_data:
89 redis_data:
90 minio_data:
91
92networks:
93 outline-net:
94 driver: bridge
95EOF
96
97# 2. Create the .env file
98cat > .env << 'EOF'
99# Outline Secrets
100SECRET_KEY=$(openssl rand -hex 32)
101UTILS_SECRET=$(openssl rand -hex 32)
102
103# PostgreSQL
104POSTGRES_USER=outline
105POSTGRES_PASSWORD=secure_postgres_password
106POSTGRES_DB=outline
107
108# MinIO
109MINIO_ACCESS_KEY=minioadmin
110MINIO_SECRET_KEY=secure_minio_password
111
112# Slack OAuth (required)
113SLACK_CLIENT_ID=xxx
114SLACK_CLIENT_SECRET=xxx
115EOF
116
117# 3. Start the services
118docker compose up -d
119
120# 4. View logs
121docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/outline-wiki-stack/run | bash

Troubleshooting

  • Outline fails to start with database connection errors: Ensure PostgreSQL health check passes and DATABASE_URL environment variable matches POSTGRES_* credentials exactly
  • File uploads fail with S3 errors: Create the 'outline' bucket in MinIO console at localhost:9001 and verify MINIO_ACCESS_KEY matches AWS_ACCESS_KEY_ID
  • Authentication redirect loops: Check that URL environment variable matches your actual domain and OAuth provider redirect URLs are configured correctly
  • Search functionality not working: PostgreSQL full-text search requires proper locale settings - ensure POSTGRES_INITDB_ARGS includes correct locale if using non-English content
  • Redis connection timeouts during collaboration: Increase Redis memory limits and check for memory pressure, as Outline uses Redis heavily for real-time features
  • NGINX 502 Bad Gateway errors: Verify Outline container is healthy and running on port 3000, check docker network connectivity between nginx and outline services

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space