diff --git a/docs/contribution/AI.md b/docs/contribution/AI.md index 92d45f419..c17a2188f 100644 --- a/docs/contribution/AI.md +++ b/docs/contribution/AI.md @@ -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/.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: --- -## �💡 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/.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 diff --git a/docs/contribution/templates_ct/AppName.sh b/docs/contribution/templates_ct/AppName.sh index a7b7e4641..12202fb16 100644 --- a/docs/contribution/templates_ct/AppName.sh +++ b/docs/contribution/templates_ct/AppName.sh @@ -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 diff --git a/docs/contribution/templates_install/AppName-install.sh b/docs/contribution/templates_install/AppName-install.sh index e96138df5..0ed423d0f 100644 --- a/docs/contribution/templates_install/AppName-install.sh +++ b/docs/contribution/templates_install/AppName-install.sh @@ -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 </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 </opt/myapp/.env # HOST=${LOCAL_IP} # PORT=8000 +# DEBUG=false +# EOF + +# ============================================================================= +# CREATE SYSTEMD SERVICE +# ============================================================================= + +msg_info "Creating Service" +cat </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" diff --git a/docs/contribution/templates_json/AppName.json b/docs/contribution/templates_json/AppName.json index 8d621171c..0b67ce327 100644 --- a/docs/contribution/templates_json/AppName.json +++ b/docs/contribution/templates_json/AppName.json @@ -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" + } + ] }