If your team’s documentation lives in scattered Google Docs, random Notion pages, and Slack messages nobody can find — Outline is the fix. It’s a fast, beautiful, open-source wiki that feels like a modern app instead of a dusty Wikipedia clone.

What is Outline?

Outline is a self-hosted knowledge base and wiki built with React and Node.js. It supports real-time collaborative editing, Markdown, nested document collections, and blazing-fast search. Think of it as Notion’s wiki feature, but running on your own hardware.

Why Self-Host Your Knowledge Base?

  • Privacy: Your documentation stays on your infrastructure
  • Speed: No external API calls — everything runs locally
  • No per-seat pricing: Add as many users as you want
  • Full control: Customize authentication, backups, and storage
  • API access: Automate documentation workflows with a REST API
  • Markdown-native: Write in Markdown, export in Markdown — no vendor lock-in

Prerequisites

Before starting, you’ll need:

  • A Linux server (Ubuntu 22.04+ or Debian 12+ recommended)
  • Docker and Docker Compose installed
  • A domain name pointed at your server (required — Outline needs HTTPS)
  • A reverse proxy like Nginx Proxy Manager, Traefik, or Caddy
  • At least 1GB RAM (2GB+ recommended for production use)
  • An authentication provider (we’ll set up a simple one)

Step 1: Create the Project Directory

mkdir -p ~/outline && cd ~/outline

Step 2: Generate Secret Keys

Outline needs two secret keys. Generate them now:

openssl rand -hex 32  # SECRET_KEY
openssl rand -hex 32  # UTILS_SECRET

Save both — you’ll need them in the next step.

Step 3: Create the Docker Compose File

Create docker-compose.yml:

version: "3.8"

services:
  outline:
    image: docker.getoutline.com/outlinewiki/outline:latest
    container_name: outline
    restart: unless-stopped
    depends_on:
      - postgres
      - redis
    environment:
      NODE_ENV: production
      SECRET_KEY: your-secret-key-here
      UTILS_SECRET: your-utils-secret-here
      DATABASE_URL: postgres://outline:outline_password@postgres:5432/outline
      REDIS_URL: redis://redis:6379
      URL: https://wiki.yourdomain.com
      PORT: 3000
      FILE_STORAGE: local
      FILE_STORAGE_LOCAL_ROOT_DIR: /var/lib/outline/data
      # Authentication — using generic OIDC
      OIDC_CLIENT_ID: outline
      OIDC_CLIENT_SECRET: your-oidc-secret
      OIDC_AUTH_URI: https://auth.yourdomain.com/authorize
      OIDC_TOKEN_URI: https://auth.yourdomain.com/token
      OIDC_USERINFO_URI: https://auth.yourdomain.com/userinfo
      OIDC_DISPLAY_NAME: SSO Login
    ports:
      - "3000:3000"
    volumes:
      - outline-data:/var/lib/outline/data

  postgres:
    image: postgres:15-alpine
    container_name: outline-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: outline
      POSTGRES_PASSWORD: outline_password
      POSTGRES_DB: outline
    volumes:
      - postgres-data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    container_name: outline-redis
    restart: unless-stopped
    volumes:
      - redis-data:/data

volumes:
  outline-data:
  postgres-data:
  redis-data:

Replace the placeholder values:

  • your-secret-key-here and your-utils-secret-here with the keys from Step 2
  • https://wiki.yourdomain.com with your actual domain
  • The OIDC values with your authentication provider’s details

Step 4: Choose an Authentication Provider

Outline requires external authentication — there’s no built-in username/password login. Here are your options:

If you already run Authentik or Authelia for SSO, create a new OIDC application and plug in the credentials. Check our Authentik guide or Authelia guide for setup.

Option B: Google OAuth

For a quick setup, use Google OAuth:

  1. Go to Google Cloud Console
  2. Create a new OAuth 2.0 Client ID
  3. Set the redirect URI to https://wiki.yourdomain.com/auth/oidc.callback
  4. Replace the OIDC environment variables:
OIDC_CLIENT_ID: your-google-client-id
OIDC_CLIENT_SECRET: your-google-client-secret
OIDC_AUTH_URI: https://accounts.google.com/o/oauth2/v2/auth
OIDC_TOKEN_URI: https://oauth2.googleapis.com/token
OIDC_USERINFO_URI: https://openidconnect.googleapis.com/v1/userinfo
OIDC_DISPLAY_NAME: Google

Option C: Slack OAuth

