#!/usr/bin/env bash set -euo pipefail APP_DIR="/app/code" DATA_DIR="/app/data" CONFIG_PATH="${DATA_DIR}/config.yaml" DEFAULT_CONFIG="/tmp/data/config.yaml" FRONTEND_DIR="${APP_DIR}/frontend" ADMIN_FILE="${DATA_DIR}/.admin_password" MAUBOT_INTERNAL_PORT="${MAUBOT_INTERNAL_PORT:-3001}" umask 0027 mkdir -p /run/nginx \ "${DATA_DIR}" \ "${DATA_DIR}/plugins" \ "${DATA_DIR}/trash" \ "${DATA_DIR}/dbs" \ "${DATA_DIR}/logs" if [ ! -f "${CONFIG_PATH}" ]; then cp "${DEFAULT_CONFIG}" "${CONFIG_PATH}" echo "Generated initial Maubot configuration at ${CONFIG_PATH}" fi if compgen -G "${DATA_DIR}/plugins/*.db" > /dev/null; then mv "${DATA_DIR}"/plugins/*.db "${DATA_DIR}/dbs/" || true fi chown -R cloudron:cloudron "${DATA_DIR}" export CONFIG_PATH DATA_DIR FRONTEND_DIR ADMIN_FILE export MAUBOT_PORT="${MAUBOT_INTERNAL_PORT}" export CLOUDRON_APP_ORIGIN="${CLOUDRON_APP_ORIGIN:-https://example.com}" export CLOUDRON_POSTGRESQL_URL="${CLOUDRON_POSTGRESQL_URL:-}" export MAUBOT_CRYPTO_DATABASE="${MAUBOT_CRYPTO_DATABASE:-default}" "${APP_DIR}/venv/bin/python3" <<'PY' import os import pathlib import secrets import string from ruamel.yaml import YAML yaml = YAML() yaml.preserve_quotes = True config_path = pathlib.Path(os.environ["CONFIG_PATH"]) data_dir = pathlib.Path(os.environ["DATA_DIR"]) frontend_dir = pathlib.Path(os.environ["FRONTEND_DIR"]) admin_file = pathlib.Path(os.environ["ADMIN_FILE"]) public_url = os.environ.get("CLOUDRON_APP_ORIGIN") or "https://example.com" db_url = os.environ.get("CLOUDRON_POSTGRESQL_URL") crypto_url = os.environ.get("MAUBOT_CRYPTO_DATABASE", "default") maubot_port = int(os.environ["MAUBOT_PORT"]) with config_path.open() as handle: config = yaml.load(handle) or {} config["database"] = db_url or f"sqlite:{data_dir / 'maubot.db'}" config["crypto_database"] = "default" if crypto_url in ("", "default") else crypto_url plugin_dirs = config.setdefault("plugin_directories", {}) plugin_dirs["upload"] = str(data_dir / "plugins") plugin_dirs["load"] = [str(data_dir / "plugins")] plugin_dirs["trash"] = str(data_dir / "trash") plugin_dbs = config.setdefault("plugin_databases", {}) plugin_dbs["sqlite"] = str(data_dir / "dbs") plugin_dbs["postgres"] = "default" if db_url else None plugin_dbs.setdefault("postgres_max_conns_per_plugin", 3) plugin_dbs.setdefault("postgres_opts", {}) server = config.setdefault("server", {}) server["hostname"] = "127.0.0.1" server["port"] = maubot_port server["public_url"] = public_url.rstrip("/") server.setdefault("ui_base_path", "/") server.setdefault("plugin_base_path", "/_matrix/maubot/plugin/") server["override_resource_path"] = str(frontend_dir) logging = config.setdefault("logging", {}) handlers = logging.setdefault("handlers", {}) file_handler = handlers.setdefault("file", {}) file_handler["filename"] = str(data_dir / "logs" / "maubot.log") file_handler.setdefault("class", "logging.handlers.RotatingFileHandler") file_handler.setdefault("formatter", "normal") file_handler.setdefault("maxBytes", 10485760) file_handler.setdefault("backupCount", 10) admins = config.setdefault("admins", {}) if admin_file.exists(): admin_password = admin_file.read_text().strip() else: alphabet = string.ascii_letters + string.digits admin_password = "".join(secrets.choice(alphabet) for _ in range(40)) admin_file.write_text(admin_password) admin_file.chmod(0o640) admins["root"] = admin_password with config_path.open("w") as handle: yaml.dump(config, handle) PY chown cloudron:cloudron "${CONFIG_PATH}" "${ADMIN_FILE}" exec /usr/bin/supervisord -c /app/code/supervisord.conf