mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-05 04:43:26 +01:00
Compare commits
1 Commits
add-script
...
feat/cloud
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6077c850ea |
@@ -398,8 +398,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-02-05
|
||||
|
||||
## 2026-02-04
|
||||
|
||||
### 🆕 New Scripts
|
||||
@@ -409,11 +407,8 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- Add log directory and permissions for koillection [@shineangelic](https://github.com/shineangelic) ([#11553](https://github.com/community-scripts/ProxmoxVE/pull/11553))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- [FIX] Scanopy: ensure Scanopy Daemon update [@vhsdream](https://github.com/vhsdream) ([#11541](https://github.com/community-scripts/ProxmoxVE/pull/11541))
|
||||
- Immich: pin version to 2.5.3 [@vhsdream](https://github.com/vhsdream) ([#11515](https://github.com/community-scripts/ProxmoxVE/pull/11515))
|
||||
|
||||
### 💾 Core
|
||||
@@ -434,10 +429,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
|
||||
|
||||
### ❔ Uncategorized
|
||||
|
||||
- [FIX] Immich Public Proxy docs link [@vhsdream](https://github.com/vhsdream) ([#11543](https://github.com/community-scripts/ProxmoxVE/pull/11543))
|
||||
|
||||
## 2026-02-03
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
____ ________ __
|
||||
/ __ \____ ___ ____ / ____/ /___ __ ______/ /
|
||||
/ / / / __ \/ _ \/ __ \/ / / / __ \/ / / / __ /
|
||||
/ /_/ / /_/ / __/ / / / /___/ / /_/ / /_/ / /_/ /
|
||||
\____/ .___/\___/_/ /_/\____/_/\____/\__,_/\__,_/
|
||||
/_/
|
||||
@@ -59,8 +59,6 @@ function update_script() {
|
||||
$STD yarn install
|
||||
$STD yarn build
|
||||
mkdir -p /opt/koillection/public/uploads
|
||||
mkdir -p /opt/koillection/var/log
|
||||
chown -R www-data:www-data /opt/koillection/var/log
|
||||
chown -R www-data:www-data /opt/koillection/public/uploads
|
||||
rm -r /opt/koillection-backup
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: vhsdream
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://opencloud.eu
|
||||
|
||||
APP="OpenCloud"
|
||||
var_tags="${var_tags:-files;cloud}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-20}"
|
||||
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 /etc/opencloud ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
RELEASE="v5.0.1"
|
||||
if check_for_gh_release "opencloud" "opencloud-eu/opencloud" "${RELEASE}"; then
|
||||
msg_info "Stopping services"
|
||||
systemctl stop opencloud opencloud-wopi
|
||||
msg_ok "Stopped services"
|
||||
|
||||
msg_info "Updating packages"
|
||||
$STD apt-get update
|
||||
$STD apt-get dist-upgrade -y
|
||||
msg_ok "Updated packages"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "opencloud" "opencloud-eu/opencloud" "singlefile" "${RELEASE}" "/usr/bin" "opencloud-*-linux-amd64"
|
||||
|
||||
msg_info "Starting services"
|
||||
systemctl start opencloud opencloud-wopi
|
||||
msg_ok "Started services"
|
||||
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}https://<your-OpenCloud-FQDN>${CL}"
|
||||
@@ -29,7 +29,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "Scanopy" "scanopy/scanopy"; then
|
||||
if check_for_gh_release "scanopy" "scanopy/scanopy"; then
|
||||
msg_info "Stopping services"
|
||||
systemctl stop scanopy-server
|
||||
[[ -f /etc/systemd/system/scanopy-daemon.service ]] && systemctl stop scanopy-daemon
|
||||
@@ -40,7 +40,7 @@ function update_script() {
|
||||
[[ -f /opt/scanopy/oidc.toml ]] && cp /opt/scanopy/oidc.toml /opt/scanopy.oidc.toml
|
||||
msg_ok "Backed up configurations"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||
|
||||
ensure_dependencies pkg-config libssl-dev
|
||||
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
||||
@@ -61,22 +61,19 @@ function update_script() {
|
||||
$STD npm run build
|
||||
msg_ok "Created frontend UI"
|
||||
|
||||
msg_info "Building Scanopy Server (patience)"
|
||||
msg_info "Building scanopy-server (patience)"
|
||||
cd /opt/scanopy/backend
|
||||
$STD cargo build --release --bin server
|
||||
mv ./target/release/server /usr/bin/scanopy-server
|
||||
msg_ok "Built Scanopy Server"
|
||||
msg_ok "Built scanopy-server"
|
||||
|
||||
if [[ -f /etc/systemd/system/scanopy-daemon.service ]]; then
|
||||
fetch_and_deploy_gh_release "Scanopy Daemon" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64"
|
||||
mv "/usr/local/bin/Scanopy Daemon" /usr/local/bin/scanopy-daemon
|
||||
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh
|
||||
[[ -f /etc/systemd/system/scanopy-daemon.service ]] &&
|
||||
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64" &&
|
||||
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh &&
|
||||
sed -i -e 's|usr/bin|usr/local/bin|' \
|
||||
-e 's/push/daemon_poll/' \
|
||||
-e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service
|
||||
-e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service &&
|
||||
systemctl daemon-reload
|
||||
msg_ok "Updated Scanopy Daemon"
|
||||
fi
|
||||
|
||||
msg_info "Starting services"
|
||||
systemctl start scanopy-server
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated": "2026-02-05T00:22:14Z",
|
||||
"generated": "2026-02-04T18:17:33Z",
|
||||
"versions": [
|
||||
{
|
||||
"slug": "2fauth",
|
||||
@@ -445,9 +445,9 @@
|
||||
{
|
||||
"slug": "headscale",
|
||||
"repo": "juanfont/headscale",
|
||||
"version": "v0.28.0",
|
||||
"version": "v0.27.1",
|
||||
"pinned": false,
|
||||
"date": "2026-02-04T20:40:23Z"
|
||||
"date": "2025-11-11T19:32:29Z"
|
||||
},
|
||||
{
|
||||
"slug": "healthchecks",
|
||||
@@ -536,9 +536,9 @@
|
||||
{
|
||||
"slug": "invoiceninja",
|
||||
"repo": "invoiceninja/invoiceninja",
|
||||
"version": "v5.12.54",
|
||||
"version": "v5.12.53",
|
||||
"pinned": false,
|
||||
"date": "2026-02-04T23:52:17Z"
|
||||
"date": "2026-02-04T00:52:01Z"
|
||||
},
|
||||
{
|
||||
"slug": "jackett",
|
||||
@@ -746,9 +746,9 @@
|
||||
{
|
||||
"slug": "mealie",
|
||||
"repo": "mealie-recipes/mealie",
|
||||
"version": "v3.10.2",
|
||||
"version": "v3.10.1",
|
||||
"pinned": false,
|
||||
"date": "2026-02-04T23:32:32Z"
|
||||
"date": "2026-02-03T01:04:38Z"
|
||||
},
|
||||
{
|
||||
"slug": "mediamanager",
|
||||
@@ -781,9 +781,9 @@
|
||||
{
|
||||
"slug": "metube",
|
||||
"repo": "alexta69/metube",
|
||||
"version": "2026.02.04",
|
||||
"version": "2026.02.03",
|
||||
"pinned": false,
|
||||
"date": "2026-02-04T20:01:18Z"
|
||||
"date": "2026-02-03T21:49:49Z"
|
||||
},
|
||||
{
|
||||
"slug": "miniflux",
|
||||
@@ -1096,9 +1096,9 @@
|
||||
{
|
||||
"slug": "pulse",
|
||||
"repo": "rcourtman/Pulse",
|
||||
"version": "v5.1.2",
|
||||
"version": "v5.1.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-05T00:18:57Z"
|
||||
"date": "2026-02-04T17:43:59Z"
|
||||
},
|
||||
{
|
||||
"slug": "pve-scripts-local",
|
||||
@@ -1271,9 +1271,9 @@
|
||||
{
|
||||
"slug": "speedtest-tracker",
|
||||
"repo": "alexjustesen/speedtest-tracker",
|
||||
"version": "v1.13.8",
|
||||
"version": "v1.13.7",
|
||||
"pinned": false,
|
||||
"date": "2026-02-04T19:24:23Z"
|
||||
"date": "2026-02-04T16:47:42Z"
|
||||
},
|
||||
{
|
||||
"slug": "spoolman",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 3000,
|
||||
"documentation": "https://github.com/alangrainger/immich-public-proxy/tree/main/docs",
|
||||
"documentation": "https://github.com/alangrainger/immich-public-proxy/docs",
|
||||
"website": "https://github.com/alangrainger/immich-public-proxy",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/immich-public-proxy.webp",
|
||||
"config_path": "/opt/immich-proxy/app/.env",
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"name": "OpenCloud",
|
||||
"slug": "opencloud",
|
||||
"categories": [
|
||||
11
|
||||
],
|
||||
"date_created": "2025-12-12",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 443,
|
||||
"documentation": "https://docs.opencloud.eu",
|
||||
"config_path": "/etc/opencloud/opencloud.env, /etc/opencloud/opencloud.yaml, /etc/opencloud/csp.yaml",
|
||||
"website": "https://opencloud.eu",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/opencloud.webp",
|
||||
"description": "OpenCloud is the file sharing and collaboration solution of the Heinlein Group. Through intelligent file management and a strong open source community, files become valuable resources, effectively structured and usable in the long term. With flexible data rooms and intelligent access rights, teams can access and work together on data anytime, anywhere without barriers, but with a lot of productivity.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/opencloud.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 20,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": "admin",
|
||||
"password": "randomly generated during the installation process"
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "Valid TLS certificates and fully-qualified domain names behind a reverse proxy (Caddy) for 3 services - OpenCloud, Collabora, and WOPI are **REQUIRED**",
|
||||
"type": "warning"
|
||||
},
|
||||
{
|
||||
"text": "Forgot your admin password? Check `admin_password` in the 'idm' section in `/etc/opencloud/opencloud.yaml`",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "**Optional External Apps**: extract zip archives from App Store to `/etc/opencloud/assets/apps`",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "**Optional CalDAV and CardDAV**: requires separate Radicale install. Edit and rename `/opt/opencloud/proxy.yaml.bak` and change your Radicale config to use `http_x_remote_user` as the auth method",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "**Optional OpenID**: Authelia and PocketID supported. Uncomment relevant lines in `/opt/opencloud/opencloud.env` and consult OpenCloud GitHub discussions for configuration tips",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "**Optional Full-text Search with Apache Tika**: requires your own Tika LXC. See `https://community-scripts.github.io/ProxmoxVE/scripts?id=apache-tika`",
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "**Relevant services**: `opencloud.service`, `opencloud-wopi.service`, `coolwsd.service`",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: vhsdream
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://opencloud.eu
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
MAX_ATTEMPTS=3
|
||||
servers=("opencloud" "collabora" "wopi")
|
||||
attempt=0
|
||||
for server in "${servers[@]}"; do
|
||||
until ((attempt >= MAX_ATTEMPTS)); do
|
||||
attempt=$((attempt + 1))
|
||||
read -rp "${TAB3}Enter the FQDN of your ${server^} server (ATTEMPT $attempt/$MAX_ATTEMPTS) (eg $server.domain.tld): " fqdn
|
||||
if [[ -z "$fqdn" ]]; then
|
||||
msg_warn "Domain cannot be empty!"
|
||||
elif [[ "$fqdn" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
msg_warn "IP address not allowed! Please use a FQDN"
|
||||
elif [[ "$fqdn" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$ ]]; then
|
||||
export ${server^^}_FQDN="$fqdn"
|
||||
attempt=0
|
||||
break
|
||||
else
|
||||
msg_warn "Invalid domain format!"
|
||||
fi
|
||||
done
|
||||
if ((attempt >= MAX_ATTEMPTS)); then
|
||||
msg_error "No more attempts - aborting script!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
msg_info "Installing Collabora Online"
|
||||
curl -fsSL https://collaboraoffice.com/downloads/gpg/collaboraonline-release-keyring.gpg -o /etc/apt/keyrings/collaboraonline-release-keyring.gpg
|
||||
cat <<EOF >/etc/apt/sources.list.d/colloboraonline.sources
|
||||
Types: deb
|
||||
URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-deb
|
||||
Suites: ./
|
||||
Signed-By: /etc/apt/keyrings/collaboraonline-release-keyring.gpg
|
||||
EOF
|
||||
$STD apt-get update
|
||||
$STD apt-get install -y coolwsd code-brand
|
||||
systemctl stop coolwsd
|
||||
mkdir -p /etc/systemd/system/coolwsd.service.d
|
||||
cat <<EOF >/etc/systemd/system/coolwsd.service.d/override.conf
|
||||
[Unit]
|
||||
Before=opencloud-wopi.service
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
COOLPASS="$(openssl rand -base64 36)"
|
||||
$STD sudo -u cool coolconfig set-admin-password --user=admin --password="$COOLPASS"
|
||||
echo "$COOLPASS" >~/.coolpass
|
||||
msg_ok "Installed Collabora Online"
|
||||
|
||||
fetch_and_deploy_gh_release "opencloud" "opencloud-eu/opencloud" "singlefile" "v5.0.1" "/usr/bin" "opencloud-*-linux-amd64"
|
||||
|
||||
msg_info "Configuring OpenCloud"
|
||||
DATA_DIR="/var/lib/opencloud/"
|
||||
CONFIG_DIR="/etc/opencloud"
|
||||
ENV_FILE="${CONFIG_DIR}/opencloud.env"
|
||||
mkdir -p "$DATA_DIR" "$CONFIG_DIR"/assets/apps
|
||||
|
||||
curl -fsSL https://raw.githubusercontent.com/opencloud-eu/opencloud-compose/refs/heads/main/config/opencloud/csp.yaml -o "$CONFIG_DIR"/csp.yaml
|
||||
curl -fsSL https://raw.githubusercontent.com/opencloud-eu/opencloud-compose/refs/heads/main/config/opencloud/proxy.yaml -o "$CONFIG_DIR"/proxy.yaml.bak
|
||||
|
||||
cat <<EOF >"$ENV_FILE"
|
||||
OC_URL=https://${OPENCLOUD_FQDN}
|
||||
OC_INSECURE=false
|
||||
IDM_CREATE_DEMO_USERS=false
|
||||
OC_LOG_LEVEL=warning
|
||||
OC_CONFIG_DIR=${CONFIG_DIR}
|
||||
OC_BASE_DATA_PATH=${DATA_DIR}
|
||||
STORAGE_SYSTEM_OC_ROOT=${DATA_DIR}/storage/metadata
|
||||
|
||||
## Web
|
||||
WEB_ASSET_CORE_PATH=${CONFIG_DIR}/web/assets
|
||||
WEB_ASSET_APPS_PATH=${CONFIG_DIR}/web/assets/apps
|
||||
WEB_UI_CONFIG_FILE=${CONFIG_DIR}/web/config.json
|
||||
# WEB_ASSET_THEMES_PATH=${CONFIG_DIR}/web/assets/themes
|
||||
# WEB_UI_THEME_PATH=
|
||||
|
||||
## Frontend
|
||||
FRONTEND_DISABLE_RADICALE=true
|
||||
FRONTEND_GROUPWARE_ENABLED=false
|
||||
GRAPH_INCLUDE_OCM_SHAREES=true
|
||||
|
||||
## Proxy
|
||||
PROXY_TLS=false
|
||||
PROXY_CSP_CONFIG_FILE_LOCATION=${CONFIG_DIR}/csp.yaml
|
||||
|
||||
## Collaboration - requires VALID TLS
|
||||
COLLABORA_DOMAIN=${COLLABORA_FQDN}
|
||||
COLLABORATION_APP_NAME="CollaboraOnline"
|
||||
COLLABORATION_APP_PRODUCT="Collabora"
|
||||
COLLABORATION_APP_ADDR=https://${COLLABORA_FQDN}
|
||||
COLLABORATION_APP_INSECURE=false
|
||||
COLLABORATION_HTTP_ADDR=0.0.0.0:9300
|
||||
COLLABORATION_WOPI_SRC=https://${WOPI_FQDN}
|
||||
COLLABORATION_JWT_SECRET=
|
||||
|
||||
## Notifications - Email settings
|
||||
# NOTIFICATIONS_SMTP_HOST=
|
||||
# NOTIFICATIONS_SMTP_PORT=
|
||||
# NOTIFICATIONS_SMTP_SENDER=
|
||||
# NOTIFICATIONS_SMTP_USERNAME=
|
||||
# NOTIFICATIONS_SMTP_PASSWORD=
|
||||
# NOTIFICATIONS_SMTP_AUTHENTICATION=login
|
||||
## Encryption method. Possible values are 'starttls', 'ssltls' and 'none'
|
||||
# NOTIFICATIONS_SMTP_ENCRYPTION=starttls
|
||||
## Allow insecure connections. Defaults to false.
|
||||
# NOTIFICATIONS_SMTP_INSECURE=false
|
||||
|
||||
## Start additional services at runtime
|
||||
## Examples: notifications, antivirus etc.
|
||||
## Do not uncomment unless configured above.
|
||||
# OC_ADD_RUN_SERVICES="notifications"
|
||||
|
||||
## OpenID - via web browser
|
||||
## uncomment for OpenID in general
|
||||
# OC_EXCLUDE_RUN_SERVICES=idp
|
||||
# OC_OIDC_ISSUER=<your auth URL>
|
||||
# IDP_DOMAIN=<your auth URL>
|
||||
# PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD=none
|
||||
# PROXY_OIDC_REWRITE_WELLKNOWN=true
|
||||
# PROXY_USER_OIDC_CLAIM=preferred_username
|
||||
# PROXY_USER_CS3_CLAIM=username
|
||||
## automatically create accounts
|
||||
# PROXY_AUTOPROVISION_ACCOUNTS=true
|
||||
# WEB_OIDC_SCOPE=openid profile email groups
|
||||
# GRAPH_ASSIGN_DEFAULT_USER_ROLE=false
|
||||
#
|
||||
## uncomment below if using PocketID
|
||||
# WEB_OIDC_CLIENT_ID=<generated in PocketID>
|
||||
# WEB_OIDC_METADATA_URL=<your auth URL>/.well-known/openid-configuration
|
||||
|
||||
## Full Text Search - Apache Tika
|
||||
## Requires a separate install of Tika - see https://community-scripts.github.io/ProxmoxVE/scripts?id=apache-tika
|
||||
# SEARCH_EXTRACTOR_TYPE=tika
|
||||
# FRONTEND_FULL_TEXT_SEARCH_ENABLED=true
|
||||
# SEARCH_EXTRACTOR_TIKA_TIKA_URL=<your-tika-url>
|
||||
|
||||
## External storage test - Only NFS v4.2+ is supported
|
||||
## User files
|
||||
# STORAGE_USERS_POSIX_ROOT=<path-to-your-bind_mount>
|
||||
EOF
|
||||
|
||||
cat <<EOF >/etc/systemd/system/opencloud.service
|
||||
[Unit]
|
||||
Description=OpenCloud server
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=opencloud
|
||||
Group=opencloud
|
||||
EnvironmentFile=${ENV_FILE}
|
||||
ExecStart=/usr/bin/opencloud server
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat <<EOF >/etc/systemd/system/opencloud-wopi.service
|
||||
[Unit]
|
||||
Description=OpenCloud WOPI Server
|
||||
Wants=coolwsd.service
|
||||
After=opencloud.service coolwsd.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=opencloud
|
||||
Group=opencloud
|
||||
EnvironmentFile=${ENV_FILE}
|
||||
ExecStartPre=/bin/sleep 10
|
||||
ExecStart=/usr/bin/opencloud collaboration server
|
||||
Restart=always
|
||||
KillSignal=SIGKILL
|
||||
KillMode=mixed
|
||||
TimeoutStopSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
$STD sudo -u cool coolconfig set ssl.enable false
|
||||
$STD sudo -u cool coolconfig set ssl.termination true
|
||||
$STD sudo -u cool coolconfig set ssl.ssl_verification true
|
||||
sed -i "s|CSP2\"/>|CSP2\">frame-ancestors https://${OPENCLOUD_FQDN}</content_security_policy>|" /etc/coolwsd/coolwsd.xml
|
||||
useradd -r -M -s /usr/sbin/nologin opencloud
|
||||
chown -R opencloud:opencloud "$CONFIG_DIR" "$DATA_DIR"
|
||||
sudo -u opencloud opencloud init --config-path "$CONFIG_DIR" --insecure no
|
||||
OPENCLOUD_SECRET="$(sed -n '/jwt/p' "$CONFIG_DIR"/opencloud.yaml | awk '{print $2}')"
|
||||
sed -i "s/JWT_SECRET=/&${OPENCLOUD_SECRET//&/\\&}/" "$ENV_FILE"
|
||||
msg_ok "Configured OpenCloud"
|
||||
|
||||
msg_info "Starting services"
|
||||
systemctl enable -q --now coolwsd opencloud
|
||||
sleep 5
|
||||
systemctl enable -q --now opencloud-wopi
|
||||
msg_ok "Started services"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -23,7 +23,7 @@ msg_ok "Installed Dependencies"
|
||||
PG_VERSION=17 setup_postgresql
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
PG_DB_NAME="scanopy_db" PG_DB_USER="scanopy" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
||||
RUST_TOOLCHAIN=$TOOLCHAIN setup_rust
|
||||
|
||||
@@ -35,11 +35,11 @@ $STD npm ci --no-fund --no-audit
|
||||
$STD npm run build
|
||||
msg_ok "Created frontend UI"
|
||||
|
||||
msg_info "Building Scanopy Server (patience)"
|
||||
msg_info "Building scanopy-server (patience)"
|
||||
cd /opt/scanopy/backend
|
||||
$STD cargo build --release --bin server
|
||||
mv ./target/release/server /usr/bin/scanopy-server
|
||||
msg_ok "Built Scanopy Server"
|
||||
msg_ok "Built scanopy-server"
|
||||
|
||||
msg_info "Configuring server for first-run"
|
||||
cat <<EOF >/opt/scanopy/.env
|
||||
|
||||
@@ -28,13 +28,210 @@
|
||||
# ==============================================================================
|
||||
# These can be overridden before sourcing this library
|
||||
|
||||
# Disable 'unbound variable' errors for this library (restored at end)
|
||||
_OLD_SET_STATE=$(set +o | grep -E 'set -(e|u|o)')
|
||||
set +u
|
||||
|
||||
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
||||
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
||||
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
||||
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-/root/.ssh/authorized_keys}"
|
||||
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-}" # Empty by default - user must explicitly provide keys
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 2: HELPER FUNCTIONS
|
||||
# SECTION 2: SSH KEY DISCOVERY AND SELECTION
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# _ci_ssh_extract_keys_from_file - Extracts valid SSH public keys from a file
|
||||
# ------------------------------------------------------------------------------
|
||||
function _ci_ssh_extract_keys_from_file() {
|
||||
local file="$1"
|
||||
[[ -f "$file" && -r "$file" ]] || return 0
|
||||
grep -E '^(ssh-(rsa|ed25519|dss|ecdsa)|ecdsa-sha2-)' "$file" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# _ci_ssh_discover_files - Scans standard paths for SSH keys
|
||||
# ------------------------------------------------------------------------------
|
||||
function _ci_ssh_discover_files() {
|
||||
local -a cand=()
|
||||
shopt -s nullglob
|
||||
cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
|
||||
cand+=(/root/.ssh/*.pub)
|
||||
cand+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
|
||||
shopt -u nullglob
|
||||
printf '%s\0' "${cand[@]}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# _ci_ssh_build_choices - Builds whiptail checklist from SSH key files
|
||||
#
|
||||
# Sets: CI_SSH_CHOICES (array), CI_SSH_COUNT (int), CI_SSH_MAPFILE (path)
|
||||
# ------------------------------------------------------------------------------
|
||||
function _ci_ssh_build_choices() {
|
||||
local -a files=("$@")
|
||||
CI_SSH_CHOICES=()
|
||||
CI_SSH_COUNT=0
|
||||
CI_SSH_MAPFILE="$(mktemp)"
|
||||
local id key typ fp cmt base
|
||||
|
||||
for f in "${files[@]}"; do
|
||||
[[ -f "$f" && -r "$f" ]] || continue
|
||||
base="$(basename -- "$f")"
|
||||
# Skip known_hosts and private keys
|
||||
case "$base" in
|
||||
known_hosts | known_hosts.* | config) continue ;;
|
||||
id_*) [[ "$f" != *.pub ]] && continue ;;
|
||||
esac
|
||||
|
||||
while IFS= read -r key; do
|
||||
[[ -n "$key" ]] || continue
|
||||
|
||||
typ=""
|
||||
fp=""
|
||||
cmt=""
|
||||
read -r _typ _b64 _cmt <<<"$key"
|
||||
typ="${_typ:-key}"
|
||||
cmt="${_cmt:-}"
|
||||
|
||||
# Get fingerprint via ssh-keygen if available
|
||||
if command -v ssh-keygen >/dev/null 2>&1; then
|
||||
fp="$(printf '%s\n' "$key" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
|
||||
fi
|
||||
|
||||
# Shorten long comments
|
||||
[[ ${#cmt} -gt 40 ]] && cmt="${cmt:0:37}..."
|
||||
|
||||
CI_SSH_COUNT=$((CI_SSH_COUNT + 1))
|
||||
id="K${CI_SSH_COUNT}"
|
||||
echo "${id}|${key}" >>"$CI_SSH_MAPFILE"
|
||||
CI_SSH_CHOICES+=("$id" "[$typ] ${fp:+$fp }${cmt:+$cmt }— ${base}" "OFF")
|
||||
done < <(_ci_ssh_extract_keys_from_file "$f")
|
||||
done
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# configure_cloudinit_ssh_keys - Interactive SSH key selection for Cloud-Init
|
||||
#
|
||||
# Usage: configure_cloudinit_ssh_keys
|
||||
# Sets: CLOUDINIT_SSH_KEYS (path to temporary file with selected keys)
|
||||
# ------------------------------------------------------------------------------
|
||||
function configure_cloudinit_ssh_keys() {
|
||||
local backtitle="Proxmox VE Helper Scripts"
|
||||
local ssh_key_mode
|
||||
|
||||
# Create temp file for selected keys
|
||||
CLOUDINIT_SSH_KEYS_TEMP="$(mktemp)"
|
||||
: >"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
|
||||
# Discover keys and build choices
|
||||
IFS=$'\0' read -r -d '' -a _def_files < <(_ci_ssh_discover_files && printf '\0')
|
||||
_ci_ssh_build_choices "${_def_files[@]}"
|
||||
local default_key_count="$CI_SSH_COUNT"
|
||||
|
||||
if [[ "$default_key_count" -gt 0 ]]; then
|
||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
||||
"Provision SSH keys for Cloud-Init VM:" 14 72 4 \
|
||||
"found" "Select from detected keys (${default_key_count})" \
|
||||
"manual" "Paste a single public key" \
|
||||
"folder" "Scan another folder (path or glob)" \
|
||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
||||
else
|
||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
||||
"No host keys detected. Choose:" 12 72 3 \
|
||||
"manual" "Paste a single public key" \
|
||||
"folder" "Scan another folder (path or glob)" \
|
||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
||||
fi
|
||||
|
||||
case "$ssh_key_mode" in
|
||||
found)
|
||||
# Show checklist with individual keys
|
||||
local selection
|
||||
selection=$(whiptail --backtitle "$backtitle" --title "SELECT SSH KEYS" \
|
||||
--checklist "Select one or more keys to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
||||
|
||||
for tag in $selection; do
|
||||
tag="${tag%\"}"
|
||||
tag="${tag#\"}"
|
||||
local line
|
||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
done
|
||||
local imported
|
||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) selected${CL}"
|
||||
;;
|
||||
manual)
|
||||
local pubkey
|
||||
pubkey=$(whiptail --backtitle "$backtitle" --title "PASTE SSH PUBLIC KEY" \
|
||||
--inputbox "Paste your SSH public key (ssh-rsa, ssh-ed25519, etc.):" 10 76 3>&1 1>&2 2>&3) || return 1
|
||||
if [[ -n "$pubkey" ]]; then
|
||||
echo "$pubkey" >"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}1 key added manually${CL}"
|
||||
else
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (empty input)${CL}"
|
||||
CLOUDINIT_SSH_KEYS=""
|
||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
folder)
|
||||
local glob_path
|
||||
glob_path=$(whiptail --backtitle "$backtitle" --title "SCAN FOLDER/GLOB" \
|
||||
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub):" 10 72 3>&1 1>&2 2>&3) || return 1
|
||||
if [[ -n "$glob_path" ]]; then
|
||||
shopt -s nullglob
|
||||
local -a _scan_files=($glob_path)
|
||||
shopt -u nullglob
|
||||
if [[ "${#_scan_files[@]}" -gt 0 ]]; then
|
||||
_ci_ssh_build_choices "${_scan_files[@]}"
|
||||
if [[ "$CI_SSH_COUNT" -gt 0 ]]; then
|
||||
local folder_selection
|
||||
folder_selection=$(whiptail --backtitle "$backtitle" --title "SELECT FOLDER KEYS" \
|
||||
--checklist "Select key(s) to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
||||
for tag in $folder_selection; do
|
||||
tag="${tag%\"}"
|
||||
tag="${tag#\"}"
|
||||
local line
|
||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
done
|
||||
local imported
|
||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) from folder${CL}"
|
||||
else
|
||||
whiptail --backtitle "$backtitle" --msgbox "No keys found in: $glob_path" 8 60
|
||||
fi
|
||||
else
|
||||
whiptail --backtitle "$backtitle" --msgbox "Path/glob returned no files." 8 60
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
none | *)
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (password auth only)${CL}"
|
||||
CLOUDINIT_SSH_KEYS=""
|
||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Cleanup mapfile
|
||||
rm -f "$CI_SSH_MAPFILE" 2>/dev/null
|
||||
|
||||
# Set the variable for setup_cloud_init to use
|
||||
if [[ -s "$CLOUDINIT_SSH_KEYS_TEMP" ]]; then
|
||||
CLOUDINIT_SSH_KEYS="$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
else
|
||||
CLOUDINIT_SSH_KEYS=""
|
||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 3: HELPER FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -144,9 +341,10 @@ function setup_cloud_init() {
|
||||
local cipassword=$(openssl rand -base64 16)
|
||||
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
||||
|
||||
# Add SSH keys if available
|
||||
if [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
||||
# Add SSH keys only if explicitly provided (not auto-imported from host)
|
||||
if [ -n "${CLOUDINIT_SSH_KEYS:-}" ] && [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
||||
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
||||
_ci_msg_info "SSH keys imported from: $CLOUDINIT_SSH_KEYS"
|
||||
fi
|
||||
|
||||
# Configure network
|
||||
@@ -459,6 +657,11 @@ export -f wait_for_cloud_init 2>/dev/null || true
|
||||
export -f validate_ip_cidr 2>/dev/null || true
|
||||
export -f validate_ip 2>/dev/null || true
|
||||
|
||||
# Restore previous shell options if they were saved
|
||||
if [ -n "${_OLD_SET_STATE:-}" ]; then
|
||||
eval "$_OLD_SET_STATE"
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 7: EXAMPLES & DOCUMENTATION
|
||||
# ==============================================================================
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
____ _ __ ____ __ ___ ____
|
||||
/ _/___ ___ ____ ___ (_)____/ /_ / __ \__ __/ /_ / (_)____ / __ \_________ _ ____ __
|
||||
/ // __ `__ \/ __ `__ \/ / ___/ __ \ / /_/ / / / / __ \/ / / ___/ / /_/ / ___/ __ \| |/_/ / / /
|
||||
_/ // / / / / / / / / / / / /__/ / / / / ____/ /_/ / /_/ / / / /__ / ____/ / / /_/ /> </ /_/ /
|
||||
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ \__,_/_.___/_/_/\___/ /_/ /_/ \____/_/|_|\__, /
|
||||
/____/
|
||||
Reference in New Issue
Block a user