Update contribution docs and templates for best practices

Refreshed AI.md with new reference scripts, expanded checklist, and improved AI assistant tips. Updated container and install script templates for modern defaults (Debian 13, larger disk, two tags), clarified helper function usage, and improved update/backup patterns. Enhanced JSON template with realistic metadata, new fields, and example notes.
This commit is contained in:
CanbiZ
2026-01-18 17:54:44 +01:00
parent 5a975901ea
commit acdf4dbb2a
4 changed files with 190 additions and 135 deletions

View File

@@ -624,40 +624,33 @@ cleanup_lxc
---
## 🔍 Checklist Before PR Creation
## 📖 Reference: Good Example Scripts
- [ ] No Docker installation used
- [ ] `fetch_and_deploy_gh_release` used for GitHub releases
- [ ] `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
- [ ] `$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
- [ ] `motd_ssh`, `customize`, `cleanup_lxc` at the end
- [ ] No custom download/version-check logic
- [ ] JSON metadata file created in `frontend/public/json/<appname>.json`
Look at these recent well-implemented applications as reference:
---
### Container Scripts (Latest 10)
- [ct/thingsboard.sh](../ct/thingsboard.sh) - IoT platform with proper update_script
- [ct/unifi-os-server.sh](../ct/unifi-os-server.sh) - Complex setup with podman
- [ct/trip.sh](../ct/trip.sh) - Simple Ruby app
- [ct/fladder.sh](../ct/fladder.sh) - Media app with database
- [ct/qui.sh](../ct/qui.sh) - Lightweight utility
- [ct/kutt.sh](../ct/kutt.sh) - Node.js with PostgreSQL
- [ct/flatnotes.sh](../ct/flatnotes.sh) - Python notes app
- [ct/investbrain.sh](../ct/investbrain.sh) - Finance app
- [ct/gwn-manager.sh](../ct/gwn-manager.sh) - Network management
- [ct/sportarr.sh](../ct/sportarr.sh) - Specialized *Arr variant
## 📖 Reference: Good Example (Termix)
### Install Scripts (Latest)
- [install/unifi-os-server-install.sh](../install/unifi-os-server-install.sh) - Complex setup with API integration
- [install/trip-install.sh](../install/trip-install.sh) - Rails application setup
- [install/mail-archiver-install.sh](../install/mail-archiver-install.sh) - Email-related service
### CT Script: [ct/termix.sh](../ct/termix.sh)
- Uses `check_for_gh_release` for version checking
- Uses `CLEAN_INSTALL=1 fetch_and_deploy_gh_release` for clean updates
- Backup/restore of `/opt/termix/data`
- Correct structure with all required variables
### Install Script: [install/termix-install.sh](../install/termix-install.sh)
- `NODE_VERSION="22" setup_nodejs` instead of manual installation
- `fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix"` instead of wget/curl
- Clean service configuration
- Correct footer with `motd_ssh`, `customize`, `cleanup_lxc`
**Key things to notice:**
- Proper error handling with `catch_errors`
- Use of `check_for_gh_release` and `fetch_and_deploy_gh_release`
- Correct backup/restore patterns in `update_script`
- Footer always ends with `motd_ssh`, `customize`, `cleanup_lxc`
- JSON metadata files created for each app
---
@@ -792,19 +785,51 @@ Or no credentials:
---
## <EFBFBD>💡 Tips for AI Assistants
## 🔍 Checklist Before PR Creation
1. **Search `tools.func` first** before implementing custom solutions
2. **Use existing scripts as reference** (e.g., `linkwarden-install.sh`, `homarr-install.sh`)
- [ ] No Docker installation used
- [ ] `fetch_and_deploy_gh_release` used for GitHub releases
- [ ] `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 (only when used multiple times)
- [ ] `$STD` before all apt/npm/build commands
- [ ] `msg_info`/`msg_ok`/`msg_error` for logging (only for custom code)
- [ ] Correct script structure followed (see templates)
- [ ] Update function present and functional (CT scripts)
- [ ] Data backup implemented in update function (if applicable)
- [ ] `motd_ssh`, `customize`, `cleanup_lxc` at the end of install scripts
- [ ] No custom download/version-check logic
- [ ] All links point to `community-scripts/ProxmoxVE` (not `ProxmoxVED`!)
- [ ] JSON metadata file created in `frontend/public/json/<appname>.json`
- [ ] Category IDs are valid (0-25)
- [ ] Default OS version is Debian 13 or newer (unless special requirement)
- [ ] Default resources are reasonable for the application
---
## 💡 Tips for AI Assistants
1. **ALWAYS search `tools.func` first** before implementing custom solutions
2. **Use recent scripts as reference** (Thingsboard, UniFi OS, Trip, Flatnotes, etc.)
3. **Ask when uncertain** instead of introducing wrong patterns
4. **Consistency > Creativity** - follow established patterns
5. **Test local variables** - use `${VAR:-default}` pattern for optional values
4. **Test locally** - try running scripts in test containers
5. **Consistency > Creativity** - follow established patterns strictly
6. **Check the templates** - they show the correct structure
7. **Don't wrap tools.func functions** - they handle their own msg_info/msg_ok output
8. **Minimal variables** - only create variables that are truly reused multiple times
9. **Always use $STD** - ensures silent/non-interactive execution
10. **Reference good examples** - look at recent additions in each category
---
## 📚 Further Documentation
- [CONTRIBUTING.md](contribution/CONTRIBUTING.md) - General contribution guidelines
- [GUIDE.md](contribution/GUIDE.md) - Detailed developer documentation
- [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) - Technical details
- [EXIT_CODES.md](EXIT_CODES.md) - Exit code reference
- [CONTRIBUTING.md](CONTRIBUTING.md) - General contribution guidelines
- [GUIDE.md](GUIDE.md) - Detailed developer documentation
- [HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md) - Complete tools.func reference
- [../TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md) - Technical deep dive
- [../EXIT_CODES.md](../EXIT_CODES.md) - Exit code reference
- [templates_ct/](templates_ct/) - CT script templates
- [templates_install/](templates_install/) - Install script templates
- [templates_json/](templates_json/) - JSON metadata templates

View File

@@ -7,12 +7,12 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# App Default Values
APP="[AppName]"
var_tags="${var_tags:-[category]}"
var_tags="${var_tags:-[category1];[category2]}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
# =============================================================================
@@ -20,12 +20,12 @@ var_unprivileged="${var_unprivileged:-1}"
# =============================================================================
# APP - Display name, title case (e.g. "Koel", "Wallabag", "Actual Budget")
# var_tags - Max 2 tags, semicolon separated (e.g. "music;streaming", "finance")
# var_cpu - CPU cores: 1-4 typical
# var_ram - RAM in MB: 512, 1024, 2048, 4096 typical
# var_disk - Disk in GB: 4, 6, 8, 10, 20 typical
# var_cpu - CPU cores: 1-4 typical, 4+ for heavy apps
# var_ram - RAM in MB: 512, 1024, 2048, 4096, 8192 typical
# var_disk - Disk in GB: 6, 8, 10, 20 typical (more for data-heavy apps)
# var_os - OS: debian, ubuntu, alpine
# var_version - OS version: 12/13 (debian), 22.04/24.04 (ubuntu), 3.20/3.21 (alpine)
# var_unprivileged - 1 = unprivileged (secure, default), 0 = privileged (for docker etc.)
# var_version - OS version: 13 (debian), 24.04 (ubuntu), 3.21 (alpine)
# var_unprivileged - 1 = unprivileged (secure, default), 0 = privileged (for podman/docker)
header_info "$APP"
variables
@@ -45,39 +45,32 @@ function update_script() {
# check_for_gh_release returns 0 (true) if update available, 1 (false) if not
if check_for_gh_release "[appname]" "[owner/repo]"; then
msg_info "Stopping Services"
msg_info "Stopping Service"
systemctl stop [appname]
msg_ok "Stopped Services"
msg_ok "Stopped Service"
# Optional: Backup important data before update
msg_info "Creating Backup"
mkdir -p /tmp/[appname]_backup
cp /opt/[appname]/.env /tmp/[appname]_backup/ 2>/dev/null || true
cp -r /opt/[appname]/data /tmp/[appname]_backup/ 2>/dev/null || true
msg_ok "Created Backup"
msg_info "Backing up Data"
cp -r /opt/[appname]/data /opt/[appname]_data_backup 2>/dev/null || true
msg_ok "Backed up Data"
# CLEAN_INSTALL=1 removes old directory before extracting new version
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "[appname]" "[owner/repo]"
# Restore configuration and data
# Restore configuration and data (if needed)
msg_info "Restoring Data"
cp /tmp/[appname]_backup/.env /opt/[appname]/ 2>/dev/null || true
cp -r /tmp/[appname]_backup/data/* /opt/[appname]/data/ 2>/dev/null || true
rm -rf /tmp/[appname]_backup
cp -r /opt/[appname]_data_backup/. /opt/[appname]/data/ 2>/dev/null || true
rm -rf /opt/[appname]_data_backup
msg_ok "Restored Data"
# Optional: Run any post-update commands
msg_info "Running Post-Update Tasks"
cd /opt/[appname]
# Examples:
# $STD npm ci --production
# $STD php artisan migrate --force
# $STD composer install --no-dev
msg_ok "Ran Post-Update Tasks"
# Optional: Run any post-update commands (npm, composer, migrations, etc.)
# cd /opt/[appname] && $STD npm ci --production
# cd /opt/[appname] && $STD composer install --no-dev
# cd /opt/[appname] && $STD php artisan migrate --force
msg_info "Starting Services"
msg_info "Starting Service"
systemctl start [appname]
msg_ok "Started Services"
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi

View File

@@ -14,90 +14,121 @@ setting_up_container
network_check
update_os
# =============================================================================
# AVAILABLE HELPER FUNCTIONS (from tools.func)
# =============================================================================
#
# LANGUAGE/RUNTIME SETUP (use these, DON'T do manual installation!):
# NODE_VERSION="22" setup_nodejs # Node.js (18, 20, 22)
# PYTHON_VERSION="3.13" setup_uv # Python with uv package manager
# GO_VERSION="1.22" setup_go # Go language
# RUST_CRATES="monolith" setup_rust # Rust
# RUBY_VERSION="3.3" setup_ruby # Ruby
# JAVA_VERSION="21" setup_java # Java (17, 21)
# PHP_VERSION="8.4" setup_php # PHP
#
# DATABASE SETUP (use these instead of manual setup!):
# setup_postgresql # PostgreSQL server
# PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db # Create DB & user
# setup_mariadb # MariaDB server
# MARIADB_DB_NAME="mydb" setup_mariadb_db # Create MariaDB DB
# setup_mysql # MySQL server
# setup_mongodb # MongoDB server
#
# GITHUB RELEASES (PREFERRED - handles versioning automatically!):
# fetch_and_deploy_gh_release "appname" "owner/repo" # Auto-detect mode
# fetch_and_deploy_gh_release "appname" "owner/repo" "binary" # .deb package
# CLEAN_INSTALL=1 fetch_and_deploy_gh_release ... # Clean install (remove old dir first)
#
# UTILITIES:
# import_local_ip # Sets $LOCAL_IP variable (call early!)
# setup_ffmpeg # FFmpeg with codecs
# setup_imagemagick # ImageMagick 7
# setup_hwaccel # GPU acceleration
# setup_docker # Docker Engine
# setup_adminer # Adminer (DB web interface)
# =============================================================================
# DEPENDENCIES
# =============================================================================
# Only install what's actually needed - curl/sudo/mc are already in the base image
msg_info "Installing Dependencies"
$STD apt install -y \
nginx \
build-essential
ca-certificates \
curl \
gnupg
msg_ok "Installed Dependencies"
# =============================================================================
# HELPER FUNCTIONS FROM tools.func
# =============================================================================
# These functions are available via $FUNCTIONS_FILE_PATH (tools.func)
# Call them with optional environment variables for configuration
#
# --- Runtime & Language Setup ---
# NODE_VERSION="22" setup_nodejs # Install Node.js (22, 24)
# NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs # With pnpm
# PYTHON_VERSION="3.13" setup_uv # Python with uv package manager
# setup_go # Install Go (latest)
# setup_rust # Install Rust via rustup
# setup_ruby # Install Ruby
# PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="mysqli,gd" setup_php
# PHP_VERSION="8.3" PHP_FPM="YES" PHP_APACHE="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
# setup_composer # Install PHP Composer
# JAVA_VERSION="21" setup_java # Install Java (17, 21)
#
# --- Database Setup ---
# setup_mariadb # Install MariaDB server
# MARIADB_DB_NAME="mydb" MARIADB_DB_USER="myuser" setup_mariadb_db
# setup_mysql # Install MySQL server
# PG_VERSION="17" setup_postgresql # Install PostgreSQL (16, 17)
# PG_VERSION="17" PG_MODULES="postgis" setup_postgresql # With extensions
# PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db
# setup_mongodb # Install MongoDB
#
# --- GitHub Release (PREFERRED METHOD) ---
# fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" # Downloads, extracts, tracks version
# fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
# fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "app-*.tar.gz"
#
# --- Tools & Utilities ---
# import_local_ip # Sets $LOCAL_IP variable (call early!)
# setup_ffmpeg # Install FFmpeg with codecs
# setup_hwaccel # Setup GPU hardware acceleration
# setup_imagemagick # Install ImageMagick 7
# setup_docker # Install Docker Engine
# setup_adminer # Install Adminer for DB management
# create_self_signed_cert # Creates cert in /etc/ssl/[appname]/
# =============================================================================
# EXAMPLE 1: Node.js Application with PostgreSQL
# EXAMPLE: Node.js App with PostgreSQL
# =============================================================================
# NODE_VERSION="22" setup_nodejs
# PG_VERSION="17" setup_postgresql
# PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
# import_local_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
#
# msg_info "Configuring MyApp"
# msg_info "Deploying Application"
# fetch_and_deploy_gh_release "myapp" "owner/myapp"
# msg_ok "Deployed Application"
#
# msg_info "Installing Dependencies"
# cd /opt/myapp
# $STD npm ci
# $STD npm ci --production
# msg_ok "Installed Dependencies"
#
# msg_info "Configuring Environment"
# cat <<EOF >/opt/myapp/.env
# DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}
# HOST=${LOCAL_IP}
# PORT=3000
# APP_HOST=${LOCAL_IP}
# APP_PORT=3000
# NODE_ENV=production
# EOF
# msg_ok "Configured MyApp"
# msg_ok "Configured Environment"
# =============================================================================
# EXAMPLE 2: Python Application with uv
# EXAMPLE: Python App with uv
# =============================================================================
# PYTHON_VERSION="3.13" setup_uv
# import_local_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
# msg_info "Deploying Application"
# fetch_and_deploy_gh_release "myapp" "owner/myapp"
# msg_ok "Deployed Application"
#
# msg_info "Setting up MyApp"
# msg_info "Installing Dependencies"
# cd /opt/myapp
# $STD uv sync
# $STD uv sync --frozen
# msg_ok "Installed Dependencies"
#
# cat <<EOF >/opt/myapp/.env
# HOST=${LOCAL_IP}
# PORT=8000
# DEBUG=false
# EOF
# =============================================================================
# CREATE SYSTEMD SERVICE
# =============================================================================
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/[appname].service
[Unit]
Description=[AppName] Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/[appname]
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/[appname]/server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now [appname]
msg_ok "Created Service"
# EOF
# msg_ok "Setup MyApp"

View File

@@ -4,25 +4,26 @@
"categories": [
0
],
"date_created": "DATE CREATED",
"date_created": "2026-01-18",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": "DEFAULT-PORT",
"documentation": null,
"website": "LINK TO WEBSITE",
"logo": "LINK TO LOGO",
"description": "Description of the app",
"interface_port": 3000,
"documentation": "https://docs.example.com/",
"website": "https://example.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/appname.webp",
"config_path": "/opt/appname/.env",
"description": "Short description of what AppName does and its main features.",
"install_methods": [
{
"type": "default",
"script": "ct/AppName.sh",
"script": "ct/appname.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "12"
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
@@ -30,5 +31,10 @@
"username": null,
"password": null
},
"notes": []
"notes": [
{
"text": "Change the default password after first login!",
"type": "warning"
}
]
}