From df5d0679ecbb1eff6296a0a7ef780d8b17ba922d Mon Sep 17 00:00:00 2001 From: MickLesk Date: Fri, 8 May 2026 09:14:20 +0200 Subject: [PATCH] Add Stoatchat and xyOps container/install scripts Introduce new container templates, installers, and metadata for Stoatchat and xyOps. Adds ct scripts (ct/stoatchat.sh, ct/xyops.sh), full install scripts (install/stoatchat-install.sh, install/xyops-install.sh) that provision dependencies, build components, and create systemd services, plus app metadata JSON (json/stoatchat.json, json/xyops.json). Stoatchat installer handles Rust backend build, SolidJS frontend build, MinIO, RabbitMQ, MongoDB, nginx reverse proxy and multiple backend services (exposes on port 80). xyOps installer builds the Node app, sets up the xySat satellite, service unit, and uses port 5522 for the web UI. Default resource recommendations and notes are included in the JSON metadata. --- ct/stoatchat.sh | 85 ++++++++++++ ct/xyops.sh | 72 +++++++++++ install/stoatchat-install.sh | 242 +++++++++++++++++++++++++++++++++++ install/xyops-install.sh | 73 +++++++++++ json/stoatchat.json | 52 ++++++++ json/xyops.json | 48 +++++++ 6 files changed, 572 insertions(+) create mode 100644 ct/stoatchat.sh create mode 100644 ct/xyops.sh create mode 100644 install/stoatchat-install.sh create mode 100644 install/xyops-install.sh create mode 100644 json/stoatchat.json create mode 100644 json/xyops.json diff --git a/ct/stoatchat.sh b/ct/stoatchat.sh new file mode 100644 index 00000000..bbdf1140 --- /dev/null +++ b/ct/stoatchat.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/stoatchat/stoatchat + +APP="Stoatchat" +var_tags="${var_tags:-chat;messaging;community}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-8192}" +var_disk="${var_disk:-30}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -d /opt/stoatchat ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "stoatchat" "stoatchat/stoatchat"; then + msg_info "Stopping Services" + systemctl stop stoatchat-api stoatchat-events stoatchat-autumn stoatchat-january stoatchat-crond + msg_ok "Stopped Services" + + msg_info "Backing up Configuration" + cp /Revolt.toml /opt/stoatchat_revolt.toml.bak + msg_ok "Backed up Configuration" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "stoatchat" "stoatchat/stoatchat" "tarball" + + msg_info "Rebuilding Backend (Patience)" + cd /opt/stoatchat + $STD cargo build --release --bins + msg_ok "Rebuilt Backend" + + msg_info "Updating Web Frontend" + FORWEB_VERSION=$(get_latest_github_release "stoatchat/for-web") + $STD git -C /opt/stoatchat-web fetch --tags + $STD git -C /opt/stoatchat-web checkout "$FORWEB_VERSION" + $STD git -C /opt/stoatchat-web submodule update --init --recursive + cd /opt/stoatchat-web + $STD pnpm install --frozen-lockfile + $STD pnpm --filter stoat.js build + $STD pnpm --filter solid-livekit-components build + $STD pnpm --filter "@lingui-solid/babel-plugin-lingui-macro" build + $STD pnpm --filter "@lingui-solid/babel-plugin-extract-messages" build + $STD pnpm --filter client exec lingui compile --typescript + $STD pnpm --filter client exec node scripts/copyAssets.mjs + $STD pnpm --filter client exec panda codegen + $STD pnpm --filter client exec vite build + msg_ok "Updated Web Frontend" + + msg_info "Restoring Configuration" + cp /opt/stoatchat_revolt.toml.bak /Revolt.toml + rm -f /opt/stoatchat_revolt.toml.bak + msg_ok "Restored Configuration" + + msg_info "Starting Services" + systemctl start stoatchat-api stoatchat-events stoatchat-autumn stoatchat-january stoatchat-crond + msg_ok "Started Services" + msg_ok "Updated successfully!" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}" diff --git a/ct/xyops.sh b/ct/xyops.sh new file mode 100644 index 00000000..43861b3a --- /dev/null +++ b/ct/xyops.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/pixlcore/xyops + +APP="xyOps" +var_tags="${var_tags:-scheduler;automation;monitoring}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-8}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -d /opt/xyops ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "xyops" "pixlcore/xyops"; then + msg_info "Stopping Service" + systemctl stop xyops + msg_ok "Stopped Service" + + msg_info "Backing up Data" + cp -r /opt/xyops/data /opt/xyops_data_backup + cp -r /opt/xyops/conf /opt/xyops_conf_backup + msg_ok "Backed up Data" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "xyops" "pixlcore/xyops" "tarball" + + msg_info "Rebuilding Application" + cd /opt/xyops + $STD npm install + $STD node bin/build.js dist + chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js + msg_ok "Rebuilt Application" + + msg_info "Restoring Data" + cp -r /opt/xyops_data_backup/. /opt/xyops/data + cp -r /opt/xyops_conf_backup/. /opt/xyops/conf + rm -rf /opt/xyops_data_backup /opt/xyops_conf_backup + msg_ok "Restored Data" + + msg_info "Starting Service" + systemctl start xyops + msg_ok "Started Service" + msg_ok "Updated successfully!" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5522${CL}" diff --git a/install/stoatchat-install.sh b/install/stoatchat-install.sh new file mode 100644 index 00000000..44ea4940 --- /dev/null +++ b/install/stoatchat-install.sh @@ -0,0 +1,242 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/stoatchat/stoatchat + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt install -y \ + pkg-config \ + libssl-dev \ + build-essential \ + git \ + redis-server \ + rabbitmq-server \ + nginx +msg_ok "Installed Dependencies" + +setup_mongodb + +msg_info "Configuring RabbitMQ" +systemctl enable -q --now rabbitmq-server +until rabbitmqctl status &>/dev/null; do sleep 1; done +$STD rabbitmqctl add_user rabbituser rabbitpass +$STD rabbitmqctl set_permissions -p / rabbituser ".*" ".*" ".*" +msg_ok "Configured RabbitMQ" + +setup_rust + +fetch_and_deploy_gh_release "stoatchat" "stoatchat/stoatchat" "tarball" + +msg_info "Building Backend (Patience)" +cd /opt/stoatchat +$STD cargo build --release --bins +msg_ok "Built Backend" + +NODE_VERSION="22" setup_nodejs + +msg_info "Installing pnpm" +$STD npm install -g pnpm@10.28.1 +msg_ok "Installed pnpm" + +msg_info "Cloning Web Frontend" +FORWEB_VERSION=$(get_latest_github_release "stoatchat/for-web") +$STD git clone --recursive "https://github.com/stoatchat/for-web" /opt/stoatchat-web +$STD git -C /opt/stoatchat-web checkout "$FORWEB_VERSION" +$STD git -C /opt/stoatchat-web submodule update --init --recursive +msg_ok "Cloned Web Frontend" + +msg_info "Building Web Frontend" +cd /opt/stoatchat-web +$STD pnpm install --frozen-lockfile +$STD pnpm --filter stoat.js build +$STD pnpm --filter solid-livekit-components build +$STD pnpm --filter "@lingui-solid/babel-plugin-lingui-macro" build +$STD pnpm --filter "@lingui-solid/babel-plugin-extract-messages" build +$STD pnpm --filter client exec lingui compile --typescript +$STD pnpm --filter client exec node scripts/copyAssets.mjs +$STD pnpm --filter client exec panda codegen +VITE_API_URL="http://${LOCAL_IP}/api" \ + VITE_WS_URL="ws://${LOCAL_IP}/ws" \ + VITE_MEDIA_URL="http://${LOCAL_IP}/autumn" \ + VITE_PROXY_URL="http://${LOCAL_IP}/january" \ + $STD pnpm --filter client exec vite build +msg_ok "Built Web Frontend" + +fetch_and_deploy_gh_release "minio" "minio/minio" "singlefile" "latest" "/opt/stoatchat" "minio_linux_amd64" +mv /opt/stoatchat/minio_linux_amd64 /usr/local/bin/minio +chmod +x /usr/local/bin/minio + +fetch_and_deploy_gh_release "mc" "minio/mc" "singlefile" "latest" "/opt/stoatchat" "mc_linux_amd64" +mv /opt/stoatchat/mc_linux_amd64 /usr/local/bin/mc +chmod +x /usr/local/bin/mc + +msg_info "Configuring MinIO" +mkdir -p /opt/stoatchat/data/minio +cat </etc/systemd/system/stoatchat-minio.service +[Unit] +Description=Stoatchat MinIO Object Storage +After=network.target + +[Service] +Type=simple +User=root +Environment=MINIO_ROOT_USER=minioautumn +Environment=MINIO_ROOT_PASSWORD=minioautumn +ExecStart=/usr/local/bin/minio server /opt/stoatchat/data/minio --console-address :9001 +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now stoatchat-minio +msg_ok "Configured MinIO" + +msg_info "Creating MinIO Bucket" +until mc alias set local http://127.0.0.1:9000 minioautumn minioautumn &>/dev/null; do sleep 1; done +$STD mc mb local/revolt-uploads +msg_ok "Created MinIO Bucket" + +FILES_ENCRYPTION_KEY=$(openssl rand -base64 32) + +msg_info "Creating Configuration" +cat </Revolt.toml +[database] +mongodb = "mongodb://127.0.0.1:27017" +redis = "redis://127.0.0.1:6379/" + +[hosts] +app = "http://${LOCAL_IP}" +api = "http://${LOCAL_IP}/api" +events = "ws://${LOCAL_IP}/ws" +autumn = "http://${LOCAL_IP}/autumn" +january = "http://${LOCAL_IP}/january" + +[rabbit] +host = "127.0.0.1" +port = 5672 +username = "rabbituser" +password = "rabbitpass" + +[files] +encryption_key = "${FILES_ENCRYPTION_KEY}" + +[files.s3] +endpoint = "http://127.0.0.1:9000" +path_style_buckets = true +region = "minio" +access_key_id = "minioautumn" +secret_access_key = "minioautumn" +default_bucket = "revolt-uploads" + +[api.registration] +invite_only = false +EOF +ln -sf /Revolt.toml /opt/stoatchat/Revolt.toml +msg_ok "Created Configuration" + +msg_info "Configuring Nginx" +cat </etc/nginx/sites-available/stoatchat +server { + listen 80; + + client_max_body_size 20M; + + location /api { + proxy_pass http://127.0.0.1:14702; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + + location /ws { + proxy_pass http://127.0.0.1:14703; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + } + + location /autumn { + proxy_pass http://127.0.0.1:14704; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + + location /january { + proxy_pass http://127.0.0.1:14705; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + + location / { + root /opt/stoatchat-web/packages/client/dist; + try_files \$uri \$uri/ /index.html; + } +} +EOF +ln -sf /etc/nginx/sites-available/stoatchat /etc/nginx/sites-enabled/stoatchat +rm -f /etc/nginx/sites-enabled/default +systemctl enable -q --now nginx +msg_ok "Configured Nginx" + +msg_info "Creating Backend Services" +for SVC in api events autumn january crond; do + case $SVC in + api) + PORT=14702 + BIN=delta + ;; + events) + PORT=14703 + BIN=bonfire + ;; + autumn) + PORT=14704 + BIN=autumn + ;; + january) + PORT=14705 + BIN=january + ;; + crond) + PORT=0 + BIN=crond + ;; + esac + cat </etc/systemd/system/stoatchat-${SVC}.service +[Unit] +Description=Stoatchat ${SVC} service +After=network.target stoatchat-minio.service + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/stoatchat +ExecStart=/opt/stoatchat/target/release/${BIN} +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q --now "stoatchat-${SVC}" +done +msg_ok "Created Backend Services" + +motd_ssh +customize +cleanup_lxc diff --git a/install/xyops-install.sh b/install/xyops-install.sh new file mode 100644 index 00000000..a9d41db2 --- /dev/null +++ b/install/xyops-install.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/pixlcore/xyops + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt install -y \ + build-essential \ + python3 \ + python3-setuptools \ + pkg-config \ + libssl-dev \ + zlib1g-dev +msg_ok "Installed Dependencies" + +NODE_VERSION="22" setup_nodejs + +fetch_and_deploy_gh_release "xyops" "pixlcore/xyops" "tarball" + +msg_info "Building Application" +cd /opt/xyops +$STD npm install +$STD node bin/build.js dist +chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js +msg_ok "Built Application" + +fetch_and_deploy_gh_release "xysat" "pixlcore/xysat" "tarball" "latest" "/opt/xyops/satellite" + +msg_info "Building xySat Satellite" +cd /opt/xyops/satellite +$STD npm install +msg_ok "Built xySat Satellite" + +msg_info "Setting up Directories" +mkdir -p /opt/xyops/data /opt/xyops/logs /opt/xyops/temp /opt/xyops/conf +msg_ok "Set up Directories" + +msg_info "Creating Service" +cat </etc/systemd/system/xyops.service +[Unit] +Description=xyOps Task Scheduler and Server Monitor +After=network.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/xyops +Environment=XYOPS_foreground=1 +Environment=XYOPS_xysat_local=1 +Environment=XYOPS_masters=${LOCAL_IP} +ExecStart=/usr/bin/node /opt/xyops/lib/main.js +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now xyops +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc diff --git a/json/stoatchat.json b/json/stoatchat.json new file mode 100644 index 00000000..0db6f99d --- /dev/null +++ b/json/stoatchat.json @@ -0,0 +1,52 @@ +{ + "name": "Stoatchat", + "slug": "stoatchat", + "categories": [ + 22 + ], + "date_created": "2026-05-08", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 80, + "documentation": "https://github.com/stoatchat/self-hosted", + "website": "https://stoat.chat", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/stoatchat.webp", + "description": "A self-hostable open-source chat platform and community server. Stoatchat is a fork of Revolt, featuring real-time messaging, voice channels, file sharing, and a full-featured web client. Built with Rust (backend) and SolidJS (frontend).", + "install_methods": [ + { + "type": "default", + "script": "ct/stoatchat.sh", + "config_path": "/Revolt.toml", + "resources": { + "cpu": 4, + "ram": 8192, + "hdd": 30, + "os": "Debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "Initial setup takes 30-60 minutes due to Rust compilation and frontend build. Do not interrupt the process.", + "type": "warning" + }, + { + "text": "The first account registered becomes the instance administrator. Registration is open by default; set invite_only = true in /Revolt.toml to restrict it.", + "type": "info" + }, + { + "text": "Voice and video calls require additional LiveKit setup. See https://github.com/stoatchat/self-hosted for details.", + "type": "info" + }, + { + "text": "The files encryption key in /Revolt.toml is generated during installation. Back it up — losing it will make all uploaded files unreadable.", + "type": "warning" + } + ] +} \ No newline at end of file diff --git a/json/xyops.json b/json/xyops.json new file mode 100644 index 00000000..2f8c31b0 --- /dev/null +++ b/json/xyops.json @@ -0,0 +1,48 @@ +{ + "name": "xyOps", + "slug": "xyops", + "categories": [ + 19 + ], + "date_created": "2026-05-08", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 5522, + "documentation": "https://github.com/pixlcore/xyops/tree/main/docs", + "website": "https://github.com/pixlcore/xyops", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/xyops.webp", + "description": "A complete task scheduler and server monitoring system with workflow automation, multi-server management, real-time monitoring, and a built-in satellite agent (xySat) for running jobs on remote servers.", + "install_methods": [ + { + "type": "default", + "script": "ct/xyops.sh", + "config_path": "/opt/xyops/conf/config.json", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "Debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": "admin", + "password": "admin" + }, + "notes": [ + { + "text": "Change the default admin password immediately after first login.", + "type": "warning" + }, + { + "text": "A local xySat satellite is started automatically alongside the conductor, allowing jobs to run on this server right away.", + "type": "info" + }, + { + "text": "The WebSocket port 5523 is used for secure wss:// connections. Port 5522 serves the web interface and ws:// connections.", + "type": "info" + } + ] +} \ No newline at end of file