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:
parent
b788310c72
commit
f45b5b461f
71
ct/zerobyte.sh
Normal file
71
ct/zerobyte.sh
Normal 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}"
|
||||||
72
docs/AI.md
72
docs/AI.md
@ -66,7 +66,7 @@ function update_script() {
|
|||||||
cp -r /opt/appname/data /opt/appname_data_backup
|
cp -r /opt/appname/data /opt/appname_data_backup
|
||||||
msg_ok "Backed up Data"
|
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...
|
# Build steps...
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ PG_VERSION="16" setup_postgresql
|
|||||||
setup_uv
|
setup_uv
|
||||||
# etc.
|
# etc.
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "appname" "owner/repo"
|
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball"
|
||||||
|
|
||||||
msg_info "Setting up Application"
|
msg_info "Setting up Application"
|
||||||
cd /opt/appname
|
cd /opt/appname
|
||||||
@ -165,13 +165,14 @@ cleanup_lxc
|
|||||||
|
|
||||||
| Function | Description | Example |
|
| 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` |
|
| `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`:**
|
**Modes for `fetch_and_deploy_gh_release`:**
|
||||||
```bash
|
```bash
|
||||||
# Tarball/Source (Standard)
|
# Tarball/Source (Standard) - always specify "tarball" explicitly
|
||||||
fetch_and_deploy_gh_release "appname" "owner/repo"
|
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball"
|
||||||
|
|
||||||
# Binary (.deb)
|
# Binary (.deb)
|
||||||
fetch_and_deploy_gh_release "appname" "owner/repo" "binary"
|
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:**
|
**Clean Install Flag:**
|
||||||
```bash
|
```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
|
### Runtime/Language Setup
|
||||||
|
|
||||||
| Function | Variable(s) | Example |
|
| 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
|
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
|
```bash
|
||||||
# ❌ WRONG - echo / printf / tee
|
# ❌ WRONG - echo / printf / tee
|
||||||
echo "# Config" > /opt/app/config.yml
|
echo "# Config" > /opt/app/config.yml
|
||||||
@ -538,7 +588,7 @@ function update_script() {
|
|||||||
msg_ok "Backed up Data"
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
# 5. Perform clean install
|
# 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)
|
# 6. Rebuild (if needed)
|
||||||
cd /opt/appname
|
cd /opt/appname
|
||||||
@ -598,18 +648,20 @@ cleanup_lxc
|
|||||||
## 🔍 Checklist Before PR Creation
|
## 🔍 Checklist Before PR Creation
|
||||||
|
|
||||||
- [ ] No Docker installation used
|
- [ ] 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
|
- [ ] `check_for_gh_release` used for update checks
|
||||||
- [ ] `setup_*` functions used for runtimes (nodejs, postgresql, etc.)
|
- [ ] `setup_*` functions used for runtimes (nodejs, postgresql, etc.)
|
||||||
- [ ] **`tools.func` functions NOT wrapped in msg_info/msg_ok blocks**
|
- [ ] **`tools.func` functions NOT wrapped in msg_info/msg_ok blocks**
|
||||||
- [ ] No redundant variables
|
- [ ] 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
|
- [ ] `$STD` before all apt/npm/build commands
|
||||||
- [ ] `msg_info`/`msg_ok`/`msg_error` for logging (only for custom code)
|
- [ ] `msg_info`/`msg_ok`/`msg_error` for logging (only for custom code)
|
||||||
- [ ] Correct script structure followed
|
- [ ] Correct script structure followed
|
||||||
- [ ] Update function present and functional
|
- [ ] 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
|
- [ ] `motd_ssh`, `customize`, `cleanup_lxc` at the end
|
||||||
- [ ] No custom download/version-check logic
|
- [ ] No custom download/version-check logic
|
||||||
|
- [ ] No default `(Patience)` text in msg_info labels
|
||||||
- [ ] JSON metadata file created in `frontend/public/json/<appname>.json`
|
- [ ] JSON metadata file created in `frontend/public/json/<appname>.json`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
40
frontend/public/json/zerobyte.json
Normal file
40
frontend/public/json/zerobyte.json
Normal 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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
94
install/zerobyte-install.sh
Normal file
94
install/zerobyte-install.sh
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user