This commit is contained in:
MickLesk
2026-06-01 16:44:41 +02:00
31 changed files with 1437 additions and 285 deletions

82
ct/grist.sh Normal file
View File

@@ -0,0 +1,82 @@
#!/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: cfurrow | Co-Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/gristlabs/grist-core
APP="Grist"
var_tags="${var_tags:-database;spreadsheet}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-3072}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/grist ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
ensure_dependencies git
if check_for_gh_release "grist" "gristlabs/grist-core"; then
msg_info "Stopping Service"
systemctl stop grist
msg_ok "Stopped Service"
msg_info "Creating backup"
rm -rf /opt/grist_bak
mv /opt/grist /opt/grist_bak
msg_ok "Backup created"
fetch_and_deploy_gh_release "grist" "gristlabs/grist-core" "tarball"
msg_info "Updating Grist"
mkdir -p /opt/grist/docs
cp -n /opt/grist_bak/.env /opt/grist/.env
if ls /opt/grist_bak/docs/* &>/dev/null; then
cp -r /opt/grist_bak/docs/* /opt/grist/docs/
fi
[[ -f /opt/grist_bak/grist-sessions.db ]] && cp /opt/grist_bak/grist-sessions.db /opt/grist/grist-sessions.db
[[ -f /opt/grist_bak/landing.db ]] && cp /opt/grist_bak/landing.db /opt/grist/landing.db
cd /opt/grist
$STD yarn install
# install:ee stalls probing the private grist-ee repo (a dev-only path it
# tries before falling back to the public tarball); GIT_TERMINAL_PROMPT=0
# makes that probe fail fast instead of waiting at a git login prompt.
export GIT_TERMINAL_PROMPT=0
$STD yarn run install:ee -y
$STD yarn run build:prod
$STD yarn run install:python
msg_ok "Updated Grist"
msg_info "Starting Service"
systemctl start grist
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}Grist: http://${IP}:8484${CL}"

6
ct/headers/grist Normal file
View File

@@ -0,0 +1,6 @@
______ _ __
/ ____/____(_)____/ /_
/ / __/ ___/ / ___/ __/
/ /_/ / / / (__ ) /_
\____/_/ /_/____/\__/

6
ct/headers/koffan Normal file
View File

@@ -0,0 +1,6 @@
__ __ ________
/ //_/___ / __/ __/___ _____
/ ,< / __ \/ /_/ /_/ __ `/ __ \
/ /| / /_/ / __/ __/ /_/ / / / /
/_/ |_\____/_/ /_/ \__,_/_/ /_/

6
ct/headers/nexterm Normal file
View File

@@ -0,0 +1,6 @@
_ __ __
/ | / /__ _ __/ /____ _________ ___
/ |/ / _ \| |/_/ __/ _ \/ ___/ __ `__ \
/ /| / __/> </ /_/ __/ / / / / / / /
/_/ |_/\___/_/|_|\__/\___/_/ /_/ /_/ /_/

6
ct/headers/onetimesecret Normal file
View File

@@ -0,0 +1,6 @@
____ _______ _____ __
/ __ \____ ___/_ __(_)___ ___ ___ / ___/___ _____________ / /_
/ / / / __ \/ _ \/ / / / __ `__ \/ _ \\__ \/ _ \/ ___/ ___/ _ \/ __/
/ /_/ / / / / __/ / / / / / / / / __/__/ / __/ /__/ / / __/ /_
\____/_/ /_/\___/_/ /_/_/ /_/ /_/\___/____/\___/\___/_/ \___/\__/

6
ct/headers/pinchflat Normal file
View File

@@ -0,0 +1,6 @@
____ _ __ ______ __
/ __ \(_)___ _____/ /_ / __/ /___ _/ /_
/ /_/ / / __ \/ ___/ __ \/ /_/ / __ `/ __/
/ ____/ / / / / /__/ / / / __/ / /_/ / /_
/_/ /_/_/ /_/\___/_/ /_/_/ /_/\__,_/\__/

View File

@@ -1,6 +0,0 @@
_____ __ ___ __
/ ___// /_ / (_)___ / /__
\__ \/ __ \/ / / __ \/ //_/
___/ / / / / / / / / / ,<
/____/_/ /_/_/_/_/ /_/_/|_|

6
ct/headers/umbraco Normal file
View File

@@ -0,0 +1,6 @@
__ __ __
/ / / /___ ___ / /_ _________ __________
/ / / / __ `__ \/ __ \/ ___/ __ `/ ___/ __ \
/ /_/ / / / / / / /_/ / / / /_/ / /__/ /_/ /
\____/_/ /_/ /_/_.___/_/ \__,_/\___/\____/

68
ct/koffan.sh Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env bash
source <(curl -s https://raw.githubusercontent.com/AminGholizad/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: (AminGholizad)
# License: MIT | https://github.com/AminGholizad/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/PanSalut/Koffan
APP="Koffan"
var_tags="${var_tags:-productivity}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/koffan/koffan ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "koffan" "PanSalut/Koffan"; then
msg_info "Stopping Service"
systemctl stop koffan
msg_ok "Stopped Service"
msg_info "Backing up Data"
cp -r /opt/koffan/data /opt/koffan_data_backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "koffan" "PanSalut/Koffan" "tarball"
msg_info "Rebuilding Koffan"
cd /opt/koffan
go build -o koffan main.go
msg_ok "Rebuild Koffan"
msg_info "Restoring Data"
cp -r /opt/koffan_data_backup/. /opt/koffan/data/
rm -rf /opt/koffan_data_backup
msg_ok "Restored Data"
msg_info "Starting Service"
systemctl start koffan
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"

75
ct/nexterm.sh Normal file
View File

@@ -0,0 +1,75 @@
#!/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: Mathias Wagner (gnmyt)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://nexterm.dev/
APP="Nexterm"
var_tags="${var_tags:-server-management}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/nexterm/server/nexterm-server ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
case "$(dpkg --print-architecture)" in
amd64) NX_ARCH="x64" ;;
arm64) NX_ARCH="arm64" ;;
*)
msg_error "Unsupported architecture"
exit 1
;;
esac
if check_for_gh_release "nexterm-engine" "gnmyt/Nexterm"; then
msg_info "Stopping nexterm-engine"
systemctl stop nexterm-engine
msg_ok "Stopped nexterm-engine"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nexterm-engine" "gnmyt/Nexterm" "prebuild" "latest" "/opt/nexterm/engine" "nexterm-engine-linux-${NX_ARCH}.tar.gz"
msg_info "Starting nexterm-engine"
systemctl start nexterm-engine
msg_ok "Started nexterm-engine"
fi
if check_for_gh_release "nexterm-server" "gnmyt/Nexterm"; then
msg_info "Stopping nexterm-server"
systemctl stop nexterm-server
msg_ok "Stopped nexterm-server"
fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-${NX_ARCH}"
msg_info "Starting nexterm-server"
systemctl start nexterm-server
msg_ok "Started nexterm-server"
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}:6989${CL}"

136
ct/onetimesecret.sh Normal file
View File

@@ -0,0 +1,136 @@
#!/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: Hai Tran (epiHATR)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://onetimesecret.com/ | Github: https://github.com/onetimesecret/onetimesecret
APP="OneTimeSecret"
var_tags="${var_tags:-security;privacy;secrets}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
SSL_VALUE="${OTS_SSL:-}"
if [[ -n "${SSL_VALUE}" ]]; then
case "${SSL_VALUE,,}" in
1 | true | yes | on) SSL_VALUE="true" ;;
0 | false | no | off) SSL_VALUE="false" ;;
*)
msg_error "Invalid OTS_SSL value '${OTS_SSL}' (use true/false)"
exit 1
;;
esac
fi
if [[ ! -d /opt/onetimesecret ]] || [[ ! -f /opt/onetimesecret/.env ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "onetimesecret" "onetimesecret/onetimesecret"; then
msg_info "Stopping Service"
systemctl stop onetimesecret
msg_ok "Stopped Service"
msg_info "Backing up Configuration"
cp /opt/onetimesecret/.env /opt/onetimesecret.env.bak
mkdir -p /opt/onetimesecret_etc_backup
for FILE in auth.yaml config.yaml logging.yaml puma.rb; do
[[ -f /opt/onetimesecret/etc/${FILE} ]] && cp "/opt/onetimesecret/etc/${FILE}" "/opt/onetimesecret_etc_backup/${FILE}"
done
msg_ok "Backed up Configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "onetimesecret" "onetimesecret/onetimesecret" "tarball"
RUBY_VERSION=$(sed -n "s/^ruby '>= \([0-9.]*\)'.*/\1/p" /opt/onetimesecret/Gemfile)
RUBY_VERSION="${RUBY_VERSION:-3.4.7}" setup_ruby
PNPM_VERSION=$(sed -n 's/.*"packageManager": "pnpm@\([^"]*\)".*/\1/p' /opt/onetimesecret/package.json)
NODE_VERSION=$(tr -d ' \n' </opt/onetimesecret/.nvmrc 2>/dev/null)
NODE_VERSION="${NODE_VERSION:-25}" NODE_MODULE="pnpm@${PNPM_VERSION:-11.1.2}" setup_nodejs
msg_info "Restoring Configuration"
cp /opt/onetimesecret.env.bak /opt/onetimesecret/.env
mkdir -p /opt/onetimesecret/etc
for FILE in auth.yaml config.yaml logging.yaml puma.rb; do
[[ -f /opt/onetimesecret_etc_backup/${FILE} ]] && cp "/opt/onetimesecret_etc_backup/${FILE}" "/opt/onetimesecret/etc/${FILE}"
done
if [[ -n "${OTS_HOST:-}" ]]; then
sed -i "s|^HOST=.*|HOST=${OTS_HOST//&/\\&}|" /opt/onetimesecret/.env
fi
if [[ -n "${SSL_VALUE}" ]]; then
sed -i "s|^SSL=.*|SSL=${SSL_VALUE}|" /opt/onetimesecret/.env
fi
if grep -q '^RACK_ENV=' /opt/onetimesecret/.env; then
sed -i 's|^RACK_ENV=.*|RACK_ENV=production|' /opt/onetimesecret/.env
else
echo "RACK_ENV=production" >>/opt/onetimesecret/.env
fi
if grep -q '^AUTHENTICATION_MODE=' /opt/onetimesecret/.env; then
sed -i 's|^AUTHENTICATION_MODE=.*|AUTHENTICATION_MODE=simple|' /opt/onetimesecret/.env
else
echo "AUTHENTICATION_MODE=simple" >>/opt/onetimesecret/.env
fi
if ! grep -q '^PORT=' /opt/onetimesecret/.env; then
echo "PORT=3000" >>/opt/onetimesecret/.env
fi
chmod 600 /opt/onetimesecret/.env
rm -f /opt/onetimesecret.env.bak
rm -rf /opt/onetimesecret_etc_backup
msg_ok "Restored Configuration"
msg_info "Reconciling Application"
systemctl enable -q --now redis-server
cd /opt/onetimesecret
mkdir -p tmp/pids log
$STD bash ./install.sh reconcile
msg_ok "Reconciled Application"
msg_info "Building Frontend"
cd /opt/onetimesecret
$STD pnpm run build
msg_ok "Built Frontend"
msg_info "Starting Service"
systemctl start onetimesecret
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
DISPLAY_HOST="${OTS_HOST:-$IP}"
case "${OTS_SSL:-false,,}" in
1 | true | yes | on)
DISPLAY_SCHEME="https"
;;
*)
DISPLAY_SCHEME="http"
;;
esac
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}${DISPLAY_SCHEME}://${DISPLAY_HOST}${CL}"
echo -e "${INFO}${YW} Configure hostname, TLS, and SMTP settings in:${CL}"
echo -e "${TAB}${BGN}/opt/onetimesecret/.env${CL}"

