Merge branch 'main' into dramikei/ente-enhancement

This commit is contained in:
Raghav Vashisht
2025-11-23 18:16:20 +05:30
committed by GitHub
114 changed files with 31283 additions and 8521 deletions

View File

@@ -1,98 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://garagehq.deuxfleurs.fr/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Preparing directories"
mkdir -p /var/lib/garage/meta /var/lib/garage/data /var/lib/garage/snapshots
msg_ok "Prepared directories"
msg_info "Setup Garage packages"
$STD apk add --no-cache garage garage-openrc openssl
msg_ok "Setup Garage packages"
# msg_info "Generating RPC secret"
# if [[ ! -s /etc/garage.rpc_secret ]]; then
# openssl rand -hex 32 | tr -d '\n' >/etc/garage.rpc_secret
# chmod 600 /etc/garage.rpc_secret
# fi
# msg_ok "Generated RPC secret"
# msg_info "Generating tokens"
# if [[ ! -s /etc/garage.tokens.env ]]; then
# ADMIN_TOKEN="$(openssl rand -base64 32)"
# METRICS_TOKEN="$(openssl rand -base64 32)"
# cat >/etc/garage.tokens.env <<EOF
# GARAGE_ADMIN_TOKEN="${ADMIN_TOKEN}"
# GARAGE_METRICS_TOKEN="${METRICS_TOKEN}"
# EOF
# chmod 600 /etc/garage.tokens.env
# else
# source /etc/garage.tokens.env
# ADMIN_TOKEN="${GARAGE_ADMIN_TOKEN}"
# METRICS_TOKEN="${GARAGE_METRICS_TOKEN}"
# fi
# msg_ok "Generated tokens"
msg_info "Writing config"
if [[ ! -f /etc/garage.toml ]]; then
cat >/etc/garage.toml <<EOF
replication_factor = 1
consistency_mode = "consistent"
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
metadata_snapshots_dir = "/var/lib/garage/snapshots"
db_engine = "lmdb"
metadata_fsync = true
data_fsync = false
metadata_auto_snapshot_interval = "6h"
rpc_bind_addr = "0.0.0.0:3901"
rpc_public_addr = "127.0.0.1:3901"
allow_world_readable_secrets = false
[s3_api]
api_bind_addr = "0.0.0.0:3900"
s3_region = "garage"
root_domain = ".s3.garage"
[s3_web]
bind_addr = "0.0.0.0:3902"
root_domain = ".web.garage"
add_host_to_metrics = true
[admin]
api_bind_addr = "0.0.0.0:3903"
metrics_require_token = false
EOF
fi
msg_ok "Wrote config"
msg_info "Enable + start service"
$STD rc-update add garage default
$STD rc-service garage restart || $STD rc-service garage start
$STD rc-service garage status || true
msg_ok "Service active"
msg_info "Setup Node"
garage node id
NODE_ID=$(garage node id | cut -d@ -f1)
garage layout assign $NODE_ID --capacity 1T
garage layout apply
garage status
msg_ok "Node setup"
motd_ssh
customize

View File

@@ -21,7 +21,6 @@ $STD apk add nano
$STD apk add mc
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
motd_ssh
customize

View File

@@ -1,87 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: jdacode
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/comfyanonymous/ComfyUI
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
echo
echo "${TAB3}Choose the GPU type for ComfyUI:"
echo "${TAB3}[1]-None [2]-NVIDIA [3]-AMD [4]-Intel"
read -rp "${TAB3}Enter your choice [1-4] (default: 1): " gpu_choice
gpu_choice=${gpu_choice:-1}
case "$gpu_choice" in
1) comfyui_gpu_type="none";;
2) comfyui_gpu_type="nvidia";;
3) comfyui_gpu_type="amd";;
4) comfyui_gpu_type="intel";;
*) comfyui_gpu_type="none"; echo "${TAB3}Invalid choice. Defaulting to ${comfyui_gpu_type}." ;;
esac
echo
PYTHON_VERSION="3.12" setup_uv
fetch_and_deploy_gh_release "ComfyUI" "comfyanonymous/ComfyUI" "tarball" "latest" "/opt/ComfyUI"
msg_info "Python dependencies"
$STD uv venv "/opt/ComfyUI/venv"
if [[ "${comfyui_gpu_type,,}" == "nvidia" ]]; then
$STD uv pip install \
torch \
torchvision \
torchaudio \
--extra-index-url "https://download.pytorch.org/whl/cu128" \
--python="/opt/ComfyUI/venv/bin/python"
elif [[ "${comfyui_gpu_type,,}" == "amd" ]]; then
$STD uv pip install \
torch \
torchvision \
torchaudio \
--index-url "https://download.pytorch.org/whl/rocm6.3" \
--python="/opt/ComfyUI/venv/bin/python"
elif [[ "${comfyui_gpu_type,,}" == "intel" ]]; then
$STD uv pip install \
torch \
torchvision \
torchaudio \
--index-url "https://download.pytorch.org/whl/xpu" \
--python="/opt/ComfyUI/venv/bin/python"
fi
$STD uv pip install -r "/opt/ComfyUI/requirements.txt" --python="/opt/ComfyUI/venv/bin/python"
msg_ok "Python dependencies"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/comfyui.service
[Unit]
Description=ComfyUI Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ComfyUI
ExecStart=/opt/ComfyUI/venv/bin/python /opt/ComfyUI/main.py --listen --port 8188 --cpu
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now comfyui
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/fccview/cronmaster
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 pciutils
msg_ok "Installed dependencies"
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
setup_deb822_repo \
"docker" \
"https://download.docker.com/linux/debian/gpg" \
"https://download.docker.com/linux/debian" \
"trixie" \
"stable"
$STD apt install -y docker-ce-cli
fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "tarball"
msg_info "Setting up CronMaster"
AUTH_PASS="$(openssl rand -base64 18 | cut -c1-13)"
cd /opt/cronmaster
$STD yarn --frozen-lockfile
export NEXT_TELEMETRY_DISABLED=1
$STD yarn build
cat <<EOF >/opt/cronmaster/.env
NODE_ENV=production
APP_URL=
LOCALE=
HOME=
AUTH_PASSWORD=${AUTH_PASS}
PORT=3000
HOSTNAME="0.0.0.0"
NEXT_TELEMETRY_DISABLED=1
EOF
{
echo "CronMaster Credentials:"
echo ""
echo "Password: $AUTH_PASS"
}>>~/cronmaster.creds
msg_ok "Setup CronMaster"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/cronmaster.service
[Unit]
Description=CronMaster Service
After=network.target
[Service]
EnvironmentFile=/opt/cronmaster/.env
WorkingDirectory=/opt/cronmaster
ExecStart=/usr/bin/yarn start
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl start --now -q cronmaster
msg_info "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -1,10 +1,9 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Test Suite for tools.func
# License: MIT
# https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Purpose: Run comprehensive test suite for all setup_* functions from tools.func
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source:
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
@@ -18,14 +17,10 @@ msg_info "Installing Base Dependencies"
$STD apt-get install -y curl wget ca-certificates
msg_ok "Installed Base Dependencies"
msg_info "Downloading and executing tools.func test suite"
bash <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/test-tools-func.sh)
msg_ok "Test suite completed"
# msg_info "Downloading and executing tools.func test suite"
# bash <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/test-tools-func.sh)
# msg_ok "Test suite completed"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
cleanup_lxc

View File

