once/docker-entrypoint.sh
Rama main · réplica de lectura del repositorio original.
#!/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 <<EOF
secrets:
- key: db
data:
database_schema: "$DATABASE_SCHEMA"
database_url: "$DATABASE_URL"
- key: audit.db
data:
database_schema: "$AUDIT_DATABASE_SCHEMA"
database_url: "$AUDIT_DATABASE_URL"
- key: search.db
data:
database_schema: "$SEARCH_DATABASE_SCHEMA"
database_url: "$SEARCH_DATABASE_URL"
- key: redis
data:
redis_url: "$REDIS_URL"
- key: analytic.redis
data:
redis_url: "$ANALYTIC_REDIS_URL"
EOF
}
docker_authgear_first_time_setup() {
docker_wrapper &
wrapper_pid=$!
# Wait 2 seconds for the server to start.
sleep 2
app_id_accounts="accounts"
init_output_accounts="$(mktemp -d)"
# The trailing . in src is important.
cp -R "$HOME/resources/." "$init_output_accounts"
authgear init --interactive=false \
--purpose=portal \
--for-helm-chart=true \
--app-id="$app_id_accounts" \
--public-origin="$AUTHGEAR_HTTP_ORIGIN_ACCOUNTS" \
--portal-origin="$AUTHGEAR_HTTP_ORIGIN_PORTAL" \
--portal-client-id=portal \
--phone-otp-mode=sms \
--disable-email-verification=false \
--disable-public-signup=true \
--smtp-host="$AUTHGEAR_SMTP_HOST" \
--smtp-port="$AUTHGEAR_SMTP_PORT" \
--smtp-username="$AUTHGEAR_SMTP_USERNAME" \
--smtp-password="$AUTHGEAR_SMTP_PASSWORD" \
--smtp-sender-address="$AUTHGEAR_SMTP_SENDER_ADDRESS" \
--search-implementation=postgresql \
-o "$init_output_accounts"
authgear-portal internal configsource create "$init_output_accounts"
rm -r "$init_output_accounts"
app_id_project="project"
init_output_project="$(mktemp -d)"
authgear init --interactive=false \
--purpose=project \
--for-helm-chart=true \
--app-id="$app_id_project" \
--public-origin="$AUTHGEAR_HTTP_ORIGIN_PROJECT" \
--phone-otp-mode=sms \
--disable-email-verification=false \
--smtp-host="$AUTHGEAR_SMTP_HOST" \
--smtp-port="$AUTHGEAR_SMTP_PORT" \
--smtp-username="$AUTHGEAR_SMTP_USERNAME" \
--smtp-password="$AUTHGEAR_SMTP_PASSWORD" \
--smtp-sender-address="$AUTHGEAR_SMTP_SENDER_ADDRESS" \
--search-implementation=postgresql \
-o "$init_output_project"
cp -R "$HOME/project-resources/." "$init_output_project"
authgear-portal internal configsource create "$init_output_project"
rm -r "$init_output_project"
# Set up domains first.
# Otherwise, Admin API server cannot resolve which project.
docker_authgear_setup_domains
query_file="$(mktemp)"
cat >"$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 "$@"