69
ct/pinchflat.sh Normal file
View File

@@ -0,0 +1,69 @@
#!/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: nnsense
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/kieraneglin/pinchflat
APP="Pinchflat"
var_tags="${var_tags:-media;youtube;downloader}"
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/pinchflat/app ]]; then
msg_error "No ${APP} installation found."
exit 1
fi
if check_for_gh_release "pinchflat" "kieraneglin/pinchflat"; then
msg_info "Stopping Service"
systemctl stop pinchflat
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pinchflat" "kieraneglin/pinchflat" "tarball" "latest" "/opt/pinchflat-src"
msg_info "Building Pinchflat"
cd /opt/pinchflat-src
export MIX_ENV=prod
export ERL_FLAGS="+JPperf true"
$STD mix deps.get --only prod
$STD mix deps.compile
$STD yarn --cwd assets install
$STD mix assets.deploy
$STD mix compile
$STD mix release --overwrite
rm -rf /opt/pinchflat/app
cp -r _build/prod/rel/pinchflat /opt/pinchflat/app
msg_ok "Built Pinchflat"
msg_info "Starting Service"
systemctl start pinchflat
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8945${CL}"

View File

@@ -1,86 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://shlink.io/
APP="Shlink"
var_tags="${var_tags:-url-shortener;analytics;php}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/shlink ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "shlink" "shlinkio/shlink"; then
msg_info "Stopping Service"
systemctl stop shlink
msg_ok "Stopped Service"
msg_info "Backing up Data"
cp /opt/shlink/.env /opt/shlink.env.bak
cp -r /opt/shlink/data /opt/shlink_data_backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "shlink" "shlinkio/shlink" "prebuild" "latest" "/opt/shlink" "shlink*_php8.5_dist.zip"
msg_info "Restoring Data"
cp /opt/shlink.env.bak /opt/shlink/.env
rm -f /opt/shlink.env.bak
cp -r /opt/shlink_data_backup/. /opt/shlink/data
rm -rf /opt/shlink_data_backup
msg_ok "Restored Data"
msg_info "Updating Application"
cd /opt/shlink
$STD php ./vendor/bin/rr get --no-interaction --location bin/
chmod +x bin/rr
set -a
source /opt/shlink/.env
set +a
$STD php vendor/bin/shlink-installer init --no-interaction --clear-db-cache --skip-download-geolite
msg_ok "Updated Application"
msg_info "Starting Service"
systemctl start shlink
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
if [[ -d /opt/shlink-web-client ]]; then
if check_for_gh_release "shlink-web-client" "shlinkio/shlink-web-client"; then
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "shlink-web-client" "shlinkio/shlink-web-client" "prebuild" "latest" "/opt/shlink-web-client" "shlink-web-client_*_dist.zip"
msg_ok "Updated Web Client"
fi
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 Shlink Web Client using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
echo -e "${INFO}${YW} Shlink HTTP API:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"

