This docker compose will not be using S3 storage or Minio bucket storage. Both storage options add too much complexity and AWS S3 isn't really selfhosted. That being said you should have a backup of your data incase local storage fails. For Authentication we are going to use Keycloak for the OIDC.
Keycloak can run using its own container stack, however we are incorporating it into the docker compose stack.
Learn more about Outline from outline/outline GitHub.
- Separated network,
backend
for the postgres databases and redis containers. frontend
network for containers,outline-app
andkeycloak-app
to be exposed to internet using a proper proxy.container_name
is added to all services,outline-app
,outline-redis
,outline-postgres
,keycloak-app
andkeycloak-db
. You can choose to rename for your deploy.- Changed all Docker volumes to bind-mounts for better backup.
- added a volume for redis
/data
. - added keycloak as the primary auth provider.
- changed docker.env file to be local storage only.
- A reverse proxy such as
Nginx Proxy Manager
. You can grab instructions to install one here. - A domain and subdomains at the ready. I recommend
outline.domain.com
andkeycloak.domain.com
. You can use others but make sure you change the URLS in the compose and .env
- A) You can clone repo here
B) Download thedocker-compose.yml
anddocker.env
file and put them into a folder to run
C) Copy the following into your owndocker-compose.yml
and thedocker.env
to your own files and folder.
The docker compose, to download go here
version: "3.2"
networks:
frontend:
external: true
backend:
services:
outline:
container_name: outline-app
image: docker.getoutline.com/outlinewiki/outline:latest
env_file: ./docker.env
environment:
- PUID=1000
- PGID=1000
ports:
- "3000:3000"
volumes:
- ./outline-data:/var/lib/outline/data
depends_on:
- postgres
- redis
networks:
- frontend
- backend
redis:
container_name: outline-redis
image: redis
env_file: ./docker.env
ports:
- "6379:6379"
volumes:
- ./outline-redis.conf:/redis.conf
- ./outline-redis-data:/data
command: ["redis-server", "/redis.conf"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 30s
retries: 3
networks:
- backend
postgres:
container_name: outline-postgres
image: postgres
env_file: ./docker.env
ports:
- "5432:5432"
volumes:
- ./outline-database-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready"]
interval: 30s
timeout: 20s
retries: 3
environment:
POSTGRES_USER: 'user'
POSTGRES_PASSWORD: 'pass'
POSTGRES_DB: 'outline'
networks:
- backend
keycloak:
container_name: keycloak-app
image: quay.io/keycloak/keycloak:latest
ports:
- "8080:8080"
- "8443:8443"
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://keycloak-db:5432/keycloakdb
KC_DB_USERNAME: keycloakdbuser
KC_DB_PASSWORD: #change me
KEYCLOAK_ADMIN: 'admin'
KEYCLOAK_ADMIN_PASSWORD: #change me to a secure password
KC_DB_PORT: 5432
KEYCLOAK_DATABASE_SCHEMA: public
KEYCLOAK_ENABLE_HEALTH_ENDPOINTS: 'true'
KEYCLOAK_ENABLE_STATISTICS: 'true'
KC_HOSTNAME: 'keycloak.domain.com'
KC_PROXY: edge
KC_PROXY_ADDRESS_FORWARDING: 'true'
KC_HTTP_ENABLED: 'true'
depends_on:
- key-postgres
networks:
- frontend
- backend
command: start
key-postgres:
image: postgres:15
container_name: keycloak-db
volumes:
- ./keycloak-db:/var/lib/postgresql/data
environment:
POSTGRES_DB: 'keycloakdb'
POSTGRES_USER: 'keycloakdbuser'
POSTGRES_PASSWORD: #same as KC_DB_PASSWORD
networks:
- backend
healthcheck:
test: [ "CMD", "pg_isready", "-q", "-d", "keycloakdb", "-U", "keycloakdbuser" ]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
restart: unless-stopped
docker.env condensed, non-condensed version with more options here
# –––––––––––––––– REQUIRED ––––––––––––––––
NODE_ENV=production
# Generate a hex-encoded 32-byte random key. You should use `openssl rand -hex 32`
# in your terminal to generate a random value.
SECRET_KEY=
# Generate a unique random key. The format is not important but you could still use
# `openssl rand -hex 32` in your terminal to produce this.
UTILS_SECRET=
DATABASE_URL=postgres://user:pass@outline-postgres:5432/outline
DATABASE_URL_TEST=postgres://user:pass@outline-postgres:5432/outline-test
DATABASE_CONNECTION_POOL_MIN=
DATABASE_CONNECTION_POOL_MAX=
PGSSLMODE=disable
REDIS_URL=redis://outline-redis:6379
URL=https://outline.domain.com
PORT=3000
FILE_STORAGE=local
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
FILE_STORAGE_UPLOAD_MAX_SIZE=26214400
# –––––––––––––– AUTHENTICATION ––––––––––––––
# To configure generic OIDC auth, you'll need some kind of identity provider.
# See documentation for whichever IdP you use to acquire the following info:
# Redirect URI is https://<URL>/auth/oidc.callback
OIDC_CLIENT_ID=outline
OIDC_CLIENT_SECRET=
OIDC_AUTH_URI=https://keycloak.domain.com/realms/outline/protocol/openid-connect/auth
OIDC_TOKEN_URI=https://keycloak.domain.com/realms/outline/protocol/openid-connect/token
OIDC_USERINFO_URI=https://keycloak.domain.com/realms/outline/protocol/openid-connect/userinfo
OIDC_USERNAME_CLAIM=email
OIDC_DISPLAY_NAME=KeyCloak
OIDC_SCOPES=openid profile email
# –––––––––––––––– OPTIONAL ––––––––––––––––
FORCE_HTTPS=true
ENABLE_UPDATES=false
WEB_CONCURRENCY=1
MAXIMUM_IMPORT_SIZE=5120000
# Configure lowest severity level for server logs. Should be one of
# error, warn, info, http, verbose, debug and silly
LOG_LEVEL=info
# To support sending outgoing transactional emails such as "document updated" or
# "you've been invited" you'll need to provide authentication for an SMTP server
SMTP_HOST=
SMTP_PORT=
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_FROM_EMAIL=hello@example.com
SMTP_REPLY_EMAIL=hello@example.com
SMTP_TLS_CIPHERS=
SMTP_SECURE=true
DEFAULT_LANGUAGE=en_US
RATE_LIMITER_ENABLED=true
RATE_LIMITER_REQUESTS=1000
RATE_LIMITER_DURATION_WINDOW=60
DEVELOPMENT_UNSAFE_INLINE_CSP=false
-
After you have cloned or nested the
docker-compose.yml
anddocker.env
into a folder. We will need to edit the two files before running them. -
Change the following
KC_DB_PASSWORD
andKEYCLOAK_ADMIN_PASSWORD
to secure passwords. Make sure they are different, you can use a terminal commandopenssl rand -hex 12
to generate a random password.KC_DB_USERNAME: keycloakdbuser KC_DB_PASSWORD: #change me KEYCLOAK_ADMIN: 'admin' KEYCLOAK_ADMIN_PASSWORD: #change me to a secure password
-
Change the
POSTGRES_PASSWORD
to the same password you set forKC_DB_PASSWORD
.POSTGRES_USER: 'keycloakdbuser' POSTGRES_PASSWORD: #same as KC_DB_PASSWORD
-
Change
OIDC_AUTH_URI
,OIDC_TOKEN_URI
andOIDC_USERINFO_URI
to the correct domain or subdomain. leave the rest of the path alone.OIDC_AUTH_URI=https://keycloak.domain.com/realms/outline/protocol/openid-connect/auth OIDC_TOKEN_URI=https://keycloak.domain.com/realms/outline/protocol/openid-connect/token OIDC_USERINFO_URI=https://keycloak.domain.com/realms/outline/protocol/openid-connect/userinfo
-
Change the URL to your domain to subdomain you plan to use for outline.
URL=https://outline.domain.com ##change this PORT=3000
-
Connect to the keycloak container by either going to
keycloak.yourdomain.com
or by connecting to the port8080
at you LAN IP for admin controls. ex.127.0.0.1:8080
-
After the login screen, you'll see the
Welcome to KeyCloak
panel. Proceed toAdministration Console
-
the login is:
Email: admin Password: [KEYCLOAK_ADMIN_PASSWORD] #from docker-compose.yml
-
Once past the login, you will need to create a
realm
in Keycloak. Click onmaster
and then selectCreate realm
.
- Don't worry about
Resource file
, inRealm name
you will enteroutline
no caps, then select enabled toon
. Then create the realm. - You should see a
Welcome to outline
page. Go to top left burger menu and selectClients
, notClient Scopes
. - Please continue with the button
Create client
.
- Make sure
Client type
isOpenID Connect
, insideClient ID
you're going to enteroutline
, no caps. You can fill outName
andDescription
if you like to. It will help if you have multiple services connecting to Keycloak going forward. Press theNext
button.
- On the Next screen you will toggle on
Client authentication
and make sure thatStandard flow
is enabled, leave all other options as is. Proceed with thenext
button.
Root URL
will be, again assuming you have a reverse proxy up,https://outline.domain.com/
.
Home URL
will behttps://outline.domain.com/
.
Valid redirect URIs
will behttps://outline.domain.com*
make sure you have the*
.
Do not fill inValid post logout redirect URIs
andWeb Origins
. Proceed toSave
- Once that's saved the page will reload and new tabs will appear. We are going to select the tab
Credentials
.
- Copy
Client Secret
into thedocker.env
. The Secret we just copied will be pasted intoOIDC_CLIENT_SECRET=
env variable.
- Next we are going to add a User or Users into the
realm
. Head to the side bar and locateUsers
, then selectAdd user
.
- Filling in the following fields:
Username
,Email
,First name
andLast name
. You will want to toggle on verified email for your 1st user or any user you know that has a vaild email address. Afterwords selectCreate user
.
- Once you've created the user new tabs will show up. Select
Credentials
to add a password to the user.
- Set a password for your new user and toggle off
Temporay
, now save the password.
- Optional if you want to you can at this point fill out the SMTP section of the
docker.env
file to set up transactional emails. Invites, password resets, view codes and notifications from outline are all transactional. I'm not going over that since SMTP settings can vary by provider.
-
Optional if you want to you can at this point fill out the SMTP section of the
docker.env
file to set up transactional emails. Invites, password resets, view codes and notifications from outline are all transactional. I'm not going over that since SMTP settings can vary by provider. -
shutdown your docker-outline-keycloak stack, exit everything gracefully.
Then bring your stack back up,docker compose up -d
, this will make sure that outline see's the changes to the docker.env file. -
Head to your outline instance in your web browser by going to
https://outline.domain.com
, login with the user you've just made and your good to go.
If you try to upload photos and are getting a failed message you will need to do the following command to the folder where outline is storing data.chown 1001 /location/on/host/filesystem/outline-data
-
If you are still having problems with uploading images to your outline instance. you may need to further fix the permissions within the
Outline
app. Access the container shell with:docker exec -u 0 -it outline-app sh
and running
chown -R nodejs:nodejs /var/lib/outline/data
and then rebooting the containers allowed file uploads to proceed successfully.
Thats it enjoy your selfhosted instance to Outline.
- For more documentation go to the Outline Official Docs