If your team lives in Slack, this is the most seamless option. Create a Slack app at api.slack.com and use the Slack-specific environment variables instead of OIDC:

SLACK_CLIENT_ID: your-slack-client-id
SLACK_CLIENT_SECRET: your-slack-client-secret

Step 5: Start the Stack

docker compose up -d

Watch the logs to make sure everything starts cleanly:

docker compose logs -f outline

You should see Outline run database migrations automatically on first boot. Once you see Listening on http://0.0.0.0:3000, you’re good.

Step 6: Configure Your Reverse Proxy

Point your domain at the Outline container. Here’s an Nginx config example:

server {
    listen 443 ssl http2;
    server_name wiki.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    client_max_body_size 100M;

    location / {
        proxy_pass http://localhost:3000;
        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;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

The Upgrade headers are important — Outline uses WebSockets for real-time collaboration.

If you’re using Nginx Proxy Manager, just create a new proxy host pointing to localhost:3000 and enable WebSocket support.

Step 7: First Login and Setup

  1. Navigate to https://wiki.yourdomain.com
  2. Click your authentication provider’s login button
  3. The first user to log in becomes the admin
  4. Create your first Collection (like a folder for related documents)
  5. Start writing

Organizing Your Knowledge Base

Outline uses a hierarchy that works well at any scale:

  • Collections: Top-level categories (Engineering, Product, HR, etc.)
  • Documents: Individual pages within collections
  • Nested documents: Sub-pages under any document (unlimited depth)
  • Templates: Reusable document structures

Pro Tips for Organization

  • Use templates for recurring docs (meeting notes, postmortems, RFCs)
  • Pin important docs to the top of collections
  • Use the / slash command while editing to insert tables, images, code blocks, and more
  • Star documents you reference often — they show up on your home screen
  • Use #tags in documents for cross-collection discovery

Setting Up Backups

Your Outline data lives in two places: PostgreSQL and the file storage volume. Back up both:

#!/bin/bash
# backup-outline.sh
BACKUP_DIR=~/backups/outline
DATE=$(date +%Y-%m-%d)

mkdir -p $BACKUP_DIR

# Database backup
docker exec outline-db pg_dump -U outline outline | gzip > $BACKUP_DIR/db-$DATE.sql.gz

# File storage backup
docker run --rm -v outline-data:/data -v $BACKUP_DIR:/backup alpine \
  tar czf /backup/files-$DATE.tar.gz -C /data .

# Keep last 30 days
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete

echo "Outline backup complete: $BACKUP_DIR"

Add it to cron:

crontab -e
# Add:
0 3 * * * /bin/bash ~/backup-outline.sh

Troubleshooting

“Authentication error” on first login

Double-check your OIDC redirect URI. It must be exactly https://wiki.yourdomain.com/auth/oidc.callback (or /auth/slack.callback for Slack).

Database migration errors

If Outline fails to start with migration errors, check that PostgreSQL is fully ready:

docker compose restart outline

The depends_on directive doesn’t wait for PostgreSQL to accept connections — just for the container to start.

WebSocket connection failed

Make sure your reverse proxy passes Upgrade and Connection headers. Without WebSocket support, real-time collaboration won’t work (though basic editing still will).

“URL must start with https”

Outline requires HTTPS in production. If you’re testing locally, set FORCE_HTTPS=false in the environment variables, but never do this in production.

File uploads failing

Check client_max_body_size in your Nginx config. The default 1MB limit will block most uploads. Set it to at least 100M.

Updating Outline

cd ~/outline
docker compose pull
docker compose up -d

Outline runs migrations automatically on startup, so updates are usually seamless. Check the changelog before major version jumps.

Why Outline Over the Alternatives?

FeatureOutlineBookStackWiki.js
Real-time collab
Markdown native❌ (WYSIWYG)
Modern UI
API✅ Full REST✅ GraphQL
Auth requiredExternal SSOBuilt-inBuilt-in
Resource usageMediumLowMedium

Outline wins on collaboration and UI polish. The trade-off is requiring external authentication — but if you’re already running Authentik or similar, that’s a non-issue.

Conclusion

Outline gives you a production-grade knowledge base that your team will actually enjoy using. The Markdown-first editing, real-time collaboration, and fast search make it feel like a premium SaaS tool — except you own every byte of data.

Once it’s running, the hardest part is getting people to actually document things. But that’s a people problem, not a software problem.

For more self-hosted documentation tools, check out our guides on Paperless-ngx for document management and Homepage Dashboard for your self-hosted services portal.