From b5895d48b82321122ee0bf042433e810b4da5b06 Mon Sep 17 00:00:00 2001 From: Noe Thalheim Date: Fri, 1 Oct 2021 11:20:07 +0200 Subject: [PATCH 1/7] feat(external-db): add support for external db --- containers/set-links | 27 ++++++++++++++++++++++ containers/update-env | 43 +++++++++++++++++++++++++++--------- containers/web_and_redis.yml | 32 +++++++++++++++++++++++++++ functions | 33 ++++++++++++++++++++++++--- internal-functions | 40 +++++++++++++++++++++++++++++---- 5 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 containers/set-links create mode 100644 containers/web_and_redis.yml diff --git a/containers/set-links b/containers/set-links new file mode 100644 index 0000000..0e6b3dd --- /dev/null +++ b/containers/set-links @@ -0,0 +1,27 @@ +#!/usr/bin/python3 + +import sys +from yaml import load, dump + +try: + from yaml import CLoader as Loader, CDumper as Dumper +except ImportError: + from yaml import Loader, Dumper + +if __name__ == "__main__": + config_file = sys.argv[1] + alias = sys.argv[2] + name = sys.argv[3] + + with open(config_file, "r") as f: + data = load(f, Loader=Loader) + links = [ + { + "link": { + "alias": alias, + "name": name, + } + }, + ] + data['links'] = links + print(dump(data, Dumper=Dumper)) diff --git a/containers/update-env b/containers/update-env index 6807af5..6e689aa 100755 --- a/containers/update-env +++ b/containers/update-env @@ -19,17 +19,40 @@ if __name__ == "__main__": smtp_port = sys.argv[5] smtp_user_name = sys.argv[6] smtp_password = sys.argv[7] + db_host = sys.argv[8] + db_port = sys.argv[9] + db_name = sys.argv[10] + db_username = sys.argv[11] + db_password = sys.argv[12] with open(config_file, "r") as f: data = load(f, Loader=Loader) - data["env"] = { - "LANG": lang, - "DISCOURSE_DEFAULT_LOCALE": default_locale, - "DISCOURSE_HOSTNAME": hostname, - "DISCOURSE_DEVELOPER_EMAILS": developer_emails, - "DISCOURSE_SMTP_ADDRESS": smtp_address, - "DISCOURSE_SMTP_PORT": smtp_port, - "DISCOURSE_SMTP_USER_NAME": smtp_user_name, - "DISCOURSE_SMTP_PASSWORD": smtp_password, - } + if db_host == "": + data["env"] = { + "LANG": lang, + "DISCOURSE_DEFAULT_LOCALE": default_locale, + "DISCOURSE_HOSTNAME": hostname, + "DISCOURSE_DEVELOPER_EMAILS": developer_emails, + "DISCOURSE_SMTP_ADDRESS": smtp_address, + "DISCOURSE_SMTP_PORT": smtp_port, + "DISCOURSE_SMTP_USER_NAME": smtp_user_name, + "DISCOURSE_SMTP_PASSWORD": smtp_password, + } + else: + data["env"] = { + "LANG": lang, + "DISCOURSE_DEFAULT_LOCALE": default_locale, + "DISCOURSE_HOSTNAME": hostname, + "DISCOURSE_DEVELOPER_EMAILS": developer_emails, + "DISCOURSE_SMTP_ADDRESS": smtp_address, + "DISCOURSE_SMTP_PORT": smtp_port, + "DISCOURSE_SMTP_USER_NAME": smtp_user_name, + "DISCOURSE_SMTP_PASSWORD": smtp_password, + "DISCOURSE_DB_HOST": db_host, + "DISCOURSE_DB_PORT": db_port, + "DISCOURSE_DB_NAME": db_name, + "DISCOURSE_DB_PASSWORD": db_password, + "DISCOURSE_DB_USERNAME": db_username, + } + print(dump(data, Dumper=Dumper)) diff --git a/containers/web_and_redis.yml b/containers/web_and_redis.yml new file mode 100644 index 0000000..3fbd8cf --- /dev/null +++ b/containers/web_and_redis.yml @@ -0,0 +1,32 @@ +templates: + - "templates/redis.template.yml" + - "templates/web.template.yml" + - "templates/web.ratelimited.template.yml" +params: + db_default_text_search_config: "pg_catalog.english" +links: + link: { alias: '', name: '' } +env: + LANG: en_US.UTF-8 + DISCOURSE_DEFAULT_LOCALE: en + DISCOURSE_HOSTNAME: 'discourse.dokku.me' + DISCOURSE_DEVELOPER_EMAILS: 'me@example.com,you@example.com' + DISCOURSE_SMTP_ADDRESS: smtp.example.com + DISCOURSE_SMTP_PORT: 587 + DISCOURSE_SMTP_USER_NAME: user@example.com + DISCOURSE_SMTP_PASSWORD: pa$$word + DISCOURSE_DB_HOST: localhost + DISCOURSE_DB_PORT: 5432 + DISCOURSE_DB_NAME: discourse + DISCOURSE_DB_USERNAME: postgres + DISCOURSE_DB_PASSWORD: pa$$word + +hooks: + after_code: + - exec: + cd: $home/plugins + cmd: + - git clone https://github.com/discourse/docker_manager.git +run: + - exec: echo "Beginning of custom commands" + - exec: echo "End of custom commands" diff --git a/functions b/functions index aa25b09..a59eefd 100755 --- a/functions +++ b/functions @@ -11,7 +11,12 @@ discourse_create_app() { SMTP_ADDRESS="$4" \ SMTP_PORT="$5" \ SMTP_USERNAME="$6" \ - SMTP_PASSWORD="$7" + SMTP_PASSWORD="$7" \ + DB_HOST="$8" \ + DB_PORT="$9" + DB_NAME="${10}" \ + DB_USERNAME="${11}" \ + DB_PASSWORD="${12}" \ ## TODO: call plugin functions instead of dokku if grep -qxF "$(dokku apps:list 2> /dev/null)" <<< "$APP_NAME"; then @@ -21,9 +26,16 @@ discourse_create_app() { echo "$APP_NAME" >> "$DISCOURSE_APPS" fi + [[ -z "$APP_NAME" ]] && dokku_log_fail "Missing app argument" + WEB_ONLY=$(fn-get-input "Setup with an external database?" "false") + + if [ "$WEB_ONLY" = "true" ]; then + export CONTAINER_TYPE="web_and_redis" + export DISCOURSE_CONTAINER_CONFIG_NAME="discourse_$CONTAINER_TYPE" + fi + fn-create-default-discourse-container-config "$APP_NAME" - [[ -z "$APP_NAME" ]] && dokku_log_fail "Missing app argument" [[ -z "$HOSTNAME" ]] && HOSTNAME=$(fn-get-input "Hostname for your Discourse?" "$(fn-get-env-config DISCOURSE_HOSTNAME)") [[ -z "$DEVELOPER_EMAILS" ]] && DEVELOPER_EMAILS=$(fn-get-input "Email address for admin account(s)?" "$(fn-get-env-config DISCOURSE_DEVELOPER_EMAILS)") [[ -z "$SMTP_ADDRESS" ]] && SMTP_ADDRESS=$(fn-get-input "SMTP server address?" "$(fn-get-env-config DISCOURSE_SMTP_ADDRESS)") @@ -31,6 +43,15 @@ discourse_create_app() { [[ -z "$SMTP_USERNAME" ]] && SMTP_USERNAME=$(fn-get-input "SMTP user name?" "$(fn-get-env-config DISCOURSE_SMTP_USER_NAME)") [[ -z "$SMTP_PASSWORD" ]] && SMTP_PASSWORD=$(fn-get-input "SMTP password?" "$(fn-get-env-config DISCOURSE_SMTP_PASSWORD)") + if [ "$WEB_ONLY" = "true" ]; then + [[ -z "$DB_HOST" ]] && DB_HOST=$(fn-get-input "Postgres server address?" "$(fn-get-env-config DISCOURSE_DB_HOST)") + [[ -z "$DB_PORT" ]] && DB_PORT=$(fn-get-input "Postgres server port?" "$(fn-get-env-config DISCOURSE_DB_PORT)") + [[ -z "$DB_NAME" ]] && DB_NAME=$(fn-get-input "Postgres database name?" "$(fn-get-env-config DISCOURSE_DB_NAME)") + [[ -z "$DB_USERNAME" ]] && DB_USERNAME=$(fn-get-input "Postgres database user name?" "$(fn-get-env-config DISCOURSE_DB_USERNAME)") + [[ -z "$DB_PASSWORD" ]] && DB_PASSWORD=$(fn-get-input "Postgres database password?" "$(fn-get-env-config DISCOURSE_DB_PASSWORD)") + [[ -z "$DB_LINK" ]] && DB_PASSWORD=$(fn-get-input "Postgres container link" "") + fi + local APP_STORAGE_ROOT="$STORAGE_ROOT/$APP_NAME" fn-update-discourse-container-config "$APP_NAME" \ @@ -40,7 +61,13 @@ discourse_create_app() { "$SMTP_ADDRESS" \ "$SMTP_PORT" \ "$SMTP_USERNAME" \ - "$SMTP_PASSWORD" + "$SMTP_PASSWORD" \ + "$DB_HOST" \ + "$DB_PORT" \ + "$DB_NAME" \ + "$DB_USERNAME" \ + "$DB_PASSWORD" \ + "$DB_LINK" fn-update-discourse-build-files diff --git a/internal-functions b/internal-functions index e87e334..7b74b63 100644 --- a/internal-functions +++ b/internal-functions @@ -38,6 +38,17 @@ fn-update-discourse-build-files() { fi } +fn-update-discourse-config-set-links() { + declare APP_NAME="$1" APP_STORAGE_ROOT="$2" DB_HOST="$3" DB_LINK="$4" + local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml" + local SET_VOLUMES_BIN_PATH="$PLUGIN_AVAILABLE_PATH/discourse/containers/set-links" + local UPDATED_CONFIG + UPDATED_CONFIG=$("$SET_VOLUMES_BIN_PATH" "$CONFIG_FILE_PATH" "$APP_STORAGE_ROOT" "$DB_HOST" $DB_LINK"" 2> /dev/null) + [[ -z "$UPDATED_CONFIG" ]] && dokku_log_fail "Error setting links in config" + echo "$UPDATED_CONFIG" > "$CONFIG_FILE_PATH" + dokku_log_info1 "Updated '$APP_NAME' discourse links" +} + fn-update-discourse-config-set-volumes() { declare APP_NAME="$1" APP_STORAGE_ROOT="$2" local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml" @@ -56,11 +67,17 @@ fn-update-discourse-config-env() { SMTP_ADDRESS="$4" \ SMTP_PORT="$5" \ SMTP_USER_NAME="$6" \ - SMTP_PASSWORD="$7" + SMTP_PASSWORD="$7" \ + DB_HOST="$8" \ + DB_PORT="$9" + DB_NAME="${10}" \ + DB_USERNAME="${11}" \ + DB_PASSWORD="${12}" + local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml" local UPDATE_ENV_BIN_PATH="$PLUGIN_AVAILABLE_PATH/discourse/containers/update-env" local UPDATED_CONFIG - UPDATED_CONFIG=$("$UPDATE_ENV_BIN_PATH" "$CONFIG_FILE_PATH" "$HOSTNAME" "$DEVELOPER_EMAILS" "$SMTP_ADDRESS" "$SMTP_PORT" "$SMTP_USER_NAME" "$SMTP_PASSWORD" 2> /dev/null) + UPDATED_CONFIG=$("$UPDATE_ENV_BIN_PATH" "$CONFIG_FILE_PATH" "$HOSTNAME" "$DEVELOPER_EMAILS" "$SMTP_ADDRESS" "$SMTP_PORT" "$SMTP_USER_NAME" "$SMTP_PASSWORD" "$DB_HOST" "$DB_PORT" "$DB_NAME" "$DB_USERNAME" "$DB_PASSWORD" 2> /dev/null) [[ -z "$UPDATED_CONFIG" ]] && dokku_log_fail "Error setting env in config" echo "$UPDATED_CONFIG" > "$CONFIG_FILE_PATH" dokku_log_info1 "Updated '$APP_NAME' discourse env" @@ -83,7 +100,13 @@ fn-update-discourse-container-config() { SMTP_ADDRESS="$5" \ SMTP_PORT="$6" \ SMTP_USER_NAME="$7" \ - SMTP_PASSWORD="$8" + SMTP_PASSWORD="$8" \ + DB_HOST="$9" \ + DB_PORT="${10}" + DB_NAME="${11}" \ + DB_USERNAME="${12}" \ + DB_PASSWORD="${13}" \ + DB_LINK="${14}" fn-update-discourse-config-env \ "$APP_NAME" \ @@ -92,10 +115,19 @@ fn-update-discourse-container-config() { "$SMTP_ADDRESS" \ "$SMTP_PORT" \ "$SMTP_USER_NAME" \ - "$SMTP_PASSWORD" + "$SMTP_PASSWORD" \ + "$DB_HOST" \ + "$DB_PORT" \ + "$DB_NAME" \ + "$DB_USERNAME" \ + "$DB_PASSWORD" fn-update-discourse-config-set-volumes "$APP_NAME" "$APP_STORAGE_ROOT" + if [ $CONTAINER_TYPE = "web_and_redis" ]; then + fn-update-discourse-config-set-links "$APP_NAME" "$APP_STORAGE_ROOT" "$DB_HOST" "$DB_LINK" + fi + local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml" dokku_log_info2 "Container config updated at location $CONFIG_FILE_PATH" } From 417dd5847b6351cf4e4b8d519a210a5fb680d604 Mon Sep 17 00:00:00 2001 From: Noe Thalheim Date: Fri, 1 Oct 2021 13:14:32 +0200 Subject: [PATCH 2/7] fix: correct variable name --- functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions b/functions index a59eefd..cb6de8e 100755 --- a/functions +++ b/functions @@ -49,7 +49,7 @@ discourse_create_app() { [[ -z "$DB_NAME" ]] && DB_NAME=$(fn-get-input "Postgres database name?" "$(fn-get-env-config DISCOURSE_DB_NAME)") [[ -z "$DB_USERNAME" ]] && DB_USERNAME=$(fn-get-input "Postgres database user name?" "$(fn-get-env-config DISCOURSE_DB_USERNAME)") [[ -z "$DB_PASSWORD" ]] && DB_PASSWORD=$(fn-get-input "Postgres database password?" "$(fn-get-env-config DISCOURSE_DB_PASSWORD)") - [[ -z "$DB_LINK" ]] && DB_PASSWORD=$(fn-get-input "Postgres container link" "") + [[ -z "$DB_LINK" ]] && DB_LINK=$(fn-get-input "Postgres container link" "") fi local APP_STORAGE_ROOT="$STORAGE_ROOT/$APP_NAME" From 76729a0b7081a559a5e20e534cc052c3311572c6 Mon Sep 17 00:00:00 2001 From: Noe Thalheim Date: Fri, 1 Oct 2021 13:17:37 +0200 Subject: [PATCH 3/7] fix: remove variable --- internal-functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal-functions b/internal-functions index 7b74b63..4373ec8 100644 --- a/internal-functions +++ b/internal-functions @@ -43,7 +43,7 @@ fn-update-discourse-config-set-links() { local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml" local SET_VOLUMES_BIN_PATH="$PLUGIN_AVAILABLE_PATH/discourse/containers/set-links" local UPDATED_CONFIG - UPDATED_CONFIG=$("$SET_VOLUMES_BIN_PATH" "$CONFIG_FILE_PATH" "$APP_STORAGE_ROOT" "$DB_HOST" $DB_LINK"" 2> /dev/null) + UPDATED_CONFIG=$("$SET_VOLUMES_BIN_PATH" "$CONFIG_FILE_PATH" "$DB_HOST" $DB_LINK"" 2> /dev/null) [[ -z "$UPDATED_CONFIG" ]] && dokku_log_fail "Error setting links in config" echo "$UPDATED_CONFIG" > "$CONFIG_FILE_PATH" dokku_log_info1 "Updated '$APP_NAME' discourse links" From f6f1efa985ce3efbdfe144b3906b263c02978f7d Mon Sep 17 00:00:00 2001 From: Noe Thalheim Date: Mon, 4 Oct 2021 10:57:35 +0200 Subject: [PATCH 4/7] chore: update readme --- README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1b4005e..6381e39 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # dokku-discourse -![Test](https://github.com/badsyntax/dokku-discourse/workflows/Test/badge.svg) -![Publish](https://github.com/badsyntax/dokku-discourse/workflows/Publish/badge.svg) +![Test](https://github.com/digital-sustainability/dokku-discourse/workflows/Test/badge.svg) +![Publish](https://github.com/digital-sustainability/dokku-discourse/workflows/Publish/badge.svg) Manages discourse apps on your dokku server. @@ -9,10 +9,10 @@ Manages discourse apps on your dokku server. ```sh # For dokku >= v0.22.0 -dokku plugin:install https://github.com/badsyntax/dokku-discourse.git +dokku plugin:install https://github.com/digital-sustainability/dokku-discourse.git # For dokku < v0.22.0 -dokku plugin:install https://github.com/badsyntax/dokku-discourse.git --committish 0.2.1 +dokku plugin:install https://github.com/digital-sustainability/dokku-discourse.git --committish 0.2.1 ``` ## Plugin update @@ -36,16 +36,65 @@ discourse:list # Lists discourse apps ### Create a new discourse app -Each discourse app is a separate _standalone_ discourse instance. +#### Standaone + +To setup a new discourse app as a separate _standalone_ discourse instance run ```sh dokku discourse:create discourse-app ``` +and choose _false_ in the first prompt. + *A new docker image will be built and this process can take some time.* You'll be prompted for various discourse configuration values. +#### External Database + +To setup a new discourse app with an external database first create a container + +```sh +dokku apps:create discourse-app +``` + +use [dokku-postgres](https://github.com/dokku/dokku-postgres) to create a new postgres service + +```sh +dokku postgres:create discourse-db +``` + +link the container with the postgres service + +```sh +dokku postgres:link discourse-db discourse-app +``` + +this will set an env DATABASE_URL with the following structure: + +```sh +postgres://postgres:@dokku-postgres-discourse-db:5432/discourse_db +``` + +you'll be asked to specify a docker link during setup, to get the necessary information run + +```sh +dokku docker-options:report discourse-app +``` +you should get something like: + +```sh +--link dokku.postgres.discourse-db:dokku-postgres-discourse-db +``` + +finally start the setup and choose _true_ in the first prompt + +```sh +dokku discourse:create discourse-app +``` + +use the database information from `DATABASE_URL` and `docker-options` to complete the setup. + Data will be stored in location `/var/lib/dokku/data/storage/APP_NAME`. Once your app is built & deployed, you can treat it as any other dokku app. You should use the [dokku-letsencrypt](https://github.com/dokku/dokku-letsencrypt) plugin for adding TLS. @@ -54,11 +103,13 @@ Continue with the offical [discourse install instructions](https://github.com/di ### Customise the discourse container config -A discourse container config file is created when a discourse app is created. The config is based on [standalone.yml](https://github.com/discourse/discourse_docker/blob/master/samples/standalone.yml). +A discourse container config file is created when a discourse app is created. Depeding on your chooise the config is based on [standalone.yml](https://github.com/discourse/discourse_docker/blob/master/samples/standalone.yml) or [web_only](https://github.com/discourse/discourse_docker/blob/master/samples/web_only.yml) including the redis template. + +You can edit the config at `/home/dokku/APP_NAME/discourse_standalone.yml` or `/home/dokku/APP_NAME/discourse_web_and_redis.yml`. Don't make any changes to the `volumes` section, but feel free to change anything else. -You can edit the config at `/home/dokku/APP_NAME/discourse_standalone.yml`. Don't make any changes to the `volumes` section, but feel free to change anything else. +*Important:* Changes to the `env` section will overwritten. -After making change be sure to run `dokku discourse:create ` to rebuild and re-deploy the discourse app. +After making change be sure to run `dokku discourse:create ` to rebuild and re-deploy the discourse app. ### Upgrade a discourse app @@ -138,6 +189,7 @@ To complete the restoration, you'll need install plugins that were previously in - https://medium.com/batary/deploying-discourse-with-dokku-5eec28e2ad8b - https://gist.github.com/julienma/a101a72fdd97932bf28909633f45c7be +- https://github.com/badsyntax/dokku-discourse ## Development From 83c6347fba069e862ef70f37fdea6136d72dac68 Mon Sep 17 00:00:00 2001 From: Noe Thalheim Date: Tue, 22 Feb 2022 10:54:46 +0100 Subject: [PATCH 5/7] fix: set correct file permission --- containers/set-links | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 containers/set-links diff --git a/containers/set-links b/containers/set-links old mode 100644 new mode 100755 From c4328300a54ec2a3b477be529c9dbea6ecce95f1 Mon Sep 17 00:00:00 2001 From: Noe Thalheim Date: Fri, 25 Feb 2022 11:45:09 +0100 Subject: [PATCH 6/7] fix: discard stdout For some, as of today, unknown reason is the output of ./launcher start-cmd redirected to stderr. Therefore we discard stdout entirely. --- internal-functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal-functions b/internal-functions index 4373ec8..ce439b6 100644 --- a/internal-functions +++ b/internal-functions @@ -224,7 +224,7 @@ fn-configure-app() { local RUN_ARGS MAC_ADDRESS SHM_SIZE ENV_VARS - RUN_ARGS=$(fn-get-run-args "$APP_NAME" 2>&1) + RUN_ARGS=$(fn-get-run-args "$APP_NAME" 2>&1 >/dev/null) MAC_ADDRESS=$(echo "$RUN_ARGS" | sed -r 's/.*--mac-address(=| )([^ ]+).*/\2/') SHM_SIZE=$(echo "$RUN_ARGS" | sed -r 's/.*--shm-size(=| )([^ ]+).*/\2/') ENV_VARS=$(fn-get-env-vars-from-run-args "$RUN_ARGS") From 136681e6a695f8618d88e4528dc353050ac8603f Mon Sep 17 00:00:00 2001 From: Noe Thalheim Date: Tue, 9 May 2023 11:28:42 +0200 Subject: [PATCH 7/7] fix(upgrade): test if app has external DB otherwise upgrade will pick the wrong yml file --- internal-functions | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal-functions b/internal-functions index ce439b6..7840598 100644 --- a/internal-functions +++ b/internal-functions @@ -192,6 +192,13 @@ fn-install-plugin() { declare APP_NAME="$1" PLUGIN_GIT_URL="$2" fn-discourse-config-add-plugin "$APP_NAME" "$PLUGIN_GIT_URL" local APP_STORAGE_ROOT="$STORAGE_ROOT/$APP_NAME" + + # if DATABASE_URL is present we're using an external DB + local DATABASE_URL=$(config_get "$APP_NAME" "DATABASE_URL") + if [ -n "$DATABASE_URL" ]; then + export CONTAINER_TYPE="web_and_redis" + export DISCOURSE_CONTAINER_CONFIG_NAME="discourse_$CONTAINER_TYPE" + fi fn-build-image "$APP_NAME" "$APP_STORAGE_ROOT" } @@ -203,6 +210,14 @@ fn-get-run-args() { fn-upgrade-app() { declare APP_NAME="$1" fn-update-discourse-build-files + + # if DATABASE_URL is present we're using an external DB + local DATABASE_URL=$(config_get "$APP_NAME" "DATABASE_URL") + if [ -n "$DATABASE_URL" ]; then + export CONTAINER_TYPE="web_and_redis" + export DISCOURSE_CONTAINER_CONFIG_NAME="discourse_$CONTAINER_TYPE" + fi + fn-build-image "$APP_NAME" }