captainVersion: 4 services: $$cap_appname-redis: image: redis:$$cap_redis_version volumes: - $$cap_appname-redis-data:/redis.conf restart: always caproverExtra: notExposeAsWebApp: 'true' $$cap_appname-db: image: postgres:$$cap_postgres_version volumes: - $$cap_appname-db-data:/var/lib/postgresql/data restart: always environment: POSTGRES_USER: $$cap_db_user POSTGRES_PASSWORD: $$cap_db_pass POSTGRES_DB: outline caproverExtra: notExposeAsWebApp: 'true' $$cap_appname: depends_on: - $$cap_appname-redis - $$cap_appname-db image: outlinewiki/outline:$$cap_outline_version environment: SECRET_KEY: $$cap_secret_key UTILS_SECRET: $$cap_utils_secret DATABASE_URL: postgres://$$cap_db_user:$$cap_db_pass@srv-captain--$$cap_appname-db:5432/outline DATABASE_URL_TEST: postgres://$$cap_db_user:$$cap_db_pass@srv-captain--$$cap_appname-db:5432/outline-test PGSSLMODE: disable REDIS_URL: redis://srv-captain--$$cap_appname-redis:6379 URL: https://$$cap_appname.$$cap_root_domain PORT: '80' AWS_S3_UPLOAD_BUCKET_URL: $$cap_s3_storage_url AWS_REGION: $$cap_s3_storage_region AWS_S3_UPLOAD_BUCKET_NAME: $$cap_s3_storage_bucket_name AWS_ACCESS_KEY_ID: $$cap_s3_storage_access_key_id AWS_SECRET_ACCESS_KEY: $$cap_s3_storage_secret_access_key AWS_S3_UPLOAD_MAX_SIZE: '26214400' AWS_S3_FORCE_PATH_STYLE: true AWS_S3_ACL: private OIDC_CLIENT_ID: $$cap_oidc_client_id OIDC_CLIENT_SECRET: $$cap_oidc_client_secret OIDC_AUTH_URI: $$cap_oidc_auth_uri OIDC_TOKEN_URI: $$cap_oidc_token_uri OIDC_USERINFO_URI: $$cap_oidc_userinfo_uri OIDC_USERNAME_CLAIM: preferred_username OIDC_DISPLAY_NAME: OpenID OIDC_SCOPES: 'openid profile email' SLACK_KEY: $$cap_slack_key SLACK_SECRET: $$cap_slack_secret GOOGLE_CLIENT_ID: $$cap_google_client_id GOOGLE_CLIENT_SECRET: $$cap_google_client_secret FORCE_HTTPS: 'false' ENABLE_UPDATES: 'false' DEBUG: http SMTP_HOST: $$cap_smtp_host SMTP_PORT: $$cap_smtp_port SMTP_USERNAME: $$cap_smtp_username SMTP_PASSWORD: $$cap_smtp_password SMTP_FROM_EMAIL: $$cap_smtp_from_email SMTP_REPLY_EMAIL: $$cap_smtp_reply_email SMTP_TLS_CIPHERS: $$cap_smtp_tls_ciphers SMTP_SECURE: $$cap_smtp_secure DEFAULT_LANGUAGE: $$cap_default_language caproverOneClickApp: variables: - id: $$cap_outline_version label: Outline Version defaultValue: 0.64.3 description: Check out their page for the valid tags https://hub.docker.com/r/outlinewiki/outline/tags validRegex: /^([^\s^\/])+$/ - id: $$cap_postgres_version label: Postgres Version defaultValue: '14.4' description: Check out their page for the valid tags https://hub.docker.com/_/postgres?tab=tags validRegex: /^([^\s^\/])+$/ - id: $$cap_redis_version label: Redis Version defaultValue: 7.0.2 description: Check out their Docker page for the valid tags https://hub.docker.com/_/redis?tab=tags validRegex: /^([^\s^\/])+$/ - id: $$cap_secret_key label: SECRET_KEY description: 'Run this command to generate a key: `openssl rand -hex 32`' validRegex: /^([0-9a-f]){64}$/ - id: $$cap_utils_secret label: UTILS_SECRET description: 'Run this command to generate a key: `openssl rand -hex 32`' validRegex: /^([0-9a-f]){64}$/ - id: $$cap_db_user label: Database user defaultValue: outline_user validRegex: /^([a-zA-Z0-9_])+$/ - id: $$cap_db_pass label: Database password description: '' defaultValue: $$cap_gen_random_hex(20) validRegex: /.{8,}/ - id: $$cap_s3_storage_url label: S3 Storage compatible API URL for instance Minio, AWS, etc. description: 'NB: You can have your own S3 storage by using the Open Source Minio alternative (there is a Caprover one-click-apps for that)' defaultValue: https://YOUR_S3_STORAGE_PROVIDER_API_URL - id: $$cap_s3_storage_region label: S3 Storage region description: 'Name of the location of the server e.g. "us-west-rack2"' defaultValue: eu-east-1 - id: $$cap_s3_storage_bucket_name label: S3 Storage bucket name description: "Log into the Minio dashboard, then select the `Create Bucket` menu option to create a new bucket (e.g. named outline-data). Don't forget to add `Read and Write` policy to the bucket so the Outline app would be able to upload content" defaultValue: outline-data - id: $$cap_s3_storage_access_key_id label: S3 storage Access Key ID description: 'For instance in your Minio instance, create a new user called outline_user for the outline app with a new policy that grants full access inside the bucket (e.g. outlineAppFullAccess - see also https://wiki.generaloutline.com/share/125de1cc-9ff6-424b-8415-0d58c809a40f#h-iam-policy)' defaultValue: outline_user - id: $$cap_s3_storage_secret_access_key label: S3 storage Secret Access Key description: 'For instance in your Minio instance it correponds to the password/secret of above outline_user' - id: $$cap_oidc_client_id label: Client ID created in your Generic OIDC server (e.g. in Keycloak) description: 'E.g. for Keycloak: In the Clients section, create a new client application. Name the app outline_app for simplicity. Also, provide the Root URL where you have installed/planned to install Outline. After that, make sure `Access Type` is set to `confidential` and `Direct Access Grants Enabled` is `OFF` so the Oauth flow initiated by Outline can work as expected.' defaultValue: outline_app - id: $$cap_oidc_client_secret label: Secret for the corresponding Client ID description: 'Found in the Credentials tab in Keycloak' - id: $$cap_oidc_auth_uri label: Authorization Endpoint description: 'In the recent version of Keycloak, the path /auth/ is optional, and the default master realm is not recommended for anything else except managing Keycloak itself. For example you could name the realm `outline`: http://localhost:8080/realms/outline/protocol/openid-connect/auth' defaultValue: 'https://YOUR_IAM_PROVIDER_URL/realms/outline/protocol/openid-connect/auth' - id: $$cap_oidc_token_uri label: Token Management Endpoint description: 'For example with the realm named `outline`: http://localhost:8080/realms/outline/protocol/openid-connect/token' defaultValue: 'https://YOUR_IAM_PROVIDER_URL/realms/outline/protocol/openid-connect/token' - id: $$cap_oidc_userinfo_uri label: User Informations Endpoint description: 'For example with the realm named `outline`: http://localhost:8080/realms/outline/protocol/openid-connect/userinfo' defaultValue: 'https://YOUR_IAM_PROVIDER_URL/realms/outline/protocol/openid-connect/userinfo' - id: $$cap_slack_key label: Slack Key - id: $$cap_slack_secret label: Slack Secret - id: $$cap_google_client_id label: Google Client ID - id: $$cap_google_client_secret label: Google Client Secret - id: $$cap_smtp_host label: SMTP host description: 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 - id: $$cap_smtp_port label: SMTP port - id: $$cap_smtp_username label: SMTP username - id: $$cap_smtp_password label: SMTP password - id: $$cap_smtp_from_email label: SMTP from email - id: $$cap_smtp_reply_email label: SMTP reply email - id: $$cap_smtp_tls_ciphers label: SMTP TLS ciphers - id: $$cap_smtp_secure label: SMTP Secure defaultValue: true - id: $$cap_default_language label: The default interface language description: See translate.getoutline.com for a list of available language codes and their rough percentage translated. defaultValue: en_US instructions: start: > Outline is an open, extensible, wiki for your team built using React and Node.js. Outline requires an external authentication provider such as Google/Slack, etc. If you don't want to rely on those solutions you can use a generic OpenID Connect Server. For instance you can use the Open Source Keycloak alternative (there is a Caprover one-click-apps for that) IMPORTANT: You need to, at least, set one 3rd party login method, either Keycloak, Slack or Google end: > IMPORTANT: before you start using Outline, you need to 1) Enable HTTPS 2) Force HTTPS 3) Enable Websocket in $$cap_appname. 4) Run database migration `npm run sequelize:migrate` within the $$cap_appname docker container. ``` var preDeployFunction = async function (captainAppObj, dockerUpdateObject) { const DockerApi = require("./built/docker/DockerApi"); const api = new DockerApi.default(); const setServiceInstances = async (service, count) => { const inspection = await service.inspect(); const updateObject = { ...inspection.Spec, Mode: { Replicated: { Replicas: count } }, version: inspection.Version.Index }; await service.update(updateObject); }; const run = async args => { const imageName = dockerUpdateObject.TaskTemplate.ContainerSpec.Image; const env = captainAppObj.envVars.map(kv => kv.key + "=" + kv.value); const config = { Env: env, HostConfig: { AutoRemove: true, NetworkMode: captainAppObj.networks[0] } }; const [output] = await api.dockerode.run(imageName, args, process.stdout, config); if (output.StatusCode !== 0) { throw new Error(`Failed to run image ${imageName} with args ${args} (status code ${output.StatusCode}).`); } }; const service = api.dockerode.getService(dockerUpdateObject.Name); await setServiceInstances(service, 0); await run(["yarn", "sequelize:migrate", "--env=production-ssl-disabled"]); dockerUpdateObject.version = (await service.inspect()).Version.Index; return dockerUpdateObject; }; ``` You can customize more settings by environmental variables described here: https://github.com/outline/outline/blob/0deecfac446c37545e0787b3d32062e608a950ab/.env.sample IMPORTANT: It will take up to 2 minutes for it to be ready. Before that, you might see a 502 error page. displayName: Outline isOfficial: true description: An open, extensible, wiki for your team built using React and Node.js. documentation: Taken from https://github.com/outline/outline/blob/master/docker-compose.yml