Compare commits

..

4 Commits

Author SHA1 Message Date
MickLesk
8f8e1d0313 Trim comments 2026-09-10 14:18:24 +02:00
MickLesk
a8c8f1cb10 Rewrite the retired Gitea base in every container before updating it
git.community-scripts.org was a mirror of the same repositories and is
gone. A container built against it cannot update: the older entrypoint
pulls ct/<app>.sh straight from the dead host, so it never reaches the
update helper that could repair itself.

Rewriting it from the host is the one place that reaches those, and it
is where people already sweep all their containers. Only the host and
Gitea's /raw/<kind>/ segment change, so a fork keeps its own owner,
repo and ref.
2026-09-10 14:11:30 +02:00
community-scripts-pr-app[bot]
2802f0fc55 Update CHANGELOG.md (#17153)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-10 11:49:47 +00:00
push-app-to-main[bot]
7c822e1642 Safebucket (#17096)
* Add safebucket (ct)

* Update default var_arm64 value to 'yes'

Changed default value of var_arm64 to 'yes' in safebucket.sh.

* safebucket-install.sh aktualisieren

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>

* Refactor ARCH variable usage in safebucket.sh

* Refactor Safebucket installation script

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-09-10 13:49:15 +02:00
6 changed files with 321 additions and 1 deletions

View File

@@ -542,6 +542,10 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
## 2026-09-10
### 🆕 New Scripts
- Safebucket ([#17096](https://github.com/community-scripts/ProxmoxVE/pull/17096))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes

6
ct/headers/safebucket Normal file
View File

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

63
ct/safebucket.sh Normal file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env bash
_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main"
_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: renizmy
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/safebucket/safebucket
APP="Safebucket"
var_tags="${var_tags:-files;sharing}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
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/safebucket/safebucket ]]; then
msg_error "No ${APP} Installation Found!"
exit 1
fi
if check_for_gh_release "safebucket" "safebucket/safebucket"; then
msg_info "Stopping Service"
systemctl stop safebucket
msg_ok "Stopped Service"
create_backup /opt/safebucket/config.yaml /opt/safebucket/data/
fetch_and_deploy_gh_release "safebucket" "safebucket/safebucket" "singlefile" "latest" "/opt/safebucket" "safebucket-linux-$(arch_resolve)"
restore_backup
msg_info "Configuring Safebucket"
chown -R safebucket:safebucket /opt/safebucket
msg_ok "Configured Safebucket"
msg_info "Starting Service"
systemctl start safebucket
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}:8080${CL}"

View File

@@ -0,0 +1,226 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: renizmy
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/safebucket/safebucket
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 awscli
msg_ok "Installed Dependencies"
msg_info "Installing Garage"
useradd --system --no-create-home --shell /usr/sbin/nologin garage 2>/dev/null || true
GARAGE_VERSION=$(get_latest_gh_tag "deuxfleurs-org/garage" "v")
if [[ -z "$GARAGE_VERSION" ]]; then
msg_error "Could not determine latest stable Garage version"
exit 1
fi
curl -fsSL "https://garagehq.deuxfleurs.fr/_releases/${GARAGE_VERSION}/$(arch_resolve "x86_64-unknown-linux-musl" "aarch64-unknown-linux-musl")/garage" -o /usr/local/bin/garage
chmod +x /usr/local/bin/garage
mkdir -p /opt/garage/{data,meta}
RPC_SECRET=$(openssl rand -hex 32)
ADMIN_TOKEN=$(openssl rand -base64 32)
cat <<EOF >/opt/garage/garage.toml
metadata_dir = "/opt/garage/meta"
data_dir = "/opt/garage/data"
db_engine = "lmdb"
replication_factor = 1
rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "${RPC_SECRET}"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3.garage.localhost"
[admin]
api_bind_addr = "[::]:3903"
admin_token = "${ADMIN_TOKEN}"
EOF
chmod 600 /opt/garage/garage.toml
chown -R garage:garage /opt/garage
cat <<EOF >/etc/systemd/system/garage.service
[Unit]
Description=Garage Object Storage
After=network.target
[Service]
Type=simple
User=garage
Group=garage
WorkingDirectory=/opt/garage
ExecStart=/usr/local/bin/garage -c /opt/garage/garage.toml server
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now garage
msg_ok "Installed Garage"
msg_info "Configuring Garage Bucket"
RETRIES=0
until garage -c /opt/garage/garage.toml status &>/dev/null; do
RETRIES=$((RETRIES + 1))
if [[ $RETRIES -ge 60 ]]; then
msg_error "Garage did not become ready within 60 seconds"
exit 1
fi
sleep 1
done
NODE_ID=$(garage -c /opt/garage/garage.toml status 2>/dev/null | awk '/^[0-9a-f]/{print $1; exit}')
if [[ -z "$NODE_ID" ]]; then
msg_error "Could not determine Garage node ID from cluster status"
exit 1
fi
GARAGE_CAPACITY="${GARAGE_CAPACITY:-$(df -BG --output=avail /opt/garage | awk 'NR==2{gsub(/G/,"",$1); v=$1-1; print (v<1?1:v)"G"}')}"
$STD garage -c /opt/garage/garage.toml layout assign -z dc1 -c "${GARAGE_CAPACITY}" "${NODE_ID}"
$STD garage -c /opt/garage/garage.toml layout apply --version 1
GARAGE_KEY_INFO=$(garage -c /opt/garage/garage.toml key create safebucket-key)
GARAGE_ACCESS_KEY=$(echo "$GARAGE_KEY_INFO" | awk '/Key ID:/{print $3}')
GARAGE_SECRET_KEY=$(echo "$GARAGE_KEY_INFO" | awk '/Secret key:/{print $3}')
$STD garage -c /opt/garage/garage.toml bucket create safebucket
$STD garage -c /opt/garage/garage.toml bucket allow --read --write --owner safebucket --key safebucket-key
msg_ok "Configured Garage Bucket"
msg_info "Applying CORS Policy to Bucket"
export AWS_ACCESS_KEY_ID="${GARAGE_ACCESS_KEY}"
export AWS_SECRET_ACCESS_KEY="${GARAGE_SECRET_KEY}"
export AWS_DEFAULT_REGION="garage"
if aws s3api put-bucket-cors \
--bucket safebucket \
--endpoint-url "http://127.0.0.1:3900" \
--cors-configuration '{"CORSRules":[{"AllowedHeaders":["*"],"AllowedMethods":["GET","PUT","POST","DELETE","HEAD"],"AllowedOrigins":["http://'"${LOCAL_IP}"':8080"],"ExposeHeaders":["ETag"]}]}' &>/dev/null; then
msg_ok "Applied CORS Policy to Bucket"
else
msg_warn "Could not apply CORS policy automatically; direct browser uploads may fail until CORS is configured manually"
fi
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_DEFAULT_REGION
fetch_and_deploy_gh_release "safebucket" "safebucket/safebucket" "singlefile" "latest" "/opt/safebucket" "safebucket-linux-$(arch_resolve)"
msg_info "Configuring Safebucket"
useradd --system --no-create-home --shell /usr/sbin/nologin safebucket 2>/dev/null || true
mkdir -p /opt/safebucket/data/{notifications,activity}
TOKEN_SECRET=$(openssl rand -base64 32)
MFA_KEY=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | cut -c1-32)
ADMIN_PASSWORD=$(openssl rand -hex 12)
cat <<EOF >/opt/safebucket/config.yaml
app:
profile: default
log_level: info
api_url: http://${LOCAL_IP}:8080
web_url: http://${LOCAL_IP}:8080
allowed_origins:
- http://${LOCAL_IP}:8080
port: 8080
token_secret: "${TOKEN_SECRET}"
mfa_encryption_key: "${MFA_KEY}"
mfa_required: false
admin_email: admin@safebucket.io
admin_password: "${ADMIN_PASSWORD}"
trash_retention_days: 7
max_upload_size: 5368709120
trusted_proxies:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8
- ::1/128
- fc00::/7
static_files:
enabled: true
database:
type: sqlite
sqlite:
path: /opt/safebucket/data/safebucket.db
cache:
type: memory
storage:
type: s3
s3:
bucket_name: safebucket
endpoint: 127.0.0.1:3900
external_endpoint: http://${LOCAL_IP}:3900
access_key: ${GARAGE_ACCESS_KEY}
secret_key: ${GARAGE_SECRET_KEY}
region: garage
force_path_style: true
use_tls: false
events:
type: memory
queues:
notifications:
name: safebucket-notifications
object_deletion:
name: safebucket-object-deletion
bucket_events:
name: safebucket-bucket-events
notifier:
type: filesystem
filesystem:
directory: /opt/safebucket/data/notifications
activity:
type: filesystem
filesystem:
directory: /opt/safebucket/data/activity
auth:
providers:
local:
name: local
type: local
sharing:
allowed: true
domains: []
EOF
chmod 600 /opt/safebucket/config.yaml
chown -R safebucket:safebucket /opt/safebucket
msg_ok "Configured Safebucket"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/safebucket.service
[Unit]
Description=Safebucket File Sharing Platform
After=network-online.target garage.service
Wants=network-online.target
Requires=garage.service
[Service]
Type=simple
User=safebucket
Group=safebucket
WorkingDirectory=/opt/safebucket
Environment=CONFIG_FILE_PATH=/opt/safebucket/config.yaml
ExecStart=/opt/safebucket/safebucket
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now safebucket
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -40,7 +40,7 @@ CM="${TAB}✔️${TAB}${CL}"
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "guest-delete" "pve"
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "lxc-delete" "pve"
GUEST_LOG=$(mktemp)
trap 'rm -f "$GUEST_LOG"' EXIT

