mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-11-09 12:53:13 +01:00
Compare commits
38
Commits
No files matched your search
+27
@@ -0,0 +1,27 @@
|
||||
name: Check Script Repo URL
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
paths:
|
||||
- "ct/**"
|
||||
- "install/**"
|
||||
- "vm/**"
|
||||
- "tools/**"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check:
|
||||
if: github.repository == 'community-scripts/ProxmoxVE'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Reject DevScripts URLs
|
||||
run: |
|
||||
if grep -rnE 'community-scripts/(ProxmoxVED|DevScripts)/' ct install vm tools; then
|
||||
echo "::error::These lines point at DevScripts, so telemetry files the runs there. Use community-scripts/ProxmoxVE."
|
||||
exit 1
|
||||
fi
|
||||
@@ -571,6 +571,70 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-11-07
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- fix: gotenberg: update to v9 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#18491](https://github.com/community-scripts/ProxmoxVE/pull/18491))
|
||||
|
||||
## 2026-11-06
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- UmbrelOS-VM: report runs as ProxmoxVE, not DevScripts [@MickLesk](https://github.com/MickLesk) ([#18497](https://github.com/community-scripts/ProxmoxVE/pull/18497))
|
||||
- Caddy: skip the xCaddy test build below 2 GB RAM [@MickLesk](https://github.com/MickLesk) ([#18472](https://github.com/community-scripts/ProxmoxVE/pull/18472))
|
||||
- Thingsboard: keep the package defaults in thingsboard.conf [@MickLesk](https://github.com/MickLesk) ([#18499](https://github.com/community-scripts/ProxmoxVE/pull/18499))
|
||||
- Nexterm: keep the extracted app out of the /tmp cleanup [@MickLesk](https://github.com/MickLesk) ([#18501](https://github.com/community-scripts/ProxmoxVE/pull/18501))
|
||||
- PLANKA: run the service with node instead of nodemon [@MickLesk](https://github.com/MickLesk) ([#18503](https://github.com/community-scripts/ProxmoxVE/pull/18503))
|
||||
- MeTube/Yubal: install Deno without its shell setup [@MickLesk](https://github.com/MickLesk) ([#18406](https://github.com/community-scripts/ProxmoxVE/pull/18406))
|
||||
- OPNsense VM: size the temp space check to the unpacked image | say why the EFI disk could not be allocated [@MickLesk](https://github.com/MickLesk) ([#18404](https://github.com/community-scripts/ProxmoxVE/pull/18404))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Technitium DNS: read the version from its GitHub releases [@MickLesk](https://github.com/MickLesk) ([#18425](https://github.com/community-scripts/ProxmoxVE/pull/18425))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- fix: spot same-filesystem bind mounts on Alpine [@rcourtman](https://github.com/rcourtman) ([core#212](https://github.com/community-scripts/core/pull/212))
|
||||
- fix: report a container that went down during setup, keep finished installs [@MickLesk](https://github.com/MickLesk) ([core#211](https://github.com/community-scripts/core/pull/211))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- ci: reject DevScripts URLs in scripts [@MickLesk](https://github.com/MickLesk) ([#18498](https://github.com/community-scripts/ProxmoxVE/pull/18498))
|
||||
|
||||
## 2026-11-05
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- OpenWRT-VM: leave the NIC untagged on a bridge without a port [@MickLesk](https://github.com/MickLesk) ([#18473](https://github.com/community-scripts/ProxmoxVE/pull/18473))
|
||||
- Podman: skip Portainer where Podman has no Quadlet [@MickLesk](https://github.com/MickLesk) ([#18469](https://github.com/community-scripts/ProxmoxVE/pull/18469))
|
||||
- Planka: change npm start argument to --production [@CerberusStyle](https://github.com/CerberusStyle) ([#18478](https://github.com/community-scripts/ProxmoxVE/pull/18478))
|
||||
- OPNsense VM: wait for the FreeBSD login prompt instead of 180 seconds [@MickLesk](https://github.com/MickLesk) ([#18467](https://github.com/community-scripts/ProxmoxVE/pull/18467))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- truenas-VM: let a failed ISO lookup reach its own error [@MickLesk](https://github.com/MickLesk) ([#18476](https://github.com/community-scripts/ProxmoxVE/pull/18476))
|
||||
- proxmox-mail-gateway: take the repo suite from the container [@MickLesk](https://github.com/MickLesk) ([#18475](https://github.com/community-scripts/ProxmoxVE/pull/18475))
|
||||
- Immich: Bump to 3.3.6 and minor improvement [@MickLesk](https://github.com/MickLesk) ([#18474](https://github.com/community-scripts/ProxmoxVE/pull/18474))
|
||||
- Tududi: run 2.0 on PostgreSQL, keep SQLite installs on 1.15.0 [@MickLesk](https://github.com/MickLesk) ([#18465](https://github.com/community-scripts/ProxmoxVE/pull/18465))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- fix: keep the existing install until the new archive has extracted [@rcourtman](https://github.com/rcourtman) ([core#201](https://github.com/community-scripts/core/pull/201))
|
||||
- fix: keep the install when a clone or an Alpine extract fails [@rcourtman](https://github.com/rcourtman) ([core#210](https://github.com/community-scripts/core/pull/210))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Arcane: write both env names, stop shipping the unused .env [@MickLesk](https://github.com/MickLesk) ([#18466](https://github.com/community-scripts/ProxmoxVE/pull/18466))
|
||||
|
||||
## 2026-11-04
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
+7
-3
@@ -55,9 +55,13 @@ update_deb_based() {
|
||||
setup_go
|
||||
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "binary"
|
||||
|
||||
msg_info "Updating xCaddy"
|
||||
$STD xcaddy build
|
||||
msg_ok "Updated xCaddy"
|
||||
if (($(awk '/^MemTotal:/ {print int($2 / 1024)}' /proc/meminfo) < 1900)); then
|
||||
msg_warn "xCaddy updated; its test build was skipped because linking Caddy needs about 2 GB RAM"
|
||||
else
|
||||
msg_info "Updating xCaddy"
|
||||
$STD xcaddy build
|
||||
msg_ok "Updated xCaddy"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
msg_ok "Updated successfully!"
|
||||
|
||||
+23
-6
@@ -45,15 +45,32 @@ function update_script() {
|
||||
export CGO_ENABLED=0
|
||||
$STD go mod download
|
||||
$STD go build -o /usr/local/bin/gotenberg \
|
||||
-ldflags "-s -w -X 'github.com/gotenberg/gotenberg/v8/cmd.Version=$(cat ~/.gotenberg)'" \
|
||||
-ldflags "-s -w -X 'github.com/gotenberg/gotenberg/v9/cmd.Version=$(cat ~/.gotenberg)'" \
|
||||
cmd/gotenberg/main.go
|
||||
msg_ok "Built gotenberg"
|
||||
|
||||
msg_info "Updating unoconverter"
|
||||
UNOCONVERTER_VERSION=$(get_latest_github_release "gotenberg/unoconverter" "false")
|
||||
download_file "https://raw.githubusercontent.com/gotenberg/unoconverter/${UNOCONVERTER_VERSION}/unoconv" /usr/local/bin/unoconverter
|
||||
chmod +x /usr/local/bin/unoconverter
|
||||
msg_ok "Updated unoconverter"
|
||||
LOK_VERSION="$(awk -F= '/^ARG LOK_VERSION=/{print $2}' /opt/gotenberg/build/Dockerfile)"
|
||||
fetch_and_deploy_gh_release "lok" "gotenberg/lok" "prebuild" "$LOK_VERSION" "/usr/local/bin" "lok_${LOK_VERSION#v}_linux_$(arch_resolve "amd64" "arm64").tar.gz"
|
||||
|
||||
msg_info "Migrating to Gotenberg 9"
|
||||
CODENAME=$(get_os_info codename)
|
||||
setup_deb822_repo \
|
||||
"debian-backports" \
|
||||
"file:///usr/share/keyrings/debian-archive-keyring.gpg" \
|
||||
"http://deb.debian.org/debian" \
|
||||
"${CODENAME}-backports" \
|
||||
"main"
|
||||
$STD apt install -y fonts-urw-base35
|
||||
$STD apt install -y -t "${CODENAME}-backports" \
|
||||
libreoffice-writer libreoffice-calc libreoffice-impress libreoffice-draw libreoffice-math
|
||||
$STD apt purge -y python3-uno python-is-python3 pdftk-java qpdf libimage-exiftool-perl
|
||||
$STD apt autoremove -y
|
||||
rm -rf /usr/local/bin/unoconverter /usr/local/bin/pdfcpu /opt/pdfcpu
|
||||
sed -i '/^Environment=\(UNOCONVERTER\|PDFTK\|QPDF\|EXIFTOOL\|PDFCPU\)_BIN_PATH=/d' /etc/systemd/system/gotenberg.service
|
||||
grep -q '^Environment=LOK_BIN_PATH=' /etc/systemd/system/gotenberg.service ||
|
||||
sed -i '/^Environment=LIBREOFFICE_BIN_PATH=/a Environment=LOK_BIN_PATH=/usr/local/bin/lok' /etc/systemd/system/gotenberg.service
|
||||
systemctl daemon-reload
|
||||
msg_ok "Migrated to Gotenberg 9"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start gotenberg
|
||||
|
||||
+3
-3
@@ -75,7 +75,7 @@ EOF
|
||||
BASE_DIR=${STAGING_DIR}/base-images
|
||||
SOURCE_DIR=${STAGING_DIR}/image-source
|
||||
cd /tmp
|
||||
RELEASE="v3.3.5"
|
||||
RELEASE="v3.3.6"
|
||||
if [[ -f ~/.intel_version ]]; then
|
||||
INTEL_SRC="https://raw.githubusercontent.com/immich-app/immich/${RELEASE}/machine-learning"
|
||||
curl -fsSL "${INTEL_SRC}/scripts/install-intel-runtime.sh" -o ./intel-runtime 2>/dev/null ||
|
||||
@@ -292,7 +292,7 @@ EOF
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Updating Intel OpenVINO machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { ML_FAILED=1; break; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
@@ -310,7 +310,7 @@ EOF
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Updating machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { ML_FAILED=1; break; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ function update_script() {
|
||||
source ~/.bashrc
|
||||
if ! command -v deno &>/dev/null; then
|
||||
export DENO_INSTALL="/usr/local"
|
||||
curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
|
||||
curl -fsSL https://deno.land/install.sh | CI=1 $STD sh -s
|
||||
else
|
||||
$STD deno upgrade
|
||||
fi
|
||||
|
||||
@@ -31,6 +31,8 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "x /tmp/nexterm-sea-*" >/etc/tmpfiles.d/nexterm.conf
|
||||
|
||||
if check_for_gh_release "nexterm-engine" "gnmyt/Nexterm"; then
|
||||
msg_info "Stopping nexterm-engine"
|
||||
systemctl stop nexterm-engine
|
||||
@@ -46,6 +48,7 @@ function update_script() {
|
||||
if check_for_gh_release "nexterm-server" "gnmyt/Nexterm"; then
|
||||
msg_info "Stopping nexterm-server"
|
||||
systemctl stop nexterm-server
|
||||
rm -rf /tmp/nexterm-sea-*
|
||||
msg_ok "Stopped nexterm-server"
|
||||
|
||||
fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-$(arch_resolve "x64" "arm64")"
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://pixelfed.org/
|
||||
|
||||
APP="Pixelfed"
|
||||
var_tags="${var_tags:-fediverse;social}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
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
|
||||
|
||||
if [[ ! -d /opt/pixelfed ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "pixelfed" "pixelfed/pixelfed"; then
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop pixelfed-horizon pixelfed-scheduler.timer
|
||||
msg_ok "Services stopped"
|
||||
|
||||
create_backup /opt/pixelfed/.env \
|
||||
/opt/pixelfed/storage
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pixelfed" "pixelfed/pixelfed" "tarball" "latest" "/opt/pixelfed"
|
||||
|
||||
restore_backup
|
||||
|
||||
msg_info "Updating Pixelfed"
|
||||
cd /opt/pixelfed
|
||||
chmod -R 755 /opt/pixelfed
|
||||
chmod -R 775 /opt/pixelfed/storage /opt/pixelfed/bootstrap/cache
|
||||
export COMPOSER_ALLOW_SUPERUSER=1
|
||||
$STD composer install --no-dev --no-ansi --no-interaction --optimize-autoloader
|
||||
chown -R pixelfed:pixelfed /opt/pixelfed
|
||||
$STD sudo -u pixelfed php artisan storage:link
|
||||
$STD sudo -u pixelfed php artisan migrate --force
|
||||
$STD sudo -u pixelfed php artisan route:cache
|
||||
$STD sudo -u pixelfed php artisan view:cache
|
||||
$STD sudo -u pixelfed php artisan config:cache
|
||||
$STD sudo -u pixelfed php artisan horizon:publish
|
||||
msg_ok "Updated Pixelfed"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start pixelfed-horizon pixelfed-scheduler.timer
|
||||
msg_ok "Services started"
|
||||
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 "${GATEWAY}${BGN}http://${IP}${CL}"
|
||||
echo -e "${INFO}${YW} Create an admin account with:${CL}"
|
||||
echo -e "${TAB}cd /opt/pixelfed && sudo -u pixelfed php artisan user:create"
|
||||
@@ -30,6 +30,15 @@ function update_script() {
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! grep -q "^Environment=HOME=" /etc/systemd/system/planka.service; then
|
||||
msg_info "Updating Service"
|
||||
sed -i -e '/^Environment=NODE_ENV=/d' -e 's|^ExecStart=.*|Environment=NODE_ENV=production\nEnvironment=HOME=/root\nExecStart=/usr/bin/node app.js --prod|' /etc/systemd/system/planka.service
|
||||
systemctl daemon-reload
|
||||
systemctl restart planka
|
||||
msg_ok "Updated Service"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "planka" "plankanban/planka"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop planka
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ function update_script() {
|
||||
$STD apt install -y aspnetcore-runtime-10.0
|
||||
fi
|
||||
|
||||
RELEASE=$(curl -fsSL https://technitium.com/dns/ | grep -oP 'Version \K[\d.]+')
|
||||
RELEASE=$(get_latest_github_release "TechnitiumSoftware/DnsServer")
|
||||
if [[ ! -f ~/.technitium || ${RELEASE} != "$(cat ~/.technitium 2>/dev/null)" ]]; then
|
||||
fetch_and_deploy_from_url "https://download.technitium.com/dns/DnsServerPortable.tar.gz" /opt/technitium/dns
|
||||
echo "${RELEASE}" >~/.technitium
|
||||
|
||||
+19
-1
@@ -31,12 +31,30 @@ function update_script() {
|
||||
fi
|
||||
|
||||
JAVA_VERSION="25" setup_java
|
||||
|
||||
if ! grep -q "install.data_dir" /etc/thingsboard/conf/thingsboard.conf; then
|
||||
msg_info "Restoring Package Defaults"
|
||||
cat <<'EOF' >>/etc/thingsboard/conf/thingsboard.conf
|
||||
|
||||
export JAVA_OPTS="$JAVA_OPTS -Dplatform=deb -Dinstall.data_dir=/usr/share/thingsboard/data"
|
||||
export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/thingsboard/gc.log:time,uptime,level,tags:filecount=10,filesize=10M"
|
||||
export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError"
|
||||
export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark"
|
||||
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10"
|
||||
export LOG_FILENAME=thingsboard.out
|
||||
export LOADER_PATH=/usr/share/thingsboard/conf,/usr/share/thingsboard/extensions
|
||||
export SQL_DATA_FOLDER=/usr/share/thingsboard/data/sql
|
||||
EOF
|
||||
systemctl restart thingsboard
|
||||
msg_ok "Restored Package Defaults"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "thingsboard" "thingsboard/thingsboard"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop thingsboard
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
fetch_and_deploy_gh_release "thingsboard" "thingsboard/thingsboard" "binary" "latest" "/tmp" "thingsboard-*.deb"
|
||||
DPKG_FORCE_CONFOLD=1 fetch_and_deploy_gh_release "thingsboard" "thingsboard/thingsboard" "binary" "latest" "/tmp" "thingsboard-*.deb"
|
||||
|
||||
msg_info "Running Database Upgrade"
|
||||
$STD /usr/share/thingsboard/bin/install/upgrade.sh
|
||||
|
||||
+14
-2
@@ -32,7 +32,14 @@ function update_script() {
|
||||
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
|
||||
if check_for_gh_release "tududi" "chrisvel/tududi"; then
|
||||
RELEASE=""
|
||||
if ! grep -qs '^DATABASE_URL=' /opt/tududi/backend/.env; then
|
||||
RELEASE="v1.15.0"
|
||||
msg_warn "Tududi 2.0 runs on PostgreSQL only, so this SQLite install stays on 1.15.0"
|
||||
msg_warn "To move to 2.0, export in Settings > Backups and import into a new Tududi LXC"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "tududi" "chrisvel/tududi" "${RELEASE}" "2.0 needs PostgreSQL"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop tududi
|
||||
msg_ok "Stopped Service"
|
||||
@@ -43,9 +50,14 @@ function update_script() {
|
||||
else
|
||||
cp /opt/tududi/.env /opt/tududi.env
|
||||
fi
|
||||
if ! grep -q '^TUDUDI_UPLOAD_PATH=' /opt/tududi.env; then
|
||||
mkdir -p /opt/tududi-uploads
|
||||
[[ -d /opt/tududi/backend/uploads ]] && cp -a /opt/tududi/backend/uploads/. /opt/tududi-uploads/
|
||||
echo "TUDUDI_UPLOAD_PATH=/opt/tududi-uploads" >>/opt/tududi.env
|
||||
fi
|
||||
msg_ok "Backed up env file"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "latest" "/opt/tududi"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "${CHECK_UPDATE_RELEASE}" "/opt/tududi"
|
||||
|
||||
msg_info "Updating Tududi"
|
||||
cd /opt/tududi
|
||||
|
||||
@@ -23,10 +23,15 @@ setup_deb_based() {
|
||||
setup_go
|
||||
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "binary"
|
||||
|
||||
msg_info "Setup xCaddy"
|
||||
$STD apt install -y git
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
if (($(awk '/^MemTotal:/ {print int($2 / 1024)}' /proc/meminfo) < 1900)); then
|
||||
msg_warn "xCaddy is installed; its test build was skipped because linking Caddy needs about 2 GB RAM"
|
||||
else
|
||||
msg_info "Setup xCaddy"
|
||||
cd /opt
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -69,10 +74,14 @@ EOF
|
||||
GO_VERSION="$(curl -fsSL https://go.dev/VERSION?m=text | head -1 | cut -c3-)" setup_go
|
||||
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "prebuild" "latest" "/opt/xcaddy" "xcaddy_*_linux_$(arch_resolve).tar.gz"
|
||||
ln -sf /opt/xcaddy/xcaddy /usr/local/bin/xcaddy
|
||||
msg_info "Setup xCaddy"
|
||||
cd /opt
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
if (($(awk '/^MemTotal:/ {print int($2 / 1024)}' /proc/meminfo) < 1900)); then
|
||||
msg_warn "xCaddy is installed; its test build was skipped because linking Caddy needs about 2 GB RAM"
|
||||
else
|
||||
msg_info "Setup xCaddy"
|
||||
cd /opt
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_info "Enabling Caddy Service"
|
||||
|
||||
@@ -14,18 +14,15 @@ network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
CODENAME=$(get_os_info codename)
|
||||
setup_deb822_repo \
|
||||
"debian-backports" \
|
||||
"file:///usr/share/keyrings/debian-archive-keyring.gpg" \
|
||||
"http://deb.debian.org/debian" \
|
||||
"${CODENAME}-backports" \
|
||||
"main"
|
||||
$STD apt install -y \
|
||||
chromium \
|
||||
libreoffice-writer \
|
||||
libreoffice-calc \
|
||||
libreoffice-impress \
|
||||
libreoffice-draw \
|
||||
libreoffice-math \
|
||||
python3-uno \
|
||||
python-is-python3 \
|
||||
pdftk-java \
|
||||
qpdf \
|
||||
libimage-exiftool-perl \
|
||||
fonts-crosextra-carlito \
|
||||
fonts-crosextra-caladea \
|
||||
fonts-liberation \
|
||||
@@ -33,28 +30,30 @@ $STD apt install -y \
|
||||
fonts-dejavu \
|
||||
fonts-noto-cjk \
|
||||
fonts-noto-color-emoji \
|
||||
fonts-noto-core
|
||||
fonts-noto-core \
|
||||
fonts-urw-base35
|
||||
# lok is built against the LibreOffice from backports
|
||||
$STD apt install -y -t "${CODENAME}-backports" \
|
||||
libreoffice-writer \
|
||||
libreoffice-calc \
|
||||
libreoffice-impress \
|
||||
libreoffice-draw \
|
||||
libreoffice-math
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
fetch_and_deploy_gh_release "pdfcpu" "pdfcpu/pdfcpu" "prebuild" "latest" "/opt/pdfcpu" "pdfcpu_*_Linux_$(arch_resolve "x86_64" "arm64").tar.xz"
|
||||
ln -sf "$(find /opt/pdfcpu -type f -name pdfcpu | head -n1)" /usr/local/bin/pdfcpu
|
||||
|
||||
msg_info "Installing unoconverter"
|
||||
UNOCONVERTER_VERSION=$(get_latest_github_release "gotenberg/unoconverter" "false")
|
||||
download_file "https://raw.githubusercontent.com/gotenberg/unoconverter/${UNOCONVERTER_VERSION}/unoconv" /usr/local/bin/unoconverter
|
||||
chmod +x /usr/local/bin/unoconverter
|
||||
msg_ok "Installed unoconverter"
|
||||
|
||||
fetch_and_deploy_gh_release "gotenberg" "gotenberg/gotenberg" "tarball" "latest" "/opt/gotenberg"
|
||||
|
||||
GO_VERSION="$(awk '$1=="go"{print $2}' /opt/gotenberg/go.mod | cut -d. -f1,2)" setup_go
|
||||
|
||||
LOK_VERSION="$(awk -F= '/^ARG LOK_VERSION=/{print $2}' /opt/gotenberg/build/Dockerfile)"
|
||||
fetch_and_deploy_gh_release "lok" "gotenberg/lok" "prebuild" "$LOK_VERSION" "/usr/local/bin" "lok_${LOK_VERSION#v}_linux_$(arch_resolve "amd64" "arm64").tar.gz"
|
||||
|
||||
msg_info "Building Gotenberg (Patience)"
|
||||
cd /opt/gotenberg
|
||||
export CGO_ENABLED=0
|
||||
$STD go mod download
|
||||
$STD go build -o /usr/local/bin/gotenberg \
|
||||
-ldflags "-s -w -X 'github.com/gotenberg/gotenberg/v8/cmd.Version=$(cat ~/.gotenberg)'" \
|
||||
-ldflags "-s -w -X 'github.com/gotenberg/gotenberg/v9/cmd.Version=$(cat ~/.gotenberg)'" \
|
||||
cmd/gotenberg/main.go
|
||||
msg_ok "Built Gotenberg"
|
||||
|
||||
@@ -70,14 +69,10 @@ Type=simple
|
||||
User=root
|
||||
Environment=LANG=C.UTF-8
|
||||
Environment=LC_ALL=C.UTF-8
|
||||
Environment=PDFTK_BIN_PATH=/usr/bin/pdftk
|
||||
Environment=QPDF_BIN_PATH=/usr/bin/qpdf
|
||||
Environment=EXIFTOOL_BIN_PATH=/usr/bin/exiftool
|
||||
Environment=PDFCPU_BIN_PATH=/usr/local/bin/pdfcpu
|
||||
Environment=CHROMIUM_BIN_PATH=/usr/bin/chromium
|
||||
Environment=CHROMIUM_HYPHEN_DATA_DIR_PATH=/opt/gotenberg/build/chromium-hyphen-data
|
||||
Environment=LIBREOFFICE_BIN_PATH=/usr/lib/libreoffice/program/soffice.bin
|
||||
Environment=UNOCONVERTER_BIN_PATH=/usr/local/bin/unoconverter
|
||||
Environment=LOK_BIN_PATH=/usr/local/bin/lok
|
||||
Environment=OTEL_TRACES_EXPORTER=none
|
||||
Environment=OTEL_METRICS_EXPORTER=none
|
||||
Environment=OTEL_LOGS_EXPORTER=none
|
||||
|
||||
@@ -23,7 +23,7 @@ if [[ "$(arch_resolve)" == "amd64" ]] && ! grep -qm1 sse4_2 /proc/cpuinfo; then
|
||||
exit 236
|
||||
fi
|
||||
|
||||
RELEASE="v3.3.5"
|
||||
RELEASE="v3.3.6"
|
||||
if lscpu | grep -q 'GenuineIntel'; then
|
||||
echo ""
|
||||
echo ""
|
||||
@@ -146,10 +146,10 @@ mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
||||
|
||||
msg_info "Installing GeoNames data"
|
||||
cd "$GEO_DIR"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin1CodesASCII.txt" "admin1CodesASCII.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin2Codes.txt" "admin2Codes.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/cities500.zip" "cities500.zip"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/admin1CodesASCII.txt" "admin1CodesASCII.txt"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/admin2Codes.txt" "admin2Codes.txt"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/cities500.zip" "cities500.zip"
|
||||
curl_with_retry "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/v5.1.2/geojson/ne_10m_admin_0_countries.geojson" "ne_10m_admin_0_countries.geojson"
|
||||
unzip -q cities500.zip
|
||||
date --iso-8601=seconds | tr -d "\n" >geodata-date.txt
|
||||
@@ -463,7 +463,7 @@ if [[ -f ~/.openvino ]]; then
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Installing Intel OpenVINO machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
@@ -481,7 +481,7 @@ else
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Installing machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
|
||||
@@ -26,7 +26,7 @@ NODE_VERSION="24" NODE_MODULE="corepack,pnpm" setup_nodejs
|
||||
|
||||
msg_info "Installing Deno"
|
||||
export DENO_INSTALL="/usr/local"
|
||||
curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
|
||||
curl -fsSL https://deno.land/install.sh | CI=1 $STD sh -s
|
||||
[[ ":$PATH:" != *":/usr/local/bin:"* ]] &&
|
||||
echo -e "\nexport PATH=\"/usr/local/bin:\$PATH\"" >>~/.bashrc &&
|
||||
source ~/.bashrc
|
||||
|
||||
@@ -33,6 +33,7 @@ LOCAL_ENGINE_TOKEN=${LOCAL_ENGINE_TOKEN}
|
||||
ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||
EOF
|
||||
chmod 0640 /etc/nexterm-engine/config.yaml /etc/nexterm-server/server.env
|
||||
echo "x /tmp/nexterm-sea-*" >/etc/tmpfiles.d/nexterm.conf
|
||||
msg_ok "Configured Nexterm"
|
||||
|
||||
msg_info "Creating Services"
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://pixelfed.org/
|
||||
|
||||
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 \
|
||||
nginx \
|
||||
redis-server \
|
||||
ffmpeg \
|
||||
jpegoptim \
|
||||
optipng \
|
||||
pngquant \
|
||||
gifsicle \
|
||||
libvips42
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Creating Pixelfed User"
|
||||
useradd -rU -s /bin/bash pixelfed
|
||||
usermod -aG redis pixelfed
|
||||
msg_ok "Created Pixelfed User"
|
||||
|
||||
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="pixelfed" PG_DB_USER="pixelfed" setup_postgresql_db
|
||||
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,ctype,curl,exif,gd,imagick,intl,mbstring,pgsql,redis,xml,zip" PHP_UPLOAD_MAX_FILESIZE="500M" PHP_POST_MAX_SIZE="500M" PHP_MAX_EXECUTION_TIME="600" setup_php
|
||||
setup_composer
|
||||
|
||||
msg_info "Configuring Redis"
|
||||
REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
sed -i "s/^# requirepass foobared/requirepass $REDIS_PASS/" /etc/redis/redis.conf
|
||||
sed -i "s/^requirepass .*/requirepass $REDIS_PASS/" /etc/redis/redis.conf
|
||||
systemctl restart redis-server
|
||||
msg_ok "Configured Redis"
|
||||
|
||||
msg_info "Configuring PHP-FPM Pool"
|
||||
cp /etc/php/8.4/fpm/pool.d/www.conf /etc/php/8.4/fpm/pool.d/pixelfed.conf
|
||||
sed -i 's/\[www\]/[pixelfed]/' /etc/php/8.4/fpm/pool.d/pixelfed.conf
|
||||
sed -i 's/^user = www-data/user = pixelfed/' /etc/php/8.4/fpm/pool.d/pixelfed.conf
|
||||
sed -i 's/^group = www-data/group = pixelfed/' /etc/php/8.4/fpm/pool.d/pixelfed.conf
|
||||
sed -i 's|^listen = .*|listen = /run/php/php8.4-fpm-pixelfed.sock|' /etc/php/8.4/fpm/pool.d/pixelfed.conf
|
||||
sed -i 's/^listen.owner = .*/listen.owner = www-data/' /etc/php/8.4/fpm/pool.d/pixelfed.conf
|
||||
sed -i 's/^listen.group = .*/listen.group = www-data/' /etc/php/8.4/fpm/pool.d/pixelfed.conf
|
||||
systemctl restart php8.4-fpm
|
||||
msg_ok "Configured PHP-FPM Pool"
|
||||
|
||||
fetch_and_deploy_gh_release "pixelfed" "pixelfed/pixelfed" "tarball" "latest" "/opt/pixelfed"
|
||||
|
||||
msg_info "Installing Pixelfed (Patience)"
|
||||
cd /opt/pixelfed
|
||||
cat <<EOF >/opt/pixelfed/.env
|
||||
APP_NAME="Pixelfed"
|
||||
APP_ENV="production"
|
||||
APP_KEY=
|
||||
APP_DEBUG="false"
|
||||
APP_URL=http://${LOCAL_IP}
|
||||
APP_DOMAIN=${LOCAL_IP}
|
||||
ADMIN_DOMAIN=${LOCAL_IP}
|
||||
SESSION_DOMAIN=${LOCAL_IP}
|
||||
TRUST_PROXIES="*"
|
||||
FORCE_HTTPS_URLS="false"
|
||||
|
||||
OPEN_REGISTRATION="false"
|
||||
ENFORCE_EMAIL_VERIFICATION="false"
|
||||
PF_MAX_USERS="1000"
|
||||
OAUTH_ENABLED="true"
|
||||
ENABLE_CONFIG_CACHE="true"
|
||||
INSTANCE_DISCOVER_PUBLIC="true"
|
||||
|
||||
PF_OPTIMIZE_IMAGES="true"
|
||||
IMAGE_QUALITY="80"
|
||||
MAX_PHOTO_SIZE="15000"
|
||||
MAX_CAPTION_LENGTH="500"
|
||||
MAX_ALBUM_LENGTH="4"
|
||||
|
||||
DB_CONNECTION="pgsql"
|
||||
DB_HOST="127.0.0.1"
|
||||
DB_PORT="5432"
|
||||
DB_DATABASE="${PG_DB_NAME}"
|
||||
DB_USERNAME="${PG_DB_USER}"
|
||||
DB_PASSWORD="${PG_DB_PASS}"
|
||||
|
||||
REDIS_CLIENT="predis"
|
||||
REDIS_SCHEME="tcp"
|
||||
REDIS_HOST="127.0.0.1"
|
||||
REDIS_PASSWORD="${REDIS_PASS}"
|
||||
REDIS_PORT="6379"
|
||||
|
||||
SESSION_DRIVER="database"
|
||||
CACHE_DRIVER="redis"
|
||||
QUEUE_DRIVER="redis"
|
||||
BROADCAST_DRIVER="log"
|
||||
LOG_CHANNEL="stack"
|
||||
HORIZON_PREFIX="horizon-"
|
||||
|
||||
ACTIVITY_PUB="true"
|
||||
AP_REMOTE_FOLLOW="true"
|
||||
AP_INBOX="true"
|
||||
AP_OUTBOX="true"
|
||||
AP_SHAREDINBOX="true"
|
||||
|
||||
EXP_EMC="true"
|
||||
|
||||
MAIL_DRIVER="log"
|
||||
MAIL_HOST="smtp.mailtrap.io"
|
||||
MAIL_PORT="2525"
|
||||
MAIL_USERNAME="null"
|
||||
MAIL_PASSWORD="null"
|
||||
MAIL_ENCRYPTION="null"
|
||||
MAIL_FROM_ADDRESS="pixelfed@example.com"
|
||||
MAIL_FROM_NAME="Pixelfed"
|
||||
|
||||
PF_ENABLE_CLOUD="false"
|
||||
FILESYSTEM_CLOUD="s3"
|
||||
SESSION_SECURE_COOKIE="false"
|
||||
HTTPS="false"
|
||||
EOF
|
||||
chmod -R 755 /opt/pixelfed
|
||||
chmod -R 775 /opt/pixelfed/storage /opt/pixelfed/bootstrap/cache
|
||||
export COMPOSER_ALLOW_SUPERUSER=1
|
||||
$STD composer install --no-dev --no-ansi --no-interaction --optimize-autoloader
|
||||
$STD php artisan key:generate --force
|
||||
$STD php artisan storage:link
|
||||
$STD php artisan migrate --force
|
||||
$STD php artisan import:cities
|
||||
$STD php artisan passport:keys
|
||||
$STD php artisan route:cache
|
||||
$STD php artisan view:cache
|
||||
$STD php artisan config:cache
|
||||
$STD php artisan instance:actor
|
||||
$STD php artisan horizon:install
|
||||
chown -R pixelfed:pixelfed /opt/pixelfed
|
||||
msg_ok "Installed Pixelfed"
|
||||
|
||||
msg_info "Configuring Nginx"
|
||||
cat <<'EOF' >/etc/nginx/sites-available/pixelfed
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /opt/pixelfed/public;
|
||||
index index.php;
|
||||
|
||||
charset utf-8;
|
||||
client_max_body_size 100M;
|
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/run/php/php8.4-fpm-pixelfed.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
}
|
||||
|
||||
location ~ /\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
ln -sf /etc/nginx/sites-available/pixelfed /etc/nginx/sites-enabled/pixelfed
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
$STD nginx -t
|
||||
systemctl reload nginx
|
||||
msg_ok "Configured Nginx"
|
||||
|
||||
msg_info "Creating Services"
|
||||
cat <<'EOF' >/etc/systemd/system/pixelfed-horizon.service
|
||||
[Unit]
|
||||
Description=Pixelfed Horizon Queue Worker
|
||||
After=network.target redis-server.service postgresql.service
|
||||
Requires=redis-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=pixelfed
|
||||
WorkingDirectory=/opt/pixelfed
|
||||
ExecStart=/usr/bin/php /opt/pixelfed/artisan horizon
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat <<'EOF' >/etc/systemd/system/pixelfed-scheduler.service
|
||||
[Unit]
|
||||
Description=Pixelfed Task Scheduler
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=pixelfed
|
||||
WorkingDirectory=/opt/pixelfed
|
||||
ExecStart=/usr/bin/php /opt/pixelfed/artisan schedule:run
|
||||
EOF
|
||||
|
||||
cat <<'EOF' >/etc/systemd/system/pixelfed-scheduler.timer
|
||||
[Unit]
|
||||
Description=Run Pixelfed Scheduler every minute
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* *:*:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
EOF
|
||||
systemctl enable -q --now pixelfed-horizon pixelfed-scheduler.timer
|
||||
msg_ok "Created Services"
|
||||
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -70,7 +70,9 @@ After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/planka
|
||||
ExecStart=/usr/bin/npm start --prod
|
||||
Environment=NODE_ENV=production
|
||||
Environment=HOME=/root
|
||||
ExecStart=/usr/bin/node app.js --prod
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
|
||||
@@ -48,6 +48,10 @@ msg_ok "Installed Podman"
|
||||
|
||||
mkdir -p /etc/containers/systemd
|
||||
|
||||
if [[ ! -x /usr/libexec/podman/quadlet ]]; then
|
||||
msg_warn "Portainer runs as a Quadlet unit, which needs Podman 4.4 or newer (Debian 13); skipping it"
|
||||
var_podman_portainer="n" var_podman_portainer_agent="n"
|
||||
fi
|
||||
prompt="${var_podman_portainer:-}"
|
||||
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt || true
|
||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
|
||||
|
||||
@@ -16,9 +16,9 @@ update_os
|
||||
msg_info "Installing Proxmox Mail Gateway"
|
||||
setup_deb822_repo \
|
||||
"pmg" \
|
||||
"https://enterprise.proxmox.com/debian/proxmox-release-trixie.gpg" \
|
||||
"https://enterprise.proxmox.com/debian/proxmox-release-$(get_os_info codename).gpg" \
|
||||
"http://download.proxmox.com/debian/pmg" \
|
||||
"trixie" \
|
||||
"$(get_os_info codename)" \
|
||||
"pmg-no-subscription"
|
||||
$STD apt install -y proxmox-mailgateway-container
|
||||
msg_ok "Installed Proxmox Mail Gateway"
|
||||
|
||||
@@ -23,7 +23,7 @@ setup_deb822_repo \
|
||||
$STD apt install -y aspnetcore-runtime-10.0
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
RELEASE=$(curl -fsSL https://technitium.com/dns/ | grep -oP 'Version \K[\d.]+')
|
||||
RELEASE=$(get_latest_github_release "TechnitiumSoftware/DnsServer")
|
||||
fetch_and_deploy_from_url "https://download.technitium.com/dns/DnsServerPortable.tar.gz" /opt/technitium/dns
|
||||
echo "${RELEASE}" >~/.technitium
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ PG_DB_NAME="thingsboard_db" PG_DB_USER="thingsboard" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "thingsboard" "thingsboard/thingsboard" "binary" "latest" "/tmp" "thingsboard-*.deb"
|
||||
|
||||
msg_info "Configuring ThingsBoard"
|
||||
cat <<EOF >/etc/thingsboard/conf/thingsboard.conf
|
||||
cat <<EOF >>/etc/thingsboard/conf/thingsboard.conf
|
||||
|
||||
# DB Configuration
|
||||
export DATABASE_TS_TYPE=sql
|
||||
export SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/${PG_DB_NAME}
|
||||
|
||||
@@ -13,13 +13,9 @@ setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
sqlite3 \
|
||||
yq
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="tududi" PG_DB_USER="tududi" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "latest" "/opt/tududi"
|
||||
|
||||
msg_info "Configuring Tududi"
|
||||
@@ -30,30 +26,22 @@ $STD npm run frontend:build
|
||||
mv ./dist ./backend
|
||||
msg_ok "Configured Tududi"
|
||||
|
||||
msg_info "Creating env and database"
|
||||
DB_LOCATION="/opt/tududi-db"
|
||||
UPLOAD_DIR="/opt/tududi-uploads"
|
||||
mkdir -p {"$DB_LOCATION","$UPLOAD_DIR"}
|
||||
msg_info "Creating env"
|
||||
mkdir -p /opt/tududi-uploads
|
||||
SECRET="$(openssl rand -hex 64)"
|
||||
sed -e '/^NODE_ENV=/s/=.*$/=production/' \
|
||||
-e 's/^TUDUDI_USER/# TUDUDI_USER/g' \
|
||||
-e "/_SECRET=/s/=.*$/=${SECRET}/" \
|
||||
-e '/^# DB_FILE=/s/^# //' \
|
||||
-e "s|^DB_FILE=.*|DB_FILE=${DB_LOCATION}/production.sqlite3|" \
|
||||
-e "/^# TUDUDI_ALLOWED/s/^# //; \
|
||||
\|_ORIGINS=|s|=.*$|=<your tududi IP or FDQN>|" \
|
||||
-e "/^# TUDUDI_UPLOAD/s/^# //; \
|
||||
\|UPLOAD_PATH=|s|=.*$|=${UPLOAD_DIR}|" \
|
||||
-e "s/^TUDUDI_SESSION_SECRET=.*/TUDUDI_SESSION_SECRET=${SECRET}/" \
|
||||
-e "s|^DATABASE_URL=.*|DATABASE_URL=postgres://tududi:${PG_DB_PASS}@localhost:5432/tududi|" \
|
||||
/opt/tududi/backend/.env.example >/opt/tududi/backend/.env
|
||||
export DB_FILE="${DB_LOCATION}/production.sqlite3"
|
||||
$STD npm run db:init
|
||||
msg_ok "Created env and database"
|
||||
echo "TUDUDI_UPLOAD_PATH=/opt/tududi-uploads" >>/opt/tududi/backend/.env
|
||||
msg_ok "Created env"
|
||||
|
||||
msg_info "Creating service"
|
||||
cat <<EOF >/etc/systemd/system/tududi.service
|
||||
[Unit]
|
||||
Description=Tududi Service
|
||||
After=network.target
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
@@ -31,7 +31,7 @@ ln -sf /opt/bun/bin/bunx /usr/local/bin/bunx
|
||||
msg_ok "Installed Bun"
|
||||
|
||||
msg_info "Installing Deno"
|
||||
$STD sh -c "curl -fsSL https://deno.land/install.sh | DENO_INSTALL=/usr/local sh -s -- -y"
|
||||
curl -fsSL https://deno.land/install.sh | CI=1 $STD sh -s
|
||||
msg_ok "Installed Deno"
|
||||
|
||||
msg_info "Creating directories"
|
||||
|
||||
+17
-13
@@ -58,8 +58,21 @@ function uninstall() {
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
# Arcane 3 needs the ARCANE_* names, the current latest image reads only the old ones.
|
||||
function sync_env_names() {
|
||||
local key
|
||||
for key in ENCRYPTION_KEY PROJECTS_DIRECTORY; do
|
||||
grep -q "^[[:space:]]*- ARCANE_${key}=" "$COMPOSE_FILE" || sed -i "/^[[:space:]]*- ${key}=/{p;s/- ${key}=/- ARCANE_${key}=/;}" "$COMPOSE_FILE"
|
||||
grep -q "^[[:space:]]*- ${key}=" "$COMPOSE_FILE" || sed -i "/^[[:space:]]*- ARCANE_${key}=/{p;s/- ARCANE_${key}=/- ${key}=/;}" "$COMPOSE_FILE"
|
||||
done
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
sed -i 's/^ARCANE_#/#ARCANE_/' "$ENV_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
function update() {
|
||||
chown -R 65532:65532 /etc/arcane/projects /etc/arcane/builds 2>/dev/null || true
|
||||
sync_env_names
|
||||
|
||||
msg_info "Pulling latest ${APP} image"
|
||||
cd "$INSTALL_PATH"
|
||||
@@ -85,9 +98,8 @@ function install() {
|
||||
msg_ok "Created ${INSTALL_PATH}"
|
||||
|
||||
# Generate secrets and config values
|
||||
local ENCRYPTION_KEY JWT_SECRET PROJ_DIR BUILDS_DIR
|
||||
local ENCRYPTION_KEY PROJ_DIR BUILDS_DIR
|
||||
ENCRYPTION_KEY=$(random_password 32)
|
||||
JWT_SECRET=$(random_password 32)
|
||||
PROJ_DIR="/etc/arcane/projects"
|
||||
BUILDS_DIR="/etc/arcane/builds"
|
||||
|
||||
@@ -108,20 +120,12 @@ function install() {
|
||||
curl -fsSL "https://raw.githubusercontent.com/getarcaneapp/arcane/refs/heads/main/docker/examples/compose.basic.yaml" -o "$COMPOSE_FILE"
|
||||
msg_ok "Downloaded Docker Compose file"
|
||||
|
||||
msg_info "Downloading .env file"
|
||||
curl -fsSL "https://raw.githubusercontent.com/getarcaneapp/arcane/refs/heads/main/.env.example" -o "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
msg_ok "Downloaded .env file"
|
||||
|
||||
msg_info "Configuring compose and env files"
|
||||
msg_info "Configuring compose file"
|
||||
sed -i '/^[[:space:]]*#/!s|/host/path/to/projects|'"$PROJ_DIR"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|/host/path/to/builds|'"$BUILDS_DIR"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|ENCRYPTION_KEY=.*|ENCRYPTION_KEY='"$ENCRYPTION_KEY"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|JWT_SECRET=.*|JWT_SECRET='"$JWT_SECRET"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|APP_URL=.*|APP_URL=http://localhost:'"$DEFAULT_PORT"'|g' "$ENV_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|ENCRYPTION_KEY=.*|#&|g' "$ENV_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|JWT_SECRET=.*|#&|g' "$ENV_FILE"
|
||||
msg_ok "Configured compose and env files"
|
||||
sync_env_names
|
||||
msg_ok "Configured compose file"
|
||||
|
||||
msg_info "Starting ${APP}"
|
||||
cd "$INSTALL_PATH"
|
||||
|
||||
+13
-1
@@ -4,7 +4,7 @@
|
||||
# License: MIT
|
||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/DevScripts/main}"
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main}"
|
||||
source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/pve/vm-core.func")
|
||||
load_functions
|
||||
|
||||
@@ -341,6 +341,18 @@ if [[ "$VM_STATE" != *stopped* ]]; then
|
||||
fi
|
||||
msg_ok "OpenWrt has shut down"
|
||||
|
||||
# pve-bridge tags a NIC on a port of the bridge; a bridge without one only takes tags when VLAN-aware
|
||||
if [[ -n "$LAN_VLAN" && -d "/sys/class/net/${LAN_BRG}/bridge" && "$(cat "/sys/class/net/${LAN_BRG}/bridge/vlan_filtering" 2>/dev/null)" != "1" ]] &&
|
||||
! ls "/sys/class/net/${LAN_BRG}/brif" 2>/dev/null | grep -qE '^((eth|bond)[0-9]+|en[^.]+)(\.[0-9]+)?$'; then
|
||||
msg_warn "LAN bridge ${LAN_BRG} has no physical port and is not VLAN-aware; the LAN NIC stays untagged"
|
||||
LAN_VLAN=""
|
||||
fi
|
||||
if [[ -n "$VLAN" && -d "/sys/class/net/${BRG}/bridge" && "$(cat "/sys/class/net/${BRG}/bridge/vlan_filtering" 2>/dev/null)" != "1" ]] &&
|
||||
! ls "/sys/class/net/${BRG}/brif" 2>/dev/null | grep -qE '^((eth|bond)[0-9]+|en[^.]+)(\.[0-9]+)?$'; then
|
||||
msg_warn "WAN bridge ${BRG} has no physical port and is not VLAN-aware; the WAN NIC stays untagged"
|
||||
VLAN=""
|
||||
fi
|
||||
|
||||
msg_info "Adding bridge interfaces on Proxmox side"
|
||||
qm set $VMID \
|
||||
-net0 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}${MTU} \
|
||||
|
||||
+27
-16
@@ -47,7 +47,7 @@ function check_disk_space() {
|
||||
}
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
if ! check_disk_space "$TEMP_DIR" 20 && [ -d "/var/tmp" ] && check_disk_space "/var/tmp" 20; then
|
||||
if ! check_disk_space "$TEMP_DIR" 4 && [ -d "/var/tmp" ] && check_disk_space "/var/tmp" 4; then
|
||||
rm -rf "$TEMP_DIR"
|
||||
TEMP_DIR=$(mktemp -d /var/tmp/opnsense-vm.XXXXXX)
|
||||
fi
|
||||
@@ -364,15 +364,6 @@ FREEBSD_VER="$VM_INDEX_LATEST"
|
||||
URL="$VM_INDEX_URL"
|
||||
msg_ok "Download URL: ${CL}${BL}${URL}${CL}"
|
||||
|
||||
# Check available disk space (require at least 20GB for safety)
|
||||
if ! check_disk_space "$TEMP_DIR" 20; then
|
||||
AVAILABLE_GB=$(df -h "$TEMP_DIR" | awk 'NR==2 {print $4}')
|
||||
msg_error "Insufficient disk space in temporary directory ($TEMP_DIR)."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~20GB for FreeBSD image decompression."
|
||||
msg_error "Please free up space or ensure /tmp has sufficient storage."
|
||||
exit 214
|
||||
fi
|
||||
|
||||
msg_info "Downloading FreeBSD Image"
|
||||
# A mirror serving an error page returns 200, so size decides whether this
|
||||
# is an image. Anything real here is far above 5 MB.
|
||||
@@ -381,11 +372,12 @@ vm_fetch_image "$URL" "$CACHE_FILE" --cache --verify-xz --min-bytes $((5 * 1024
|
||||
echo -en "\e[1A\e[0K"
|
||||
msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
||||
|
||||
# Check disk space again before decompression
|
||||
if ! check_disk_space "$TEMP_DIR" 15; then
|
||||
NEED_GB=$(($(xz --robot -l "$CACHE_FILE" | awk '$1 == "totals" {print $5}') / 1024 / 1024 / 1024 + 1))
|
||||
if ! check_disk_space "$TEMP_DIR" "$NEED_GB"; then
|
||||
AVAILABLE_GB=$(df -h "$TEMP_DIR" | awk 'NR==2 {print $4}')
|
||||
msg_error "Insufficient disk space for decompression."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~15GB for decompressed image."
|
||||
msg_error "Insufficient disk space for decompression in ${TEMP_DIR}."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~${NEED_GB}GB for the decompressed image."
|
||||
msg_error "Please free up space or ensure /tmp or /var/tmp has sufficient storage."
|
||||
exit 214
|
||||
fi
|
||||
|
||||
@@ -417,7 +409,7 @@ while :; do
|
||||
alloc_delay=$((alloc_delay * 2))
|
||||
continue
|
||||
fi
|
||||
echo -e "$alloc_err" >&2
|
||||
msg_error "Could not allocate the EFI disk on ${STORAGE}: ${alloc_err}"
|
||||
exit 220
|
||||
done
|
||||
vm_import_disk "$VMID" "$FILE" "$STORAGE"
|
||||
@@ -442,7 +434,26 @@ msg_ok "Bridge interfaces have been successfully added."
|
||||
msg_ok "Created a OPNsense VM ${CL}${BL}(${HN})"
|
||||
msg_ok "Starting OPNsense VM (the bootstrap takes 10-30 minutes)"
|
||||
$STD qm start $VMID
|
||||
sleep 180
|
||||
# The FreeBSD image prints its login prompt on the serial console too. Boot takes
|
||||
# under a minute with DHCP, each NIC without a DHCP server adds a 60s timeout.
|
||||
SERIAL_LOG="${TEMP_DIR}/serial-${VMID}.log"
|
||||
timeout 900 socat -u "UNIX-CONNECT:/var/run/qemu-server/${VMID}.serial0" - >"$SERIAL_LOG" 2>/dev/null &
|
||||
SERIAL_PID=$!
|
||||
boot_wait=0
|
||||
until grep -aq 'login:' "$SERIAL_LOG" 2>/dev/null || ! kill -0 "$SERIAL_PID" 2>/dev/null; do
|
||||
sleep 5
|
||||
boot_wait=$((boot_wait + 5))
|
||||
done
|
||||
kill "$SERIAL_PID" 2>/dev/null || true
|
||||
if grep -aq 'login:' "$SERIAL_LOG" 2>/dev/null; then
|
||||
msg_ok "FreeBSD booted after ${boot_wait}s"
|
||||
elif [ $boot_wait -lt 180 ]; then
|
||||
msg_warn "Could not read the serial console, waiting 3 minutes instead"
|
||||
sleep $((180 - boot_wait))
|
||||
else
|
||||
msg_warn "No login prompt on the serial console after $((boot_wait / 60)) minutes; continuing"
|
||||
fi
|
||||
sleep 3
|
||||
send_line_to_vm "root"
|
||||
sleep 2
|
||||
send_line_to_vm ""
|
||||
|
||||
+3
-2
@@ -39,7 +39,7 @@ function truenas_iso_lookup() {
|
||||
local pre_releases=()
|
||||
|
||||
local all_paths=$(
|
||||
curl -sL "$BASE_URL" |
|
||||
curl -fsSL "${_CS_CURL_RETRY[@]}" --max-time 90 "$BASE_URL" |
|
||||
grep -oE 'href="[^"]+\.iso"' |
|
||||
sed 's/href="//; s/"$//' |
|
||||
grep -vE '(MASTER|ALPHA)' |
|
||||
@@ -47,6 +47,7 @@ function truenas_iso_lookup() {
|
||||
)
|
||||
|
||||
while read -r path; do
|
||||
[[ -n "$path" ]] || continue
|
||||
local filename=$(basename "$path")
|
||||
local version=$(echo "$filename" | sed -E 's/.*TrueNAS-SCALE-([0-9]{2}\.[0-9]{2}(\.[0-9]+)*(-RC[0-9]|-BETA[0-9])?)\.iso.*/\1/')
|
||||
if [[ "$version" =~ (RC|BETA) ]]; then
|
||||
@@ -139,7 +140,7 @@ post_to_api_vm
|
||||
vm_select_storage "$HN"
|
||||
|
||||
if [ -z "${SELECTED_ISO:-}" ]; then
|
||||
SELECTED_ISO=$(truenas_iso_lookup | grep -vE 'RC|BETA' | sort -V | tail -n 1)
|
||||
SELECTED_ISO=$(truenas_iso_lookup | grep -vE 'RC|BETA' | sort -V | tail -n 1) || true
|
||||
|
||||
if [ -z "$SELECTED_ISO" ]; then
|
||||
msg_error "Could not find a stable ISO for fallback."
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main}"
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main}"
|
||||
source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/pve/vm-core.func")
|
||||
load_functions
|
||||
|
||||
|
||||
Reference in new issue
Block a user