48
ct/umbraco.sh Normal file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/montagneid/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Joost van den Berg
# License: MIT | https://github.com/montagneid/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/umbraco/Umbraco-CMS
APP="Umbraco"
var_tags="${var_tags:-website}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /var/www ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating ${APP} LXC"
$STD apt update
$STD apt -y upgrade
msg_ok "Updated ${APP} LXC"
msg_info "Updating Umbraco Templates"
$STD dotnet new update
msg_ok "Updated Umbraco Templates"
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}https://${IP}"

65
install/grist-install.sh Normal file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: cfurrow | Co-Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/gristlabs/grist-core
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 \
make \
ca-certificates \
python3-venv \
git
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
fetch_and_deploy_gh_release "grist" "gristlabs/grist-core" "tarball"
msg_info "Installing Grist"
export CYPRESS_INSTALL_BINARY=0
export NODE_OPTIONS="--max-old-space-size=2048"
# install:ee stalls probing the private grist-ee repo (a dev-only path it
# tries before falling back to the public tarball); GIT_TERMINAL_PROMPT=0
# makes that probe fail fast instead of waiting at a git login prompt.
export GIT_TERMINAL_PROMPT=0
cd /opt/grist
$STD yarn install
$STD yarn run install:ee -y
$STD yarn run build:prod
$STD yarn run install:python
cat <<EOF >/opt/grist/.env
NODE_ENV=production
GRIST_HOST=0.0.0.0
EOF
msg_ok "Installed Grist"
msg_info "Create Service"
cat <<EOF >/etc/systemd/system/grist.service
[Unit]
Description=Grist
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/grist
ExecStart=/usr/bin/yarn run start:prod
EnvironmentFile=-/opt/grist/.env
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now grist
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

63
install/koffan-install.sh Normal file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: (AminGholizad)
# License: MIT | https://github.com/AminGholizad/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/PanSalut/Koffan
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
ensure_dependencies build-essential
setup_go
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "koffan" "PanSalut/Koffan" "tarball"
msg_info "Building Koffan"
cd /opt/koffan
go build -o koffan main.go
msg_ok "Built Koffan"
msg_info "Configuring Koffan"
PASSWORD=$(openssl rand -base64 12)
mkdir /opt/koffan/data
cat <<EOF >/opt/koffan/data/.env
APP_ENV=production
APP_PASSWORD=${PASSWORD}
PORT=3000
DB_PATH=/opt/koffan/data/shopping.db
EOF
cat <<EOF >~/koffan.creds
Password: ${PASSWORD}
EOF
msg_ok "Configured Koffan"
msg_info "Creating systemd service"
cat <<EOF >/etc/systemd/system/koffan.service
[Unit]
Description=Koffan Service
After=network.target
[Service]
EnvironmentFile=/opt/koffan/data/.env
WorkingDirectory=/opt/koffan
ExecStart=/opt/koffan/koffan
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now koffan
msg_ok "Created systemd service"
motd_ssh
customize
cleanup_lxc

View File

@@ -24,10 +24,12 @@ msg_ok "Installed MatterJS-Server"
msg_info "Configuring Network"
cat <<EOF >/etc/sysctl.d/60-ipv6-ra-rio.conf
net.ipv6.conf.default.accept_ra=1
net.ipv6.conf.default.accept_ra_rtr_pref=1
net.ipv6.conf.default.accept_ra_rt_info_max_plen=128
net.ipv6.conf.default.accept_ra_rt_info_max_plen=64
net.ipv6.conf.eth0.accept_ra=1
net.ipv6.conf.eth0.accept_ra_rtr_pref=1
net.ipv6.conf.eth0.accept_ra_rt_info_max_plen=128
net.ipv6.conf.eth0.accept_ra_rt_info_max_plen=64
EOF
$STD sysctl -p /etc/sysctl.d/60-ipv6-ra-rio.conf
msg_ok "Configured Network"

View File

