Add Zerobyte installer, CT script, and docs

Introduce Zerobyte support: add LXC container installer (install/zerobyte-install.sh), container template/update script (ct/zerobyte.sh), and frontend metadata (frontend/public/json/zerobyte.json). Update docs (docs/AI.md) to require explicit "tarball" mode for fetch_and_deploy_gh_release, add helper notes and best-practices, and include a new get_latest_github_release usage. Also switch the shellscript formatter in .vscode/settings.json to foxundermoon.shell-format. The installer fetches required binaries (restic, rclone, shoutrrr), installs Bun, builds Zerobyte, configures a systemd service, and prepares runtime directories and env config.
This commit is contained in:
CanbiZ (MickLesk) 2026-02-18 10:24:58 +01:00
parent b788310c72
commit f45b5b461f
4 changed files with 267 additions and 10 deletions

71
ct/zerobyte.sh Normal file
View File

@ -0,0 +1,71 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: community-scripts
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/nicotsx/zerobyte
APP="Zerobyte"
var_tags="${var_tags:-backup;encryption;restic}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_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/zerobyte ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "zerobyte" "nicotsx/zerobyte"; then
msg_info "Stopping Service"
systemctl stop zerobyte
msg_ok "Stopped Service"
msg_info "Backing up Configuration"
cp /opt/zerobyte/.env /opt/zerobyte.env.bak
msg_ok "Backed up Configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "zerobyte" "nicotsx/zerobyte" "tarball"
msg_info "Building Zerobyte"
cd /opt/zerobyte
$STD bun install
$STD bun run build
mkdir -p /opt/zerobyte/assets
cp -r /opt/zerobyte/app/drizzle /opt/zerobyte/assets/migrations
msg_ok "Built Zerobyte"
msg_info "Restoring Configuration"
cp /opt/zerobyte.env.bak /opt/zerobyte/.env
rm -f /opt/zerobyte.env.bak
msg_ok "Restored Configuration"
msg_info "Starting Service"
systemctl start zerobyte
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}:4096${CL}"

View File

