├── .gitignore
├── README.md
├── database-setup.sh
├── docker-compose.yml
├── docker-setup
├── install-docker
├── install-docker-compose
├── install.sh
├── redis.conf
└── update.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 | .docker.env
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | An open, extensible, knowledge base for your team.
Try out Outline using our hosted version at www.getoutline.com.
7 |
8 |
9 |
10 |
11 | ## Outline on-prem
12 |
13 | Deploy Outline on-premises to manage all of your data within your own cloud environment. This repository contains all the necessary scripts to install and run the enterprise edition of Outline on-prem. Please refer to the [On Premise Guide](https://wiki.generaloutline.com/share/13dec265-c002-4c73-8025-75981f29b0d0) during installation.
14 |
15 | ## Simple reference deployment (15-20 min)
16 |
17 | In this guide, we will walk through a simple, straightforward, setup on AWS EC2. Outline comes with images for a Postgres DB instance, as well a Minio for file storage.
18 |
19 | **For production deployments, we highly recommend you use something like RDS and S3 for these purposes.** This can be done during the initial install process or configured after setup is complete.
20 |
21 | #### Spin up a new EC2 instance:
22 | 1. Choose **Launch Instance** from the EC2 dashboard.
23 | 1. Select Ubuntu. Outline should work on any modern version.
24 | 1. Select an instance type of `t2.small` or higher.
25 | 1. Set the network security groups for ports `22`, `80`, `443`, and `3000`. Set sources set to `0.0.0.0/0` and `::/0`, and click **Review and Launch**.
26 | 1. On the next screen, click **Launch** to start your instance.
27 |
28 | #### Set up your DNS and other services:
29 | 1. Before proceeding, go to your DNS provider and provision a subdomain where you would like to locate your Outline instance. For example `wiki.mycompany.com`. Point this subdomain at the public IPv4 address of your EC2 instance.
30 | 1. If you're planning on using a managed database and file storage (like RDS and S3), this would be a good time to provision those as well:
31 | 1. Our [setup guide for S3](https://wiki.generaloutline.com/share/13dec265-c002-4c73-8025-75981f29b0d0/doc/aws-s3-N4M0T6Ypu7)
32 | 1. Our [setup guide for RDS](https://wiki.generaloutline.com/share/13dec265-c002-4c73-8025-75981f29b0d0/doc/aws-rds-etUZYyP2jV)
33 |
34 | #### Configure your EC2 instance and start Outline:
35 | 1. From your command line tool, SSH into your EC2 instance. You will need to clone this repository into your instance, so we recommend you use [SSH agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding)
36 | 1. Clone this repo on your instance: `git clone git@github.com:outline/outline-onprem.git`.
37 | 1. Go into the cloned repo directory: `cd outline-onprem`.
38 | 1. Run `./install.sh`. This will install **Docker** and **Docker Compose**, and initialize some configuration files to be edited later.
39 | 1. Follow the instruction prompts. You will be asked to provide your provisioned subdomain at the end of this process.
40 | 1. Run `sudo docker-compose pull` to download images.
41 | 1. Open the configuration file `docker.env` and add your **license key** as the value for the variable `LICENSE_KEY`. If you don't yet have a key because you're setting up a proof-of-concept or a trial, set the value to `trial`.
42 | 1. **If you are using your own database and/or file storage**, open `docker.env` and modify the Postgres and S3 related configuration values.
43 | 1. Run `./database-setup.sh` to initialize your database.
44 | 1. Now you're read to start your Outline server with: `sudo docker-compose up -d`.
45 | 1. Navigate to your server's address in a web browser. You will see a login screen with a placeholder Slack authentication method.
46 | 1. To configure authentication for your org, open `docker.env` and add your keys there for the identity providers you will be using.
47 |
48 | ## Customizing your install
49 |
50 | Configuration for your installation of Outline is located in `docker.env`. Here, you can set up authentication (SSO and SAML), database, and file storage.
51 |
52 | If you are using your own database and file storage, you can optimize your install footprint by modifying `docker-compose.yml` and removing the dependencies on `postgres` and `minio`.
53 |
54 | ## Configuring SAML
55 |
56 | Adding SAML to your outline install is a simple configuration change. Open `docker.env` and modify `SAML_SSO_ENDPOINT` and `SAML_CERT` to values provided by your IdP.
57 |
58 | For an example setup guide using One Login, see the article below:
59 | - [One Login Setup](https://wiki.generaloutline.com/share/13dec265-c002-4c73-8025-75981f29b0d0/doc/onelogin-setup-hCmJIfmAjt)
60 |
61 | ---
62 |
63 | ## Updating your instance
64 |
65 | When there is patch or an update available for Outline, you can apply the updates to your instance by stopping your server and running the included update script: `./update.sh`. We recommend backing up your database before updating.
66 |
67 | ## Docker reference
68 |
69 | Below is a list of common Docker commands. Note that you may need to prefix with `sudo`, depending on your setup
70 |
71 | | Command | Description
72 | | ----------------------------|-------------------------------------------------------------------------------------------------------------------------------|
73 | | `docker-compose up -d` | Starts containers `-d` means "detached", so containers continue to run in the background. |
74 | | `docker-compose down` | Stops containers |
75 | | `docker-compose logs -f` | Stream all container logs to stdout |
76 |
--------------------------------------------------------------------------------
/database-setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | sudo docker-compose up postgres -d
4 | sudo docker-compose run --rm outline yarn sequelize db:create --env=production-ssl-disabled
5 | sudo docker-compose run --rm outline yarn sequelize db:migrate --env=production-ssl-disabled
6 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 |
4 | outline:
5 | image: outlinewiki/outline-enterprise
6 | env_file: ./docker.env
7 | ports:
8 | - "3000:3000"
9 | depends_on:
10 | - postgres
11 | - redis
12 | - storage
13 |
14 | redis:
15 | image: redis
16 | env_file: ./docker.env
17 | ports:
18 | - "6379:6379"
19 | volumes:
20 | - ./redis.conf:/redis.conf
21 | command: ["redis-server", "/redis.conf"]
22 | healthcheck:
23 | test: ["CMD", "redis-cli", "ping"]
24 | interval: 10s
25 | timeout: 30s
26 | retries: 3
27 |
28 | postgres:
29 | image: postgres
30 | env_file: ./docker.env
31 | ports:
32 | - "5432:5432"
33 | volumes:
34 | - database-data:/var/lib/postgresql/data
35 | healthcheck:
36 | test: ["CMD", "pg_isready -U user"]
37 | interval: 30s
38 | timeout: 20s
39 | retries: 3
40 |
41 | storage:
42 | image: minio/minio
43 | env_file: ./docker.env
44 | ports:
45 | - "9000:9000"
46 | entrypoint: sh
47 | command: -c 'mkdir -p /opt/uploads && /usr/bin/minio server /opt'
48 | deploy:
49 | restart_policy:
50 | condition: on-failure
51 | volumes:
52 | - storage-data:/data
53 | healthcheck:
54 | test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
55 | interval: 30s
56 | timeout: 20s
57 | retries: 3
58 |
59 | https-portal:
60 | image: steveltn/https-portal
61 | env_file: ./docker.env
62 | ports:
63 | - '80:80'
64 | - '443:443'
65 | links:
66 | - outline
67 | - storage
68 | restart: always
69 | volumes:
70 | - https-portal-data:/var/lib/https-portal
71 | healthcheck:
72 | test: ["CMD", "service", "nginx", "status"]
73 | interval: 30s
74 | timeout: 20s
75 | retries: 3
76 |
77 | volumes:
78 | https-portal-data:
79 | storage-data:
80 | database-data:
81 |
--------------------------------------------------------------------------------
/docker-setup:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | minioAccessKeyId=$(cat /dev/urandom | base64 | head -c 64)
4 | minioSecretKey=$(cat /dev/urandom | base64 | head -c 64)
5 | postgresPassword=$(openssl rand -hex 64)
6 | encryptionKey=$(openssl rand -hex 32)
7 | utilsSecret=$(openssl rand -hex 32)
8 | publicIpAddress=$(dig +short myip.opendns.com @resolver1.opendns.com)
9 |
10 | echo "Hey, let's get started setting up Outline on-premise."
11 | echo
12 | echo "First up: Do you have a fully qualified domain pointed at this server?"
13 | echo
14 | echo "If you have a domain that points to your Outline server, the installation script can request a HTTPS certificate from LetsEncrypt automatically. If you do not provide one, a self-signed certificate will be used instead."
15 | echo
16 | echo "Now is a good time to point your fully qualified domain at this server's public address. Make sure the fully qualified domain resolves to the correct IP address before proceeding."
17 | echo
18 | echo "Please type your fully qualified domain below. Press enter to skip."
19 | read -p "Enter it here: (default is your public ip address: ${publicIpAddress}) " hostname
20 |
21 | # If no hostname was entered then default to the public ip address
22 | if [ -z "$hostname" ]; then
23 | if [ -z "$publicIpAddress" ]; then
24 | echo "IP address could not be determined and a hostname was not provided, sorry we have to exit."
25 | exit 1
26 | fi
27 | hostname=$publicIpAddress
28 | fi
29 |
30 | # If an env file exists then back it up in case they accidentally reran this
31 | # script, and then create a new blank file
32 | if [ -f ./docker.env ]; then
33 | mv docker.env docker.env.$(date +"%Y-%m-%d_%H-%M-%S")
34 | fi
35 | touch docker.env
36 |
37 | echo "## Enterprise License" >> docker.env
38 | echo "# Obtain a license key by contacting support, hello@getoutline.com" >> docker.env
39 | echo "LICENSE_KEY=" >> docker.env
40 | echo '' >> docker.env
41 |
42 | echo '## Set node environment to production' >> docker.env
43 | echo 'NODE_ENV=production' >> docker.env
44 | echo 'DEBUG=events,emails,mailer,utils,commands,server,services' >> docker.env
45 | echo '' >> docker.env
46 |
47 | echo '## Encryption key for passwords etc in the database' >> docker.env
48 | echo "SECRET_KEY=${encryptionKey}" >> docker.env
49 | echo '' >> docker.env
50 | echo '## Access key for admin utilities over API' >> docker.env
51 | echo "UTILS_SECRET=${utilsSecret}" >> docker.env
52 | echo '' >> docker.env
53 |
54 | echo '## Storage credentials' >> docker.env
55 | echo '# If you want to connect to a Postgres database on another host make sure' >> docker.env
56 | echo '# to use SSL and comment out or remove the PGSSLMODE line below' >> docker.env
57 | echo "DATABASE_URL=postgres://user:${postgresPassword}@postgres:5432/outline" >> docker.env
58 | echo 'PGSSLMODE=disable' >> docker.env
59 | echo '' >> docker.env
60 | echo "POSTGRES_USER=user" >> docker.env
61 | echo "POSTGRES_PASSWORD=${postgresPassword}" >> docker.env
62 | echo '' >> docker.env
63 | echo 'REDIS_URL=redis://redis:6379' >> docker.env
64 | echo '' >> docker.env
65 |
66 | echo '## Nginx server' >> docker.env
67 | echo "WEBSOCKET=true" >> docker.env
68 | echo "ACCESS_LOG=stdout" >> docker.env
69 | if [ "$hostname" == "$publicIpAddress" ]; then
70 | echo "STAGE=local" >> docker.env
71 | echo "# Change '${hostname}' to wiki.yourcompany.com to set up SSL" >> docker.env
72 | else
73 | echo "# Change stage=local to use a self-signed SSL certificate" >> docker.env
74 | echo "STAGE=production" >> docker.env
75 | fi
76 | echo "# The fully qualified hostname in the following two variables must match" >> docker.env
77 | echo "DOMAINS=${hostname} -> http://outline:3000" >> docker.env
78 | echo "URL=https://${hostname}" >> docker.env
79 | echo '' >> docker.env
80 |
81 | echo "# Third party signin credentials, at least one of EITHER Google OR Slack is" >> docker.env
82 | echo "# required for a working installation or you'll have no sign-in options." >> docker.env
83 | echo "" >> docker.env
84 | echo "# To configure Slack auth, you'll need to create an Application at" >> docker.env
85 | echo "# => https://api.slack.com/apps" >> docker.env
86 | echo '#' >> docker.env
87 | echo '# When configuring the Client ID, add a redirect URL under "OAuth & Permissions":' >> docker.env
88 | echo "# https:///auth/slack.callback" >> docker.env
89 | echo "SLACK_KEY=" >> docker.env
90 | echo "SLACK_SECRET=" >> docker.env
91 | echo '' >> docker.env
92 | echo "# To configure Google auth, you'll need to create an OAuth Client ID at" >> docker.env
93 | echo "# => https://console.cloud.google.com/apis/credentials" >> docker.env
94 | echo '#' >> docker.env
95 | echo "# When configuring the Client ID, add an Authorized redirect URI:" >> docker.env
96 | echo "# https:///auth/google.callback" >> docker.env
97 | echo "GOOGLE_CLIENT_ID=" >> docker.env
98 | echo "GOOGLE_CLIENT_SECRET=" >> docker.env
99 | echo '' >> docker.env
100 |
101 | echo "## File Storage" >> docker.env
102 | echo "MINIO_ROOT_USER=${minioAccessKeyId}" >> docker.env
103 | echo "MINIO_ROOT_PASSWORD=${minioSecretKey}" >> docker.env
104 | echo "MINIO_REGION_NAME=us-east-1" >> docker.env
105 | echo '' >> docker.env
106 |
107 | echo "# For details on setting up Outline to use AWS S3 instead of Minio, see:" >> docker.env
108 | echo "# https://wiki.generaloutline.com/share/125de1cc-9ff6-424b-8415-0d58c809a40f" >> docker.env
109 | echo "# Set AWS_S3_FORCE_PATH_STYLE to true if using minio, false if using S3" >> docker.env
110 | echo "AWS_S3_FORCE_PATH_STYLE=true" >> docker.env
111 | echo "AWS_ACCESS_KEY_ID=${minioAccessKeyId}" >> docker.env
112 | echo "AWS_SECRET_ACCESS_KEY=${minioSecretKey}" >> docker.env
113 | echo "AWS_REGION=us-east-1" >> docker.env
114 | echo "AWS_S3_UPLOAD_BUCKET_URL=https://mybucketname.s3.us-east-1.amazonaws.com" >> docker.env
115 | echo "AWS_S3_UPLOAD_BUCKET_NAME=mybucketname" >> docker.env
116 | echo "AWS_S3_UPLOAD_MAX_SIZE=26214400" >> docker.env
117 | echo "AWS_S3_ACL=private" >> docker.env
118 | echo '' >> docker.env
119 |
120 | echo "# To support sending outgoing transactional emails such as 'document updated' or" >> docker.env
121 | echo "# 'youve been invited' you'll need to provide authentication for an SMTP server." >> docker.env
122 | echo "# This is optional and not included in this package." >> docker.env
123 | echo "SMTP_HOST=" >> docker.env
124 | echo "SMTP_PORT=" >> docker.env
125 | echo "SMTP_USERNAME=" >> docker.env
126 | echo "SMTP_PASSWORD=" >> docker.env
127 | echo "SMTP_FROM_EMAIL=" >> docker.env
128 | echo "SMTP_REPLY_EMAIL=" >> docker.env
129 | echo '' >> docker.env
130 |
131 | echo "All done, to enter your license key and set up authentication take a look in docker.env"
132 |
--------------------------------------------------------------------------------
/install-docker:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | command_present() {
3 | type "$1" >/dev/null 2>&1
4 | }
5 |
6 | if ! command_present wget && command_present yum; then
7 | sudo yum install wget
8 | fi
9 | wget -qO- https://get.docker.com/ | sh
--------------------------------------------------------------------------------
/install-docker-compose:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | sudo -E curl -L https://github.com/docker/compose/releases/download/1.28.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
4 | sudo chmod +x /usr/local/bin/docker-compose
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | ./install-docker
2 | ./install-docker-compose
3 | ./docker-setup
4 |
--------------------------------------------------------------------------------
/redis.conf:
--------------------------------------------------------------------------------
1 | maxmemory 256mb
2 | maxmemory-policy allkeys-lru
3 |
--------------------------------------------------------------------------------
/update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | sudo docker-compose pull outline
4 | sudo docker-compose run --rm outline yarn sequelize db:migrate --env=production-ssl-disabled
5 |
--------------------------------------------------------------------------------