@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Mathias Wagner (gnmyt)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://nexterm.dev/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
case "$(dpkg --print-architecture)" in
amd64) NX_ARCH="x64" ;;
arm64) NX_ARCH="arm64" ;;
*)
msg_error "Unsupported architecture: $(dpkg --print-architecture)"
exit 1
;;
esac
fetch_and_deploy_gh_release "nexterm-engine" "gnmyt/Nexterm" "prebuild" "latest" "/opt/nexterm/engine" "nexterm-engine-linux-${NX_ARCH}.tar.gz"
fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-${NX_ARCH}"
msg_info "Configuring Nexterm"
LOCAL_ENGINE_TOKEN=$(tr -d '-' </proc/sys/kernel/random/uuid)$(tr -d '-' </proc/sys/kernel/random/uuid)
ENCRYPTION_KEY=$(tr -d '-' </proc/sys/kernel/random/uuid)$(tr -d '-' </proc/sys/kernel/random/uuid)
mkdir -p /etc/nexterm-engine /etc/nexterm-server /opt/nexterm/data
cat <<EOF >/etc/nexterm-engine/config.yaml
server_host: "127.0.0.1"
server_port: 7800
registration_token: "${LOCAL_ENGINE_TOKEN}"
tls: false
EOF
cat <<EOF >/etc/nexterm-server/server.env
NODE_ENV=production
SERVER_PORT=6989
LOCAL_ENGINE_TOKEN=${LOCAL_ENGINE_TOKEN}
ENCRYPTION_KEY=${ENCRYPTION_KEY}
EOF
chmod 0640 /etc/nexterm-engine/config.yaml /etc/nexterm-server/server.env
msg_ok "Configured Nexterm"
msg_info "Creating Server Service"
cat <<EOF >/etc/systemd/system/nexterm-server.service
[Unit]
Description=Nexterm Server
Documentation=https://docs.nexterm.dev/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/nexterm/data
EnvironmentFile=/etc/nexterm-server/server.env
ExecStart=/opt/nexterm/server/nexterm-server
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now nexterm-server
msg_ok "Created Server Service"
msg_info "Creating Engine Service"
cat <<EOF >/etc/systemd/system/nexterm-engine.service
[Unit]
Description=Nexterm Engine
Documentation=https://docs.nexterm.dev/
After=network-online.target nexterm-server.service
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/etc/nexterm-engine
Environment=FREERDP_EXTENSION_PATH=/opt/nexterm/engine/lib/freerdp2
Environment=LD_LIBRARY_PATH=/opt/nexterm/engine/lib
ExecStart=/opt/nexterm/engine/nexterm-engine
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now nexterm-engine
msg_ok "Created Engine Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -0,0 +1,142 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Hai Tran (epiHATR)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://onetimesecret.com/ | Github: https://github.com/onetimesecret/onetimesecret
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 \
git \
libffi-dev \
libgmp-dev \
libpq-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
libxslt1-dev \
libyaml-dev \
nginx \
pkg-config \
python3 \
redis-server \
zlib1g-dev
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "onetimesecret" "onetimesecret/onetimesecret" "tarball"
RUBY_VERSION=$(sed -n "s/^ruby '>= \([0-9.]*\)'.*/\1/p" /opt/onetimesecret/Gemfile)
RUBY_VERSION="${RUBY_VERSION:-3.4.7}" setup_ruby
PNPM_VERSION=$(sed -n 's/.*"packageManager": "pnpm@\([^"]*\)".*/\1/p' /opt/onetimesecret/package.json)
NODE_VERSION=$(tr -d ' \n' </opt/onetimesecret/.nvmrc 2>/dev/null)
NODE_VERSION="${NODE_VERSION:-25}" NODE_MODULE="pnpm@${PNPM_VERSION:-11.1.2}" setup_nodejs
HOST_VALUE="${OTS_HOST:-$LOCAL_IP}"
SSL_VALUE="${OTS_SSL:-false}"
case "${SSL_VALUE,,}" in
1 | true | yes | on) SSL_VALUE="true" ;;
0 | false | no | off | "") SSL_VALUE="false" ;;
*)
msg_error "Invalid OTS_SSL value '${OTS_SSL}' (use true/false)"
exit 1
;;
esac
msg_info "Configuring Application"
systemctl enable -q --now redis-server
cd /opt/onetimesecret
$STD bash ./install.sh init
sed -i \
-e "s|^REDIS_URL=.*|REDIS_URL=redis://127.0.0.1:6379/0|" \
-e "s|^HOST=.*|HOST=${HOST_VALUE//&/\\&}|" \
-e "s|^SSL=.*|SSL=${SSL_VALUE}|" \
/opt/onetimesecret/.env
if grep -q '^RACK_ENV=' /opt/onetimesecret/.env; then
sed -i 's|^RACK_ENV=.*|RACK_ENV=production|' /opt/onetimesecret/.env
else
echo "RACK_ENV=production" >>/opt/onetimesecret/.env
fi
if grep -q '^AUTHENTICATION_MODE=' /opt/onetimesecret/.env; then
sed -i 's|^AUTHENTICATION_MODE=.*|AUTHENTICATION_MODE=simple|' /opt/onetimesecret/.env
else
echo "AUTHENTICATION_MODE=simple" >>/opt/onetimesecret/.env
fi
if ! grep -q '^PORT=' /opt/onetimesecret/.env; then
echo "PORT=3000" >>/opt/onetimesecret/.env
fi
chmod 600 /opt/onetimesecret/.env
mkdir -p /opt/onetimesecret/tmp/pids /opt/onetimesecret/log
msg_ok "Configured Application"
msg_info "Reconciling Application"
cd /opt/onetimesecret
$STD bash ./install.sh reconcile
msg_ok "Reconciled Application"
msg_info "Building Frontend"
cd /opt/onetimesecret
$STD pnpm run build
msg_ok "Built Frontend"
msg_info "Creating Service"
cat <<'EOF' >/etc/systemd/system/onetimesecret.service
[Unit]
Description=Onetime Secret Service
After=network.target redis-server.service
Requires=redis-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/onetimesecret
Environment=HOME=/root
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/bin/bash -lc 'source .env.sh && exec bundle exec puma -C etc/puma.rb'
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now onetimesecret
msg_ok "Created Service"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/onetimesecret
server {
listen 80 default_server;
server_name _;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
EOF
ln -sf /etc/nginx/sites-available/onetimesecret /etc/nginx/sites-enabled/onetimesecret
rm -f /etc/nginx/sites-enabled/default
$STD nginx -t
systemctl enable -q --now nginx
systemctl reload nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc

View File

@@ -18,7 +18,7 @@ $STD apt install -y \
build-essential
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
PG_VERSION="17" PG_MODULES="pg_trgm,ltree" setup_postgresql
PG_DB_NAME="oxicloud" PG_DB_USER="oxicloud" setup_postgresql_db
fetch_and_deploy_gh_release "OxiCloud" "DioCrafts/OxiCloud" "tarball" "latest" "/opt/oxicloud"
TOOLCHAIN="$(sed -n '2s/[^:]*://p' /opt/oxicloud/Dockerfile | awk -F- '{print $1}')"

View File

@@ -17,7 +17,6 @@ msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
git \
python3 \
ripgrep
msg_ok "Installed Dependencies"
@@ -28,7 +27,7 @@ PG_DB_NAME="paperclip" PG_DB_USER="paperclip" setup_postgresql_db
fetch_and_deploy_gh_release "paperclip-ai" "paperclipai/paperclip" "tarball"
msg_info "Building Paperclip"
cd /opt/paperclip
cd /opt/paperclip-ai
export HUSKY=0
export NODE_OPTIONS="--max-old-space-size=8192"
$STD pnpm install --frozen-lockfile
@@ -43,15 +42,19 @@ $STD npm install -g \
msg_ok "Installed Agent CLIs"
msg_info "Configuring Paperclip"
PAPERCLIP_HOME="/opt/paperclip-data"
PAPERCLIP_CONFIG="${PAPERCLIP_HOME}/instances/default/config.json"
mkdir -p /opt/paperclip-data
mkdir -p /root/.claude /root/.codex
BETTER_AUTH_SECRET=$(openssl rand -hex 32)
cat <<EOF >/opt/paperclip/.env
cat <<EOF >/opt/paperclip-ai/.env
DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
HOST=0.0.0.0
PORT=3100
SERVE_UI=true
PAPERCLIP_HOME=/opt/paperclip-data
PAPERCLIP_HOME=${PAPERCLIP_HOME}
PAPERCLIP_CONFIG=${PAPERCLIP_CONFIG}
PAPERCLIP_INSTANCE_ID=default
PAPERCLIP_DEPLOYMENT_MODE=authenticated
PAPERCLIP_DEPLOYMENT_EXPOSURE=private
@@ -61,22 +64,26 @@ EOF
msg_ok "Configured Paperclip"
msg_info "Running Database Migrations"
set -a && source /opt/paperclip/.env && set +a
set -a && source /opt/paperclip-ai/.env && set +a
$STD pnpm db:migrate
msg_ok "Ran Database Migrations"
msg_info "Bootstrapping Paperclip"
PAPERCLIP_ONBOARD_LOG=/opt/paperclip/paperclip-onboard.log
PAPERCLIP_BOOTSTRAP_LOG=/opt/paperclip/paperclip-bootstrap.log
PAPERCLIP_ONBOARD_LOG=/opt/paperclip-ai/paperclip-onboard.log
PAPERCLIP_BOOTSTRAP_LOG=/opt/paperclip-ai/paperclip-bootstrap.log
for PAPERCLIP_ONBOARD_CMD in \
"pnpm paperclipai onboard --yes --bind lan" \
"pnpm paperclipai onboard --yes"; do
rm -f "$PAPERCLIP_ONBOARD_LOG"
setsid bash -c "cd /opt/paperclip && ${PAPERCLIP_ONBOARD_CMD}" >"$PAPERCLIP_ONBOARD_LOG" 2>&1 &
setsid env \
PAPERCLIP_HOME="$PAPERCLIP_HOME" \
PAPERCLIP_CONFIG="$PAPERCLIP_CONFIG" \
bash -c 'cd /opt/paperclip-ai && exec "$@"' _ $PAPERCLIP_ONBOARD_CMD \
>"$PAPERCLIP_ONBOARD_LOG" 2>&1 &
PAPERCLIP_ONBOARD_PID=$!
for _ in {1..60}; do
if [[ -f /opt/paperclip-data/instances/default/config.json ]]; then
if [[ -f "$PAPERCLIP_CONFIG" ]]; then
break
fi
if ! kill -0 "$PAPERCLIP_ONBOARD_PID" 2>/dev/null; then
@@ -88,19 +95,19 @@ for PAPERCLIP_ONBOARD_CMD in \
kill -- -"${PAPERCLIP_ONBOARD_PID}" >/dev/null 2>&1 || true
wait "$PAPERCLIP_ONBOARD_PID" 2>/dev/null || true
fi
[[ -f /opt/paperclip-data/instances/default/config.json ]] && break
[[ -f "$PAPERCLIP_CONFIG" ]] && break
if ! grep -q "unknown option '--bind'" "$PAPERCLIP_ONBOARD_LOG"; then
break
fi
msg_info "Retrying Paperclip Onboarding"
done
if [[ ! -f /opt/paperclip-data/instances/default/config.json ]]; then
if [[ ! -f "$PAPERCLIP_CONFIG" ]]; then
msg_error "Failed to bootstrap Paperclip"
exit 1
fi
if grep -q 'authenticated' /opt/paperclip-data/instances/default/config.json; then
if grep -q 'authenticated' $PAPERCLIP_CONFIG; then
pnpm paperclipai auth bootstrap-ceo >"$PAPERCLIP_BOOTSTRAP_LOG" 2>&1 || true
PAPERCLIP_INVITE_URL=$(awk -F'Invite URL: ' '/Invite URL:/ {print $2; exit}' "$PAPERCLIP_BOOTSTRAP_LOG")
PAPERCLIP_INVITE_EXPIRY=$(awk -F'Expires: ' '/Expires:/ {print $2; exit}' "$PAPERCLIP_BOOTSTRAP_LOG")
@@ -134,8 +141,8 @@ Requires=postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/paperclip
EnvironmentFile=/opt/paperclip/.env
WorkingDirectory=/opt/paperclip-ai
EnvironmentFile=/opt/paperclip-ai/.env
Environment=HOME=/root
Environment=CODEX_HOME=/root/.codex
Environment=PATH=/root/.local/bin:/usr/local/bin:/usr/bin:/bin

View File

@@ -0,0 +1,125 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: nnsense
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/kieraneglin/pinchflat
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 \
elixir \
erlang-dev \
erlang-inets \
erlang-os-mon \
erlang-runtime-tools \
erlang-syntax-tools \
erlang-xmerl \
git \
libsqlite3-dev \
locales \
openssh-client \
openssl \
pipx \
pkg-config \
procps \
python3-mutagen \
zip
msg_ok "Installed Dependencies"
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
FFMPEG_TYPE="binary" setup_ffmpeg
setup_hwaccel
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-x86_64-unknown-linux-gnu.zip"
fetch_and_deploy_gh_release "yt-dlp" "yt-dlp/yt-dlp" "singlefile" "latest" "/usr/local/bin" "yt-dlp_linux"
msg_info "Installing Apprise"
export PIPX_HOME=/opt/pipx
export PIPX_BIN_DIR=/usr/local/bin
$STD pipx install apprise
msg_ok "Installed Apprise"
fetch_and_deploy_gh_release "pinchflat" "kieraneglin/pinchflat" "tarball" "latest" "/opt/pinchflat-src"
msg_info "Configuring Pinchflat"
CONFIG_PATH="/opt/pinchflat/config"
DOWNLOADS_PATH="/opt/pinchflat/downloads"
mkdir -p \
/etc/elixir_tzdata_data \
/etc/yt-dlp/plugins \
/opt/pinchflat/app \
"$CONFIG_PATH/db" \
"$CONFIG_PATH/extras" \
"$CONFIG_PATH/logs" \
"$CONFIG_PATH/metadata" \
"$DOWNLOADS_PATH"
ln -sfn "$CONFIG_PATH" /config
ln -sfn "$DOWNLOADS_PATH" /downloads
chmod ugo+rw /etc/elixir_tzdata_data /etc/yt-dlp /etc/yt-dlp/plugins
cat <<EOF >/opt/pinchflat/.env
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_ALL=en_US.UTF-8
MIX_ENV=prod
PHX_SERVER=true
PORT=8945
RUN_CONTEXT=selfhosted
CONFIG_PATH=${CONFIG_PATH}
MEDIA_PATH=${DOWNLOADS_PATH}
TZ_DATA_PATH=/etc/elixir_tzdata_data
SECRET_KEY_BASE=$(openssl rand -base64 48)
EOF
msg_ok "Configured Pinchflat"
msg_info "Building Pinchflat"
cd /opt/pinchflat-src
export MIX_ENV=prod
export ERL_FLAGS="+JPperf true"
$STD mix local.hex --force
$STD mix local.rebar --force
$STD mix deps.get --only prod
$STD mix deps.compile
$STD yarn --cwd assets install
$STD mix assets.deploy
$STD mix compile
$STD mix release --overwrite
rm -rf /opt/pinchflat/app
cp -r _build/prod/rel/pinchflat /opt/pinchflat/app
msg_ok "Built Pinchflat"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/pinchflat.service
[Unit]
Description=Pinchflat
After=network.target
[Service]
Type=simple
EnvironmentFile=/opt/pinchflat/.env
WorkingDirectory=/opt/pinchflat/app
UMask=0022
ExecStartPre=/opt/pinchflat/app/bin/check_file_permissions
ExecStartPre=/opt/pinchflat/app/bin/migrate
ExecStart=/opt/pinchflat/app/bin/pinchflat start
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now pinchflat
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -1,126 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://shlink.io/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
PHP_VERSION="8.5" setup_php
setup_mariadb
MARIADB_DB_NAME="shlink" MARIADB_DB_USER="shlink" setup_mariadb_db
fetch_and_deploy_gh_release "shlink" "shlinkio/shlink" "prebuild" "latest" "/opt/shlink" "shlink*_php8.5_dist.zip"
msg_info "Setting up Application"
cd /opt/shlink
$STD php ./vendor/bin/rr get --no-interaction --location bin/
chmod +x bin/rr
mkdir -p data/cache data/locks data/log data/proxies data/temp-geolite
chmod -R 775 data
cat <<EOF >/opt/shlink/.env
DEFAULT_DOMAIN=${LOCAL_IP}:8080
IS_HTTPS_ENABLED=false
DB_DRIVER=maria
DB_NAME=${MARIADB_DB_NAME}
DB_USER=${MARIADB_DB_USER}
DB_PASSWORD=${MARIADB_DB_PASS}
DB_HOST=127.0.0.1
DB_PORT=3306
EOF
set -a
source /opt/shlink/.env
set +a
$STD php vendor/bin/shlink-installer init --no-interaction --clear-db-cache --skip-download-geolite
API_OUTPUT=$(php bin/cli api-key:generate --name=default 2>&1)
INITIAL_API_KEY=$(echo "$API_OUTPUT" | sed -n 's/.*Generated API key: "\([^"]*\)".*/\1/p')
if [[ -n "$INITIAL_API_KEY" ]]; then
echo "INITIAL_API_KEY=${INITIAL_API_KEY}" >>/opt/shlink/.env
fi
msg_ok "Set up Application"
if prompt_confirm "Install Shlink Web Client?" "y" 60; then
msg_info "Installing Dependencies"
$STD apt install -y nginx
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "shlink-web-client" "shlinkio/shlink-web-client" "prebuild" "latest" "/opt/shlink-web-client" "shlink-web-client_*_dist.zip"
msg_info "Setting up Web Client"
cat <<EOF >/opt/shlink-web-client/servers.json
[
{
"name": "Shlink",
"url": "http://${LOCAL_IP}:8080",
"apiKey": "${INITIAL_API_KEY}"
}
]
EOF
cat <<'EOF' >/etc/nginx/sites-available/shlink-web-client
server {
listen 3000 default_server;
charset utf-8;
root /opt/shlink-web-client;
index index.html;
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
expires -1;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 1M;
add_header Cache-Control "public";
}
location ~* \.(?:css|js)$ {
expires 1y;
add_header Cache-Control "public";
}
location = /servers.json {
try_files /servers.json /conf.d/servers.json;
}
location / {
try_files $uri $uri/ /index.html$is_args$args;
}
}
EOF
ln -sf /etc/nginx/sites-available/shlink-web-client /etc/nginx/sites-enabled/shlink-web-client
rm -f /etc/nginx/sites-enabled/default
systemctl enable -q nginx
$STD systemctl restart nginx
msg_ok "Set up Web Client"
fi
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/shlink.service
[Unit]
Description=Shlink URL Shortener
After=network.target mariadb.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/shlink
EnvironmentFile=/opt/shlink/.env
ExecStart=/opt/shlink/bin/rr serve -c config/roadrunner/.rr.yml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now shlink
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