@@ -1,79 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://hanko.io/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
setup_yq
PG_VERSION="16" setup_postgresql
NODE_VERSION=22 NODE_MODULE="yarn@latest,npm@latest" setup_nodejs
msg_info "Setting up PostgreSQL Database"
DB_NAME=hanko
DB_USER=hanko
DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
APP_SECRET=$(openssl rand -base64 32)
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
{
echo "Hanko-Credentials"
echo "Hanko Database User: $DB_USER"
echo "Hanko Database Password: $DB_PASS"
echo "Hanko Database Name: $DB_NAME"
} >>~/hanko.creds
msg_ok "Set up PostgreSQL Database"
msg_info "Setup Hanko"
fetch_and_deploy_gh_release "hanko" "teamhanko/hanko" "prebuild" "latest" "/opt/hanko" "hanko_Linux_x86_64.tar.gz"
curl -fsSL https://raw.githubusercontent.com/teamhanko/hanko/refs/heads/main/backend/config/config.yaml -o /opt/hanko/config.yaml
env DB_USER="$DB_USER" DB_PASS="$DB_PASS" APP_SECRET="$APP_SECRET" \
yq eval '
.database.user = strenv(DB_USER) |
.database.password = strenv(DB_PASS) |
.database.host = "localhost" |
.database.port = "5432" |
.database.dialect = "postgres" |
.app.secret = strenv(APP_SECRET)
' -i /opt/hanko/config.yaml
$STD /opt/hanko/hanko --config /opt/hanko/config.yaml migrate up
yarn add @teamhanko/hanko-elements
msg_ok "Setup Hanko"
msg_info "Setup Service"
cat <<EOF >/etc/systemd/system/hanko.service
[Unit]
Description=Hanko Service
After=network.target
[Service]
Type=simple
ExecStart=/opt/hanko/hanko serve all --config /opt/hanko/config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now hanko
msg_ok "Service Setup"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,266 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: ekke85
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Dispatcharr/Dispatcharr
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 \
gcc \
python3-dev \
libpq-dev \
nginx \
redis-server \
ffmpeg \
procps \
streamlink
msg_ok "Installed Dependencies"
setup_uv
NODE_VERSION="24" setup_nodejs
PG_VERSION="16" setup_postgresql
msg_info "Creating PostgreSQL Database"
DB_NAME=dispatcharr_db
DB_USER=dispatcharr_usr
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
cat <<EOF >~/dispatcharr.creds
Dispatcharr-Credentials
Dispatcharr Database Name: $DB_NAME
Dispatcharr Database User: $DB_USER
Dispatcharr Database Password: $DB_PASS
EOF
msg_ok "Created PostgreSQL Database"
fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
msg_info "Installing Python Dependencies with uv"
cd /opt/dispatcharr || exit
$STD uv venv
$STD uv pip install -r requirements.txt --index-strategy unsafe-best-match
$STD uv pip install gunicorn gevent celery redis daphne
msg_ok "Installed Python Dependencies"
msg_info "Configuring Dispatcharr"
export DATABASE_URL="postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}"
export POSTGRES_DB=$DB_NAME
export POSTGRES_USER=$DB_USER
export POSTGRES_PASSWORD=$DB_PASS
export POSTGRES_HOST=localhost
$STD uv run python manage.py migrate --noinput
$STD uv run python manage.py collectstatic --noinput
cat <<EOF >/opt/dispatcharr/.env
DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}
POSTGRES_DB=$DB_NAME
POSTGRES_USER=$DB_USER
POSTGRES_PASSWORD=$DB_PASS
POSTGRES_HOST=localhost
CELERY_BROKER_URL=redis://localhost:6379/0
EOF
cd /opt/dispatcharr/frontend || exit
$STD npm install --legacy-peer-deps
$STD npm run build
msg_ok "Configured Dispatcharr"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/dispatcharr.conf
server {
listen 80;
server_name _;
# Serve static assets with correct MIME types
location /assets/ {
alias /opt/dispatcharr/frontend/dist/assets/;
expires 30d;
add_header Cache-Control "public, immutable";
# Explicitly set MIME types for webpack-built assets
types {
text/javascript js;
text/css css;
image/png png;
image/svg+xml svg svgz;
font/woff2 woff2;
font/woff woff;
font/ttf ttf;
}
}
location /static/ {
alias /opt/dispatcharr/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /opt/dispatcharr/media/;
}
location /ws/ {
proxy_pass http://127.0.0.1:8001;
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;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# All other requests proxy to Gunicorn
location / {
include proxy_params;
proxy_pass http://127.0.0.1:5656;
}
}
EOF
ln -sf /etc/nginx/sites-available/dispatcharr.conf /etc/nginx/sites-enabled/dispatcharr.conf
rm -f /etc/nginx/sites-enabled/default
systemctl restart nginx
msg_ok "Configured Nginx"
msg_info "Creating Services"
cat <<EOF >/opt/dispatcharr/start-gunicorn.sh
#!/usr/bin/env bash
cd /opt/dispatcharr
set -a
source .env
set +a
exec uv run gunicorn \\
--workers=4 \\
--worker-class=gevent \\
--timeout=300 \\
--bind 0.0.0.0:5656 \\
dispatcharr.wsgi:application
EOF
chmod +x /opt/dispatcharr/start-gunicorn.sh
cat <<EOF >/opt/dispatcharr/start-celery.sh
#!/usr/bin/env bash
cd /opt/dispatcharr
set -a
source .env
set +a
exec uv run celery -A dispatcharr worker -l info -c 4
EOF
chmod +x /opt/dispatcharr/start-celery.sh
cat <<EOF >/opt/dispatcharr/start-celerybeat.sh
#!/usr/bin/env bash
cd /opt/dispatcharr
set -a
source .env
set +a
exec uv run celery -A dispatcharr beat -l info
EOF
chmod +x /opt/dispatcharr/start-celerybeat.sh
cat <<EOF >/opt/dispatcharr/start-daphne.sh
#!/usr/bin/env bash
cd /opt/dispatcharr
set -a
source .env
set +a
exec uv run daphne -b 0.0.0.0 -p 8001 dispatcharr.asgi:application
EOF
chmod +x /opt/dispatcharr/start-daphne.sh
cat <<EOF >/etc/systemd/system/dispatcharr.service
[Unit]
Description=Dispatcharr Web Server
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
WorkingDirectory=/opt/dispatcharr
ExecStart=/opt/dispatcharr/start-gunicorn.sh
Restart=on-failure
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/dispatcharr-celery.service
[Unit]
Description=Dispatcharr Celery Worker
After=network.target redis-server.service
Requires=dispatcharr.service
[Service]
Type=simple
WorkingDirectory=/opt/dispatcharr
ExecStart=/opt/dispatcharr/start-celery.sh
Restart=on-failure
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/dispatcharr-celerybeat.service
[Unit]
Description=Dispatcharr Celery Beat Scheduler
After=network.target redis-server.service
Requires=dispatcharr.service
[Service]
Type=simple
WorkingDirectory=/opt/dispatcharr
ExecStart=/opt/dispatcharr/start-celerybeat.sh
Restart=on-failure
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/dispatcharr-daphne.service
[Unit]
Description=Dispatcharr WebSocket Server (Daphne)
After=network.target
Requires=dispatcharr.service
[Service]
Type=simple
WorkingDirectory=/opt/dispatcharr
ExecStart=/opt/dispatcharr/start-daphne.sh
Restart=on-failure
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now dispatcharr dispatcharr-celery dispatcharr-celerybeat dispatcharr-daphne
msg_ok "Created Services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

121
install/docker-install.sh Normal file
View File

@@ -0,0 +1,121 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.docker.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
# Apply AppArmor workaround BEFORE installing Docker
# See: https://github.com/opencontainers/runc/issues/4968
apply_docker_apparmor_workaround
get_latest_release() {
curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4
}
DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby")
PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer")
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent")
DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose")
msg_info "Installing Docker $DOCKER_LATEST_VERSION"
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p $(dirname $DOCKER_CONFIG_PATH)
echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json
$STD sh <(curl -fsSL https://get.docker.com)
msg_ok "Installed Docker $DOCKER_LATEST_VERSION"
# Restart Docker to apply AppArmor workaround (if running in LXC)
$STD systemctl restart docker
read -r -p "${TAB3}Install Docker Compose v2 plugin? <y/N> " prompt_compose
if [[ ${prompt_compose,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
mkdir -p /usr/local/lib/docker/cli-plugins
curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_LATEST_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
fi
read -r -p "${TAB3}Would you like to add Portainer (UI)? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Portainer $PORTAINER_LATEST_VERSION"
docker volume create portainer_data >/dev/null
$STD docker run -d \
-p 8000:8000 \
-p 9443:9443 \
--name=portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION"
else
read -r -p "${TAB3}Would you like to install the Portainer Agent (for remote management)? <y/N> " prompt_agent
if [[ ${prompt_agent,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Portainer Agent $PORTAINER_AGENT_LATEST_VERSION"
$STD docker run -d \
-p 9001:9001 \
--name portainer_agent \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
portainer/agent
msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION"
fi
fi
read -r -p "${TAB3}Expose Docker TCP socket (insecure) ? [n = No, l = Local only (127.0.0.1), a = All interfaces (0.0.0.0)] <n/l/a>: " socket_choice
case "${socket_choice,,}" in
l)
socket="tcp://127.0.0.1:2375"
;;
a)
socket="tcp://0.0.0.0:2375"
;;
*)
socket=""
;;
esac
if [[ -n "$socket" ]]; then
msg_info "Enabling Docker TCP socket on $socket"
$STD apt-get install -y jq
tmpfile=$(mktemp)
jq --arg sock "$socket" '. + { "hosts": ["unix:///var/run/docker.sock", $sock] }' /etc/docker/daemon.json >"$tmpfile" && mv "$tmpfile" /etc/docker/daemon.json
mkdir -p /etc/systemd/system/docker.service.d
cat <<EOF >/etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
EOF
$STD systemctl daemon-reexec
$STD systemctl daemon-reload
if systemctl restart docker; then
msg_ok "Docker TCP socket available on $socket"
else
msg_error "Docker failed to restart. Check journalctl -xeu docker.service"
exit 1
fi
fi
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -15,17 +15,21 @@ update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
libsodium23 \
libsodium-dev \
pkg-config \
caddy \
gcc
libsodium23 \
libsodium-dev \
pkg-config \
caddy \
gcc \
curl \
jq
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
setup_go
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
ENTE_CLI_VERSION=$(curl -s https://api.github.com/repos/ente-io/ente/releases | jq -r '[.[] | select(.tag_name | startswith("cli-v"))][0].tag_name')
fetch_and_deploy_gh_release "ente" "ente-io/ente" "tarball" "latest" "/opt/ente"
fetch_and_deploy_gh_release "ente" "ente-io/ente" "tarball" "$ENTE_CLI_VERSION" "/usr/local/bin/ente" "ente-cli-$ENTE_CLI_VERSION-linux-amd64.tar.gz"
msg_info "Setting up PostgreSQL"
DB_NAME="ente_db"
@@ -37,10 +41,28 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8'
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
{
echo "Ente Credentials"
echo "Database Name: $DB_NAME"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Ente Credentials"
echo "Database Name: $DB_NAME"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo ""
echo "Important Configuration Notes:"
echo "- Frontend is built with IP: $(hostname -I | awk '{print $1}')"
echo "- If IP changes, run: /opt/ente/rebuild-frontend.sh"
echo "- Museum API: http://$(hostname -I | awk '{print $1}'):8080"
echo "- Photos UI: http://$(hostname -I | awk '{print $1}'):3000"
echo "- Accounts UI: http://$(hostname -I | awk '{print $1}'):3001"
echo "- Auth UI: http://$(hostname -I | awk '{print $1}'):3003"
echo ""
echo "Post-Installation Steps Required:"
echo "1. Create your first user account via the web UI"
echo "2. Check museum logs for email verification code:"
echo " journalctl -u ente-museum -n 100 | grep -i 'verification'"
echo "3. Use verification code to complete account setup"
echo "4. Remove subscription limit (replace <email> with your account):"
echo " ente admin update-subscription -a <email> -u <email> --no-limit"
echo ""
echo "Note: Email verification requires manual intervention since SMTP is not configured"
} >>~/ente.creds
msg_ok "Set up PostgreSQL"
@@ -78,10 +100,10 @@ export CGO_ENABLED=1
CGO_CFLAGS="$(pkg-config --cflags libsodium || true)"
CGO_LDFLAGS="$(pkg-config --libs libsodium || true)"
if [ -z "$CGO_CFLAGS" ]; then
CGO_CFLAGS="-I/usr/include"
CGO_CFLAGS="-I/usr/include"
fi
if [ -z "$CGO_LDFLAGS" ]; then
CGO_LDFLAGS="-lsodium"
CGO_LDFLAGS="-lsodium"
fi
export CGO_CFLAGS
export CGO_LDFLAGS
@@ -89,12 +111,13 @@ $STD go build cmd/museum/main.go
msg_ok "Built Museum"
msg_info "Generating Secrets"
SECRET_ENC=$($STD go run tools/gen-random-keys/main.go | grep "encryption" | awk '{print $2}')
SECRET_HASH=$($STD go run tools/gen-random-keys/main.go | grep "hash" | awk '{print $2}')
SECRET_JWT=$($STD go run tools/gen-random-keys/main.go | grep "jwt" | awk '{print $2}')
SECRET_ENC=$(go run tools/gen-random-keys/main.go 2>/dev/null | grep "encryption" | awk '{print $2}')
SECRET_HASH=$(go run tools/gen-random-keys/main.go 2>/dev/null | grep "hash" | awk '{print $2}')
SECRET_JWT=$(go run tools/gen-random-keys/main.go 2>/dev/null | grep "jwt" | awk '{print $2}')
msg_ok "Generated Secrets"
msg_info "Creating museum.yaml"
CONTAINER_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/ente/server/museum.yaml
db:
host: 127.0.0.1
@@ -114,9 +137,9 @@ s3:
bucket: ente-dev
apps:
public-albums: http://localhost:3002
cast: http://localhost:3004
accounts: http://localhost:3001
public-albums: http://${CONTAINER_IP}:3002
cast: http://${CONTAINER_IP}:3004
accounts: http://${CONTAINER_IP}:3001
key:
encryption: $SECRET_ENC
@@ -124,6 +147,15 @@ key:
jwt:
secret: $SECRET_JWT
# SMTP not configured - verification codes will appear in logs
# To configure SMTP, add:
# smtp:
# host: your-smtp-server
# port: 587
# username: your-username
# password: your-password
# email: noreply@yourdomain.com
EOF
msg_ok "Created museum.yaml"
@@ -172,6 +204,30 @@ cp -r apps/photos/out /var/www/ente/apps/photos
cp -r apps/accounts/out /var/www/ente/apps/accounts
cp -r apps/auth/out /var/www/ente/apps/auth
cp -r apps/cast/out /var/www/ente/apps/cast
# Save build configuration for future rebuilds
cat <<REBUILD_EOF >/opt/ente/rebuild-frontend.sh
#!/usr/bin/env bash
# Rebuild Ente frontend with current IP
CONTAINER_IP=\$(hostname -I | awk '{print \$1}')
echo "Building frontend with IP: \$CONTAINER_IP"
cd /opt/ente/web
export
=http://\${CONTAINER_IP}:8080
export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://\${CONTAINER_IP}:3002
yarn build
yarn build:accounts
yarn build:auth
yarn build:cast
rm -rf /var/www/ente/apps/*
cp -r apps/photos/out /var/www/ente/apps/photos
cp -r apps/accounts/out /var/www/ente/apps/accounts
cp -r apps/auth/out /var/www/ente/apps/auth
cp -r apps/cast/out /var/www/ente/apps/cast
systemctl reload caddy
echo "Frontend rebuilt successfully!"
REBUILD_EOF
chmod +x /opt/ente/rebuild-frontend.sh
msg_ok "Built Web Applications"
msg_info "Creating Museum Service"
@@ -192,31 +248,82 @@ systemctl enable -q --now ente-museum
msg_ok "Created Museum Service"
msg_info "Configuring Caddy"
CONTAINER_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/etc/caddy/Caddyfile
# Ente Photos - Main Application
:3000 {
root * /var/www/ente/apps/photos
file_server
try_files {path} {path}.html /index.html
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers *
}
}
# Ente Accounts
:3001 {
root * /var/www/ente/apps/accounts
file_server
try_files {path} {path}.html /index.html
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers *
}
}
# Public Albums
:3002 {
root * /var/www/ente/apps/photos
file_server
try_files {path} {path}.html /index.html
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers *
}
}
# Auth
:3003 {
root * /var/www/ente/apps/auth
file_server
try_files {path} {path}.html /index.html
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers *
}
}
# Cast
:3004 {
root * /var/www/ente/apps/cast
file_server
try_files {path} {path}.html /index.html
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers *
}
}
# Museum API Proxy
:8080 {
reverse_proxy localhost:8080
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers *
}
}
EOF
systemctl reload caddy
@@ -225,7 +332,63 @@ msg_ok "Configured Caddy"
motd_ssh
customize
msg_info "Creating helper scripts"
cat <<'HELPER_EOF' >/usr/local/bin/ente-get-verification
#!/usr/bin/env bash
echo "Searching for verification codes in museum logs..."
journalctl -u ente-museum --no-pager | grep -i "verification\|verify\|code" | tail -20
HELPER_EOF
chmod +x /usr/local/bin/ente-get-verification
cat <<'HELPER_EOF' >/usr/local/bin/ente-upgrade-subscription
#!/usr/bin/env bash
if [ -z "$1" ]; then
echo "Usage: ente-upgrade-subscription <email>"
echo "Example: ente-upgrade-subscription user@example.com"
exit 1
fi
EMAIL="$1"
echo "Upgrading subscription for: $EMAIL"
ente admin update-subscription -a "$EMAIL" -u "$EMAIL" --no-limit
HELPER_EOF
chmod +x /usr/local/bin/ente-upgrade-subscription
msg_ok "Created helper scripts"
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
$STD apt -y autoremove
$STD apt -y autoclean
msg_ok "Cleaned"
# Final setup summary
CONTAINER_IP=$(hostname -I | awk '{print $1}')
echo -e "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e " ${GN}Ente Installation Complete!${CL}"
echo -e "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "\n${BL}Access URLs:${CL}"
echo -e " Photos: http://${CONTAINER_IP}:3000"
echo -e " Accounts: http://${CONTAINER_IP}:3001"
echo -e " Auth: http://${CONTAINER_IP}:3003"
echo -e " API: http://${CONTAINER_IP}:8080"
echo -e "\n${YW}⚠️ Important Post-Installation Steps:${CL}"
echo -e "\n${BL}1. Create your first account:${CL}"
echo -e " • Open http://${CONTAINER_IP}:3000 in your browser"
echo -e " • Click 'Sign Up' and create an account"
echo -e "\n${BL}2. Verify your email (required):${CL}"
echo -e " • Run: ${GN}ente-get-verification${CL}"
echo -e " • Look for the verification code in the output"
echo -e " • Enter the code in the web UI to complete registration"
echo -e "\n${BL}3. Remove storage limit:${CL}"
echo -e " • After email verification is complete"
echo -e " • Run: ${GN}ente-upgrade-subscription your@email.com${CL}"
echo -e " • This removes the 10GB limit"
echo -e "\n${BL}4. If IP changes:${CL}"
echo -e " • Run: ${GN}/opt/ente/rebuild-frontend.sh${CL}"
echo -e " • This rebuilds the frontend with the new IP"
echo -e "\n${YW}Known Limitations:${CL}"
echo -e " • Email verification requires checking logs (no SMTP configured)"
echo -e " • Account creation must be done manually via web UI"
echo -e " • Subscription upgrade requires CLI after account creation"
echo -e " • Frontend must be rebuilt if container IP changes"
echo -e "\n${BL}Credentials saved to:${CL} ~/ente.creds"
echo -e "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"

View File

@@ -13,21 +13,7 @@ setting_up_container
network_check
update_os
msg_info "Installing dependencies"
$STD apt-get install -y \
build-essential \
openssl \
sqlite3 \
unzip
msg_ok "Installed Dependencies"
msg_info "Installing Bun"
export BUN_INSTALL=/opt/bun
curl -fsSL https://bun.sh/install | $STD bash
ln -sf /opt/bun/bin/bun /usr/local/bin/bun
ln -sf /opt/bun/bin/bun /usr/local/bin/bunx
msg_ok "Installed Bun"
NODE_VERSION="22" NODE_MODULES="bun" setup_nodejs
fetch_and_deploy_gh_release "gitea-mirror" "RayLabsHQ/gitea-mirror"
msg_info "Installing gitea-mirror"
@@ -70,8 +56,4 @@ msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
cleanup_lxc

View File

@@ -1,153 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: michelroegl-brunner
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/opf/openproject
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
lsb-release \
ca-certificates \
acl \
fping \
graphviz \
imagemagick \
mtr-tiny \
nginx \
nmap \
rrdtool \
snmp \
snmpd
msg_ok "Installed Dependencies"
PHP_VERSION="8.3" PHP_FPM="YES" PHP_MODULE="gmp,mysql,snmp" setup_php
setup_mariadb
setup_composer
PYTHON_VERSION="3.13" setup_uv
msg_info "Installing Python"
$STD apt-get install -y \
python3-{dotenv,pymysql,redis,setuptools,systemd,pip}
msg_ok "Installed Python"
msg_info "Configuring Database"
DB_NAME=librenms
DB_USER=librenms
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 "LibreNMS-Credentials"
echo "LibreNMS Database User: $DB_USER"
echo "LibreNMS Database Password: $DB_PASS"
echo "LibreNMS Database Name: $DB_NAME"
} >>~/librenms.creds
msg_ok "Configured Database"
fetch_and_deploy_gh_release "LibreNMS" "librenms/librenms"
msg_info "Configuring LibreNMS"
$STD useradd librenms -d /opt/librenms -M -r -s "$(which bash)"
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
cd /opt/librenms
$STD uv venv .venv
$STD source .venv/bin/activate
$STD uv pip install -r requirements.txt
cat <<EOF >/opt/librenms/.env
DB_DATABASE=${DB_NAME}
DB_USERNAME=${DB_USER}
DB_PASSWORD=${DB_PASS}
EOF
chown -R librenms:librenms /opt/librenms
chmod 771 /opt/librenms
setfacl -d -m g::rwx /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
chmod -R ug=rwX /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
msg_ok "Configured LibreNMS"
msg_info "Configure MariaDB"
sed -i "/\[mysqld\]/a innodb_file_per_table=1\nlower_case_table_names=0" /etc/mysql/mariadb.conf.d/50-server.cnf
systemctl enable -q --now mariadb
msg_ok "Configured MariaDB"
msg_info "Configure PHP-FPM"
cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/librenms.conf
sed -i "s/\[www\]/\[librenms\]/g" /etc/php/8.2/fpm/pool.d/librenms.conf
sed -i "s/user = www-data/user = librenms/g" /etc/php/8.2/fpm/pool.d/librenms.conf
sed -i "s/group = www-data/group = librenms/g" /etc/php/8.2/fpm/pool.d/librenms.conf
sed -i "s/listen = \/run\/php\/php8.2-fpm.sock/listen = \/run\/php-fpm-librenms.sock/g" /etc/php/8.2/fpm/pool.d/librenms.conf
msg_ok "Configured PHP-FPM"
msg_info "Configure Nginx"
IP_ADDR=$(hostname -I | awk '{print $1}')
cat >/etc/nginx/sites-enabled/librenms <<'EOF'
server {
listen 80;
server_name ${IP_ADDR};
root /opt/librenms/html;
index index.php;
charset utf-8;
gzip on;
gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ [^/]\.php(/|$) {
fastcgi_pass unix:/run/php-fpm-librenms.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi.conf;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
EOF
rm /etc/nginx/sites-enabled/default
$STD systemctl reload nginx
systemctl restart php8.2-fpm
msg_ok "Configured Nginx"
msg_info "Configure Services"
COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev
$STD php8.2 artisan migrate --force
$STD php8.2 artisan key:generate --force
$STD su librenms -s /bin/bash -c "lnms db:seed --force"
$STD su librenms -s /bin/bash -c "lnms user:add -p admin -r admin admin"
ln -s /opt/librenms/lnms /usr/bin/lnms
mkdir -p /etc/bash_completion.d/
cp /opt/librenms/misc/lnms-completion.bash /etc/bash_completion.d/
cp /opt/librenms/snmpd.conf.example /etc/snmp/snmpd.conf
RANDOM_STRING=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9')
sed -i "s/RANDOMSTRINGHERE/$RANDOM_STRING/g" /etc/snmp/snmpd.conf
echo "SNMP Community String: $RANDOM_STRING" >>~/librenms.creds
curl -qo /usr/bin/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro
chmod +x /usr/bin/distro
systemctl enable -q --now snmpd
cp /opt/librenms/dist/librenms.cron /etc/cron.d/librenms
cp /opt/librenms/dist/librenms-scheduler.service /opt/librenms/dist/librenms-scheduler.timer /etc/systemd/system/
systemctl enable -q --now librenms-scheduler.timer
cp /opt/librenms/misc/librenms.logrotate /etc/logrotate.d/librenms
msg_ok "Configured Services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,105 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: dkuku
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/livebook-dev/livebook
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
build-essential \
ca-certificates \
cmake \
git \
libncurses5-dev
msg_ok "Installed Dependencies"
msg_info "Creating livebook user"
mkdir -p /opt/livebook /data
export HOME=/opt/livebook
$STD adduser --system --group --home /opt/livebook --shell /bin/bash livebook
msg_ok "Created livebook user"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://elixir-lang.org)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://elixir-lang.org/install.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
bash <(curl -sL https://elixir-lang.org/install.sh)
msg_info "Setup Erlang and Elixir"
ERLANG_VERSION=$(ls /opt/livebook/.elixir-install/installs/otp/ | head -n1)
ELIXIR_VERSION=$(ls /opt/livebook/.elixir-install/installs/elixir/ | head -n1)
LIVEBOOK_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
export ERLANG_BIN="/opt/livebook/.elixir-install/installs/otp/$ERLANG_VERSION/bin"
export ELIXIR_BIN="/opt/livebook/.elixir-install/installs/elixir/$ELIXIR_VERSION/bin"
export PATH="$ERLANG_BIN:$ELIXIR_BIN:$PATH"
$STD mix local.hex --force
$STD mix local.rebar --force
$STD mix escript.install hex livebook --force
cat <<EOF >/opt/livebook/.env
export HOME=/opt/livebook
export ERLANG_VERSION=$ERLANG_VERSION
export ELIXIR_VERSION=$ELIXIR_VERSION
export LIVEBOOK_PORT=8080
export LIVEBOOK_IP="::"
export LIVEBOOK_HOME=/data
export LIVEBOOK_PASSWORD="$LIVEBOOK_PASSWORD"
export ESCRIPTS_BIN=/opt/livebook/.mix/escripts
export ERLANG_BIN="/opt/livebook/.elixir-install/installs/otp/\${ERLANG_VERSION}/bin"
export ELIXIR_BIN="/opt/livebook/.elixir-install/installs/elixir/\${ELIXIR_VERSION}/bin"
export PATH="\$ESCRIPTS_BIN:\$ERLANG_BIN:\$ELIXIR_BIN:\$PATH"
EOF
cat <<EOF >/opt/livebook/livebook.creds
Livebook-Credentials
Livebook Password: $LIVEBOOK_PASSWORD
EOF
msg_ok "Installed Erlang $ERLANG_VERSION and Elixir $ELIXIR_VERSION"
msg_info "Installing Livebook"
cat <<EOF >/etc/systemd/system/livebook.service
[Unit]
Description=Livebook
After=network.target
[Service]
Type=exec
User=livebook
Group=livebook
WorkingDirectory=/data
EnvironmentFile=-/opt/livebook/.env
ExecStart=/bin/bash -c 'source /opt/livebook/.env && cd /opt/livebook && livebook server'
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
chown -R livebook:livebook /opt/livebook /data
systemctl enable -q --now livebook
msg_ok "Installed Livebook"
motd_ssh
customize
msg_info "Cleaning Up"
$STD apt-get autoremove -y
$STD apt-get autoclean
msg_ok "Cleaned Up"

110
install/mealie-install.sh Normal file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://mealie.io
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 \
libpq-dev \
libwebp-dev \
libsasl2-dev \
libldap2-dev \
libssl-dev
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
POSTGRES_VERSION="16" setup_postgresql
NODE_MODULE="yarn" NODE_VERSION="24" setup_nodejs
fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie"
PG_DB_NAME="mealie_db" PG_DB_USER="mealie_user" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
msg_info "Installing Python Dependencies with uv"
cd /opt/mealie
$STD uv sync --frozen --extra pgsql
msg_ok "Installed Python Dependencies"
msg_info "Building Frontend"
export NUXT_TELEMETRY_DISABLED=1
cd /opt/mealie/frontend
$STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000
$STD yarn generate
msg_ok "Built Frontend"
msg_info "Copying Built Frontend"
mkdir -p /opt/mealie/mealie/frontend
cp -r /opt/mealie/frontend/dist/* /opt/mealie/mealie/frontend/
msg_ok "Copied Frontend"
msg_info "Downloading NLTK Data"
mkdir -p /nltk_data/
cd /opt/mealie
$STD uv run python -m nltk.downloader -d /nltk_data averaged_perceptron_tagger_eng
msg_ok "Downloaded NLTK Data"
msg_info "Writing Environment File"
SECRET=$(openssl rand -hex 32)
mkdir -p /run/secrets
cat <<EOF >/opt/mealie/mealie.env
MEALIE_HOME=/opt/mealie
NLTK_DATA=/nltk_data
SECRET=${SECRET}
DB_ENGINE=postgres
POSTGRES_SERVER=localhost
POSTGRES_PORT=5432
POSTGRES_USER=${PG_DB_USER}
POSTGRES_PASSWORD=${PG_DB_PASS}
POSTGRES_DB=${PG_DB_NAME}
PRODUCTION=true
HOST=0.0.0.0
PORT=9000
EOF
msg_ok "Wrote Environment File"
msg_info "Creating Start Script"
cat <<'EOF' >/opt/mealie/start.sh
#!/bin/bash
set -a
source /opt/mealie/mealie.env
set +a
exec uv run mealie
EOF
chmod +x /opt/mealie/start.sh
msg_ok "Created Start Script"
msg_info "Creating Systemd Service"
cat <<'EOF' >/etc/systemd/system/mealie.service
[Unit]
Description=Mealie Recipe Manager
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/mealie
ExecStart=/opt/mealie/start.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now mealie
msg_ok "Created and Started Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://www.metabase.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
JAVA_VERSION="21" setup_java
PG_VERSION="17" setup_postgresql
PG_DB_NAME="metabase_db" PG_DB_USER="metabase" setup_postgresql_db
msg_info "Setting up Metabase"
mkdir -p /opt/metabase
RELEASE=$(get_latest_github_release "metabase/metabase")
curl -fsSL "https://downloads.metabase.com/v${RELEASE}.x/metabase.jar" -o /opt/metabase/metabase.jar
cd /opt/metabase
cat <<EOF >/opt/metabase/.env
MB_DB_TYPE=postgres
MB_DB_DBNAME=$PG_DB_NAME
MB_DB_PORT=5432
MB_DB_USER=$PG_DB_USER
MB_DB_PASS=$PG_DB_PASS
MB_DB_HOST=localhost
EOF
echo $RELEASE >~/.metabase
msg_ok "Setup Metabase"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/metabase.service
[Unit]
Description=Metabase Service
After=network.target
[Service]
EnvironmentFile=/opt/metabase/.env
WorkingDirectory=/opt/metabase
ExecStart=/usr/bin/java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
Restart=always
SuccessExitStatus=143
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now metabase
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -1,72 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/streetwriters/notesnook
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
make \
git \
caddy
msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "notesnook" "streetwriters/notesnook" "tarball"
msg_info "Configuring Notesnook (Patience)"
cd /opt/notesnook
export NODE_OPTIONS="--max-old-space-size=2560"
$STD npm install
$STD npm run build:web
msg_ok "Configured Notesnook"
msg_info "Configuring Caddy"
LOCAL_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/etc/caddy/Caddyfile
{
email admin@example.com
}
${LOCAL_IP} {
reverse_proxy 127.0.0.1:3000
}
EOF
msg_ok "Configured Caddy"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/notesnook.service
[Unit]
Description=Notesnook Service
After=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/notesnook
ExecStart=/usr/bin/npx serve apps/web/build
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl reload caddy
systemctl enable -q --now notesnook
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,289 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/PatcMmon/PatchMon
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 \
gcc \
nginx \
redis-server
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
PG_VERSION="17" setup_postgresql
msg_info "Creating PostgreSQL Database"
DB_NAME=patchmon_db
DB_USER=patchmon_usr
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
cat <<EOF >~/patchmon.creds
PatchMon Credentials
PatchMon Database Name: $DB_NAME
PatchMon Database User: $DB_USER
PatchMon Database Password: $DB_PASS
EOF
msg_ok "Created PostgreSQL Database"
fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon"
msg_info "Configuring PatchMon"
cd /opt/patchmon
export NODE_ENV=production
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
cd /opt/patchmon/backend
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
cd /opt/patchmon/frontend
$STD npm install --include=dev --no-audit --no-fund --no-save --ignore-scripts
$STD npm run build
JWT_SECRET="$(openssl rand -base64 64 | tr -d "=+/" | cut -c1-50)"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
cat <<EOF >/opt/patchmon/backend/.env
# Database Configuration
DATABASE_URL="postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME"
PY_THRESHOLD=3M_DB_CONN_MAX_ATTEMPTS=30
PM_DB_CONN_WAIT_INTERVAL=2
# JWT Configuration
JWT_SECRET="$JWT_SECRET"
JWT_EXPIRES_IN=1h
JWT_REFRESH_EXPIRES_IN=7d
# Server Configuration
PORT=3399
NODE_ENV=production
# API Configuration
API_VERSION=v1
# CORS Configuration
CORS_ORIGIN="http://$LOCAL_IP"
# Session Configuration
SESSION_INACTIVITY_TIMEOUT_MINUTES=30
# User Configuration
DEFAULT_USER_ROLE=user
# Rate Limiting (times in milliseconds)
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX=5000
AUTH_RATE_LIMIT_WINDOW_MS=600000
AUTH_RATE_LIMIT_MAX=500
AGENT_RATE_LIMIT_WINDOW_MS=60000
AGENT_RATE_LIMIT_MAX=1000
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
# Logging
LOG_LEVEL=info
ENABLE_LOGGING=true
# TFA Configuration
TFA_REMEMBER_ME_EXPIRES_IN=30d
TFA_MAX_REMEMBER_SESSIONS=5
TFA_SUSPICIOUS_ACTIVITY_THRESHOLD=3
EOF
cat <<EOF >/opt/patchmon/frontend/.env
VITE_API_URL=http://$LOCAL_IP/api/v1
VITE_APP_NAME=PatchMon
VITE_APP_VERSION=1.3.0
EOF
cd /opt/patchmon/backend
$STD npx prisma migrate deploy
$STD npx prisma generate
msg_ok "Configured PatchMon"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/patchmon.conf
server {
listen 80;
server_name $LOCAL_IP;
# Security headers
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Frontend
location / {
root /opt/patchmon/frontend/dist;
try_files \$uri \$uri/ /index.html;
}
# Bull Board proxy
location /bullboard {
proxy_pass http://127.0.0.1:3399;
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;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-Host \$host;
proxy_set_header Cookie \$http_cookie;
proxy_cache_bypass \$http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
# Enable cookie passthrough
proxy_pass_header Set-Cookie;
proxy_cookie_path / /;
# Preserve original client IP
proxy_set_header X-Original-Forwarded-For \$http_x_forwarded_for;
if (\$request_method = 'OPTIONS') {
return 204;
}
}
# API proxy
location /api/ {
proxy_pass http://127.0.0.1:3399;
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;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
# Preserve original client IP
proxy_set_header X-Original-Forwarded-For \$http_x_forwarded_for;
if (\$request_method = 'OPTIONS') {
return 204;
}
}
# Static assets caching (exclude Bull Board assets)
location ~* ^/(?!bullboard).*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
root /opt/patchmon/frontend/dist;
expires 1y;
add_header Cache-Control "public, immutable";
}
# Health check endpoint
location /health {
proxy_pass http://127.0.0.1:3399/health;
access_log off;
}
}
EOF
ln -sf /etc/nginx/sites-available/patchmon.conf /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
$STD nginx -t
systemctl restart nginx
msg_ok "Configured Nginx"
msg_info "Creating service"
cat <<EOF >/etc/systemd/system/patchmon-server.service
[Unit]
Description=PatchMon Service
After=network.target postgresql.service
[Service]
Type=simple
WorkingDirectory=/opt/patchmon/backend
ExecStart=/usr/bin/node src/server.js
Restart=always
RestartSec=10
Environment=NODE_ENV=production
Environment=PATH=/usr/bin:/usr/local/bin
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/patchmon
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now patchmon-server
msg_ok "Created and started service"
msg_info "Updating settings"
cat <<EOF >/opt/patchmon/backend/update-settings.js
const { PrismaClient } = require('@prisma/client');
const { v4: uuidv4 } = require('uuid');
const prisma = new PrismaClient();
async function updateSettings() {
try {
const existingSettings = await prisma.settings.findFirst();
const settingsData = {
id: uuidv4(),
server_url: 'http://$LOCAL_IP',
server_protocol: 'http',
server_host: '$LOCAL_IP',
server_port: 3399,
update_interval: 60,
auto_update: true,
signup_enabled: false,
ignore_ssl_self_signed: false,
updated_at: new Date()
};
if (existingSettings) {
// Update existing settings
await prisma.settings.update({
where: { id: existingSettings.id },
data: settingsData
});
} else {
// Create new settings record
await prisma.settings.create({
data: settingsData
});
}
console.log('✅ Database settings updated successfully');
} catch (error) {
console.error('❌ Error updating settings:', error.message);
process.exit(1);
} finally {
await prisma.\$disconnect();
}
}
updateSettings();
EOF
cd /opt/patchmon/backend
$STD node update-settings.js
msg_ok "Settings updated successfully"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@@ -1,112 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/gitroomhq/postiz-app
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing dependencies"
$STD apt-get install -y \
build-essential \
python3-pip \
supervisor \
debian-keyring \
debian-archive-keyring \
apt-transport-https \
redis
msg_ok "Installed dependencies"
NODE_VERSION="20" setup_nodejs
PG_VERSION="17" setup_postgresql
msg_info "Setting up PostgreSQL Database"
DB_NAME=postiz
DB_USER=postiz
DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
{
echo "Postiz DB Credentials"
echo "Postiz Database User: $DB_USER"
echo "Postiz Database Password: $DB_PASS"
echo "Postiz Database Name: $DB_NAME"
} >>~/postiz.creds
msg_ok "Set up PostgreSQL Database"
msg_info "Setting up Caddy"
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/gpg.key" | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt" >/etc/apt/sources.list.d/caddy-stable.list
$STD apt-get update
$STD apt-get install caddy
msg_ok "Set up Caddy"
fetch_and_deploy_gh_release "postiz" "gitroomhq/postiz-app"
msg_info "Configuring Postiz"
LOCAL_IP=$(hostname -I | awk '{print $1}')
JWT_SECRET=$(openssl rand -base64 64 | tr '+/' '-_' | tr -d '=')
cd /opt/postiz
mkdir -p /etc/supervisor.d
$STD npm --no-update-notifier --no-fund --global install pnpm@10.6.1 pm2
cp var/docker/supervisord.conf /etc/supervisord.conf
cp var/docker/Caddyfile ./Caddyfile
cp var/docker/entrypoint.sh ./entrypoint.sh
cp var/docker/supervisord/caddy.conf /etc/supervisor.d/caddy.conf
sed -i "s#/app/Caddyfile#/opt/postiz/Caddyfile#g" /etc/supervisor.d/caddy.conf
sed -i "s#/app/Caddyfile#/opt/postiz/Caddyfile#g" /opt/postiz/entrypoint.sh
sed -i "s#directory=/app#directory=/opt/postiz#g" /etc/supervisor.d/caddy.conf
export NODE_OPTIONS="--max-old-space-size=2560"
$STD pnpm install
$STD pnpm run build
chmod +x entrypoint.sh
cat <<EOF >.env
NOT_SECURED="true"
IS_GENERAL="true"
DATABASE_URL="postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME"
REDIS_URL="redis://localhost:6379"
JWT_SECRET="$JWT_SECRET"
FRONTEND_URL="http://$LOCAL_IP:4200"
NEXT_PUBLIC_BACKEND_URL="http://$LOCAL_IP:3000"
BACKEND_INTERNAL_URL="http://$LOCAL_IP:3000"
EOF
msg_ok "Configured Postiz"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/postiz.service
[Unit]
Description=Postiz Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/postiz
EnvironmentFile=/opt/postiz/.env
ExecStart=/usr/bin/pnpm run pm2-run
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now postiz
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,33 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: Proxmox Server Solution GmbH
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Proxmox Datacenter Manager"
curl -fsSL https://enterprise.proxmox.com/debian/proxmox-archive-keyring-trixie.gpg -o /usr/share/keyrings/proxmox-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/proxmox-archive-keyring.gpg] http://download.proxmox.com/debian/pdm bookworm pdm-test " >/etc/apt/sources.list.d/pdm-test.list
$STD apt-get update
DEBIAN_FRONTEND=noninteractive
$STD apt-get -o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
install -y proxmox-datacenter-manager \
proxmox-datacenter-manager-ui
msg_ok "Installed Proxmox Datacenter Manager"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -13,69 +13,105 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
caddy \
apt-transport-https \
ca-certificates
msg_ok "Installed Dependencies"
setup_clickhouse
PG_VERSION=17 setup_postgresql
NODE_VERSION="20" NODE_MODULE="next" setup_nodejs
#sed -i 's|<default_profile>default</default_profile>|<default_profile>read_only</default_profile>|' /etc/clickhouse-server/users.xml
#sed -i 's|<default_password></default_password>|<default_password>DISABLED</default_password>|' /etc/clickhouse-server/users.xml
msg_info "Setting up PostgreSQL Database"
DB_NAME=rybbit_db
DB_USER=rybbit
DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
{
echo "Rybbit-Credentials"
echo "Rybbit Database User: $DB_USER"
echo "Rybbit Database Password: $DB_PASS"
echo "Rybbit Database Name: $DB_NAME"
} >>~/rybbit.creds
msg_ok "Set up PostgreSQL Database"
NODE_VERSION="24" NODE_MODULE="next" setup_nodejs
PG_DB_NAME="rybbit_db" PG_DB_USER="rybbit" setup_postgresql_db
fetch_and_deploy_gh_release "rybbit" "rybbit-io/rybbit" "tarball" "latest" "/opt/rybbit"
msg_info "Building Rybbit Shared Module"
cd /opt/rybbit/shared
npm install
npm run build
$STD npm install
$STD npm run build
msg_ok "Built Shared Module"
msg_info "Building Rybbit Server"
cd /opt/rybbit/server
npm ci
npm run build
$STD npm ci
$STD npm run build
msg_ok "Built Server"
msg_info "Building Rybbit Client"
cd /opt/rybbit/client
npm ci --legacy-peer-deps
npm run build
NEXT_PUBLIC_BACKEND_URL="http://localhost:3001" \
NEXT_PUBLIC_DISABLE_SIGNUP="false" \
$STD npm ci --legacy-peer-deps
$STD npm run build
msg_ok "Built Client"
mv /opt/rybbit/.env.example /opt/rybbit/.env
sed -i "s|^POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g" /opt/rybbit/.env
sed -i "s|^POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g" /opt/rybbit/.env
sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" /opt/rybbit/.env
sed -i "s|^DOMAIN_NAME=.*|DOMAIN_NAME=localhost|g" /opt/rybbit/.env
sed -i "s|^BASE_URL=.*|BASE_URL=\"http://localhost\"|g" /opt/rybbit/.env
msg_ok "Rybbit Installed"
msg_info "Configuring Rybbit"
CONTAINER_IP=$(hostname -I | awk '{print $1}')
BETTER_AUTH_SECRET=$(openssl rand -hex 32)
msg_info "Setting up Caddy"
mkdir -p /etc/caddy
cp /opt/rybbit/Caddyfile /etc/caddy/Caddyfile
systemctl enable -q --now caddy
msg_ok "Caddy Setup"
cat >/opt/rybbit/.env <<EOF
# Database Configuration
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=$PG_DB_NAME
POSTGRES_USER=$PG_DB_USER
POSTGRES_PASSWORD=$PG_DB_PASS
CLICKHOUSE_HOST=http://localhost:8123
CLICKHOUSE_DB=analytics
CLICKHOUSE_PASSWORD=
# Application Configuration
NODE_ENV=production
BASE_URL=http://${CONTAINER_IP}:3002
BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
DISABLE_SIGNUP=false
DISABLE_TELEMETRY=true
MAPBOX_TOKEN=
EOF
msg_ok "Configured Rybbit"
msg_info "Creating Rybbit Services"
cat >/etc/systemd/system/rybbit-server.service <<EOF
[Unit]
Description=Rybbit Server
After=network.target postgresql.service clickhouse-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/rybbit/server
EnvironmentFile=/opt/rybbit/.env
ExecStart=/usr/bin/node /opt/rybbit/server/dist/index.js
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/rybbit-client.service <<EOF
[Unit]
Description=Rybbit Client
After=network.target rybbit-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/rybbit/client
Environment="NODE_ENV=production"
Environment="NEXT_PUBLIC_BACKEND_URL=http://${CONTAINER_IP}:3001"
Environment="NEXT_PUBLIC_DISABLE_SIGNUP=false"
Environment="PORT=3002"
Environment="HOSTNAME=0.0.0.0"
ExecStart=/usr/bin/node /opt/rybbit/client/.next/standalone/server.js
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable -q --now rybbit-server.service
systemctl enable -q --now rybbit-client.service
msg_ok "Created and Started Rybbit Services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
cleanup_lxc

View File

@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: TuroYT
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
setup_nodejs
setup_postgresql
fetch_and_deploy_gh_release "snowshare" "TuroYT/snowshare"
msg_info "Setting up PostgreSQL Database"
DB_NAME=snowshare
DB_USER=snowshare
DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
{
echo "SnowShare-Database-Credentials"
echo "Database Username: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/snowshare.creds
msg_ok "Set up PostgreSQL Database"
msg_info "Installing SnowShare"
cd /opt/snowshare
$STD npm ci
cat <<EOF >/opt/snowshare.env
DATABASE_URL="postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME"
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="$(openssl rand -base64 32)"
ALLOW_SIGNUP=true
NODE_ENV=production
EOF
set -a
source /opt/snowshare.env
set +a
$STD npx prisma generate
$STD npx prisma migrate deploy
$STD npm run build
cat <<EOF >/etc/systemd/system/snowshare.service
[Unit]
Description=SnowShare - Modern File Sharing Platform
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
WorkingDirectory=/opt/snowshare
EnvironmentFile=/opt/snowshare.env
ExecStart=/usr/bin/npm start
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now snowshare
msg_ok "Installed SnowShare"
msg_info "Setting up Cleanup Cron Job"
cat <<EOF >/etc/cron.d/snowshare-cleanup
0 2 * * * root cd /opt/snowshare && /usr/bin/npm run cleanup:expired >> /var/log/snowshare-cleanup.log 2>&1
EOF
msg_ok "Set up Cleanup Cron Job"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@@ -16,15 +16,15 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
dnsutils \
iputils-ping \
ufw \
iproute2
dnsutils \
iputils-ping \
ufw \
iproute2
mkdir -p /etc/systemd/system-preset
echo "disable *" > /etc/systemd/system-preset/99-no-autostart.preset
echo "disable *" >/etc/systemd/system-preset/99-no-autostart.preset
$STD apt install -y \
transmission-daemon \
privoxy
transmission-daemon \
privoxy
rm -f /etc/systemd/system-preset/99-no-autostart.preset
$STD systemctl preset-all
$STD systemctl disable --now transmission-daemon
@@ -49,12 +49,13 @@ chmod +x /opt/privoxy/*.sh
$STD ln -s /usr/bin/transmission-daemon /usr/local/bin/transmission-daemon
$STD update-alternatives --set iptables /usr/sbin/iptables-legacy
$STD update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
rm -rf /opt/docker-transmission-openvpn
msg_ok "Configured transmission-openvpn"
msg_info "Creating Service"
LOCAL_SUBNETS=$(
ip -o -4 addr show \
| awk '!/127.0.0.1/ {
ip -o -4 addr show |
awk '!/127.0.0.1/ {
split($4, a, "/"); ip=a[1]; mask=a[2];
split(ip, o, ".");
if (mask < 8) {
@@ -66,12 +67,12 @@ LOCAL_SUBNETS=$(
} else {
print o[1]"."o[2]"."o[3]".*";
}
}' \
| sort -u | paste -sd, -
}' |
sort -u | paste -sd, -
)
TRANSMISSION_RPC_WHITELIST="127.0.0.*,${LOCAL_SUBNETS}"
mkdir -p /opt/transmission-openvpn
cat <<EOF > "/opt/transmission-openvpn/.env"
cat <<EOF >"/opt/transmission-openvpn/.env"
OPENVPN_USERNAME="username"
OPENVPN_PASSWORD="password"
OPENVPN_PROVIDER="PIA"
@@ -111,7 +112,7 @@ LOG_TO_STDOUT="false"
HEALTH_CHECK_HOST="google.com"
SELFHEAL="false"
EOF
cat <<EOF > /etc/systemd/system/openvpn-custom.service
cat <<EOF >/etc/systemd/system/openvpn-custom.service
[Unit]
Description=Custom OpenVPN start service
After=network.target
@@ -126,15 +127,9 @@ EnvironmentFile=/opt/transmission-openvpn/.env
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now -q openvpn-custom.service
systemctl enable -q --now openvpn-custom
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
rm -rf /opt/docker-transmission-openvpn
msg_ok "Cleaned"
cleanup_lxc

View File

@@ -4,7 +4,7 @@
# Author: MickLesk (Canbiz)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
@@ -14,10 +14,10 @@ update_os
msg_info "Installing Dependencies (Patience)"
$STD apt-get install -y \
make \
apache2 \
libapache2-mod-php \
redis
make \
apache2 \
libapache2-mod-php \
redis
msg_ok "Installed Dependencies"
setup_mariadb
@@ -33,10 +33,10 @@ $STD mariadb -u root -e "CREATE DATABASE $DB_NAME;"
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "Wallabag Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
echo "Wallabag Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/wallabag.creds
msg_ok "Set up Database"
@@ -48,12 +48,12 @@ useradd -d /opt/wallabag -s /bin/bash -M wallabag
chown -R wallabag:wallabag /opt/wallabag
mv /opt/wallabag/app/config/parameters.yml.dist /opt/wallabag/app/config/parameters.yml
sed -i \
-e 's|database_name: wallabag|database_name: wallabag_db|' \
-e 's|database_port: ~|database_port: 3306|' \
-e 's|database_user: root|database_user: wallabag|' \
-e 's|database_password: ~|database_password: '"$DB_PASS"'|' \
-e 's|secret: .*|secret: '"$SECRET_KEY"'|' \
/opt/wallabag/app/config/parameters.yml
-e 's|database_name: wallabag|database_name: wallabag_db|' \
-e 's|database_port: ~|database_port: 3306|' \
-e 's|database_user: root|database_user: wallabag|' \
-e 's|database_password: ~|database_password: '"$DB_PASS"'|' \
-e 's|secret: .*|secret: '"$SECRET_KEY"'|' \
/opt/wallabag/app/config/parameters.yml
export COMPOSER_ALLOW_SUPERUSER=1
sudo -u wallabag make install --no-interaction

View File

@@ -0,0 +1,141 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/lissy93/web-check
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
export DEBIAN_FRONTEND=noninteractive
$STD apt -y install --no-install-recommends \
git \
traceroute \
make \
g++ \
traceroute \
xvfb \
dbus \
xorg \
xvfb \
gtk2-engines-pixbuf \
dbus-x11 \
xfonts-base \
xfonts-100dpi \
xfonts-75dpi \
xfonts-scalable \
imagemagick \
x11-apps
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
msg_info "Setup Python3"
$STD apt install -y python3
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
msg_ok "Setup Python3"
msg_info "Installing Chromium"
curl -fsSL https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome-keyring.gpg
cat <<EOF | sudo tee /etc/apt/sources.list.d/google-chrome.sources >/dev/null
Types: deb
URIs: http://dl.google.com/linux/chrome/deb/
Suites: stable
Components: main
Architectures: amd64
Signed-By: /usr/share/keyrings/google-chrome-keyring.gpg
EOF
$STD apt update
$STD apt -y install \
chromium \
libxss1 \
lsb-release
msg_ok "Installed Chromium"
msg_info "Setting up Chromium"
/usr/bin/chromium --no-sandbox --version >/etc/chromium-version
chmod 755 /usr/bin/chromium
msg_ok "Setup Chromium"
fetch_and_deploy_gh_release "web-check" "MickLesk/web-check"
msg_info "Installing Web-Check (Patience)"
cd /opt/web-check
cat <<'EOF' >/opt/web-check/.env
CHROME_PATH=/usr/bin/chromium
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
HEADLESS=true
GOOGLE_CLOUD_API_KEY=''
REACT_APP_SHODAN_API_KEY=''
REACT_APP_WHO_API_KEY=''
SECURITY_TRAILS_API_KEY=''
CLOUDMERSIVE_API_KEY=''
TRANCO_USERNAME=''
TRANCO_API_KEY=''
URL_SCAN_API_KEY=''
BUILT_WITH_API_KEY=''
TORRENT_IP_API_KEY=''
PORT='3000'
DISABLE_GUI='false'
API_TIMEOUT_LIMIT='10000'
API_CORS_ORIGIN='*'
API_ENABLE_RATE_LIMIT='false'
REACT_APP_API_ENDPOINT='/api'
ENABLE_ANALYTICS='false'
EOF
$STD yarn install --frozen-lockfile --network-timeout 100000
msg_ok "Installed Web-Check"
msg_info "Building Web-Check"
$STD yarn build --production
rm -rf /var/lib/apt/lists/* /app/node_modules/.cache
msg_ok "Built Web-Check"
msg_info "Creating Service"
cat <<'EOF' >/opt/run_web-check.sh
#!/bin/bash
SCREEN_RESOLUTION="1280x1024x24"
if ! systemctl is-active --quiet dbus; then
echo "Warning: dbus service is not running. Some features may not work properly."
fi
[[ -z "${DISPLAY}" ]] && export DISPLAY=":99"
Xvfb "${DISPLAY}" -screen 0 "${SCREEN_RESOLUTION}" &
XVFB_PID=$!
sleep 2
cd /opt/web-check
exec yarn start
EOF
chmod +x /opt/run_web-check.sh
cat <<'EOF' >/etc/systemd/system/web-check.service
[Unit]
Description=Web Check Service
After=network.target
[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/opt/web-check
EnvironmentFile=/opt/web-check/.env
ExecStartPre=/bin/bash -c "service dbus start || true"
ExecStartPre=/bin/bash -c "if ! pgrep -f 'Xvfb.*:99' > /dev/null; then Xvfb :99 -screen 0 1280x1024x24 & fi"
ExecStart=/opt/run_web-check.sh
Restart=on-failure
Environment=DISPLAY=:99
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now web-check
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc