#!/bin/bash set -euo pipefail # eLabFTW runtime setup for Cloudron: # 1. bind persistent storage: /elabftw/{uploads,exports} -> /app/data # 2. wait for the Cloudron mysql addon (the image entrypoint runs # db:install / db:update immediately, without any DB wait) # 3. persist the SECRET_KEY (rotating it would lose the encrypted # SMTP / timestamping passwords stored in the DB) # 4. map the Cloudron env into elabimg's runtime variables # 5. exec the upstream s6-overlay init (nginx + php-fpm + invoker + # chronos), which applies the config and starts the web server # # Authentication: eLabFTW has NO OIDC support (auth methods: local, SAML, # LDAP). Cloudron SSO therefore goes through the platform LDAP directory: # the manifest enables the `ldap` addon and the sysconfig admin maps # CLOUDRON_LDAP_* into Admin panel -> LDAP (see package README). This is # flagged auth-risk: LDAP in STATUS.md / README.md. DATA_DIR="/app/data" SECRET_FILE="${DATA_DIR}/.secret_key" # --- 1. persistent uploads / exports ----------------------------------------- mkdir -p "${DATA_DIR}/uploads" "${DATA_DIR}/exports" # replace the in-image directories with symlinks into the Cloudron volume; # the upstream entrypoint will chown/chmod them for the nginx user rm -rf /elabftw/uploads /elabftw/exports ln -sfn "${DATA_DIR}/uploads" /elabftw/uploads ln -sfn "${DATA_DIR}/exports" /elabftw/exports # --- 2. wait for the mysql addon ---------------------------------------------- wait_tcp() { local host="$1" port="$2" name="$3" echo "Waiting for ${name} at ${host}:${port} ..." until (exec 3<>"/dev/tcp/${host}/${port}") 2>/dev/null; do echo "${name} is unavailable - sleeping" sleep 2 done echo "${name} is up" } wait_tcp "${CLOUDRON_MYSQL_HOST:-127.0.0.1}" "${CLOUDRON_MYSQL_PORT:-3306}" "MySQL" # --- 3. persistent SECRET_KEY -------------------------------------------------- # hex on purpose: the image entrypoint substitutes it into the php-fpm pool # config with an unescaped `sed s/.../.../`, so the value must not contain # `/`, `&` or other sed metacharacters (base64 would break it). if [[ ! -s "${SECRET_FILE}" ]]; then ( umask 077; openssl rand -hex 32 > "${SECRET_FILE}" ) echo "Generated new eLabFTW secret key" fi export SECRET_KEY="$(cat "${SECRET_FILE}")" # --- 4. Cloudron -> elabimg environment ---------------------------------------- export DB_HOST="${CLOUDRON_MYSQL_HOST:-127.0.0.1}" export DB_PORT="${CLOUDRON_MYSQL_PORT:-3306}" export DB_NAME="${CLOUDRON_MYSQL_DATABASE:-elabftw}" export DB_USER="${CLOUDRON_MYSQL_USERNAME:-elabftw}" export DB_PASSWORD="${CLOUDRON_MYSQL_PASSWORD:-}" # Cloudron terminates TLS at the platform proxy; elabimg serves plain HTTP export DISABLE_HTTPS=true export SITE_URL="${CLOUDRON_APP_ORIGIN:-http://localhost}" export SERVER_NAME="${CLOUDRON_APP_DOMAIN:-localhost}" export TZ="${ELABFTW_TZ:-UTC}" export PHP_TIMEZONE="${ELABFTW_TZ:-UTC}" # schema lifecycle handled by the image entrypoint (runs after this script # hands over): db:install on first boot, db:update on every boot export AUTO_DB_INIT="${ELABFTW_AUTO_DB_INIT:-true}" export AUTO_DB_UPDATE="${ELABFTW_AUTO_DB_UPDATE:-true}" # resource knobs (defaults tuned for the 1536 MB manifest memory limit) export MAX_UPLOAD_SIZE="${ELABFTW_MAX_UPLOAD_SIZE:-100M}" export PHP_MAX_CHILDREN="${ELABFTW_PHP_MAX_CHILDREN:-15}" export MAX_PHP_MEMORY="${ELABFTW_MAX_PHP_MEMORY:-512M}" # --- 5. hand over to the upstream init ------------------------------------------ exec /init