188
install/umbraco-install.sh Normal file
View File

@@ -0,0 +1,188 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Joost van den Berg
# License: MIT | https://github.com/montagneid/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/umbraco/Umbraco-CMS
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
var_project_name="cms"
msg_info "Installing Dependencies"
$STD apt install -y \
ca-certificates \
uuid-runtime \
nginx \
vsftpd
msg_ok "Installed Dependencies"
msg_info "Installing .NET SDK 10.0"
setup_deb822_repo \
"microsoft" \
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
"https://packages.microsoft.com/debian/13/prod/" \
"trixie"
$STD apt install -y dotnet-sdk-10.0
msg_ok "Installed .NET SDK 10.0"
msg_info "Installing dotnet Umbraco templates and create project (Patience)"
cd /var/www/html
$STD dotnet new install Umbraco.Templates
$STD dotnet new umbraco --force -n "$var_project_name"
msg_ok "Umbraco templates installed and project created"
msg_info "Configuring database connection and unattended setup"
cd /var/www/html/$var_project_name
UMBRACO_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
jq --arg umbracopass "$UMBRACO_PASS" '. + {
"ConnectionStrings": {
"umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
"umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite"
},
"Umbraco": {
"CMS": {
"_Comment": "Remove the Unattended section after first run",
"Unattended": {
"InstallUnattended": true,
"UnattendedUserName": "admin",
"UnattendedUserEmail": "admin@umbraco.local",
"UnattendedUserPassword": $umbracopass
}
}
}
}' /var/www/html/$var_project_name/appsettings.json > /tmp/appsettings.tmp && mv /tmp/appsettings.tmp /var/www/html/$var_project_name/appsettings.json
ln -sf /var/www/html/$var_project_name/appsettings.json ~/umbraco.creds
msg_ok "Database connection and unattended setup configured"
msg_info "Setting up Nginx Server"
rm -f /var/www/html/index.nginx-debian.html
cat <<EOF >/etc/nginx/sites-available/default
map \$http_connection \$connection_upgrade {
"~*Upgrade" \$http_connection;
default keep-alive;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /etc/ssl/umbraco/umbraco.crt;
ssl_certificate_key /etc/ssl/umbraco/umbraco.key;
location / {
proxy_pass https://127.0.0.1:7000/;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection \$connection_upgrade;
proxy_set_header Host \$host;
proxy_cache_bypass \$http_upgrade;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 8 32k;
proxy_busy_buffers_size 64k;
}
}
EOF
create_self_signed_cert
systemctl reload nginx
msg_ok "Nginx Server created"
msg_info "Creating Kestrel Umbraco Service"
cat <<EOF >/usr/local/bin/umbraco-start.sh
#!/usr/bin/env bash
/usr/bin/dotnet /var/www/html/$var_project_name-publish/$var_project_name.dll --urls "https://0.0.0.0:7000" &
EOF
chmod +x /usr/local/bin/umbraco-start.sh
cat <<EOF >/etc/systemd/system/umbraco-kestrel.service
[Unit]
Description=Umbraco CMS running on Linux
[Service]
WorkingDirectory=/var/www/html/$var_project_name-publish
ExecStart=/usr/local/bin/umbraco-start.sh
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=umbraco
User=root
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now umbraco-kestrel
msg_ok "Umbraco Kestrel Service created"
msg_info "Creating dotnet publish script"
cat <<EOF >/var/www/html/$var_project_name/publish.sh
#!/usr/bin/env bash
cd /var/www/html/$var_project_name
systemctl stop umbraco-kestrel.service
dotnet publish -c Release -o /var/www/html/$var_project_name-publish
systemctl start umbraco-kestrel.service
EOF
chmod +x /var/www/html/$var_project_name/publish.sh
msg_ok "Dotnet publish script created"
msg_info "Building and publishing project (Patience)"
$STD /var/www/html/$var_project_name/publish.sh
msg_ok "Umbraco published successfully to /var/www/html/$var_project_name-publish"
msg_info "Setting up FTP Server"
useradd ftpuser
FTP_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
usermod --password $(echo ${FTP_PASS} | openssl passwd -1 -stdin) ftpuser
mkdir -p /var/www/html
usermod -d /var/www/html ftp
usermod -d /var/www/html ftpuser
chown -R ftpuser:ftpuser /var/www/html
sed -i "s|#write_enable=YES|write_enable=YES|g" /etc/vsftpd.conf
sed -i "s|#chroot_local_user=YES|chroot_local_user=NO|g" /etc/vsftpd.conf
systemctl restart -q vsftpd.service
{
echo "FTP Credentials"
echo "Username: ftpuser"
echo "Password: $FTP_PASS"
} >>~/ftp.creds
msg_ok "FTP server setup completed"
msg_info "Creating Visual Studio FTP Publish Profile"
PROJECT_GUID=$(uuidgen | tr '[:upper:]' '[:lower:]')
CONTAINER_IP=$(hostname -I | awk '{print $1}')
PUBLISH_PROFILE_DIR="/var/www/html/${var_project_name}/Properties/PublishProfiles"
mkdir -p "$PUBLISH_PROFILE_DIR"
cat >"$PUBLISH_PROFILE_DIR/FTPProfile.pubxml" <<EOF
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<WebPublishMethod>FTP</WebPublishMethod>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>https://${CONTAINER_IP}</SiteUrlToLaunchAfterPublish>
<ExcludeApp_Data>false</ExcludeApp_Data>
<ProjectGuid>${PROJECT_GUID}</ProjectGuid>
<publishUrl>${CONTAINER_IP}</publishUrl>
<DeleteExistingFiles>false</DeleteExistingFiles>
<FtpPassiveMode>true</FtpPassiveMode>
<FtpSitePath>${var_project_name}-publish</FtpSitePath>
<UserName>ftpuser</UserName>
<_SavePWD>true</_SavePWD>
<_TargetId>FTP</_TargetId>
</PropertyGroup>
</Project>
EOF
msg_ok "Publish Profile created"
motd_ssh
customize
cleanup_lxc

