#!/bin/bash # We use /bin/bash instead of /bin/sh because we need process substitution. # See https://www.shellcheck.net/wiki/SC3001 check_user_is_correct() { if [[ "$(id -u -n)" != "authgear" ]]; then printf 1>&2 "docker-entrypoint.sh is supposed to be run with the user authgear.\n" exit 1 fi } generate_password() { # We are going to use base64url to encode the generated bytes. # Since base64url encodes every 3 bytes into 4 base64 characters without padding, # The length of the random bytes must be a multiple of 3. # 33 bytes = 264 bits. head -c 33 /dev/urandom | basenc --base64url -w 0 } docker_authgearonce_check_immutable_environment_variables_are_set() { if [[ -z "$AUTHGEAR_ONCE_LICENSE_KEY" ]]; then printf 1>&2 "AUTHGEAR_ONCE_LICENSE_KEY must be set.\n" exit 1 fi if [[ -z "$AUTHGEAR_ONCE_LICENSE_EXPIRE_AT" ]]; then printf 1>&2 "AUTHGEAR_ONCE_LICENSE_EXPIRE_AT must be set.\n" exit 1 fi # AUTHGEAR_ONCE_LICENSEE_EMAIL is optional. if [[ -z "$AUTHGEAR_ONCE_MACHINE_FINGERPRINT" ]]; then printf 1>&2 "AUTHGEAR_ONCE_MACHINE_FINGERPRINT must be set.\n" exit 1 fi if [[ -z "$AUTHGEAR_ONCE_ADMIN_USER_EMAIL" ]]; then printf 1>&2 "AUTHGEAR_ONCE_ADMIN_USER_EMAIL must be set.\n" exit 1 fi if [[ -z "$AUTHGEAR_ONCE_ADMIN_USER_PASSWORD" ]]; then printf 1>&2 "AUTHGEAR_ONCE_ADMIN_USER_PASSWORD must be set.\n" exit 1 fi if [[ "$(printf "%s" "$AUTHGEAR_ONCE_ADMIN_USER_PASSWORD" | wc -c)" -lt 8 ]]; then printf 1>&2 "AUTHGEAR_ONCE_ADMIN_USER_PASSWORD must be at least 8 characters long.\n" exit 1 fi } check_http_origin_is_set() { name="AUTHGEAR_HTTP_ORIGIN_$1" value="${!name}" if [[ -z "$value" ]]; then printf 1>&2 "%s must be set. This will be used to configure nginx and certbot.\n" "$name" exit 1 fi } check_http_origin_not_equal_to_each_other() { name1="AUTHGEAR_HTTP_ORIGIN_$1" name2="AUTHGEAR_HTTP_ORIGIN_$2" value1="${!name1}" value2="${!name2}" if [[ "$value1" == "$value2" ]]; then printf 1>&2 "%s must not equal %s.\n" "$name1" "$name2" exit 1 fi } docker_authgearonce_create_directory() { dir="$(dirname "$AUTHGEARONCE_ENV_SHELL_SCRIPT")" sudo mkdir -p "$dir" sudo chmod 0755 "$dir" sudo find "$dir" \! -user "authgear" -exec chown "authgear":"authgear" '{}' + } docker_postgresql_create_database_directories() { sudo mkdir -p "$PGDATA" sudo chmod 0700 "$PGDATA" sudo mkdir -p /var/run/postgresql sudo chmod 0775 /var/run/postgresql sudo find "$PGDATA" \! -user "authgear" -exec chown "authgear":"authgear" '{}' + sudo find /var/run/postgresql \! -user "authgear" -exec chown "authgear":"authgear" '{}' + } docker_postgresql_initdb() { # This is the most secure method supported by PostgreSQL 16. # See https://www.postgresql.org/docs/16/auth-password.html auth_method="scram-sha-256" # Google Cloud SQL PostgreSQL uses libc as the locale provider. # So we just follow it. # Since --locale-provider=libc is the default, we need not specify it. # NOTE: --pwfile uses process substitution. initdb \ --username="authgear" \ --pwfile=<(printf "%s\n" "$POSTGRES_PASSWORD") \ --encoding="UTF8" \ --auth-host="$auth_method" \ --auth-local="$auth_method" } docker_postgresql_temp_server_start() { pg_ctl start --wait } docker_postgresql_temp_server_stop() { pg_ctl stop \ --mode fast \ --wait } # docker_postgresql_psql is a wrapper of psql. docker_postgresql_psql() { PGPASSWORD="$POSTGRES_PASSWORD" psql \ --variable ON_ERROR_STOP=1 \ --no-psqlrc "$@" } docker_postgresql_create_database() { docker_postgresql_temp_server_start # Connect to the database `postgres` that must exists. db_exists="$(docker_postgresql_psql \ --dbname postgres \ --set db="authgear" \ --tuples-only <<-'EOSQL' SELECT 1 FROM pg_database WHERE datname = :'db'; EOSQL )" if [[ -z "$db_exists" ]]; then docker_postgresql_psql \ --dbname postgres \ --set db="authgear" <<-'EOSQL' CREATE DATABASE :"db"; EOSQL fi docker_postgresql_temp_server_stop } docker_redis_create_directories() { sudo mkdir -p "$AUTHGEARONCE_REDIS_DATA_DIRECTORY" sudo chmod 0700 "$AUTHGEARONCE_REDIS_DATA_DIRECTORY" sudo mkdir -p /var/run/redis sudo chmod 0700 /var/run/redis sudo find "$AUTHGEARONCE_REDIS_DATA_DIRECTORY" \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find /var/run/redis \! -user "authgear" -exec chown "authgear:authgear" '{}' + } docker_redis_write_acl_file() { printf "user default on +@all ~* >%s\n" "$REDIS_PASSWORD" > /var/run/redis/users.acl } docker_nginx_create_directories() { # This is the default location of --prefix sudo mkdir -p /usr/share/nginx sudo chmod 0755 /usr/share/nginx # Ubuntu nginx-common installs files to here. sudo mkdir -p /etc/nginx sudo chmod 0755 /etc/nginx # When I run `nginx -t`, it tries to write files to /var/lib/nginx. sudo mkdir -p /var/lib/nginx sudo chmod 0755 /var/lib/nginx # The directory to contain the pid file. sudo mkdir -p /var/run/nginx sudo chmod 0755 /var/run/nginx # The directory to contain the log file. sudo mkdir -p /var/log/nginx sudo chmod 0755 /var/log/nginx # The directory to write temp files. sudo mkdir -p /tmp/nginx sudo chmod 0755 /tmp/nginx # There is a broken symlink /usr/share/nginx/modules # I do not know why. sudo rm -f /usr/share/nginx/modules sudo find /usr/share/nginx \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find /etc/nginx \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find /var/lib/nginx \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find /var/run/nginx \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find /var/log/nginx \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find /tmp/nginx \! -user "authgear" -exec chown "authgear:authgear" '{}' + } docker_nginx_render_server_block() { name="AUTHGEAR_HTTP_ORIGIN_$1" value="${!name}" if [[ -z "$value" ]]; then printf 1>&2 "%s must be set. This will be used to configure nginx and certbot.\n" "$name" exit 1 fi scheme="" without_scheme="" case "$value" in "http://"*) scheme="http" without_scheme="${value#http://}" ;; "https://"*) scheme="https" without_scheme="${value#https://}" ;; *) ;; esac if [[ -z "$without_scheme" ]]; then printf 1>&2 "%s must start with http:// or https://.\n" "$name" exit 1 fi contains_port="false" contains_path="false" contains_query="false" contains_fragment="false" case "$without_scheme" in *:*) contains_port="true" ;; */*) contains_path="true" ;; *'?'*) contains_query="true" ;; *'#'*) contains_fragment="true" ;; *) ;; esac if [[ "$contains_port" == "true" ]]; then printf 1>&2 "%s must not contain port.\n" "$name" exit 1 fi if [[ "$contains_path" == "true" ]]; then printf 1>&2 "%s must not contain path.\n" "$name" exit 1 fi if [[ "$contains_query" == "true" ]]; then printf 1>&2 "%s must not contain query.\n" "$name" exit 1 fi if [[ "$contains_fragment" == "true" ]]; then printf 1>&2 "%s must not contain fragment.\n" "$name" exit 1 fi sed -i -E "s,__AUTHGEAR_HTTP_HOST_${1}__,${without_scheme}," /etc/nginx/nginx.conf sed -i -E "s,__AUTHGEAR_HTTP_EXPECTED_SCHEME_${1}__,${scheme}," /etc/nginx/nginx.conf } docker_authgearonce_check_mutable_environment_variables_are_set() { if [[ -z "$AUTHGEAR_ONCE_IMAGE" ]]; then printf 1>&2 "AUTHGEAR_ONCE_IMAGE must be set.\n" exit 1 fi check_http_origin_is_set "PORTAL" check_http_origin_is_set "ACCOUNTS" check_http_origin_is_set "PROJECT" check_http_origin_not_equal_to_each_other "PORTAL" "ACCOUNTS" check_http_origin_not_equal_to_each_other "PORTAL" "PROJECT" check_http_origin_not_equal_to_each_other "ACCOUNTS" "PROJECT" } docker_nginx_create_nginx_conf() { cp /etc/nginx/nginx.conf.sample /etc/nginx/nginx.conf docker_nginx_render_server_block "PORTAL" docker_nginx_render_server_block "ACCOUNTS" docker_nginx_render_server_block "PROJECT" } docker_nginx_create_fake_certificate() { openssl req \ -batch \ -x509 \ -newkey rsa:4096 \ -noenc \ -keyout /etc/nginx/fake_certficate.key \ -out /etc/nginx/fake_certficate.crt \ -subj "/CN=invalid.invalid/OU=Fake certificate generated by docker-entrypoint.sh" \ -days 365 } docker_certbot_create_directories() { # --work-dir sudo mkdir -p /var/lib/letsencrypt # --logs-dir sudo mkdir -p /var/log/letsencrypt # --config-dir sudo mkdir -p "$AUTHGEARONCE_CERTBOT_DATA_DIRECTORY" sudo find /var/lib/letsencrypt \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find /var/log/letsencrypt \! -user "authgear" -exec chown "authgear:authgear" '{}' + sudo find "$AUTHGEARONCE_CERTBOT_DATA_DIRECTORY" \! -user "authgear" -exec chown "authgear:authgear" '{}' + } docker_certbot_create_cli_ini() { # certbot stores its data (like certificates, accounts) in --config-dir # It also reads its config (cli.ini) in --config-dir. # If we naively volume mount --config-dir, --config-dir/cli.ini will be obscured by the mount. # Therefore, when we build the image, we copy the original /etc/letsencrypt/cli.ini to /home/authgear/certbot.ini, # and we always write a fresh --config-dir/cli.ini. cli_ini="$AUTHGEARONCE_CERTBOT_DATA_DIRECTORY/cli.ini" cp /home/authgear/certbot.ini.example "$cli_ini" sed -E -i 's,^#?\s*(max-log-backups)\s+.*,\1 = 10,' "$cli_ini" sed -E -i 's,^#?\s*(preconfigured-renewal)\s+.*,\1 = False,' "$cli_ini" if ! grep -E '^max-log-backups = 10' "$cli_ini" 1>/dev/null; then printf 1>&2 "failed to set max-log-backups in %s\n" "$cli_ini" exit 1 fi if ! grep -E '^preconfigured-renewal = False' "$cli_ini" 1>/dev/null; then printf 1>&2 "failed to set preconfigured-renewal in %s\n" "$cli_ini" exit 1 fi } docker_minio_create_directories() { sudo mkdir -p "$AUTHGEARONCE_MINIO_DATA_DIRECTORY" sudo chmod 0700 "$AUTHGEARONCE_MINIO_DATA_DIRECTORY" sudo find "$AUTHGEARONCE_MINIO_DATA_DIRECTORY" \! -user "authgear" -exec chown "authgear:authgear" '{}' + } docker_minio_create_buckets() { # We need to start the server temporarily. minio server "$AUTHGEARONCE_MINIO_DATA_DIRECTORY" & minio_pid=$! # 1 second should be enough. It starts very fast. sleep 1 mcli alias set local http://localhost:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD" mcli mb --ignore-existing local/images mcli mb --ignore-existing local/userexport kill -SIGTERM "$minio_pid" } docker_tls_update_ca_certificates() { # Make the certificates in /usr/local/share/ca-certificates take effect. sudo update-ca-certificates } docker_dns_update_etc_hosts() { echo '127.0.0.1 accounts.projects.authgear' | sudo tee -a /etc/hosts >/dev/null echo '127.0.0.1 project.projects.authgear' | sudo tee -a /etc/hosts >/dev/null } docker_authgear_source_env() { # It is put at ~/.bashrc so that # `docker compose exec THE_SERVICE bash` will also source this file. source "/home/authgear/.bashrc" } docker_authgear_run_database_migrations() { docker_postgresql_temp_server_start authgear database migrate up authgear audit database migrate up authgear images database migrate up authgear search database migrate up authgear-portal database migrate up docker_postgresql_temp_server_stop } docker_authgear_create_deployment_runtime_directory() { mkdir -p /home/authgear/authgear_deployment_runtime cat > /home/authgear/authgear_deployment_runtime/authgear.secrets.yaml <"$query_file" <<'EOF' mutation createUser($email: String!, $password: String!) { createUser(input: { definition: { loginID: { key: "email" value: $email } } password: $password }) { user { id } } } EOF query_output="$(mktemp)" authgear internal admin-api invoke \ --app-id accounts \ --endpoint "http://localhost:3002" \ --host "accounts.projects.authgear" \ --query-file "$query_file" \ --operation-name "createUser" \ --variables-json "$(jq -cn --arg email "$AUTHGEAR_ONCE_ADMIN_USER_EMAIL" --arg password "$AUTHGEAR_ONCE_ADMIN_USER_PASSWORD" '{email: $email, password: $password}')" | tee "$query_output" decoded_node_id="$(jq <"$query_output" --raw-output '.data.createUser.user.id' | basenc --base64url --decode)" raw_id="${decoded_node_id#User:}" # Add collaborator to both projects. authgear-portal internal collaborator add \ --app-id "$app_id_accounts" \ --user-id "$raw_id" \ --role owner authgear-portal internal collaborator add \ --app-id "$app_id_project" \ --user-id "$raw_id" \ --role owner kill -SIGTERM "$wrapper_pid" # Wait 2 seconds to let the process exits. sleep 2 } docker_authgear_rerun_setup() { docker_wrapper & wrapper_pid=$! # Wait 2 seconds for the server to start. sleep 2 docker_authgear_setup_domains kill -SIGTERM "$wrapper_pid" # Wait 2 seconds to let the process exits. sleep 2 } docker_authgearonce_generate_passwords() { { printf "export POSTGRES_PASSWORD=%s\n" "$(generate_password)" printf "export REDIS_PASSWORD=%s\n" "$(generate_password)" printf "export MINIO_ROOT_PASSWORD=%s\n" "$(generate_password)" } >> "$1" } docker_authgearonce_persist_immutable_environment_variables() { # We persist the environment variables # NOTE(once): Possibly breaking change # These environment variables are part of the public API between the once image and the once command. # The once command provide these variables with `-e` in `docker run`. # If you introduce a new environment variable in the future, # you must think of the missing case of the environment variable, # as there is a running installation of the old version without this environment variable. { printf "export AUTHGEAR_ONCE_LICENSE_KEY=%s\n" "$AUTHGEAR_ONCE_LICENSE_KEY" printf "export AUTHGEAR_ONCE_LICENSE_EXPIRE_AT=%s\n" "$AUTHGEAR_ONCE_LICENSE_EXPIRE_AT" printf "export AUTHGEAR_ONCE_LICENSEE_EMAIL=%s\n" "$AUTHGEAR_ONCE_LICENSEE_EMAIL" printf "export AUTHGEAR_ONCE_MACHINE_FINGERPRINT=%s\n" "$AUTHGEAR_ONCE_MACHINE_FINGERPRINT" printf "export AUTHGEAR_ONCE_ADMIN_USER_EMAIL=%s\n" "$AUTHGEAR_ONCE_ADMIN_USER_EMAIL" printf "export AUTHGEAR_ONCE_ADMIN_USER_PASSWORD=%s\n" "$AUTHGEAR_ONCE_ADMIN_USER_PASSWORD" } >> "$1" if [[ -n "$AUTHGEAR_SMTP_HOST" ]]; then printf "export AUTHGEAR_SMTP_HOST=%s\n" "$AUTHGEAR_SMTP_HOST" >> "$1" fi if [[ -n "$AUTHGEAR_SMTP_PORT" ]]; then printf "export AUTHGEAR_SMTP_PORT=%s\n" "$AUTHGEAR_SMTP_PORT" >> "$1" fi if [[ -n "$AUTHGEAR_SMTP_USERNAME" ]]; then printf "export AUTHGEAR_SMTP_USERNAME=%s\n" "$AUTHGEAR_SMTP_USERNAME" >> "$1" fi if [[ -n "$AUTHGEAR_SMTP_PASSWORD" ]]; then printf "export AUTHGEAR_SMTP_PASSWORD=%s\n" "$AUTHGEAR_SMTP_PASSWORD" >> "$1" fi if [[ -n "$AUTHGEAR_SMTP_SENDER_ADDRESS" ]]; then printf "export AUTHGEAR_SMTP_SENDER_ADDRESS=%s\n" "$AUTHGEAR_SMTP_SENDER_ADDRESS" >> "$1" fi } docker_authgearonce_persist_mutable_environment_variables() { { printf "export AUTHGEAR_ONCE_IMAGE=%s\n" "$AUTHGEAR_ONCE_IMAGE" printf "export AUTHGEAR_HTTP_ORIGIN_PROJECT=%s\n" "$AUTHGEAR_HTTP_ORIGIN_PROJECT" printf "export AUTHGEAR_HTTP_ORIGIN_PORTAL=%s\n" "$AUTHGEAR_HTTP_ORIGIN_PORTAL" printf "export AUTHGEAR_HTTP_ORIGIN_ACCOUNTS=%s\n" "$AUTHGEAR_HTTP_ORIGIN_ACCOUNTS" printf "export AUTHGEAR_CERTBOT_ENABLED=%s\n" "$AUTHGEAR_CERTBOT_ENABLED" printf "export AUTHGEAR_CERTBOT_ENVIRONMENT=%s\n" "$AUTHGEAR_CERTBOT_ENVIRONMENT" printf "export AUTHGEAR_CERTBOT_RUN_INTERVAL=%s\n" "$AUTHGEAR_CERTBOT_RUN_INTERVAL" } >> "$1" } docker_authgearonce_create_env_sh() { docker_authgearonce_check_immutable_environment_variables_are_set docker_authgearonce_check_mutable_environment_variables_are_set printf 1>&2 "Creating %s\n" "$AUTHGEARONCE_ENV_SHELL_SCRIPT" docker_authgearonce_generate_passwords "$AUTHGEARONCE_ENV_SHELL_SCRIPT" docker_authgearonce_persist_immutable_environment_variables "$AUTHGEARONCE_ENV_SHELL_SCRIPT" docker_authgearonce_persist_mutable_environment_variables "$AUTHGEARONCE_ENV_SHELL_SCRIPT" } docker_authgearonce_update_env_sh() { docker_authgearonce_check_mutable_environment_variables_are_set printf 1>&2 "Updating %s\n" "$AUTHGEARONCE_ENV_SHELL_SCRIPT" original="$AUTHGEARONCE_ENV_SHELL_SCRIPT" updated="${AUTHGEARONCE_ENV_SHELL_SCRIPT}.tmp" sed <"$original" >"$updated" -E '/^export (AUTHGEAR_ONCE_IMAGE|AUTHGEAR_HTTP_ORIGIN_PROJECT|AUTHGEAR_HTTP_ORIGIN_PORTAL|AUTHGEAR_HTTP_ORIGIN_ACCOUNTS|AUTHGEAR_CERTBOT_ENABLED|AUTHGEAR_CERTBOT_ENVIRONMENT|AUTHGEAR_CERTBOT_RUN_INTERVAL)=/d' docker_authgearonce_persist_mutable_environment_variables "$updated" mv "$updated" "$original" } docker_authgear_setup_domains() { docker_postgresql_psql \ --dbname authgear <<-'EOSQL' DELETE FROM _portal_domain; EOSQL app_id_accounts="accounts" host_accounts="$(echo "$AUTHGEAR_HTTP_ORIGIN_ACCOUNTS" | awk -F '://' '{ print $2 }')" authgear-portal internal domain create-custom "$app_id_accounts" --domain "$host_accounts" --apex-domain "$host_accounts" app_id_project="project" host_project="$(echo "$AUTHGEAR_HTTP_ORIGIN_PROJECT" | awk -F '://' '{ print $2 }')" authgear-portal internal domain create-custom "$app_id_project" --domain "$host_project" --apex-domain "$host_project" authgear-portal internal domain create-default --default-domain-suffix '.projects.authgear' # We need to update the public_origin, as well as, # the redirect URIs of the portal. sql_output=$(docker_postgresql_psql \ --dbname authgear \ --tuples-only \ --set app_id="$app_id_accounts" <<-'EOSQL' SELECT data->>'authgear.yaml' FROM _portal_config_source where app_id = :'app_id'; EOSQL ) updated=$(echo -n "$sql_output" \ | sed -E 's/[[:space:]]//' \ | base64 -d \ | yq --yaml-output --arg public_origin "$AUTHGEAR_HTTP_ORIGIN_ACCOUNTS" '.http.public_origin = $public_origin' \ | yq --yaml-output --arg portal_origin "$AUTHGEAR_HTTP_ORIGIN_PORTAL" '.oauth.clients[0].post_logout_redirect_uris[0] = "\($portal_origin)/"' \ | yq --yaml-output --arg portal_origin "$AUTHGEAR_HTTP_ORIGIN_PORTAL" '.oauth.clients[0].redirect_uris[0] = "\($portal_origin)/oauth-redirect"' \ | base64 -w 0) docker_postgresql_psql \ --dbname authgear \ --set app_id="$app_id_accounts" \ --set v="$updated" <<-'EOSQL' UPDATE _portal_config_source SET data = jsonb_set(data, '{authgear.yaml}', to_jsonb(:'v' ::text)) WHERE app_id = :'app_id'; EOSQL # This is rather simple. # We just need to update the public_origin. sql_output=$(docker_postgresql_psql \ --dbname authgear \ --tuples-only \ --set app_id="$app_id_project" <<-'EOSQL' SELECT data->>'authgear.yaml' FROM _portal_config_source where app_id = :'app_id'; EOSQL ) updated=$(echo -n "$sql_output" \ | sed -E 's/[[:space:]]//' \ | base64 -d \ | yq --yaml-output --arg public_origin "$AUTHGEAR_HTTP_ORIGIN_PROJECT" '.http.public_origin = $public_origin' \ | base64 -w 0) docker_postgresql_psql \ --dbname authgear \ --set app_id="$app_id_project" \ --set v="$updated" <<-'EOSQL' UPDATE _portal_config_source SET data = jsonb_set(data, '{authgear.yaml}', to_jsonb(:'v' ::text)) WHERE app_id = :'app_id'; EOSQL } main() { check_user_is_correct docker_authgearonce_create_directory what_to_do='' if [[ ! -r "$AUTHGEARONCE_ENV_SHELL_SCRIPT" ]]; then # The env file does not exist. # This means the volume is new. # In this case, we require the environment variables to be set. what_to_do='first_time_setup' docker_authgearonce_create_env_sh elif [[ -n "$AUTHGEAR_ONCE_IMAGE" ]]; then # Just pick one of the required environment to check. # If it is non-empty, then the setup command is re-run. what_to_do='rerun_setup' docker_authgearonce_update_env_sh else # Otherwise, the start command is run. printf 1>&2 "Reading %s\n" "$AUTHGEARONCE_ENV_SHELL_SCRIPT" fi # Always source the env file. . "$AUTHGEARONCE_ENV_SHELL_SCRIPT" docker_nginx_create_directories docker_nginx_create_fake_certificate docker_nginx_create_nginx_conf docker_certbot_create_directories docker_certbot_create_cli_ini docker_postgresql_create_database_directories # If this file exists and its size is greater than zero, # then we consider the database has initialized. if [[ -s "$PGDATA/PG_VERSION" ]]; then printf 1>&2 "PostgreSQL database directory (%s) seems initialized. Skipping initialization.\n" "$PGDATA" else docker_postgresql_initdb # initdb will create the given database user (--username), and # the database `postgres`, `template1` and `template0`. # It does not provide an option to create more additional databases. # Thus we need to do that in a separate step. docker_postgresql_create_database fi docker_redis_create_directories docker_redis_write_acl_file docker_minio_create_directories docker_minio_create_buckets docker_tls_update_ca_certificates docker_dns_update_etc_hosts docker_authgear_source_env docker_authgear_run_database_migrations docker_authgear_create_deployment_runtime_directory if [[ "$what_to_do" == 'first_time_setup' ]]; then docker_authgear_first_time_setup exit_status="$?" if [[ "$exit_status" -ne 0 ]]; then exit "$exit_status" fi elif [[ "$what_to_do" == 'rerun_setup' ]]; then docker_authgear_rerun_setup exit_status="$?" if [[ "$exit_status" -ne 0 ]]; then exit "$exit_status" fi fi # Replace this process with the given arguments. exec "$@" } main "$@"