# 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.

## Key facts

| Fact | Value |
|---|---|
| App | Outline (https://appsgit.com/apps/outline) |
| Difficulty | intermediate |
| Time | about 30 minutes |
| Requirements | 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 |
| Last updated | 2026-10-06 |

## 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](https://docs.docker.com/engine/install/ubuntu/). Create a folder and a data directory that the Outline container user (UID 1001) can write to:

```bash
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`:

```yaml
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:

```bash
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`](https://github.com/outline/outline/blob/main/.env.sample) file:

```bash
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

```bash
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](https://caddyserver.com/docs/):

```caddyfile
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:

```bash
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](https://github.com/outline/outline/releases), then:

```bash
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.

## FAQ

### 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.

Prefer not to do it yourself? [appsgit installation help](https://appsgit.com/services/install) installs it on your server for a fixed quote.

---

Canonical page: https://appsgit.com/guides/outline
Source: appsgit (https://appsgit.com), the app store for github. Data from the GitHub API, refreshed nightly.
Machine access: JSON API https://appsgit.com/api/v1/apps (OpenAPI: https://appsgit.com/openapi.json), MCP server https://mcp.appsgit.com/mcp, full index https://appsgit.com/llms-full.txt.
