Skip to content
appsgit

Deploy guide

How to self-host Outline with Docker Compose

Deploy the Outline team wiki with Docker Compose, Postgres and Redis: secrets, local file storage, OIDC or email login, HTTPS reverse proxy, backups, upgrades.

  • Updated
  • Intermediate
  • About 30 minutes

You will need

  • 2 vCPU / 2 GB RAM
  • Docker + Docker Compose v2
  • A domain name with HTTPS
  • An auth provider (OIDC, Google, Slack, Microsoft) or SMTP for email login

What is Outline?

Outline is a fast, collaborative knowledge base for teams, with real-time editing, Markdown shortcuts, nested documents, powerful search and integrations with Slack and other tools. It is source-available on GitHub under the Business Source License 1.1 (BUSL-1.1), which lets you self-host it for your own organisation for free. It is a popular self-hosted alternative to Notion and Confluence for internal documentation.

Requirements

  • A Linux server with 2 vCPU and 2 GB of RAM.
  • Docker Engine and Docker Compose v2.
  • A domain name such as wiki.example.com. Outline expects to run on HTTPS.
  • A way for users to sign in. Outline has no local passwords: configure an OIDC provider (Authentik, Keycloak, Authelia, Pocket ID and others), Google, Microsoft, Slack, or SMTP for email magic links.

Step 1: Prepare the server

This guide assumes Ubuntu 24.04 with Docker installed. If you need Docker, follow the official install guide. Create a folder and a data directory that the Outline container user (UID 1001) can write to:

mkdir -p ~/outline/data && cd ~/outline
sudo chown -R 1001:1001 data

Step 2: Create the Docker Compose file

Save this as docker-compose.yml:

services:
  outline:
    image: outlinewiki/outline:1.10.1
    restart: unless-stopped
    env_file: ./docker.env
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - ./data:/var/lib/outline/data
    depends_on:
      - postgres
      - redis

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

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: outline
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: outline
    volumes:
      - pg-data:/var/lib/postgresql/data

volumes:
  redis-data:
  pg-data:

Create .env for Compose itself:

POSTGRES_PASSWORD=CHANGE_ME

Then create docker.env with Outline's settings. This example uses OIDC; the full list of options is in the .env.sample file:

NODE_ENV=production
URL=https://wiki.example.com
PORT=3000
SECRET_KEY=CHANGE_ME
UTILS_SECRET=CHANGE_ME
DATABASE_URL=postgres://outline:CHANGE_ME@postgres:5432/outline
PGSSLMODE=disable
REDIS_URL=redis://redis:6379
FILE_STORAGE=local
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
FILE_STORAGE_UPLOAD_MAX_SIZE=262144000
FORCE_HTTPS=false
OIDC_CLIENT_ID=CHANGE_ME
OIDC_CLIENT_SECRET=CHANGE_ME
OIDC_AUTH_URI=https://auth.example.com/application/o/authorize/
OIDC_TOKEN_URI=https://auth.example.com/application/o/token/
OIDC_USERINFO_URI=https://auth.example.com/application/o/userinfo/
OIDC_DISPLAY_NAME=Company SSO

Generate SECRET_KEY and UTILS_SECRET with openssl rand -hex 32. Outline requires SECRET_KEY to be a 64-character hex string, which this produces. Use another openssl rand -hex 32 value as the Postgres password, and put the same value in both .env and DATABASE_URL. FORCE_HTTPS=false is correct here because TLS ends at your reverse proxy. In your identity provider, register the redirect URI https://wiki.example.com/auth/oidc.callback. Protect both env files with chmod 600.

Step 3: Start and open the app

docker compose up -d
docker compose logs -f outline

Outline runs its database migrations on first start. After Step 4 is done, open https://wiki.example.com and sign in with your provider. The first person to sign in creates the workspace and becomes its admin. Under Settings, Security, restrict sign-ups to your email domains so only your team can join.

Step 4: Put it behind HTTPS

With Caddy:

wiki.example.com {
    reverse_proxy 127.0.0.1:3000
}

Outline uses WebSockets for real-time collaboration, which Caddy supports without extra config. With Nginx Proxy Manager, enable "Websockets Support". The URL variable must match the domain exactly, or logins and collaboration will fail.

Backups and upgrades

Back up the Postgres database and the data folder with uploaded attachments:

docker compose exec -T postgres pg_dump -U outline outline | gzip > outline-$(date +%F).sql.gz
tar czf outline-files-$(date +%F).tgz data

Keep .env and docker.env as well, because SECRET_KEY is needed to decrypt stored integration secrets. Outline can also export the whole workspace as Markdown or JSON from Settings, Export.

To upgrade, change the image tag to a newer release from the releases page, then:

docker compose pull && docker compose up -d

Migrations run automatically on start.

Troubleshooting

  • No sign-in buttons on the login page: no authentication provider is configured. Add OIDC, Google, Slack or Microsoft settings, or SMTP for email login.
  • "redirect_uri mismatch" from the identity provider: the callback URL registered in the provider does not match URL plus /auth/oidc.callback.
  • Uploads fail with permission errors: the data folder must be owned by UID 1001.
  • Editor shows "Trying to reconnect": the proxy is not forwarding WebSocket connections.

Next steps

Connect the Slack integration for link previews and search, import existing docs from Notion, Confluence or Markdown, set up groups and collection permissions, and configure SMTP for notification emails.

Spotted something out of date? Tell us and we will update the guide.

FAQ

Outline questions

Still curious? Email info@appsgit.com.

What port does Outline use?

Outline listens on port 3000 by default, set with the PORT environment variable. In production you put an HTTPS reverse proxy in front and set URL to the public address.

Is Outline free to self-host?

Yes, for most uses. Outline is source-available under the Business Source License 1.1, which allows free self-hosting for your own team but not offering Outline as a competing hosted service. Each release converts to Apache 2.0 after a set period.

Why can I not log in to my new Outline instance?

Outline has no username and password login. You must configure at least one authentication provider, such as OIDC, Google, Slack or Microsoft, or set up SMTP so users can sign in with email magic links.

Can Outline store files without S3?

Yes. Set FILE_STORAGE=local and mount a volume at FILE_STORAGE_LOCAL_ROOT_DIR. S3-compatible storage such as MinIO or Cloudflare R2 is only needed if you prefer object storage.

Outline vs Notion?

Outline focuses on fast team documentation with Markdown shortcuts, real-time collaboration and search, and can run on your own server. Notion adds databases and many more page types but is cloud-only.