5 changed files with 468 additions and 0 deletions
@ -0,0 +1,212 @@ |
|||||||
|
# Outline Wiki |
||||||
|
|
||||||
|
This is the hardest deployment I’ve ever done. I wouldn’t have been able to deploy this without [Guru Computing’s Blog](https://blog.gurucomputing.com.au/Knowledgebases%20with%20Outline/Installing%20Outline%20Knowledgebase/)! I do not advise deploying this unless you’ve had some experience with deploying any of the other apps in this repostitory. If you get stuck here please refer to Guru’s Computing’s blog! |
||||||
|
|
||||||
|
## Minimum File Structure |
||||||
|
|
||||||
|
``` |
||||||
|
/home/ |
||||||
|
└── ~/ |
||||||
|
└── docker/ |
||||||
|
└── outline/ |
||||||
|
├── .env |
||||||
|
├── docker-compose.yml |
||||||
|
├── docker.env |
||||||
|
|
||||||
|
└── keycloak/ |
||||||
|
├── .env |
||||||
|
├── docker-compose.yml |
||||||
|
``` |
||||||
|
|
||||||
|
## Add to Caddyfile (from \~/docker/caddy) |
||||||
|
|
||||||
|
Remember to `docker exec -w /etc/caddy caddy caddy reload` after editing your Caddyfile. |
||||||
|
|
||||||
|
``` |
||||||
|
outline.yourdomain.com { |
||||||
|
reverse_proxy outline:3000 |
||||||
|
} |
||||||
|
outlinedata.yourdomain.com { |
||||||
|
reverse_proxy outline-minio:9000 |
||||||
|
} |
||||||
|
outlinedata-admin.yourdomain.com { |
||||||
|
reverse_proxy outline-minio:9001 |
||||||
|
} |
||||||
|
auth.yourdomain.com { |
||||||
|
reverse_proxy keycloak:8080 |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
outline-minio is the s3 bucket we’ll be using. |
||||||
|
|
||||||
|
keycloak is the auth provider we will be self hosting |
||||||
|
|
||||||
|
# The “keycloak” directory |
||||||
|
|
||||||
|
We will start with keycloak for single sign on first because it is easier and we need to get the client secret from it for outline! Start by creating a empty keycloak directory similar to the minimum file structure section above. |
||||||
|
|
||||||
|
## docker-compose.yml |
||||||
|
|
||||||
|
Copy and use the same docker-compose.yml in this repo’s ./keycloak directory |
||||||
|
|
||||||
|
Then you copy the .env in this repo to the same directory and modify it |
||||||
|
|
||||||
|
## modifying the .env |
||||||
|
|
||||||
|
This is self explanatory. There are 3 lines to modify after the = sign |
||||||
|
|
||||||
|
```javascript |
||||||
|
KC_DB_PASSWORD=<insert long and scary password> |
||||||
|
KC_HOSTNAME=auth.yourdomain.com |
||||||
|
KEYCLOAK_ADMIN_PASSWORD=<insert another long and scary password> |
||||||
|
``` |
||||||
|
|
||||||
|
After you have both the docker-compose.yml and .env ready it’s time to start up the instances |
||||||
|
|
||||||
|
```javascript |
||||||
|
docker-compose up -d |
||||||
|
``` |
||||||
|
|
||||||
|
### Keycloak Configuration |
||||||
|
|
||||||
|
On your browser go to `https://auth.yourdomain.com/`and login to the Administration Console |
||||||
|
|
||||||
|
* In your keycloak portal, under **clients**, create a new **oidc** client for **outline.yourdomain.com**. Set the following values: |
||||||
|
|
||||||
|
```javascript |
||||||
|
Client Auth: On |
||||||
|
Client ID (can be whatever): outline.<your-domain>.com |
||||||
|
Name (can be whatever): outline.<your-domain>.com |
||||||
|
Root URL: https://outline.<your-domain>.com |
||||||
|
Home URL: https://outline.<your-domain>.com |
||||||
|
redirect URI: https://outline.<your-domain>.com/auth/oidc.callback |
||||||
|
``` |
||||||
|
|
||||||
|
#### PLACEHOLDER GIF 0 |
||||||
|
|
||||||
|
Finally create an account under users and set a password. |
||||||
|
|
||||||
|
#### PLACEHOLDER GIF 1 |
||||||
|
|
||||||
|
#### PLACEHOLDER GIF 2 |
||||||
|
|
||||||
|
# The “outline” directory |
||||||
|
|
||||||
|
This one is much harder! |
||||||
|
|
||||||
|
## docker-compose.yml |
||||||
|
|
||||||
|
Use the same docker-compose.yml located inside the outline directory of this repository |
||||||
|
|
||||||
|
## docker.env |
||||||
|
|
||||||
|
From the same directory in this repo copy and make modifications to `docker.env` to suit your environment |
||||||
|
|
||||||
|
5 variables that contain `yourdomain.com`needs to have `yourdomain.com`substituted with your own domain |
||||||
|
|
||||||
|
1 variables that say `<insert long and scary minio password>` need to be replaced with your own password |
||||||
|
|
||||||
|
2 variables that say `<insert long and scary PG password>` need to be replaced with your own password |
||||||
|
|
||||||
|
1 variable `SECRET_KEY=<Generate with openssl rand -hex 32>` needs to have it’s SECRET_KEY replaced by the output of `openssl rand -hex 32` |
||||||
|
|
||||||
|
1 variable `UTILS_SECRET=<Generate with openssl rand -hex 32>` needs to have it’s UTIL_SECRET replaced by the output of `openssl rand -hex 32` |
||||||
|
|
||||||
|
### Modify the OIDC Authentication section of docker.env |
||||||
|
|
||||||
|
The 5 lines below need modification where `yourdomain.com` is replaced with your actual domain! |
||||||
|
|
||||||
|
```javascript |
||||||
|
OIDC_CLIENT_ID=outline.yourdomain.com |
||||||
|
OIDC_CLIENT_SECRET=<use your own client secret generated in keycloak> |
||||||
|
OIDC_AUTH_URI=https://auth.yourdomain.com/realms/master/protocol/openid-connect/auth |
||||||
|
OIDC_TOKEN_URI=https://auth.yourdomain.com/realms/master/protocol/openid-connect/token |
||||||
|
OIDC_USERINFO_URI=https://auth.yourdomain.com/realms/master/protocol/openid-connect/userinfo |
||||||
|
``` |
||||||
|
|
||||||
|
### Optional: Set up SMTP variables to receive emails from outline |
||||||
|
|
||||||
|
```javascript |
||||||
|
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 |
||||||
|
``` |
||||||
|
|
||||||
|
## .env modifications needed |
||||||
|
|
||||||
|
The three variables `MINIO_ROOT_PASSWORD`, `MINIO_BROWSER_REDIRECT_URL`, and `POSTGRES_PW` need to be replaced similarly to docker.env. Use the same minio password `<insert long and scary minio password>` and PG `<insert long and scary PG password>` password as above. As for the URL replace `yourdomain.com` with your actual domain you will be hosting this on. |
||||||
|
|
||||||
|
```javascript |
||||||
|
MINIO_ROOT_PASSWORD=<insert long and scary minio password> |
||||||
|
MINIO_BROWSER_REDIRECT_URL=https://outlinedata.yourdomain.com |
||||||
|
POSTGRES_PW=<insert long and scary PG password> |
||||||
|
``` |
||||||
|
|
||||||
|
## Now that all files and modifications are in place. In the outline directory… |
||||||
|
|
||||||
|
Create the db by running |
||||||
|
|
||||||
|
```javascript |
||||||
|
docker-compose run --rm outline yarn db:create --env=production-ssl-disabled |
||||||
|
``` |
||||||
|
|
||||||
|
You’ll get some error saying |
||||||
|
|
||||||
|
```javascript |
||||||
|
ERROR: getaddrinfo EAI_AGAIN outline-postgres |
||||||
|
``` |
||||||
|
|
||||||
|
Don’t worry we will carry on. Now run |
||||||
|
|
||||||
|
```javascript |
||||||
|
sudo chown -R 999:999 ./psqldatabase-data |
||||||
|
``` |
||||||
|
|
||||||
|
Then run the migration command below |
||||||
|
|
||||||
|
```javascript |
||||||
|
docker-compose run --rm outline yarn db:migrate --env=production-ssl-disabled |
||||||
|
``` |
||||||
|
|
||||||
|
After migration is complete. You can start the app with |
||||||
|
|
||||||
|
```javascript |
||||||
|
docker-compose up -d |
||||||
|
``` |
||||||
|
|
||||||
|
Optional: If you run into any problems inspect the logs with |
||||||
|
|
||||||
|
```javascript |
||||||
|
docker-compose logs -f |
||||||
|
``` |
||||||
|
|
||||||
|
Optional: Anytime you want to start over from scratch you can run the following in the ./outline directory |
||||||
|
|
||||||
|
```javascript |
||||||
|
docker-compose down --remove-orphans -v |
||||||
|
sudo rm -R container-data/ psqldatabase-data/ redis.conf/ |
||||||
|
``` |
||||||
|
|
||||||
|
Okay so outline is finished hosting! |
||||||
|
|
||||||
|
## Logging into your minio bucket and creating outlinebucket |
||||||
|
|
||||||
|
This step needs to be done so you can drag / drop upload files to your outline pages |
||||||
|
|
||||||
|
In your browser go to `https://outlinedata-admin.yourdomain.com` and login |
||||||
|
|
||||||
|
Finally create a bucket called `outlinebucket` |
||||||
|
|
||||||
|
After creation, under the anonymous tab add two access rules: `avatar` and `public` as readonly access rules. Don’t worry if you’re confused here’s a gif below explaining all this. |
||||||
|
|
||||||
|
|
||||||
|
#### PLACEHOLDER GIF 3 |
||||||
|
|
||||||
|
That’s it! |
||||||
|
|
||||||
|
Now login to outline with your keycloak account. And you should be able to drag and drop images to your documents! |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
version: '3.3' |
||||||
|
|
||||||
|
services: |
||||||
|
keycloak: |
||||||
|
container_name: keycloak |
||||||
|
image: quay.io/keycloak/keycloak:22.0 |
||||||
|
restart: always |
||||||
|
environment: |
||||||
|
KC_DB: postgres |
||||||
|
KC_DB_URL: jdbc:postgresql://keycloak-db:5432/keycloak |
||||||
|
KC_DB_USER: keycloak |
||||||
|
KC_DB_SCHEMA: public |
||||||
|
KC_DB_PASSWORD: ${KC_DB_PASSWORD} |
||||||
|
KC_HOSTNAME: ${KC_HOSTNAME} |
||||||
|
KEYCLOAK_ADMIN: admin |
||||||
|
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} |
||||||
|
KC_PROXY: edge |
||||||
|
depends_on: |
||||||
|
- keycloak-db |
||||||
|
command: start |
||||||
|
networks: |
||||||
|
- caddy_net |
||||||
|
|
||||||
|
keycloak-db: |
||||||
|
container_name: keycloak-db |
||||||
|
image: postgres:16 |
||||||
|
restart: always |
||||||
|
security_opt: |
||||||
|
- label:disable |
||||||
|
volumes: |
||||||
|
- ./container-data/db:/var/lib/postgresql/data |
||||||
|
- /etc/localtime:/etc/localtime:ro |
||||||
|
environment: |
||||||
|
POSTGRES_DB: keycloak |
||||||
|
POSTGRES_USER: keycloak |
||||||
|
POSTGRES_PASSWORD: ${KC_DB_PASSWORD} |
||||||
|
networks: |
||||||
|
- caddy_net |
||||||
|
|
||||||
|
networks: |
||||||
|
caddy_net: |
||||||
|
external: true |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
#.env |
||||||
|
AWS_ACCESS_KEY_ID=minio |
||||||
|
MINIO_ROOT_USER=minio |
||||||
|
MINIO_ROOT_PASSWORD=<insert long and scary minio password> |
||||||
|
MINIO_BROWSER_REDIRECT_URL=https://outlinedata.yourdomain.com |
||||||
|
POSTGRES_PW=<insert long and scary PG password> |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
version: '3.3' |
||||||
|
|
||||||
|
services: |
||||||
|
keycloak: |
||||||
|
container_name: keycloak |
||||||
|
image: quay.io/keycloak/keycloak:22.0 |
||||||
|
restart: always |
||||||
|
environment: |
||||||
|
KC_DB: postgres |
||||||
|
KC_DB_URL: jdbc:postgresql://keycloak-db:5432/keycloak |
||||||
|
KC_DB_USER: keycloak |
||||||
|
KC_DB_SCHEMA: public |
||||||
|
KC_DB_PASSWORD: ${KC_DB_PASSWORD} |
||||||
|
KC_HOSTNAME: ${KC_HOSTNAME} |
||||||
|
KEYCLOAK_ADMIN: admin |
||||||
|
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} |
||||||
|
KC_PROXY: edge |
||||||
|
depends_on: |
||||||
|
- keycloak-db |
||||||
|
command: start |
||||||
|
networks: |
||||||
|
- caddy_net |
||||||
|
|
||||||
|
keycloak-db: |
||||||
|
container_name: keycloak-db |
||||||
|
image: postgres:16 |
||||||
|
restart: always |
||||||
|
security_opt: |
||||||
|
- label:disable |
||||||
|
volumes: |
||||||
|
- ./container-data/db:/var/lib/postgresql/data |
||||||
|
- /etc/localtime:/etc/localtime:ro |
||||||
|
environment: |
||||||
|
POSTGRES_DB: keycloak |
||||||
|
POSTGRES_USER: keycloak |
||||||
|
POSTGRES_PASSWORD: ${KC_DB_PASSWORD} |
||||||
|
networks: |
||||||
|
- caddy_net |
||||||
|
|
||||||
|
networks: |
||||||
|
caddy_net: |
||||||
|
external: true |
||||||
@ -0,0 +1,166 @@ |
|||||||
|
# –––––––––––––––– 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 with openssl rand -hex 32> |
||||||
|
|
||||||
|
# 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=<Generate with openssl rand -hex 32> |
||||||
|
|
||||||
|
# For production point these at your databases, in development the default |
||||||
|
# should work out of the box. |
||||||
|
DATABASE_URL=postgres://postgres:<insert long and scary PG password>@outline-postgres:5432/outline |
||||||
|
DATABASE_URL_TEST=postgres://postgres:<insert long and scary PG password>@outline-postgres:5432/outline-test |
||||||
|
DATABASE_CONNECTION_POOL_MIN= |
||||||
|
DATABASE_CONNECTION_POOL_MAX= |
||||||
|
# Uncomment this to disable SSL for connecting to Postgres |
||||||
|
PGSSLMODE=disable |
||||||
|
|
||||||
|
# For redis you can either specify an ioredis compatible url like this |
||||||
|
REDIS_URL=redis://outline-redis:6379 |
||||||
|
# or alternatively, if you would like to provide additional connection options, |
||||||
|
# use a base64 encoded JSON connection option object. Refer to the ioredis documentation |
||||||
|
# for a list of available options. |
||||||
|
# Example: Use Redis Sentinel for high availability |
||||||
|
# {"sentinels":[{"host":"sentinel-0","port":26379},{"host":"sentinel-1","port":26379}],"name":"mymaster"} |
||||||
|
# REDIS_URL=ioredis://eyJzZW50aW5lbHMiOlt7Imhvc3QiOiJzZW50aW5lbC0wIiwicG9ydCI6MjYzNzl9LHsiaG9zdCI6InNlbnRpbmVsLTEiLCJwb3J0IjoyNjM3OX1dLCJuYW1lIjoibXltYXN0ZXIifQ== |
||||||
|
|
||||||
|
# URL should point to the fully qualified, publicly accessible URL. If using a |
||||||
|
# proxy the port in URL and PORT may be different. |
||||||
|
URL=https://outline.yourdomain.com |
||||||
|
PORT=3000 |
||||||
|
|
||||||
|
# See [documentation](/SERVICES.md) on running a separate collaboration |
||||||
|
# server, for normal operation this does not need to be set. |
||||||
|
COLLABORATION_URL= |
||||||
|
|
||||||
|
# To support uploading of images for avatars and document attachments an |
||||||
|
# s3-compatible storage must be provided. AWS S3 is recommended for redundancy |
||||||
|
# however if you want to keep all file storage local an alternative such as |
||||||
|
# minio (https://github.com/minio/minio) can be used. |
||||||
|
|
||||||
|
# A more detailed guide on setting up S3 is available here: |
||||||
|
# => https://wiki.generaloutline.com/share/125de1cc-9ff6-424b-8415-0d58c809a40f |
||||||
|
# |
||||||
|
AWS_ACCESS_KEY_ID=minio |
||||||
|
AWS_SECRET_ACCESS_KEY=<insert long and scary minio password> |
||||||
|
AWS_REGION=us-east-1 |
||||||
|
AWS_S3_ACCELERATE_URL= |
||||||
|
AWS_S3_UPLOAD_BUCKET_URL=https://outlinedata.yourdomain.com |
||||||
|
AWS_S3_UPLOAD_BUCKET_NAME=outlinebucket |
||||||
|
AWS_S3_UPLOAD_MAX_SIZE=26214400 |
||||||
|
AWS_S3_FORCE_PATH_STYLE=true |
||||||
|
AWS_S3_ACL=private |
||||||
|
|
||||||
|
|
||||||
|
# –––––––––––––– AUTHENTICATION –––––––––––––– |
||||||
|
|
||||||
|
# Third party signin credentials, at least ONE OF EITHER Google, Slack, |
||||||
|
# or Microsoft is required for a working installation or you'll have no sign-in |
||||||
|
# options. |
||||||
|
|
||||||
|
# To configure Slack auth, you'll need to create an Application at |
||||||
|
# => https://api.slack.com/apps |
||||||
|
# |
||||||
|
# When configuring the Client ID, add a redirect URL under "OAuth & Permissions": |
||||||
|
# https://<URL>/auth/slack.callback |
||||||
|
SLACK_CLIENT_ID= |
||||||
|
SLACK_CLIENT_SECRET= |
||||||
|
|
||||||
|
# To configure Google auth, you'll need to create an OAuth Client ID at |
||||||
|
# => https://console.cloud.google.com/apis/credentials |
||||||
|
# |
||||||
|
# When configuring the Client ID, add an Authorized redirect URI: |
||||||
|
# https://<URL>/auth/google.callback |
||||||
|
GOOGLE_CLIENT_ID= |
||||||
|
GOOGLE_CLIENT_SECRET= |
||||||
|
|
||||||
|
# To configure Microsoft/Azure auth, you'll need to create an OAuth Client. See |
||||||
|
# the guide for details on setting up your Azure App: |
||||||
|
# => https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4 |
||||||
|
AZURE_CLIENT_ID= |
||||||
|
AZURE_CLIENT_SECRET= |
||||||
|
AZURE_RESOURCE_APP_ID= |
||||||
|
|
||||||
|
# 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 |
||||||
|
|
||||||
|
## Because I'm using personal gmail accounts I put CLIENT_ID and CLIENT_SECRET Here in OIDC instead of the Google Section |
||||||
|
OIDC_CLIENT_ID=outline.yourdomain.com |
||||||
|
OIDC_CLIENT_SECRET=<use your own client secret generated in keycloak> |
||||||
|
OIDC_AUTH_URI=https://auth.yourdomain.com/realms/master/protocol/openid-connect/auth |
||||||
|
OIDC_TOKEN_URI=https://auth.yourdomain.com/realms/master/protocol/openid-connect/token |
||||||
|
OIDC_USERINFO_URI=https://auth.yourdomain.com/realms/master/protocol/openid-connect/userinfo |
||||||
|
|
||||||
|
# Specify which claims to derive user information from |
||||||
|
# Supports any valid JSON path with the JWT payload |
||||||
|
OIDC_USERNAME_CLAIM=preferred_username |
||||||
|
|
||||||
|
# Display name for OIDC authentication |
||||||
|
OIDC_DISPLAY_NAME=Keycloak |
||||||
|
|
||||||
|
# Space separated auth scopes. |
||||||
|
OIDC_SCOPES=openid profile email |
||||||
|
|
||||||
|
|
||||||
|
# –––––––––––––––– OPTIONAL –––––––––––––––– |
||||||
|
|
||||||
|
# If using a Cloudfront/Cloudflare distribution or similar it can be set below. |
||||||
|
# This will cause paths to javascript, stylesheets, and images to be updated to |
||||||
|
# the hostname defined in CDN_URL. In your CDN configuration the origin server |
||||||
|
# should be set to the same as URL. |
||||||
|
CDN_URL= |
||||||
|
|
||||||
|
# Auto-redirect to https in production. The default is true but you may set to |
||||||
|
# false if you can be sure that SSL is terminated at an external loadbalancer. |
||||||
|
FORCE_HTTPS=true |
||||||
|
|
||||||
|
# Have the installation check for updates by sending anonymized statistics to |
||||||
|
# the maintainers |
||||||
|
ENABLE_UPDATES=true |
||||||
|
|
||||||
|
# How many processes should be spawned. As a reasonable rule divide your servers |
||||||
|
# available memory by 512 for a rough estimate |
||||||
|
WEB_CONCURRENCY=1 |
||||||
|
|
||||||
|
# Override the maximum size of document imports, could be required if you have |
||||||
|
# especially large Word documents with embedded imagery |
||||||
|
MAXIMUM_IMPORT_SIZE=5120000 |
||||||
|
|
||||||
|
# You can remove this line if your reverse proxy already logs incoming http |
||||||
|
# requests and this ends up being duplicative |
||||||
|
DEBUG=http |
||||||
|
|
||||||
|
# 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 |
||||||
|
|
||||||
|
# The default interface language. See translate.getoutline.com for a list of |
||||||
|
# available language codes and their rough percentage translated. |
||||||
|
DEFAULT_LANGUAGE=en_US |
||||||
|
|
||||||
|
# Optionally enable rate limiter at application web server |
||||||
|
RATE_LIMITER_ENABLED=true |
||||||
|
|
||||||
|
# Configure default throttling parameters for rate limiter |
||||||
|
RATE_LIMITER_REQUESTS=1000 |
||||||
|
RATE_LIMITER_DURATION_WINDOW=60 |
||||||
|
|
||||||
|
# Iframely API config |
||||||
|
# IFRAMELY_URL= |
||||||
|
# IFRAMELY_API_KEY= |
||||||
Loading…
Reference in new issue