update romm script - working now

This commit is contained in:
AlphaLawless 2025-12-25 22:28:50 -03:00
parent 9ee22f9af9
commit a104248244
No known key found for this signature in database
GPG Key ID: 2AAB1A79B36DBB3C
3 changed files with 304 additions and 144 deletions

View File

@ -2,7 +2,8 @@
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Co-author: AlphaLawless
# License: MIT | https://github.com/AlphaLawless/ProxmoxVED/raw/main/LICENSE
# Source: https://romm.app
APP="RomM"
@ -10,10 +11,9 @@ var_tags="${var_tags:-emulation}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-20}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_fuse="${var_fuse:-1}"
header_info "$APP"
variables
@ -30,35 +30,44 @@ function update_script() {
exit
fi
msg_info "Stopping $APP"
systemctl stop romm
systemctl stop nginx
msg_ok "Stopped $APP"
if check_for_gh_release "romm" "rommapp/romm"; then
msg_info "Stopping ${APP} services"
systemctl stop romm-backend romm-worker romm-scheduler romm-watcher
msg_ok "Stopped ${APP} services"
msg_info "Updating $APP"
cd /opt/romm/app
git pull
msg_info "Backing up configuration"
cp /opt/romm/.env /opt/romm/.env.backup
msg_ok "Backed up configuration"
# Update backend
cd /opt/romm/app
source /opt/romm/venv/bin/activate
pip install --upgrade pip
pip install poetry
poetry install
msg_info "Updating ${APP}"
fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball" "latest" "/opt/romm"
# Update frontend
cd /opt/romm/app/frontend
npm install
npm run build
cp /opt/romm/.env.backup /opt/romm/.env
echo "Updated on $(date)" >/opt/romm/version.txt
msg_ok "Updated $APP"
cd /opt/romm
$STD uv sync --all-extras
msg_info "Starting $APP"
systemctl start romm
systemctl start nginx
msg_ok "Started $APP"
msg_ok "Update Successful"
cd /opt/romm/backend
$STD uv run alembic upgrade head
cd /opt/romm/frontend
$STD npm install
$STD npm run build
# Merge static assets into dist folder
cp -rf /opt/romm/frontend/assets/* /opt/romm/frontend/dist/assets/
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/assets /opt/romm/frontend/dist/assets/romm/assets
msg_ok "Updated ${APP}"
msg_info "Starting ${APP} services"
systemctl start romm-backend romm-worker romm-scheduler romm-watcher
msg_ok "Started ${APP} services"
msg_ok "Update Successful"
fi
exit
}
@ -69,4 +78,4 @@ 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}:8080${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

View File

@ -2,9 +2,10 @@
# Copyright (c) 2021-2025 community-scripts ORG
# Author: DevelopmentCats
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Co-author: AlphaLawless
# License: MIT | https://github.com/AlphaLawless/ProxmoxVED/raw/main/LICENSE
# Source: https://romm.app
# Updated: 03/10/2025
# Updated: 25/12/2025
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
@ -18,65 +19,126 @@ msg_info "Installing dependencies"
$STD apt-get install -y \
acl \
build-essential \
gcc \
g++ \
make \
git \
curl \
libssl-dev \
libffi-dev \
libmagic-dev \
python3-dev \
python3-pip \
python3-venv \
libmariadb3 \
libmariadb-dev \
libpq-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
zlib1g-dev \
liblzma-dev \
libncurses5-dev \
libncursesw5-dev \
redis-server \
redis-tools \
p7zip \
p7zip-full \
tzdata \
jq
msg_ok "Installed core dependencies"
jq \
nginx
msg_ok "Installed dependencies"
PYTHON_VERSION="3.12" setup_uv
NODE_VERSION="22" NODE_MODULE="serve" setup_nodejs
UV_VERSION="0.7.19" PYTHON_VERSION="3.13" setup_uv
NODE_VERSION="22" setup_nodejs
setup_mariadb
MARIADB_DB_NAME="romm" MARIADB_DB_USER="romm" setup_mariadb_db
msg_info "Configuring Database"
DB_NAME=romm
DB_USER=romm
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$STD mariadb -u root -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "RomM-Credentials"
echo "RomM Database User: $DB_USER"
echo "RomM Database Password: $DB_PASS"
echo "RomM Database Name: $DB_NAME"
} >~/romm.creds
chmod 600 ~/romm.creds
msg_ok "Configured Database"
msg_info "Creating romm user and directories"
id -u romm &>/dev/null || useradd -r -m -d /var/lib/romm -s /bin/bash romm
msg_info "Creating directories"
mkdir -p /opt/romm \
/var/lib/romm/config \
/var/lib/romm/resources \
/var/lib/romm/assets/{saves,states,screenshots} \
/var/lib/romm/library/roms/{gba,gbc,ps} \
/var/lib/romm/library/bios/{gba,ps}
chown -R romm:romm /opt/romm /var/lib/romm
msg_ok "Created romm user and directories"
/var/lib/romm/library/roms \
/var/lib/romm/library/bios
msg_ok "Created directories"
msg_info "Configuring Database"
DB_NAME=romm
DB_USER=romm
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "RomM-Credentials"
echo "RomM Database User: $DB_USER"
echo "RomM Database Password: $DB_PASS"
echo "RomM Database Name: $DB_NAME"
} >~/romm.creds
msg_ok "Configured Database"
msg_info "Creating configuration file"
cat >/var/lib/romm/config/config.yml <<'CONFIGEOF'
# RomM Configuration File
# Documentation: https://docs.romm.app/latest/Getting-Started/Configuration-File/
# Only uncomment the lines you want to use/modify
# exclude:
# platforms:
# - excluded_folder_a
# roms:
# single_file:
# extensions:
# - xml
# - txt
# names:
# - '._*'
# - '*.nfo'
# multi_file:
# names:
# - downloaded_media
# - media
# system:
# platforms:
# gc: ngc
# ps1: psx
# The folder name where your roms are located (relative to library path)
# filesystem:
# roms_folder: 'roms'
# scan:
# priority:
# metadata:
# - "igdb"
# - "moby"
# - "ss"
# - "ra"
# artwork:
# - "igdb"
# - "moby"
# - "ss"
# region:
# - "us"
# - "eu"
# - "jp"
# language:
# - "en"
# media:
# - box2d
# - box3d
# - screenshot
# - manual
# emulatorjs:
# debug: false
# cache_limit: null
CONFIGEOF
chmod 644 /var/lib/romm/config/config.yml
msg_ok "Created configuration file"
msg_info "Building RAHasher (RetroAchievements)"
RAHASHER_VERSION="1.8.1"
cd /tmp
git clone --recursive --branch "$RAHASHER_VERSION" --depth 1 https://github.com/RetroAchievements/RALibretro.git
cd RALibretro
sed -i '22a #include <ctime>' ./src/Util.h
sed -i '6a #include <unistd.h>' \
./src/libchdr/deps/zlib-1.3.1/gzlib.c \
./src/libchdr/deps/zlib-1.3.1/gzread.c \
./src/libchdr/deps/zlib-1.3.1/gzwrite.c
$STD make HAVE_CHD=1 -f ./Makefile.RAHasher
cp ./bin64/RAHasher /usr/bin/RAHasher
chmod +x /usr/bin/RAHasher
cd /tmp
rm -rf /tmp/RALibretro
msg_ok "Built RAHasher"
fetch_and_deploy_gh_release "romm" "rommapp/romm"
@ -88,13 +150,14 @@ AUTH_SECRET_KEY=$(openssl rand -hex 32)
cat >/opt/romm/.env <<EOF
ROMM_BASE_PATH=/var/lib/romm
ROMM_CONFIG_PATH=/var/lib/romm/config/config.yml
WEB_CONCURRENCY=4
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=$DB_NAME
DB_USER=$DB_USER
DB_PASSWD=$DB_PASS
DB_NAME=$MARIADB_DB_NAME
DB_USER=$MARIADB_DB_USER
DB_PASSWD=$MARIADB_DB_PASS
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
@ -114,29 +177,101 @@ SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON=0 4 * * *
LOGLEVEL=INFO
EOF
chown romm:romm /opt/romm/.env
chmod 600 /opt/romm/.env
msg_ok "Created environment file"
msg_info "Installing backend"
cd /opt/romm
uv pip install --all-extras .
# Limit concurrent downloads to avoid DNS resolution failures in LXC containers
# See: https://github.com/astral-sh/uv/issues/12054
export UV_CONCURRENT_DOWNLOADS=1
$STD uv sync --all-extras
cd /opt/romm/backend
uv run alembic upgrade head
chown -R romm:romm /opt/romm
$STD uv run alembic upgrade head
msg_ok "Installed backend"
msg_info "Installing frontend"
cd /opt/romm/frontend
npm install
npm run build
ln -sfn /var/lib/romm/resources /opt/romm/frontend/assets/romm/resources
ln -sfn /var/lib/romm/assets /opt/romm/frontend/assets/romm/assets
chown -R romm:romm /opt/romm
$STD npm install
$STD npm run build
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/assets /opt/romm/frontend/dist/assets/romm/assets
msg_ok "Installed frontend"
msg_info "Creating services"
msg_info "Configuring nginx"
cat >/etc/nginx/sites-available/romm <<'EOF'
upstream romm_backend {
server 127.0.0.1:5000;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name _;
root /opt/romm/frontend/dist;
client_max_body_size 0;
# Frontend SPA
location / {
try_files $uri $uri/ /index.html;
}
# EmulatorJS player - requires COOP/COEP headers for SharedArrayBuffer
location ~ ^/rom/.*/ejs$ {
add_header Cross-Origin-Embedder-Policy "require-corp";
add_header Cross-Origin-Opener-Policy "same-origin";
try_files $uri /index.html;
}
# Backend API
location /api {
proxy_pass http://romm_backend;
proxy_buffering off;
proxy_request_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# WebSocket and Netplay
location ~ ^/(ws|netplay) {
proxy_pass http://romm_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
# OpenAPI docs
location = /openapi.json {
proxy_pass http://romm_backend;
}
# Internal library file serving
location /library/ {
internal;
alias /var/lib/romm/library/;
}
}
EOF
rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/romm /etc/nginx/sites-enabled/romm
$STD nginx -t
systemctl restart nginx
systemctl enable -q nginx
msg_ok "Configured nginx"
msg_info "Creating services"
cat >/etc/systemd/system/romm-backend.service <<EOF
[Unit]
Description=RomM Backend
@ -145,27 +280,12 @@ Requires=mariadb.service redis-server.service
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/backend
EnvironmentFile=/opt/romm/.env
Environment="PYTHONPATH=/opt/romm"
ExecStart=/opt/romm/.venv/bin/uv run gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:5000
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/romm-frontend.service <<EOF
[Unit]
Description=RomM Frontend
After=network.target
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/frontend
ExecStart=$(which serve) -s dist -l 8080
ExecStart=/opt/romm/.venv/bin/python main.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
@ -173,17 +293,18 @@ EOF
cat >/etc/systemd/system/romm-worker.service <<EOF
[Unit]
Description=RomM Worker
Description=RomM RQ Worker
After=network.target mariadb.service redis-server.service romm-backend.service
Requires=mariadb.service redis-server.service
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/backend
Environment="PYTHONPATH=/opt/romm"
ExecStart=/opt/romm/.venv/bin/uv run python3 worker.py
EnvironmentFile=/opt/romm/.env
Environment="PYTHONPATH=/opt/romm/backend"
ExecStart=/opt/romm/.venv/bin/rq worker --path /opt/romm/backend --url redis://127.0.0.1:6379/0 high default low
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
@ -191,33 +312,48 @@ EOF
cat >/etc/systemd/system/romm-scheduler.service <<EOF
[Unit]
Description=RomM Scheduler
Description=RomM RQ Scheduler
After=network.target mariadb.service redis-server.service romm-backend.service
Requires=mariadb.service redis-server.service
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/backend
Environment="PYTHONPATH=/opt/romm"
ExecStart=/opt/romm/.venv/bin/uv run python3 scheduler.py
EnvironmentFile=/opt/romm/.env
Environment="PYTHONPATH=/opt/romm/backend"
Environment="RQ_REDIS_HOST=127.0.0.1"
Environment="RQ_REDIS_PORT=6379"
ExecStart=/opt/romm/.venv/bin/rqscheduler --path /opt/romm/backend
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now romm-backend romm-frontend romm-worker romm-scheduler
msg_ok "Created services"
cat >/etc/systemd/system/romm-watcher.service <<EOF
[Unit]
Description=RomM Filesystem Watcher
After=network.target romm-backend.service
Requires=romm-backend.service
# Install serve globally
su - ${ROMM_USER} -c "npm install -g serve"
[Service]
Type=simple
WorkingDirectory=/opt/romm/backend
EnvironmentFile=/opt/romm/.env
Environment="PYTHONPATH=/opt/romm/backend"
ExecStart=/opt/romm/.venv/bin/watchfiles --target-type command '/opt/romm/.venv/bin/python watcher.py' /var/lib/romm/library
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable -q --now romm-backend romm-worker romm-scheduler romm-watcher
msg_ok "Created services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
$STD apt-get -y clean
msg_ok "Cleaned up"
cleanup_lxc

View File

@ -4675,6 +4675,8 @@ function setup_uv() {
local UVX_BIN="/usr/local/bin/uvx"
local TMP_DIR=$(mktemp -d)
local CACHED_VERSION
local TARGET_VERSION=""
local USE_PINNED_VERSION=false
# trap for TMP Cleanup
trap "rm -rf '$TMP_DIR'" EXIT
@ -4710,22 +4712,27 @@ function setup_uv() {
ensure_dependencies jq
# Fetch latest version
local releases_json
releases_json=$(curl -fsSL --max-time 15 \
"https://api.github.com/repos/astral-sh/uv/releases/latest" 2>/dev/null || echo "")
# Check if specific version is requested via UV_VERSION environment variable
if [[ -n "${UV_VERSION:-}" ]]; then
TARGET_VERSION="${UV_VERSION}"
USE_PINNED_VERSION=true
else
# Fetch latest version from GitHub API
local releases_json
releases_json=$(curl -fsSL --max-time 15 \
"https://api.github.com/repos/astral-sh/uv/releases/latest" 2>/dev/null || echo "")
if [[ -z "$releases_json" ]]; then
msg_error "Could not fetch latest uv version from GitHub API"
return 1
fi
if [[ -z "$releases_json" ]]; then
msg_error "Could not fetch latest uv version from GitHub API"
return 1
fi
local LATEST_VERSION
LATEST_VERSION=$(echo "$releases_json" | jq -r '.tag_name' 2>/dev/null | sed 's/^v//')
TARGET_VERSION=$(echo "$releases_json" | jq -r '.tag_name' 2>/dev/null | sed 's/^v//')
if [[ -z "$LATEST_VERSION" ]]; then
msg_error "Could not parse uv version from GitHub API response"
return 1
if [[ -z "$TARGET_VERSION" ]]; then
msg_error "Could not parse uv version from GitHub API response"
return 1
fi
fi
# Get currently installed version
@ -4734,9 +4741,9 @@ function setup_uv() {
INSTALLED_VERSION=$("$UV_BIN" --version 2>/dev/null | awk '{print $2}')
fi
# Scenario 1: Already at latest version
if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" == "$LATEST_VERSION" ]]; then
cache_installed_version "uv" "$LATEST_VERSION"
# Scenario 1: Already at target version
if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" == "$TARGET_VERSION" ]]; then
cache_installed_version "uv" "$TARGET_VERSION"
# Check if uvx is needed and missing
if [[ "${USE_UVX:-NO}" == "YES" ]] && [[ ! -x "$UVX_BIN" ]]; then
@ -4748,14 +4755,22 @@ function setup_uv() {
return 0
fi
# Scenario 2: New install or upgrade
if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" != "$LATEST_VERSION" ]]; then
msg_info "Upgrade uv from $INSTALLED_VERSION to $LATEST_VERSION"
# Scenario 2: New install or upgrade/downgrade
if [[ -n "$INSTALLED_VERSION" ]]; then
if [[ "$USE_PINNED_VERSION" == true ]]; then
msg_info "Switching uv from $INSTALLED_VERSION to pinned version $TARGET_VERSION"
else
msg_info "Upgrade uv from $INSTALLED_VERSION to $TARGET_VERSION"
fi
else
msg_info "Setup uv $LATEST_VERSION"
if [[ "$USE_PINNED_VERSION" == true ]]; then
msg_info "Setup uv $TARGET_VERSION (pinned)"
else
msg_info "Setup uv $TARGET_VERSION"
fi
fi
local UV_URL="https://github.com/astral-sh/uv/releases/download/${LATEST_VERSION}/${UV_TAR}"
local UV_URL="https://github.com/astral-sh/uv/releases/download/${TARGET_VERSION}/${UV_TAR}"
$STD curl -fsSL "$UV_URL" -o "$TMP_DIR/uv.tar.gz" || {
msg_error "Failed to download uv from $UV_URL"
@ -4809,8 +4824,8 @@ function setup_uv() {
msg_ok "Python $PYTHON_VERSION installed"
fi
cache_installed_version "uv" "$LATEST_VERSION"
msg_ok "Setup uv $LATEST_VERSION"
cache_installed_version "uv" "$TARGET_VERSION"
msg_ok "Setup uv $TARGET_VERSION"
}
# Helper function to install uvx wrapper