View File

@@ -178,6 +178,24 @@ function resolve_service_script() {
return 1
}
# The retired Gitea mirror. The old entrypoint pulls ct/<app>.sh straight from
# it and never reaches the update helper that would repair itself, so rewrite it
# here. Only host and /raw/<kind>/ change; owner, repo and ref are kept.
function repair_update_url() {
local container="$1"
pct exec "$container" -- sh -c '
[ -f /usr/bin/update ] || exit 1
grep -q git.community-scripts.org /usr/bin/update || exit 1
sed -i \
-e "s|https://git[.]community-scripts[.]org/|https://raw.githubusercontent.com/|g" \
-e "s|/raw/branch/|/|g" -e "s|/raw/tag/|/|g" -e "s|/raw/commit/|/|g" \
/usr/bin/update
' >/dev/null 2>&1 || return 1
echo -e "${BL}[INFO]${CL} Repaired update URL (Gitea -> GitHub) in container $container"
log_write "Container $container: rewrote the retired Gitea base in /usr/bin/update"
}
function detect_service() {
local container="$1"
local tmpdir update_file
@@ -489,6 +507,9 @@ for container in $CHOICE; do
sleep 5
fi
#0.5) Rewrite a retired Gitea base before anything reads it.
repair_update_url "$container"
#1) Detect service using the service name in the update command
detect_service $container