40
json/koffan.json Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "Koffan",
"slug": "koffan",
"categories": [
12
],
"date_created": "2026-05-25",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": null,
"website": null,
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/koffan.webp",
"description": "Koffan is a lightweight web application for managing shopping lists, designed for couples and families. It allows real-time synchronization between multiple devices, so everyone knows what to buy and what's already in the cart.\n\nThe app works in any browser on both mobile and desktop. Just one password to log in - no complicated registration required.",
"install_methods": [
{
"type": "default",
"script": "ct/koffan.sh",
"config_path": "/opt/koffan/data/.env",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 4,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": "shopping123"
},
"notes": [
{
"text": "Credentials are saved to `~/koffan.creds`.",
"type": "info"
}
]
}

36
json/nexterm.json Normal file
View File

@@ -0,0 +1,36 @@
{
"name": "Nexterm",
"slug": "nexterm",
"categories": [
10
],
"date_created": "2026-05-25",
"type": "ct",
"updateable": true,
"privileged": false,
"has_arm": false,
"interface_port": 6989,
"documentation": "https://docs.nexterm.dev/",
"website": "https://nexterm.dev/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/nexterm.webp",
"description": "Nexterm is an open-source server management software for SSH, VNC & RDP. It bundles a web interface, file management, monitoring, and team collaboration with two-factor authentication, OIDC SSO, and encrypted credential storage.",
"install_methods": [
{
"type": "default",
"script": "ct/nexterm.sh",
"config_path": "/etc/nexterm-server/server.env",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 6,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

47
json/onetimesecret.json Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "Onetime Secret",
"slug": "onetimesecret",
"categories": [6],
"date_created": "2026-05-26",
"type": "ct",
"updateable": true,
"privileged": false,
"has_arm": false,
"interface_port": 80,
"documentation": "https://docs.onetimesecret.com/en/self-hosting/installation/",
"website": "https://onetimesecret.com/",
"logo": "https://onetimesecret.com/favicon.svg",
"description": "Onetime Secret is a self-hosted secret sharing app that creates self-destructing links for passwords, API keys, and other sensitive text.",
"install_methods": [
{
"type": "default",
"script": "ct/onetimesecret.sh",
"config_path": "/opt/onetimesecret/.env",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 10,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Update HOST and set SSL=true in /opt/onetimesecret/.env when using a domain or TLS-terminating reverse proxy.",
"type": "warning"
},
{
"text": "Configure SMTP settings in /opt/onetimesecret/.env if you want email notifications or account verification features.",
"type": "info"
},
{
"text": "Back up /opt/onetimesecret/.env because it contains the root SECRET used to derive the app's other cryptographic keys.",
"type": "warning"
}
]
}

48
json/pinchflat.json Normal file
View File

@@ -0,0 +1,48 @@
{
"name": "Pinchflat",
"slug": "pinchflat",
"categories": [
13
],
"date_created": "2026-05-05",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8945,
"documentation": "https://github.com/kieraneglin/pinchflat/wiki",
"website": "https://github.com/kieraneglin/pinchflat",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/pinchflat.webp",
"description": "Pinchflat is a self-hosted YouTube media manager built with yt-dlp for automatically downloading and organizing content from channels and playlists.",
"install_methods": [
{
"type": "default",
"script": "ct/pinchflat.sh",
"config_path": "/opt/pinchflat/.env",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "For large media libraries, increase disk space or mount external storage at `/opt/pinchflat/downloads` before downloading media to avoid filling the LXC disk.",
"type": "warning"
},
{
"text": "Pinchflat data is stored in `/opt/pinchflat/config`",
"type": "info"
},
{
"text": "downloaded media is stored in `/opt/pinchflat/downloads`",
"type": "info"
}
]
}

View File

@@ -1,49 +0,0 @@
{
"name": "Shlink",
"slug": "shlink",
"categories": [
0
],
"date_created": "2026-04-20",
"type": "ct",
"updateable": true,
"privileged": false,
"has_arm": false,
"interface_port": 3000,
"documentation": "https://shlink.io/documentation/",
"website": "https://shlink.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/shlink.webp",
"description": "Shlink is a self-hosted URL shortener built in PHP that provides detailed analytics, a REST API, tags, expiration dates, and integrations via webhooks.",
"install_methods": [
{
"type": "default",
"script": "ct/shlink.sh",
"config_path": "/opt/shlink/.env",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "The initial API key is stored in /opt/shlink/.env. You need it to connect Shlink Web Client or any API consumer.",
"type": "warning"
},
{
"text": "Configure your short domain by editing DEFAULT_DOMAIN in /opt/shlink/.env and restarting the service.",
"type": "info"
},
{
"text": "Shlink API runs on port 8080, the Web Client (if installed) on port 3000.",
"type": "info"
}
]
}

44
json/umbraco.json Normal file
View File

@@ -0,0 +1,44 @@
{
"name": "Umbraco CMS",
"slug": "umbraco",
"categories": [
25
],
"date_created": "2026-05-06",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 443,
"documentation": "https://docs.umbraco.com/",
"website": "https://umbraco.com/",
"logo": "https://umbraco.com/media/54xnncgt/umbraco_logo_blue05.webp?rmode=pad&width=680&quality=85&v=1dad6b6701b24f0",
"config_path": "",
"description": "Umbraco is a free, open-source .NET CMS with a friendly editing experience, beautiful backoffice, and powerful customization options. Automatically setup a Umbraco server up, as well as a FTP server so you can publish to this container from Visual Studio.",
"install_methods": [
{
"type": "default",
"script": "ct/umbraco.sh",
"resources": {
"cpu": 2,
"ram": 512,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Cridentials are saved in /root",
"type": "info"
},
{
"text": "The FTPProfile.pubxml can be used to publish directly from Visual Studio, but you can also use the built-in code editor in the Umbraco backoffice.",
"type": "info"
}
]
}

View File

@@ -7979,7 +7979,7 @@ setup_postgresql_db() {
IFS=',' read -ra EXT_LIST <<<"${PG_DB_EXTENSIONS:-}"
for ext in "${EXT_LIST[@]}"; do
ext=$(echo "$ext" | xargs) # Trim whitespace
$STD sudo -u postgres psql -d "$PG_DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS $ext;"
$STD sudo -u postgres psql -d "$PG_DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS \"$ext\";"
done
fi