├── .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**. sshscreen 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 | --------------------------------------------------------------------------------