@ -66,7 +66,7 @@ function update_script() {
cp -r /opt/appname/data /opt/appname_data_backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball"
# Build steps...
@ -125,7 +125,7 @@ PG_VERSION="16" setup_postgresql
setup_uv
# etc.
fetch_and_deploy_gh_release "appname" "owner/repo"
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball"
msg_info "Setting up Application"
cd /opt/appname
@ -165,13 +165,14 @@ cleanup_lxc
| Function | Description | Example |
|----------|-------------|----------|
| `fetch_and_deploy_gh_release` | Fetches and installs GitHub Release | `fetch_and_deploy_gh_release "app" "owner/repo"` |
| `fetch_and_deploy_gh_release` | Fetches and installs GitHub Release | `fetch_and_deploy_gh_release "app" "owner/repo" "tarball"` |
| `check_for_gh_release` | Checks for new version | `if check_for_gh_release "app" "owner/repo"; then` |
| `get_latest_github_release` | Returns latest release version string | `VERSION=$(get_latest_github_release "owner/repo")` |
**Modes for `fetch_and_deploy_gh_release`:**
```bash
# Tarball/Source (Standard)
fetch_and_deploy_gh_release "appname" "owner/repo"
# Tarball/Source (Standard) - always specify "tarball" explicitly
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball"
# Binary (.deb)
fetch_and_deploy_gh_release "appname" "owner/repo" "binary"
@ -185,9 +186,11 @@ fetch_and_deploy_gh_release "appname" "owner/repo" "singlefile" "latest" "/opt/a
**Clean Install Flag:**
```bash
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball"
```
**Version file:** After `fetch_and_deploy_gh_release`, the deployed version is stored in `~/.appname`. You can read it with `cat ~/.appname` — useful when you need the version later (e.g. for build-time environment variables).
### Runtime/Language Setup
| Function | Variable(s) | Example |
@ -477,7 +480,54 @@ $STD sudo -u postgres psql -d mydb -c "CREATE EXTENSION IF NOT EXISTS postgis;"
PG_DB_NAME="mydb" PG_DB_USER="myuser" PG_DB_EXTENSIONS="postgis" setup_postgresql_db
```
### 17. Writing Files Without Heredocs
### 18. Hardcoded Versions for External Tools
```bash
# ❌ WRONG - hardcoded versions that will become outdated
RESTIC_VERSION="0.18.1"
RCLONE_VERSION="1.73.0"
curl -L -o restic.bz2 "https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_amd64.bz2"
# ✅ CORRECT - use fetch_and_deploy_gh_release (always fetches latest)
fetch_and_deploy_gh_release "restic" "restic/restic" "singlefile" "latest" "/usr/local/bin" "restic_*_linux_amd64.bz2"
# If you need the version number later, read from the version file:
RES_VERSION=$(cat ~/.restic)
# Or use get_latest_github_release:
VERSION=$(get_latest_github_release "restic/restic")
```
### 19. Backing Up to /tmp in Update Scripts
```bash
# ❌ WRONG - /tmp can be cleared by the system
msg_info "Backing up Configuration"
cp /opt/appname/.env /tmp/appname.env.bak
msg_ok "Backed up Configuration"
# ... update ...
cp /tmp/appname.env.bak /opt/appname/.env
# ✅ CORRECT - back up directly into /opt
msg_info "Backing up Configuration"
cp /opt/appname/.env /opt/appname.env.bak
msg_ok "Backed up Configuration"
# ... update ...
cp /opt/appname.env.bak /opt/appname/.env
rm -f /opt/appname.env.bak
```
### 20. Using "(Patience)" in msg_info by Default
```bash
# ❌ WRONG - "(Patience)" should not be a default label
msg_info "Building Application (Patience)"
$STD npm run build
msg_ok "Built Application"
# ✅ CORRECT - use a plain label; only add (Patience) if the build truly takes 10+ minutes
msg_info "Building Application"
$STD npm run build
msg_ok "Built Application"
```
### 21. Writing Files Without Heredocs
```bash
# ❌ WRONG - echo / printf / tee
echo "# Config" > /opt/app/config.yml
@ -538,7 +588,7 @@ function update_script() {
msg_ok "Backed up Data"
# 5. Perform clean install
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball"
# 6. Rebuild (if needed)
cd /opt/appname
@ -598,18 +648,20 @@ cleanup_lxc
## 🔍 Checklist Before PR Creation
- [ ] No Docker installation used
- [ ] `fetch_and_deploy_gh_release` used for GitHub releases
- [ ] `fetch_and_deploy_gh_release` used for GitHub releases (with explicit mode like `"tarball"`)
- [ ] `check_for_gh_release` used for update checks
- [ ] `setup_*` functions used for runtimes (nodejs, postgresql, etc.)
- [ ] **`tools.func` functions NOT wrapped in msg_info/msg_ok blocks**
- [ ] No redundant variables
- [ ] No hardcoded versions for external tools (use `fetch_and_deploy_gh_release` or `get_latest_github_release`)
- [ ] `$STD` before all apt/npm/build commands
- [ ] `msg_info`/`msg_ok`/`msg_error` for logging (only for custom code)
- [ ] Correct script structure followed
- [ ] Update function present and functional
- [ ] Data backup implemented in update function
- [ ] Data backup implemented in update function (backups go to `/opt`, NOT `/tmp`)
- [ ] `motd_ssh`, `customize`, `cleanup_lxc` at the end
- [ ] No custom download/version-check logic
- [ ] No default `(Patience)` text in msg_info labels
- [ ] JSON metadata file created in `frontend/public/json/<appname>.json`
---

View File

@ -0,0 +1,40 @@
{
"name": "Zerobyte",
"slug": "zerobyte",
"categories": [
7
],
"date_created": "2026-02-18",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 4096,
"documentation": "https://github.com/nicotsx/zerobyte#readme",
"website": "https://github.com/nicotsx/zerobyte",
"logo": "https://cdn.jsdelivr.net/gh/nicotsx/zerobyte@main/public/images/favicon.svg",
"config_path": "/opt/zerobyte/.env",
"description": "Zerobyte is a backup automation tool built on top of Restic that provides a modern web interface to schedule, manage, and monitor encrypted backups across multiple storage backends including NFS, SMB, WebDAV, SFTP, S3, and local directories.",
"install_methods": [
{
"type": "default",
"script": "ct/zerobyte.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 10,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "For remote mount support (NFS, SMB, WebDAV, SFTP), enable FUSE device passthrough on the LXC container.",
"type": "info"
}
]
}

View File

@ -0,0 +1,94 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: community-scripts
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/nicotsx/zerobyte
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
bzip2 \
fuse3 \
sshfs \
davfs2 \
openssh-client
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "restic" "restic/restic" "singlefile" "latest" "/usr/local/bin" "restic_*_linux_amd64.bz2"
mv /usr/local/bin/restic /usr/local/bin/restic.bz2
bzip2 -d /usr/local/bin/restic.bz2
chmod +x /usr/local/bin/restic
fetch_and_deploy_gh_release "rclone" "rclone/rclone" "prebuild" "latest" "/opt/rclone" "rclone-*-linux-amd64.zip"
ln -sf /opt/rclone/rclone /usr/local/bin/rclone
fetch_and_deploy_gh_release "shoutrrr" "nicholas-fedor/shoutrrr" "prebuild" "latest" "/opt/shoutrrr" "shoutrrr_linux_amd64_*.tar.gz"
ln -sf /opt/shoutrrr/shoutrrr /usr/local/bin/shoutrrr
msg_info "Installing Bun"
export BUN_INSTALL="/root/.bun"
curl -fsSL https://bun.sh/install | $STD bash
ln -sf /root/.bun/bin/bun /usr/local/bin/bun
ln -sf /root/.bun/bin/bunx /usr/local/bin/bunx
msg_ok "Installed Bun"
fetch_and_deploy_gh_release "zerobyte" "nicotsx/zerobyte" "tarball"
msg_info "Building Zerobyte"
cd /opt/zerobyte
export VITE_RESTIC_VERSION=$(cat ~/.restic)
export VITE_RCLONE_VERSION=$(cat ~/.rclone)
export VITE_SHOUTRRR_VERSION=$(cat ~/.shoutrrr)
$STD bun install
$STD bun run build
mkdir -p /opt/zerobyte/assets
cp -r /opt/zerobyte/app/drizzle /opt/zerobyte/assets/migrations
msg_ok "Built Zerobyte"
msg_info "Configuring Zerobyte"
mkdir -p /var/lib/zerobyte/{data,restic/cache,repositories,volumes}
APP_SECRET=$(openssl rand -hex 32)
cat <<EOF >/opt/zerobyte/.env
BASE_URL=http://${LOCAL_IP}:4096
APP_SECRET=${APP_SECRET}
PORT=4096
ZEROBYTE_DATABASE_URL=/var/lib/zerobyte/data/zerobyte.db
RESTIC_CACHE_DIR=/var/lib/zerobyte/restic/cache
ZEROBYTE_REPOSITORIES_DIR=/var/lib/zerobyte/repositories
ZEROBYTE_VOLUMES_DIR=/var/lib/zerobyte/volumes
NODE_ENV=production
EOF
msg_ok "Configured Zerobyte"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/zerobyte.service
[Unit]
Description=Zerobyte Backup Automation
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/zerobyte
EnvironmentFile=/opt/zerobyte/.env
ExecStart=/usr/local/bin/bun .output/server/index.mjs
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now zerobyte
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc