Initial packaging
This commit is contained in:
180
start.sh
Normal file
180
start.sh
Normal file
@@ -0,0 +1,180 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
APP_CODE_DIR=${APP_CODE_DIR:-/app/code}
|
||||
APP_DATA_DIR=${APP_DATA_DIR:-/app/data}
|
||||
APP_RUNTIME_DIR=${APP_RUNTIME_DIR:-/run/affine}
|
||||
APP_TMP_DIR=${APP_TMP_DIR:-/tmp/data}
|
||||
APP_BUILD_DIR=${APP_BUILD_DIR:-/app/code/affine}
|
||||
AFFINE_HOME=/home/cloudron/.affine
|
||||
export APP_CODE_DIR APP_DATA_DIR APP_RUNTIME_DIR APP_TMP_DIR APP_BUILD_DIR
|
||||
|
||||
log() {
|
||||
printf '[%s] %s\n' "$(date --iso-8601=seconds)" "$*"
|
||||
}
|
||||
|
||||
require_env() {
|
||||
local var_name="$1"
|
||||
if [ -z "${!var_name:-}" ]; then
|
||||
echo "Environment variable ${var_name} is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_data_dirs() {
|
||||
log "Preparing persistent directories"
|
||||
mkdir -p "$APP_DATA_DIR/config" "$APP_DATA_DIR/storage" "$APP_DATA_DIR/logs" "$APP_RUNTIME_DIR" "$AFFINE_HOME"
|
||||
|
||||
if [ ! -f "$APP_DATA_DIR/config/config.json" ]; then
|
||||
log "Seeding default configuration"
|
||||
cp "$APP_TMP_DIR/config/config.json" "$APP_DATA_DIR/config/config.json"
|
||||
fi
|
||||
|
||||
local storage_contents=""
|
||||
if [ -d "$APP_DATA_DIR/storage" ]; then
|
||||
storage_contents=$(ls -A "$APP_DATA_DIR/storage" 2>/dev/null || true)
|
||||
fi
|
||||
if [ ! -d "$APP_DATA_DIR/storage" ] || [ -z "$storage_contents" ]; then
|
||||
cp -a "$APP_TMP_DIR/storage/." "$APP_DATA_DIR/storage/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
rm -rf "$AFFINE_HOME/config" "$AFFINE_HOME/storage"
|
||||
ln -sf "$APP_DATA_DIR/config" "$AFFINE_HOME/config"
|
||||
ln -sf "$APP_DATA_DIR/storage" "$AFFINE_HOME/storage"
|
||||
|
||||
chown -R cloudron:cloudron "$APP_DATA_DIR" "$APP_RUNTIME_DIR" /home/cloudron
|
||||
}
|
||||
|
||||
configure_database() {
|
||||
require_env CLOUDRON_POSTGRESQL_URL
|
||||
local db_url="$CLOUDRON_POSTGRESQL_URL"
|
||||
if [[ "$db_url" == postgres://* ]]; then
|
||||
db_url="postgresql://${db_url#postgres://}"
|
||||
fi
|
||||
export DATABASE_URL="$db_url"
|
||||
log "Configured PostgreSQL endpoint"
|
||||
}
|
||||
|
||||
configure_redis() {
|
||||
require_env CLOUDRON_REDIS_URL
|
||||
local redis_info
|
||||
redis_info=$(python3 - <<'PY'
|
||||
import os
|
||||
from urllib.parse import urlparse
|
||||
url = os.environ.get('CLOUDRON_REDIS_URL')
|
||||
if not url:
|
||||
raise SystemExit('redis url missing')
|
||||
parsed = urlparse(url)
|
||||
host = parsed.hostname or 'localhost'
|
||||
port = parsed.port or 6379
|
||||
password = parsed.password or ''
|
||||
db = (parsed.path or '/0').lstrip('/') or '0'
|
||||
print(f"{host}\n{port}\n{password}\n{db}")
|
||||
PY
|
||||
)
|
||||
IFS=$'\n' read -r host port password db <<<"$redis_info"
|
||||
export REDIS_SERVER_HOST="$host"
|
||||
export REDIS_SERVER_PORT="$port"
|
||||
export REDIS_SERVER_PASSWORD="$password"
|
||||
export REDIS_URL="$CLOUDRON_REDIS_URL"
|
||||
export REDIS_SERVER_URL="$CLOUDRON_REDIS_URL"
|
||||
log "Configured Redis endpoint"
|
||||
}
|
||||
|
||||
configure_mail() {
|
||||
if [ -z "${CLOUDRON_MAIL_SMTP_SERVER:-}" ]; then
|
||||
log "Cloudron mail addon not configured, skipping SMTP setup"
|
||||
return
|
||||
fi
|
||||
export MAILER_HOST="$CLOUDRON_MAIL_SMTP_SERVER"
|
||||
export MAILER_PORT="${CLOUDRON_MAIL_SMTP_PORT:-587}"
|
||||
export MAILER_USER="${CLOUDRON_MAIL_SMTP_USERNAME:-}"
|
||||
export MAILER_PASSWORD="${CLOUDRON_MAIL_SMTP_PASSWORD:-}"
|
||||
export MAILER_SENDER="${CLOUDRON_MAIL_FROM:-AFFiNE <no-reply@cloudron.local>}"
|
||||
export MAILER_SERVERNAME="${MAILER_SERVERNAME:-AFFiNE Server}"
|
||||
log "Configured SMTP relay"
|
||||
}
|
||||
|
||||
configure_server_metadata() {
|
||||
if [ -n "${CLOUDRON_APP_ORIGIN:-}" ]; then
|
||||
export AFFINE_SERVER_EXTERNAL_URL="$CLOUDRON_APP_ORIGIN"
|
||||
local host
|
||||
host=$(python3 - <<PY
|
||||
from urllib.parse import urlparse
|
||||
import os
|
||||
url = os.environ.get('CLOUDRON_APP_ORIGIN', '')
|
||||
parsed = urlparse(url)
|
||||
print(parsed.hostname or '')
|
||||
PY
|
||||
)
|
||||
export AFFINE_SERVER_HOST="$host"
|
||||
if [[ "$CLOUDRON_APP_ORIGIN" == https://* ]]; then
|
||||
export AFFINE_SERVER_HTTPS=true
|
||||
else
|
||||
export AFFINE_SERVER_HTTPS=false
|
||||
fi
|
||||
fi
|
||||
export AFFINE_INDEXER_ENABLED=${AFFINE_INDEXER_ENABLED:-false}
|
||||
}
|
||||
|
||||
configure_auth() {
|
||||
if [ -n "${CLOUDRON_OIDC_CLIENT_ID:-}" ]; then
|
||||
export CLOUDRON_OIDC_IDENTIFIER="${CLOUDRON_OIDC_IDENTIFIER:-cloudron}"
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
config_path = Path(os.environ['APP_DATA_DIR']) / 'config' / 'config.json'
|
||||
data = json.loads(config_path.read_text())
|
||||
auth = data.setdefault('auth', {})
|
||||
providers = auth.setdefault('providers', {})
|
||||
oidc = providers.setdefault('oidc', {})
|
||||
oidc['clientId'] = os.environ.get('CLOUDRON_OIDC_CLIENT_ID', '')
|
||||
oidc['clientSecret'] = os.environ.get('CLOUDRON_OIDC_CLIENT_SECRET', '')
|
||||
oidc['issuer'] = os.environ.get('CLOUDRON_OIDC_ISSUER') or os.environ.get('CLOUDRON_OIDC_DISCOVERY_URL', '')
|
||||
args = oidc.setdefault('args', {})
|
||||
args.setdefault('scope', 'openid profile email')
|
||||
config_path.write_text(json.dumps(data, indent=2))
|
||||
PY
|
||||
log "Enabled Cloudron OIDC for AFFiNE"
|
||||
fi
|
||||
}
|
||||
|
||||
finalize_permissions() {
|
||||
chown -R cloudron:cloudron "$APP_DATA_DIR"
|
||||
}
|
||||
|
||||
update_server_config() {
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
config_path = Path(os.environ['APP_DATA_DIR']) / 'config' / 'config.json'
|
||||
data = json.loads(config_path.read_text())
|
||||
server = data.setdefault('server', {})
|
||||
origin = os.environ.get('CLOUDRON_APP_ORIGIN')
|
||||
if origin:
|
||||
parsed = urlparse(origin)
|
||||
server['externalUrl'] = origin
|
||||
server['host'] = parsed.hostname or ''
|
||||
server['https'] = parsed.scheme == 'https'
|
||||
config_path.write_text(json.dumps(data, indent=2))
|
||||
PY
|
||||
}
|
||||
|
||||
main() {
|
||||
export HOME=/home/cloudron
|
||||
prepare_data_dirs
|
||||
configure_database
|
||||
configure_redis
|
||||
configure_mail
|
||||
configure_server_metadata
|
||||
update_server_config
|
||||
configure_auth
|
||||
finalize_permissions
|
||||
log "Starting supervisor"
|
||||
exec /usr/bin/supervisord -c "$APP_CODE_DIR/supervisord.conf"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user