This commit is contained in:
CanbiZ (MickLesk) 2026-01-23 09:42:23 +01:00
commit f6c5d0cc18
5 changed files with 277 additions and 47 deletions

68
ct/fileflows.sh Normal file
View File

@ -0,0 +1,68 @@
#!/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: kkroboth
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://fileflows.com/
APP="FileFlows"
var_tags="${var_tags:-media;automation}"
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}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/fileflows ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if ! [[ $(dpkg -s jq 2>/dev/null) ]]; then
$STD apt-get update
$STD apt-get install -y jq
fi
update_available=$(curl -fsSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' | jq .UpdateAvailable)
if [[ "${update_available}" == "true" ]]; then
msg_info "Stopping Service"
systemctl stop fileflows
msg_info "Stopped Service"
msg_info "Creating Backup"
backup_filename="/opt/${APP}_backup_$(date +%F).tar.gz"
tar -czf "$backup_filename" -C /opt/fileflows Data
msg_ok "Backup Created"
fetch_and_deploy_archive "https://fileflows.com/downloads/zip" "/opt/fileflows"
msg_info "Starting Service"
systemctl start fileflows
msg_ok "Started Service"
msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at latest version"
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}:19200${CL}"

View File

@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: kkroboth
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://fileflows.com/
# Import Functions und Setup
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 \
ffmpeg \
imagemagick
msg_ok "Installed Dependencies"
setup_hwaccel
setup_deb822_repo \
"microsoft" \
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
"https://packages.microsoft.com/debian/13/prod/" \
"trixie"
fetch_and_deploy_archive "https://fileflows.com/downloads/zip" "/opt/fileflows"
msg_info "Installing ASP.NET Core Runtime"
$STD apt install -y aspnetcore-runtime-8.0
msg_ok "Installed ASP.NET Core Runtime"
msg_info "Setting up FileFlows"
$STD ln -svf /usr/bin/ffmpeg /usr/local/bin/ffmpeg
$STD ln -svf /usr/bin/ffprobe /usr/local/bin/ffprobe
cd /opt/fileflows/Server
$STD dotnet FileFlows.Server.dll --systemd install --root true
systemctl enable -q --now fileflows
msg_ok "Setup FileFlows"
motd_ssh
customize
cleanup_lxc

View File

@ -15,28 +15,29 @@ update_os
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
#fetch_and_deploy_gh_release "jotty" "fccview/jotty" "tarball" "latest" "/opt/jotty" #fetch_and_deploy_gh_release "jotty" "fccview/jotty" "tarball" "latest" "/opt/jotty"
mkdir -p /opt/jotty
wget -q https://github.com/fccview/jotty/releases/download/develop/jotty-prebuild-develop.tar.gz -O /tmp/jotty.tar.gz
tar -xzf /tmp/jotty.tar.gz -C /opt/jotty --strip-components=1
msg_info "Setup jotty" msg_info "Setup jotty"
mkdir -p /opt/jotty
wget -q https://github.com/fccview/jotty/releases/download/develop/jotty-prebuild-develop.tar.gz -O /opt/jotty.tar.gz
cd /opt
tar -xzf jotty.tar.gz
cd /opt/jotty cd /opt/jotty
unset NODE_OPTIONS # unset NODE_OPTIONS
export NODE_OPTIONS="--max-old-space-size=3072" # export NODE_OPTIONS="--max-old-space-size=3072"
# $STD yarn --frozen-lockfiled # # $STD yarn --frozen-lockfiled
# $STD yarn next telemetry disable # # $STD yarn next telemetry disable
# $STD yarn build # # $STD yarn build
[ -d "public" ] && cp -r public .next/standalone/ # [ -d "public" ] && cp -r public .next/standalone/
[ -d "howto" ] && cp -r howto .next/standalone/ # [ -d "howto" ] && cp -r howto .next/standalone/
mkdir -p .next/standalone/.next # mkdir -p .next/standalone/.next
cp -r .next/static .next/standalone/.next/ # cp -r .next/static .next/standalone/.next/
mv .next/standalone /tmp/jotty_standalone # mv .next/standalone /tmp/jotty_standalone
rm -rf ./* .next .git .gitignore .yarn # rm -rf ./* .next .git .gitignore .yarn
mv /tmp/jotty_standalone/* . # mv /tmp/jotty_standalone/* .
mv /tmp/jotty_standalone/.[!.]* . 2>/dev/null || true # mv /tmp/jotty_standalone/.[!.]* . 2>/dev/null || true
rm -rf /tmp/jotty_standalone # rm -rf /tmp/jotty_standalone
mkdir -p data/{users,checklists,notes} mkdir -p data/{users,checklists,notes}

View File

@ -15,13 +15,11 @@ setting_up_container
network_check network_check
update_os update_os
msg_info "Installing dependencies" msg_info "Installing Dependencies"
$STD apt-get install -y \ $STD apt install -y \
acl \ acl \
git \
build-essential \ build-essential \
gcc \
g++ \
make \
libssl-dev \ libssl-dev \
libffi-dev \ libffi-dev \
libmagic-dev \ libmagic-dev \
@ -43,9 +41,9 @@ $STD apt-get install -y \
p7zip-full \ p7zip-full \
tzdata \ tzdata \
nginx nginx
msg_ok "Installed dependencies" msg_ok "Installed Dependencies"
UV_VERSION="0.7.19" PYTHON_VERSION="3.13" setup_uv PYTHON_VERSION="3.13" setup_uv
NODE_VERSION="22" setup_nodejs NODE_VERSION="22" setup_nodejs
setup_mariadb setup_mariadb
MARIADB_DB_NAME="romm" MARIADB_DB_USER="romm" setup_mariadb_db MARIADB_DB_NAME="romm" MARIADB_DB_USER="romm" setup_mariadb_db
@ -60,7 +58,7 @@ mkdir -p /opt/romm \
msg_ok "Created directories" msg_ok "Created directories"
msg_info "Creating configuration file" msg_info "Creating configuration file"
cat >/var/lib/romm/config/config.yml <<'CONFIGEOF' cat <<'EOF' >/var/lib/romm/config/config.yml
# RomM Configuration File # RomM Configuration File
# Documentation: https://docs.romm.app/latest/Getting-Started/Configuration-File/ # Documentation: https://docs.romm.app/latest/Getting-Started/Configuration-File/
# Only uncomment the lines you want to use/modify # Only uncomment the lines you want to use/modify
@ -116,15 +114,13 @@ cat >/var/lib/romm/config/config.yml <<'CONFIGEOF'
# emulatorjs: # emulatorjs:
# debug: false # debug: false
# cache_limit: null # cache_limit: null
CONFIGEOF EOF
chmod 644 /var/lib/romm/config/config.yml chmod 644 /var/lib/romm/config/config.yml
msg_ok "Created configuration file" msg_ok "Created configuration file"
msg_info "Installing RAHasher (RetroAchievements)" fetch_and_deploy_gh_release "RAHasher" "RetroAchievements/RALibretro" "prebuild" "latest" "/opt/RALibretro" "RAHasher-x64-Linux-*.zip"
fetch_and_deploy_gh_release "RetroAchievements" "RetroAchievements/RALibretro" "prebuild" "latest" "/opt/RALibretro" "RAHasher-x64-Linux-*.zip"
cp /opt/RALibretro/RAHasher /usr/bin/RAHasher cp /opt/RALibretro/RAHasher /usr/bin/RAHasher
chmod +x /usr/bin/RAHasher chmod +x /usr/bin/RAHasher
msg_ok "Installed RAHasher"
fetch_and_deploy_gh_release "romm" "rommapp/romm" fetch_and_deploy_gh_release "romm" "rommapp/romm"
@ -134,7 +130,7 @@ systemctl restart redis-server
systemctl enable -q --now redis-server systemctl enable -q --now redis-server
AUTH_SECRET_KEY=$(openssl rand -hex 32) AUTH_SECRET_KEY=$(openssl rand -hex 32)
cat >/opt/romm/.env <<EOF cat <<EOF >/opt/romm/.env
ROMM_BASE_PATH=/var/lib/romm ROMM_BASE_PATH=/var/lib/romm
ROMM_CONFIG_PATH=/var/lib/romm/config/config.yml ROMM_CONFIG_PATH=/var/lib/romm/config/config.yml
WEB_CONCURRENCY=4 WEB_CONCURRENCY=4
@ -166,24 +162,25 @@ EOF
chmod 600 /opt/romm/.env chmod 600 /opt/romm/.env
msg_ok "Created environment file" msg_ok "Created environment file"
msg_info "Setup Romm backend" msg_info "Setting up RomM Backend"
cd /opt/romm cd /opt/romm
export UV_CONCURRENT_DOWNLOADS=1 export UV_CONCURRENT_DOWNLOADS=1
$STD uv sync --all-extras $STD uv sync --all-extras
cd /opt/romm/backend cd /opt/romm/backend
$STD uv run alembic upgrade head $STD uv run alembic upgrade head
msg_ok "Installed backend" msg_ok "Set up RomM Backend"
msg_info "Setup Romm frontend" msg_info "Setting up RomM Frontend"
cd /opt/romm/frontend cd /opt/romm/frontend
$STD npm install $STD npm install
$STD npm run build $STD npm run build
mkdir -p /opt/romm/frontend/dist/assets/romm mkdir -p /opt/romm/frontend/dist/assets/romm
ln -sfn /var/lib/romm/resources /opt/romm/frontend/dist/assets/romm/resources ln -sfn /var/lib/romm/resources /opt/romm/frontend/dist/assets/romm/resources
ln -sfn /var/lib/romm/assets /opt/romm/frontend/dist/assets/romm/assets ln -sfn /var/lib/romm/assets /opt/romm/frontend/dist/assets/romm/assets
msg_ok "Setup Romm frontend" msg_ok "Set up RomM Frontend"
msg_info "Configuring nginx"
cat >/etc/nginx/sites-available/romm <<'EOF' msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/romm
upstream romm_backend { upstream romm_backend {
server 127.0.0.1:5000; server 127.0.0.1:5000;
} }
@ -204,6 +201,14 @@ server {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
# Static assets
location /assets {
alias /opt/romm/frontend/dist/assets;
try_files $uri $uri/ =404;
expires 1y;
add_header Cache-Control "public, immutable";
}
# EmulatorJS player - requires COOP/COEP headers for SharedArrayBuffer # EmulatorJS player - requires COOP/COEP headers for SharedArrayBuffer
location ~ ^/rom/.*/ejs$ { location ~ ^/rom/.*/ejs$ {
add_header Cross-Origin-Embedder-Policy "require-corp"; add_header Cross-Origin-Embedder-Policy "require-corp";
@ -247,13 +252,12 @@ EOF
rm -f /etc/nginx/sites-enabled/default rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/romm /etc/nginx/sites-enabled/romm ln -sf /etc/nginx/sites-available/romm /etc/nginx/sites-enabled/romm
$STD nginx -t
systemctl restart nginx systemctl restart nginx
systemctl enable -q nginx systemctl enable -q --now nginx
msg_ok "Configured nginx" msg_ok "Configured Nginx"
msg_info "Creating services" msg_info "Creating Services"
cat >/etc/systemd/system/romm-backend.service <<EOF cat <<EOF >/etc/systemd/system/romm-backend.service
[Unit] [Unit]
Description=RomM Backend Description=RomM Backend
After=network.target mariadb.service redis-server.service After=network.target mariadb.service redis-server.service
@ -272,7 +276,7 @@ RestartSec=5
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
cat >/etc/systemd/system/romm-worker.service <<EOF cat <<EOF >/etc/systemd/system/romm-worker.service
[Unit] [Unit]
Description=RomM RQ Worker Description=RomM RQ Worker
After=network.target mariadb.service redis-server.service romm-backend.service After=network.target mariadb.service redis-server.service romm-backend.service
@ -291,7 +295,7 @@ RestartSec=5
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
cat >/etc/systemd/system/romm-scheduler.service <<EOF cat <<EOF >/etc/systemd/system/romm-scheduler.service
[Unit] [Unit]
Description=RomM RQ Scheduler Description=RomM RQ Scheduler
After=network.target mariadb.service redis-server.service romm-backend.service After=network.target mariadb.service redis-server.service romm-backend.service
@ -312,7 +316,7 @@ RestartSec=5
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
cat >/etc/systemd/system/romm-watcher.service <<EOF cat <<EOF >/etc/systemd/system/romm-watcher.service
[Unit] [Unit]
Description=RomM Filesystem Watcher Description=RomM Filesystem Watcher
After=network.target romm-backend.service After=network.target romm-backend.service
@ -331,9 +335,8 @@ RestartSec=5
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
systemctl daemon-reload
systemctl enable -q --now romm-backend romm-worker romm-scheduler romm-watcher systemctl enable -q --now romm-backend romm-worker romm-scheduler romm-watcher
msg_ok "Created services" msg_ok "Created Services"
motd_ssh motd_ssh
customize customize

View File

@ -5922,3 +5922,116 @@ EOF
msg_ok "Docker setup completed" msg_ok "Docker setup completed"
} }
# ------------------------------------------------------------------------------
# Fetch and deploy archive from URL
# Downloads an archive (zip or tar.gz) from a URL and extracts it to a directory
#
# Usage: fetch_and_deploy_archive "url" "directory"
# url - URL to the archive (zip or tar.gz)
# directory - Destination path where the archive will be extracted
#
# Examples:
# fetch_and_deploy_archive "https://example.com/app.tar.gz" "/opt/myapp"
# fetch_and_deploy_archive "https://example.com/app.zip" "/opt/myapp"
# ------------------------------------------------------------------------------
function fetch_and_deploy_archive() {
local url="$1"
local directory="$2"
if [[ -z "$url" ]]; then
msg_error "URL parameter is required"
return 1
fi
if [[ -z "$directory" ]]; then
msg_error "Directory parameter is required"
return 1
fi
local filename="${url##*/}"
local archive_type="zip"
if [[ "$filename" == *.tar.gz || "$filename" == *.tgz ]]; then
archive_type="tar"
fi
msg_info "Downloading archive from $url"
local tmpdir
tmpdir=$(mktemp -d) || {
msg_error "Failed to create temporary directory"
return 1
}
curl -fsSL -o "$tmpdir/$filename" "$url" || {
msg_error "Download failed: $url"
rm -rf "$tmpdir"
return 1
}
msg_info "Extracting archive to $directory"
mkdir -p "$directory"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
rm -rf "${directory:?}/"*
fi
local unpack_tmp
unpack_tmp=$(mktemp -d)
if [[ "$archive_type" == "zip" ]]; then
ensure_dependencies unzip
unzip -q "$tmpdir/$filename" -d "$unpack_tmp" || {
msg_error "Failed to extract ZIP archive"
rm -rf "$tmpdir" "$unpack_tmp"
return 1
}
elif [[ "$archive_type" == "tar" ]]; then
tar --no-same-owner -xf "$tmpdir/$filename" -C "$unpack_tmp" || {
msg_error "Failed to extract TAR archive"
rm -rf "$tmpdir" "$unpack_tmp"
return 1
}
fi
local top_entries
top_entries=$(find "$unpack_tmp" -mindepth 1 -maxdepth 1)
if [[ "$(echo "$top_entries" | wc -l)" -eq 1 && -d "$top_entries" ]]; then
local inner_dir="$top_entries"
shopt -s dotglob nullglob
if compgen -G "$inner_dir/*" >/dev/null; then
cp -r "$inner_dir"/* "$directory/" || {
msg_error "Failed to copy contents from $inner_dir to $directory"
rm -rf "$tmpdir" "$unpack_tmp"
return 1
}
else
msg_error "Inner directory is empty: $inner_dir"
rm -rf "$tmpdir" "$unpack_tmp"
return 1
fi
shopt -u dotglob nullglob
else
shopt -s dotglob nullglob
if compgen -G "$unpack_tmp/*" >/dev/null; then
cp -r "$unpack_tmp"/* "$directory/" || {
msg_error "Failed to copy contents to $directory"
rm -rf "$tmpdir" "$unpack_tmp"
return 1
}
else
msg_error "Unpacked archive is empty"
rm -rf "$tmpdir" "$unpack_tmp"
return 1
fi
shopt -u dotglob nullglob
fi
rm -rf "$tmpdir" "$unpack_tmp"
msg_ok "Successfully deployed archive to $directory"
return 0
}