diff --git a/docs/contribution/AI.md b/docs/contribution/AI.md new file mode 100644 index 000000000..2da59ed8e --- /dev/null +++ b/docs/contribution/AI.md @@ -0,0 +1,868 @@ +# ๐Ÿค– AI Contribution Guidelines for ProxmoxVE + +> **This documentation is intended for all AI assistants (GitHub Copilot, Claude, ChatGPT, etc.) contributing to this project.** + +## ๐ŸŽฏ Core Principles + +### 1. **Maximum Use of `tools.func` Functions** + +We have an extensive library of helper functions. **NEVER** implement your own solutions when a function already exists! + +### 2. **No Pointless Variables** + +Only create variables when they: + +- Are used multiple times +- Improve readability +- Are intended for configuration + +### 3. **Consistent Script Structure** + +All scripts follow an identical structure. Deviations are not acceptable. + +### 4. **Bare-Metal Installation** + +We do **NOT use Docker** for our installation scripts. All applications are installed directly on the system. + +--- + +## ๐Ÿ“ Script Types and Their Structure + +### CT Script (`ct/AppName.sh`) + +```bash +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: AuthorName (GitHubUsername) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://application-url.com + +APP="AppName" +var_tags="${var_tags:-tag1;tag2;tag3}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-8}" +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/appname ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "appname" "YourUsername/YourRepo"; then + msg_info "Stopping Service" + systemctl stop appname + msg_ok "Stopped Service" + + msg_info "Backing up Data" + 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" "tarball" "latest" "/opt/appname" + + # Build steps... + + msg_info "Restoring Data" + cp -r /opt/appname_data_backup/. /opt/appname/data + rm -rf /opt/appname_data_backup + msg_ok "Restored Data" + + msg_info "Starting Service" + systemctl start appname + 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}:PORT${CL}" +``` + +### Install Script (`install/AppName-install.sh`) + +```bash +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: AuthorName (GitHubUsername) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://application-url.com + +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 \ + dependency1 \ + dependency2 +msg_ok "Installed Dependencies" + +# Runtime Setup (ALWAYS use our functions!) +NODE_VERSION="22" setup_nodejs +# or +PG_VERSION="16" setup_postgresql +# or +setup_uv +# etc. + +fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname" + +msg_info "Setting up Application" +cd /opt/appname +# Build/Setup Schritte... +msg_ok "Set up Application" + +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 +ExecStart=/path/to/executable +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now appname +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc +``` + +--- + +## ๐Ÿ”ง Available Helper Functions + +### Release Management + +| Function | Description | Example | +| ----------------------------- | ----------------------------------- | ------------------------------------------------------------- | +| `fetch_and_deploy_gh_release` | Fetches and installs GitHub Release | `fetch_and_deploy_gh_release "app" "owner/repo"` | +| `check_for_gh_release` | Checks for new version | `if check_for_gh_release "app" "YourUsername/YourRepo"; then` | + +**Modes for `fetch_and_deploy_gh_release`:** + +```bash +# Tarball/Source (Standard) +fetch_and_deploy_gh_release "appname" "owner/repo" + +# Binary (.deb) +fetch_and_deploy_gh_release "appname" "owner/repo" "binary" + +# Prebuilt Archive +fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "filename.tar.gz" + +# Single Binary +fetch_and_deploy_gh_release "appname" "owner/repo" "singlefile" "latest" "/opt/appname" "binary-linux-amd64" +``` + +**Clean Install Flag:** + +```bash +CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" +``` + +### Runtime/Language Setup + +| Function | Variable(s) | Example | +| -------------- | ----------------------------- | ---------------------------------------------------- | +| `setup_nodejs` | `NODE_VERSION`, `NODE_MODULE` | `NODE_VERSION="22" setup_nodejs` | +| `setup_uv` | `PYTHON_VERSION` | `PYTHON_VERSION="3.12" setup_uv` | +| `setup_go` | `GO_VERSION` | `GO_VERSION="1.22" setup_go` | +| `setup_rust` | `RUST_VERSION`, `RUST_CRATES` | `RUST_CRATES="monolith" setup_rust` | +| `setup_ruby` | `RUBY_VERSION` | `RUBY_VERSION="3.3" setup_ruby` | +| `setup_java` | `JAVA_VERSION` | `JAVA_VERSION="21" setup_java` | +| `setup_php` | `PHP_VERSION`, `PHP_MODULES` | `PHP_VERSION="8.3" PHP_MODULES="redis,gd" setup_php` | + +### Database Setup + +| Function | Variable(s) | Example | +| --------------------- | ------------------------------------ | ----------------------------------------------------------- | +| `setup_postgresql` | `PG_VERSION`, `PG_MODULES` | `PG_VERSION="16" setup_postgresql` | +| `setup_postgresql_db` | `PG_DB_NAME`, `PG_DB_USER` | `PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db` | +| `setup_mariadb_db` | `MARIADB_DB_NAME`, `MARIADB_DB_USER` | `MARIADB_DB_NAME="mydb" setup_mariadb_db` | +| `setup_mysql` | `MYSQL_VERSION` | `setup_mysql` | +| `setup_mongodb` | `MONGO_VERSION` | `setup_mongodb` | +| `setup_clickhouse` | - | `setup_clickhouse` | + +### Tools & Utilities + +| Function | Description | +| ------------------- | ---------------------------------- | +| `setup_adminer` | Installs Adminer for DB management | +| `setup_composer` | Install PHP Composer | +| `setup_ffmpeg` | Install FFmpeg | +| `setup_imagemagick` | Install ImageMagick | +| `setup_gs` | Install Ghostscript | +| `setup_hwaccel` | Configure hardware acceleration | + +### Helper Utilities + +| Function | Description | Example | +| ----------------------------- | ---------------------------- | ----------------------------------------- | +| `import_local_ip` | Sets `$LOCAL_IP` variable | `import_local_ip` | +| `ensure_dependencies` | Checks/installs dependencies | `ensure_dependencies curl jq` | +| `install_packages_with_retry` | APT install with retry | `install_packages_with_retry nginx redis` | + +--- + +## โŒ Anti-Patterns (NEVER use!) + +### 1. Pointless Variables + +```bash +# โŒ WRONG - unnecessary variables +APP_NAME="myapp" +APP_DIR="/opt/${APP_NAME}" +APP_USER="root" +APP_PORT="3000" +cd $APP_DIR + +# โœ… CORRECT - use directly +cd /opt/myapp +``` + +### 2. Custom Download Logic + +```bash +# โŒ WRONG - custom wget/curl logic +RELEASE=$(curl -s https://api.github.com/repos/YourUsername/YourRepo/releases/latest | jq -r '.tag_name') +wget https://github.com/YourUsername/YourRepo/archive/${RELEASE}.tar.gz +tar -xzf ${RELEASE}.tar.gz +mv repo-${RELEASE} /opt/myapp + +# โœ… CORRECT - use our function +fetch_and_deploy_gh_release "myapp" "YourUsername/YourRepo" "tarball" "latest" "/opt/myapp" +``` + +### 3. Custom Version-Check Logic + +```bash +# โŒ WRONG - custom version check +CURRENT=$(cat /opt/myapp/version.txt) +LATEST=$(curl -s https://api.github.com/repos/YourUsername/YourRepo/releases/latest | jq -r '.tag_name') +if [[ "$CURRENT" != "$LATEST" ]]; then + # update... +fi + +# โœ… CORRECT - use our function +if check_for_gh_release "myapp" "YourUsername/YourRepo"; then + # update... +fi +``` + +### 4. Docker-based Installation + +```bash +# โŒ WRONG - using Docker +docker pull myapp/myapp:latest +docker run -d --name myapp myapp/myapp:latest + +# โœ… CORRECT - Bare-Metal Installation +fetch_and_deploy_gh_release "myapp" "YourUsername/YourRepo" +npm install && npm run build +``` + +### 5. Custom Runtime Installation + +```bash +# โŒ WRONG - custom Node.js installation +curl -fsSL https://deb.nodesource.com/setup_22.x | bash - +apt install -y nodejs + +# โœ… CORRECT - use our function +NODE_VERSION="22" setup_nodejs +``` + +### 6. Redundant echo Statements + +```bash +# โŒ WRONG - custom logging messages +echo "Installing dependencies..." +apt install -y curl +echo "Done!" + +# โœ… CORRECT - use msg_info/msg_ok +msg_info "Installing Dependencies" +$STD apt install -y curl +msg_ok "Installed Dependencies" +``` + +### 7. Missing $STD Usage + +```bash +# โŒ WRONG - apt without $STD +apt install -y nginx + +# โœ… CORRECT - with $STD for silent output +$STD apt install -y nginx +``` + +### 8. Wrapping `tools.func` Functions in msg Blocks + +```bash +# โŒ WRONG - tools.func functions have their own msg_info/msg_ok! +msg_info "Installing Node.js" +NODE_VERSION="22" setup_nodejs +msg_ok "Installed Node.js" + +msg_info "Updating Application" +CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname" +msg_ok "Updated Application" + +# โœ… CORRECT - call directly without msg wrapper +NODE_VERSION="22" setup_nodejs + +CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname" +``` + +**Functions with built-in messages (NEVER wrap in msg blocks):** + +- `fetch_and_deploy_gh_release` +- `check_for_gh_release` +- `setup_nodejs` +- `setup_postgresql` / `setup_postgresql_db` +- `setup_mariadb` / `setup_mariadb_db` +- `setup_mongodb` +- `setup_mysql` +- `setup_ruby` +- `setup_go` +- `setup_java` +- `setup_php` +- `setup_uv` +- `setup_rust` +- `setup_composer` +- `setup_ffmpeg` +- `setup_imagemagick` +- `setup_gs` +- `setup_adminer` +- `setup_hwaccel` + +### 9. Creating Unnecessary System Users + +```bash +# โŒ WRONG - LXC containers run as root, no separate user needed +useradd -m -s /usr/bin/bash appuser +chown -R appuser:appuser /opt/appname +sudo -u appuser npm install + +# โœ… CORRECT - run directly as root +cd /opt/appname +$STD npm install +``` + +### 10. Using `export` in .env Files + +```bash +# โŒ WRONG - export is unnecessary in .env files +cat </opt/appname/.env +export DATABASE_URL=postgres://... +export SECRET_KEY=abc123 +export NODE_ENV=production +EOF + +# โœ… CORRECT - simple KEY=VALUE format (files are sourced with set -a) +cat </opt/appname/.env +DATABASE_URL=postgres://... +SECRET_KEY=abc123 +NODE_ENV=production +EOF +``` + +### 11. Using External Shell Scripts + +```bash +# โŒ WRONG - external script that gets executed +cat <<'EOF' >/opt/appname/install_script.sh +#!/bin/bash +cd /opt/appname +npm install +npm run build +EOF +chmod +x /opt/appname/install_script.sh +$STD bash /opt/appname/install_script.sh +rm -f /opt/appname/install_script.sh + +# โœ… CORRECT - run commands directly +cd /opt/appname +$STD npm install +$STD npm run build +``` + +### 12. Using `sudo` in LXC Containers + +```bash +# โŒ WRONG - sudo is unnecessary in LXC (already root) +sudo -u postgres psql -c "CREATE DATABASE mydb;" +sudo -u appuser npm install + +# โœ… CORRECT - use functions or run directly as root +PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db + +cd /opt/appname +$STD npm install +``` + +### 13. Unnecessary `systemctl daemon-reload` + +```bash +# โŒ WRONG - daemon-reload is only needed when MODIFYING existing services +cat </etc/systemd/system/appname.service +# ... service config ... +EOF +systemctl daemon-reload # Unnecessary for new services! +systemctl enable -q --now appname + +# โœ… CORRECT - new services don't need daemon-reload +cat </etc/systemd/system/appname.service +# ... service config ... +EOF +systemctl enable -q --now appname +``` + +### 14. Creating Custom Credentials Files + +```bash +# โŒ WRONG - custom credentials file is not part of the standard template +msg_info "Saving Credentials" +cat <~/appname.creds +Database User: ${DB_USER} +Database Pass: ${DB_PASS} +EOF +msg_ok "Saved Credentials" + +# โœ… CORRECT - credentials are stored in .env or shown in final message only +# If you use setup_postgresql_db / setup_mariadb_db, a standard ~/[appname].creds is created automatically +``` + +### 15. Wrong Footer Pattern + +```bash +# โŒ WRONG - old cleanup pattern with msg blocks +motd_ssh +customize + +msg_info "Cleaning up" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" + +# โœ… CORRECT - use cleanup_lxc function +motd_ssh +customize +cleanup_lxc +``` + +### 16. Manual Database Creation Instead of Functions + +```bash +# โŒ WRONG - manual database creation +DB_USER="myuser" +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) +$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "CREATE DATABASE mydb WITH OWNER $DB_USER;" +$STD sudo -u postgres psql -d mydb -c "CREATE EXTENSION IF NOT EXISTS postgis;" + +# โœ… CORRECT - use setup_postgresql_db function +# This sets PG_DB_USER, PG_DB_PASS, PG_DB_NAME automatically +PG_DB_NAME="mydb" PG_DB_USER="myuser" PG_DB_EXTENSIONS="postgis" setup_postgresql_db +``` + +### 17. Writing Files Without Heredocs + +```bash +# โŒ WRONG - echo / printf / tee +echo "# Config" > /opt/app/config.yml +echo "port: 3000" >> /opt/app/config.yml + +printf "# Config\nport: 3000\n" > /opt/app/config.yml +cat config.yml | tee /opt/app/config.yml +``` + +```bash +# โœ… CORRECT - always use a single heredoc +cat </opt/app/config.yml +# Config +port: 3000 +EOF +``` + +--- + +## ๐Ÿ“ Important Rules + +### Variable Declarations (CT Script) + +```bash +# Standard declarations (ALWAYS present) +APP="AppName" +var_tags="${var_tags:-tag1;tag2}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-8}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" +``` + +### Update-Script Pattern + +```bash +function update_script() { + header_info + check_container_storage + check_container_resources + + # 1. Check if installation exists + if [[ ! -d /opt/appname ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + # 2. Check for update + if check_for_gh_release "appname" "YourUsername/YourRepo"; then + # 3. Stop service + msg_info "Stopping Service" + systemctl stop appname + msg_ok "Stopped Service" + + # 4. Backup data (if present) + msg_info "Backing up Data" + cp -r /opt/appname/data /opt/appname_data_backup + msg_ok "Backed up Data" + + # 5. Perform clean install + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname" + + # 6. Rebuild (if needed) + cd /opt/appname + $STD npm install + $STD npm run build + + # 7. Restore data + msg_info "Restoring Data" + cp -r /opt/appname_data_backup/. /opt/appname/data + rm -rf /opt/appname_data_backup + msg_ok "Restored Data" + + # 8. Start service + msg_info "Starting Service" + systemctl start appname + msg_ok "Started Service" + msg_ok "Updated successfully!" + fi + exit # IMPORTANT: Always end with exit! +} +``` + +### Systemd Service Pattern + +```bash +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" +``` + +### Installation Script Footer + +```bash +# ALWAYS at the end of the install script: +motd_ssh +customize +cleanup_lxc +``` + +--- + +## ๐Ÿ“– Reference: Good Example Scripts + +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 + +### 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 + +**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 + +--- + +## ๏ฟฝ JSON Metadata Files + +Every application requires a JSON metadata file in `frontend/public/json/.json`. + +### JSON Structure + +```json +{ + "name": "AppName", + "slug": "appname", + "categories": [1], + "date_created": "2026-01-16", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3000, + "documentation": "https://docs.appname.com/", + "website": "https://appname.com/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/appname.webp", + "config_path": "/opt/appname/.env", + "description": "Short description of the application and its purpose.", + "install_methods": [ + { + "type": "default", + "script": "ct/appname.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "Debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} +``` + +### Required Fields + +| Field | Type | Description | +| --------------------- | ------- | -------------------------------------------------- | +| `name` | string | Display name of the application | +| `slug` | string | Lowercase, no spaces, used for filenames | +| `categories` | array | Category ID(s) - see category list below | +| `date_created` | string | Creation date (YYYY-MM-DD) | +| `type` | string | `ct` for container, `vm` for virtual machine | +| `updateable` | boolean | Whether update_script is implemented | +| `privileged` | boolean | Whether container needs privileged mode | +| `interface_port` | number | Primary web interface port (or `null`) | +| `documentation` | string | Link to official docs | +| `website` | string | Link to official website | +| `logo` | string | URL to application logo (preferably selfhst icons) | +| `config_path` | string | Path to main config file (or empty string) | +| `description` | string | Brief description of the application | +| `install_methods` | array | Installation configurations | +| `default_credentials` | object | Default username/password (or null) | +| `notes` | array | Additional notes/warnings | + +### Categories + +| ID | Category | +| --- | ------------------------- | +| 0 | Miscellaneous | +| 1 | Proxmox & Virtualization | +| 2 | Operating Systems | +| 3 | Containers & Docker | +| 4 | Network & Firewall | +| 5 | Adblock & DNS | +| 6 | Authentication & Security | +| 7 | Backup & Recovery | +| 8 | Databases | +| 9 | Monitoring & Analytics | +| 10 | Dashboards & Frontends | +| 11 | Files & Downloads | +| 12 | Documents & Notes | +| 13 | Media & Streaming | +| 14 | \*Arr Suite | +| 15 | NVR & Cameras | +| 16 | IoT & Smart Home | +| 17 | ZigBee, Z-Wave & Matter | +| 18 | MQTT & Messaging | +| 19 | Automation & Scheduling | +| 20 | AI / Coding & Dev-Tools | +| 21 | Webservers & Proxies | +| 22 | Bots & ChatOps | +| 23 | Finance & Budgeting | +| 24 | Gaming & Leisure | +| 25 | Business & ERP | + +### Notes Format + +```json +"notes": [ + { + "text": "Change the default password after first login!", + "type": "warning" + }, + { + "text": "Requires at least 4GB RAM for optimal performance.", + "type": "info" + } +] +``` + +**Note types:** `info`, `warning`, `error` + +### Examples with Credentials + +```json +"default_credentials": { + "username": "admin", + "password": "admin" +} +``` + +Or no credentials: + +```json +"default_credentials": { + "username": null, + "password": null +} +``` + +--- + +## ๐Ÿ” Checklist Before PR Creation + +- [ ] 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. **Test via GitHub** - push to your fork and test with curl (not local bash) + ```bash + bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" + # Wait 10-30 seconds after pushing - GitHub takes time to update files + ``` +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 + +--- + +## ๐Ÿ’ Important: Cherry-Picking Your Files for PR Submission + +โš ๏ธ **CRITICAL**: When you submit your PR, you must use git cherry-pick to send ONLY your 3-4 files! + +Why? Because `setup-fork.sh` modifies 600+ files to update links. If you commit all changes, your PR will be impossible to merge. + +**See**: [README.md - Cherry-Pick Section](README.md#-cherry-pick-submitting-only-your-changes) for complete instructions on: + +- Creating a clean submission branch +- Cherry-picking only your files (ct/myapp.sh, install/myapp-install.sh, frontend/public/json/myapp.json) +- Verifying your PR has only 3 file changes (not 600+) + +**Quick reference**: + +```bash +# Create clean branch from upstream +git fetch upstream +git checkout -b submit/myapp upstream/main + +# Cherry-pick your commit(s) or manually add your 3-4 files +# Then push to your fork and create PR +``` + +--- + +## ๐Ÿ“š Further Documentation + +- [CONTRIBUTING.md](CONTRIBUTING.md) - General contribution guidelines +- [GUIDE.md](GUIDE.md) - Detailed developer documentation +- [HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md) - Complete tools.func reference +- [README.md](README.md) - Cherry-pick guide and workflow instructions +- [../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/CODE-AUDIT.md b/docs/contribution/CODE-AUDIT.md index 17a1ff4a4..d1aedf275 100644 --- a/docs/contribution/CODE-AUDIT.md +++ b/docs/contribution/CODE-AUDIT.md @@ -1,14 +1,41 @@ -
- -
-

Exploring the Scripts and Steps Involved in an Application LXC Installation

+# ๐Ÿงช Code Audit: LXC Script Flow -1) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh): This script collects system parameters. (Also holds the function to update the application.) -2) [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func): Adds user settings and integrates collected information. -3) [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh): Constructs the LXC container. -4) [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), and installs the application. -5) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh) (again): To display the completion message. +This guide explains the current execution flow and what to verify during reviews. -The installation process uses reusable scripts: [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func), [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh), and [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), which are not specific to any particular application. +## Execution Flow (CT + Install) -To gain a better understanding, focus on reviewing [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh). This script contains the commands and configurations for installing and configuring AdGuard Home within the LXC container. +1. `ct/appname.sh` runs on the Proxmox host and sources `misc/build.func`. +2. `build.func` orchestrates prompts, container creation, and invokes the install script. +3. Inside the container, `misc/install.func` exposes helper functions via `$FUNCTIONS_FILE_PATH`. +4. `install/appname-install.sh` performs the application install. +5. The CT script prints the completion message. + +## Audit Checklist + +### CT Script (ct/) + +- Sources `misc/build.func` from `community-scripts/ProxmoxVE/main` (setup-fork.sh updates for forks). +- Uses `check_for_gh_release` + `fetch_and_deploy_gh_release` for updates. +- No Docker-based installs. + +### Install Script (install/) + +- Sources `$FUNCTIONS_FILE_PATH`. +- Uses `tools.func` helpers (setup\_\*). +- Ends with `motd_ssh`, `customize`, `cleanup_lxc`. + +### JSON Metadata + +- File in `frontend/public/json/.json` matches template schema. + +### Testing + +- Test via curl from your fork (CT script only). +- Wait 10-30 seconds after push. + +## References + +- `docs/contribution/templates_ct/AppName.sh` +- `docs/contribution/templates_install/AppName-install.sh` +- `docs/contribution/templates_json/AppName.json` +- `docs/contribution/GUIDE.md` diff --git a/docs/contribution/CONTRIBUTING.md b/docs/contribution/CONTRIBUTING.md index 02eb9d24b..619204378 100644 --- a/docs/contribution/CONTRIBUTING.md +++ b/docs/contribution/CONTRIBUTING.md @@ -81,11 +81,22 @@ git clone https://github.com/yourUserName/ForkName git switch -c your-feature-branch ``` -### 4. Change paths in build.func install.func and AppName.sh +### 4. Run setup-fork.sh to auto-configure your fork -To be able to develop from your own branch you need to change `https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main` to `https://raw.githubusercontent.com/[USER]/[REPOSITORY]/refs/heads/[BRANCH]`. You need to make this change atleast in misc/build.func misc/install.func and in your ct/AppName.sh. This change is only for testing. Before opening a Pull Request you should change this line change all this back to point to `https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main`. +```bash +bash docs/contribution/setup-fork.sh --full +``` -### 4. Commit changes (without build.func and install.func!) +This script automatically: + +- Detects your GitHub username +- Updates ALL curl URLs to point to your fork (for testing) +- Creates `.git-setup-info` with your config +- Backs up all modified files (\*.backup) + +**IMPORTANT**: This modifies 600+ files! Use cherry-pick when submitting your PR (see below). + +### 5. Commit ONLY your new application files ```bash git commit -m "Your commit message" @@ -97,9 +108,66 @@ git commit -m "Your commit message" git push origin your-feature-branch ``` -### 6. Create a Pull Request +### 6. Cherry-Pick: Submit Only Your Files for PR -Open a Pull Request from your feature branch to the main repository branch. You must only include your **$AppName.sh**, **$AppName-install.sh** and **$AppName.json** files in the pull request. +โš ๏ธ **IMPORTANT**: setup-fork.sh modified 600+ files. You MUST only submit your 3 new files! + +See [README.md - Cherry-Pick Guide](README.md#-cherry-pick-submitting-only-your-changes) for step-by-step instructions. + +Quick version: + +```bash +# Create clean branch from upstream +git fetch upstream +git checkout -b submit/myapp upstream/main + +# Copy only your files +cp ../your-work-branch/ct/myapp.sh ct/myapp.sh +cp ../your-work-branch/install/myapp-install.sh install/myapp-install.sh +cp ../your-work-branch/frontend/public/json/myapp.json frontend/public/json/myapp.json + +# Commit and verify +git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json +git commit -m "feat: add MyApp" +git diff upstream/main --name-only # Should show ONLY your 3 files + +# Push and create PR +git push origin submit/myapp +``` + +### 7. Create a Pull Request + +Open a Pull Request from `submit/myapp` โ†’ `community-scripts/ProxmoxVE/main`. + +Verify the PR shows ONLY these 3 files: + +- `ct/myapp.sh` +- `install/myapp-install.sh` +- `frontend/public/json/myapp.json` + +--- + +# ๐Ÿ› ๏ธ Developer Mode & Debugging + +When building or testing scripts, you can use the `dev_mode` variable to enable powerful debugging features. These flags can be combined (comma-separated). + +**Usage**: +```bash +# Example: Run with trace and keep the container even if it fails +dev_mode="trace,keep" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)" +``` + +### Available Flags: + +| Flag | Description | +| :--- | :--- | +| `trace` | Enables `set -x` for maximum verbosity during execution. | +| `keep` | Prevents the container from being deleted if the build fails. | +| `pause` | Pauses execution at key points (e.g., before customization). | +| `breakpoint` | Allows hardcoded `breakpoint` calls in scripts to drop to a shell. | +| `logs` | Saves detailed build logs to `/var/log/community-scripts/`. | +| `dryrun` | Bypasses actual container creation (limited support). | +| `motd` | Forces an update of the Message of the Day (MOTD). | --- diff --git a/docs/contribution/FORK_SETUP.md b/docs/contribution/FORK_SETUP.md index 3fa3ab71c..0a25a30c7 100644 --- a/docs/contribution/FORK_SETUP.md +++ b/docs/contribution/FORK_SETUP.md @@ -10,7 +10,7 @@ git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git cd ProxmoxVE # Run setup script (auto-detects your username from git) -bash setup-fork.sh +bash docs/contribution/setup-fork.sh --full ``` That's it! โœ… @@ -22,64 +22,101 @@ That's it! โœ… The `setup-fork.sh` script automatically: 1. **Detects** your GitHub username from git config -2. **Updates** 22 hardcoded links in documentation to point to your fork -3. **Creates** `.git-setup-info` with recommended git workflows -4. **Backs up** all modified files (*.backup) +2. **Updates ALL hardcoded links** to point to your fork: + - Documentation links pointing to `community-scripts/ProxmoxVE` + - **Curl download URLs** in scripts (e.g., `curl ... github.com/community-scripts/ProxmoxVE/main/...`) +3. **Creates** `.git-setup-info` with your configuration details +4. **Backs up** all modified files (\*.backup for safety) + +### Why Updating Curl Links Matters + +Your scripts contain `curl` commands that download dependencies from GitHub (build.func, tools.func, etc.): + +```bash +# First line of ct/myapp.sh +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +``` + +**WITHOUT setup-fork.sh:** + +- Script URLs still point to `community-scripts/ProxmoxVE/main` +- If you test locally with `bash ct/myapp.sh`, you're testing local files, but the script's curl commands would download from **upstream** repo +- Your modifications aren't actually being tested via the curl commands! โŒ + +**AFTER setup-fork.sh:** + +- Script URLs are updated to `YourUsername/ProxmoxVE/main` +- When you test via curl from GitHub: `bash -c "$(curl ... YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"`, it downloads from **your fork** +- The script's curl commands also point to your fork, so you're actually testing your changes! โœ… +- โฑ๏ธ **Important:** GitHub takes 10-30 seconds to recognize pushed files - wait before testing! + +```bash +# Example: What setup-fork.sh changes + +# BEFORE (points to upstream): +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) + +# AFTER (points to your fork): +source <(curl -fsSL https://raw.githubusercontent.com/john/ProxmoxVE/main/misc/build.func) +``` --- ## Usage ### Auto-Detect (Recommended) + ```bash -bash setup-fork.sh +bash docs/contribution/setup-fork.sh --full ``` + Automatically reads your GitHub username from `git remote origin url` ### Specify Username + ```bash -bash setup-fork.sh john +bash docs/contribution/setup-fork.sh --full john ``` + Updates links to `github.com/john/ProxmoxVE` ### Custom Repository Name + ```bash -bash setup-fork.sh john my-fork +bash docs/contribution/setup-fork.sh --full john my-fork ``` + Updates links to `github.com/john/my-fork` --- ## What Gets Updated? -The script updates these documentation files: -- `docs/CONTRIBUTION_GUIDE.md` (4 links) -- `docs/README.md` (1 link) -- `docs/INDEX.md` (3 links) -- `docs/EXIT_CODES.md` (2 links) -- `docs/DEFAULTS_SYSTEM_GUIDE.md` (2 links) -- `docs/api/README.md` (1 link) -- `docs/APP-ct.md` (1 link) -- `docs/APP-install.md` (1 link) -- `docs/alpine-install.func.md` (2 links) -- `docs/install.func.md` (1 link) -- And code examples in documentation +The script updates hardcoded links in these areas when using `--full`: + +- `ct/`, `install/`, `vm/` scripts +- `misc/` function libraries +- `docs/` (including `docs/contribution/`) +- Code examples in documentation --- ## After Setup 1. **Review changes** + ```bash git diff docs/ ``` 2. **Read git workflow tips** + ```bash cat .git-setup-info ``` 3. **Start contributing** + ```bash git checkout -b feature/my-app # Make your changes... @@ -88,7 +125,7 @@ The script updates these documentation files: 4. **Follow the guide** ```bash - cat docs/CONTRIBUTION_GUIDE.md + cat docs/contribution/GUIDE.md ``` --- @@ -96,6 +133,7 @@ The script updates these documentation files: ## Common Workflows ### Keep Your Fork Updated + ```bash # Add upstream if you haven't already git remote add upstream https://github.com/community-scripts/ProxmoxVE.git @@ -107,6 +145,7 @@ git push origin main ``` ### Create a Feature Branch + ```bash git checkout -b feature/docker-improvements # Make changes... @@ -115,6 +154,7 @@ git push origin feature/docker-improvements ``` ### Sync Before Contributing + ```bash git fetch upstream git rebase upstream/main @@ -127,14 +167,16 @@ git checkout -b feature/my-feature ## Troubleshooting ### "Git is not installed" or "not a git repository" + ```bash # Make sure you cloned the repo first git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git cd ProxmoxVE -bash setup-fork.sh +bash docs/contribution/setup-fork.sh --full ``` ### "Could not auto-detect GitHub username" + ```bash # Your git origin URL isn't set up correctly git remote -v @@ -142,29 +184,32 @@ git remote -v # Fix it: git remote set-url origin https://github.com/YOUR_USERNAME/ProxmoxVE.git -bash setup-fork.sh +bash docs/contribution/setup-fork.sh --full ``` ### "Permission denied" + ```bash # Make script executable -chmod +x setup-fork.sh -bash setup-fork.sh +chmod +x docs/contribution/setup-fork.sh +bash docs/contribution/setup-fork.sh --full ``` ### Reverted Changes by Accident? + ```bash # Backups are created automatically git checkout docs/*.backup # Or just re-run setup-fork.sh +bash docs/contribution/setup-fork.sh --full ``` --- ## Next Steps -1. โœ… Run `bash setup-fork.sh` -2. ๐Ÿ“– Read [docs/CONTRIBUTION_GUIDE.md](docs/CONTRIBUTION_GUIDE.md) +1. โœ… Run `bash docs/contribution/setup-fork.sh --full` +2. ๐Ÿ“– Read [docs/contribution/GUIDE.md](GUIDE.md) 3. ๐Ÿด Choose your contribution path: - **Containers** โ†’ [docs/ct/README.md](docs/ct/README.md) - **Installation** โ†’ [docs/install/README.md](docs/install/README.md) @@ -177,10 +222,10 @@ git checkout docs/*.backup ## Questions? - **Fork Setup Issues?** โ†’ See [Troubleshooting](#troubleshooting) above -- **How to Contribute?** โ†’ [docs/CONTRIBUTION_GUIDE.md](docs/CONTRIBUTION_GUIDE.md) +- **How to Contribute?** โ†’ [docs/contribution/GUIDE.md](GUIDE.md) - **Git Workflows?** โ†’ `cat .git-setup-info` - **Project Structure?** โ†’ [docs/README.md](docs/README.md) --- -**Happy Contributing! ๐Ÿš€** +## Happy Contributing! ๐Ÿš€ diff --git a/docs/contribution/GUIDE.md b/docs/contribution/GUIDE.md index e5a078b00..a014b3cdb 100644 --- a/docs/contribution/GUIDE.md +++ b/docs/contribution/GUIDE.md @@ -38,8 +38,8 @@ git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git cd ProxmoxVE # 3. Run fork setup script (automatically configures everything) -bash setup-fork.sh -# This auto-detects your username and updates all documentation links +bash docs/contribution/setup-fork.sh --full +# --full updates ct/, install/, vm/, docs/, misc/ links for fork testing # 4. Read the git workflow tips cat .git-setup-info @@ -51,28 +51,29 @@ cat .git-setup-info # 1. Create feature branch git checkout -b add/my-awesome-app -# 2. Create application scripts -cp ct/example.sh ct/myapp.sh -cp install/example-install.sh install/myapp-install.sh +# 2. Create application scripts from templates +cp docs/contribution/templates_ct/AppName.sh ct/myapp.sh +cp docs/contribution/templates_install/AppName-install.sh install/myapp-install.sh +cp docs/contribution/templates_json/AppName.json frontend/public/json/myapp.json # 3. Edit your scripts nano ct/myapp.sh nano install/myapp-install.sh +nano frontend/public/json/myapp.json -# 4. Test locally -bash ct/myapp.sh # Will prompt for container creation - -# 5. Commit and push -git add ct/myapp.sh install/myapp-install.sh -git commit -m "feat: add MyApp container" +# 4. Commit and push to your fork +git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json +git commit -m "feat: add MyApp container and install scripts" git push origin add/my-awesome-app -# 6. Open Pull Request on GitHub -# Click: New Pull Request (GitHub will show this automatically) +# 5. Test via curl from your fork (GitHub may take 10-30 seconds) +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" -# 7. Keep your fork updated -git fetch upstream -git rebase upstream/main +# 6. Use cherry-pick to submit only your files (see Cherry-Pick section) +# DO NOT submit the 600+ files modified by setup-fork.sh! + +# 7. Open Pull Request on GitHub +# Create PR from: your-fork/add/my-awesome-app โ†’ community-scripts/ProxmoxVE/main ``` **๐Ÿ’ก Tip**: See `../FORK_SETUP.md` for detailed fork setup and troubleshooting @@ -112,9 +113,9 @@ ProxmoxVE/ โ”‚ โ””โ”€โ”€ alpine-tools.func # Alpine tools โ”‚ โ”œโ”€โ”€ docs/ # ๐Ÿ“š Documentation -โ”‚ โ”œโ”€โ”€ UPDATED_APP-ct.md # Container script guide -โ”‚ โ”œโ”€โ”€ UPDATED_APP-install.md # Install script guide -โ”‚ โ””โ”€โ”€ CONTRIBUTING.md # (This file!) +โ”‚ โ”œโ”€โ”€ ct/DETAILED_GUIDE.md # Container script guide +โ”‚ โ”œโ”€โ”€ install/DETAILED_GUIDE.md # Install script guide +โ”‚ โ””โ”€โ”€ contribution/README.md # Contribution overview โ”‚ โ”œโ”€โ”€ tools/ # ๐Ÿ”ง Proxmox management tools โ”‚ โ””โ”€โ”€ pve/ @@ -137,6 +138,7 @@ Examples: ``` **Rules**: + - Container script name: **Title Case** (PiHole, Docker, NextCloud) - Install script name: **lowercase** with **hyphens** (pihole-install, docker-install) - Must match: `ct/AppName.sh` โ†” `install/appname-install.sh` @@ -156,6 +158,7 @@ Examples: - Ubuntu 20.04 / Debian 11+ on host 2. **Git** installed + ```bash apt-get install -y git ``` @@ -198,32 +201,33 @@ git rebase upstream/main git push origin feat/add-myapp ``` -#### Option B: Local Testing on Proxmox Host +#### Option B: Testing on a Proxmox Host (still via curl) ```bash # 1. SSH into Proxmox host ssh root@192.168.1.100 -# 2. Download your script -curl -O https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/ct/myapp.sh - -# 3. Make it executable -chmod +x myapp.sh - -# 4. Update URLs to your fork -# Edit: curl -s https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/... - -# 5. Run and test -bash myapp.sh - -# 6. If container created successfully, script is working! +# 2. Test via curl from your fork (CT script only) +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" +# โฑ๏ธ Wait 10-30 seconds after pushing - GitHub takes time to update ``` -#### Option C: Docker Testing (Without Proxmox) +> **Note:** Do not edit URLs manually or run install scripts directly. The CT script calls the install script inside the container. + +#### Option C: Using Curl (Recommended for Real Testing) ```bash -# You can test script syntax/functionality locally -# Note: Won't fully test (no Proxmox, no actual container) +# Always test via curl from your fork (GitHub takes 10-30 seconds after push) +git push origin feature/myapp +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" +# This tests the actual GitHub URLs, not local files +``` + +#### Option D: Static Checks (Without Proxmox) + +```bash +# You can validate syntax and linting locally (limited) +# Note: This does NOT replace real Proxmox testing # Run ShellCheck shellcheck ct/myapp.sh @@ -241,18 +245,18 @@ bash -n install/myapp-install.sh ### Step 1: Choose Your Template **For Simple Web Apps** (Node.js, Python, PHP): + ```bash cp ct/example.sh ct/myapp.sh cp install/example-install.sh install/myapp-install.sh ``` -**For Database Apps** (PostgreSQL, MongoDB): -```bash -cp ct/docker.sh ct/myapp.sh # Use Docker container -# OR manual setup for more control -``` +**For Database Apps** (PostgreSQL, MariaDB, MongoDB): + +Use the standard templates and the database helpers from `tools.func` (no Docker). **For Alpine Linux Apps** (lightweight): + ```bash # Use ct/alpine.sh as reference # Edit install script to use Alpine packages (apk not apt) @@ -264,7 +268,7 @@ cp ct/docker.sh ct/myapp.sh # Use Docker container ```bash #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/misc/build.func) # Update these: APP="MyAwesomeApp" # Display name @@ -291,17 +295,19 @@ function update_script() { exit fi - # Get latest version - RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \ - grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}') + if check_for_gh_release "myapp" "owner/repo"; then + msg_info "Stopping Service" + systemctl stop myapp + msg_ok "Stopped Service" - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - msg_info "Updating ${APP} to v${RELEASE}" - # ... update logic ... - echo "${RELEASE}" > /opt/${APP}_version.txt - msg_ok "Updated ${APP}" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}." + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "myapp" "owner/repo" "tarball" "latest" "/opt/myapp" + + # ... update logic (migrations, rebuilds, etc.) ... + + msg_info "Starting Service" + systemctl start myapp + msg_ok "Started Service" + msg_ok "Updated successfully!" fi exit } @@ -317,6 +323,7 @@ echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:PORT${CL}" ``` **Checklist**: + - [ ] APP variable matches filename - [ ] var_tags semicolon-separated (no spaces) - [ ] Realistic CPU/RAM/disk values @@ -345,24 +352,12 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y \ - curl \ - wget \ - git \ build-essential msg_ok "Installed Dependencies" -msg_info "Setting up Node.js" NODE_VERSION="22" setup_nodejs -msg_ok "Node.js installed" -msg_info "Downloading Application" -cd /opt -wget -q "https://github.com/user/repo/releases/download/v1.0.0/myapp.tar.gz" -tar -xzf myapp.tar.gz -rm -f myapp.tar.gz -msg_ok "Application installed" - -echo "1.0.0" > /opt/${APP}_version.txt +fetch_and_deploy_gh_release "myapp" "owner/repo" "tarball" "latest" "/opt/myapp" motd_ssh customize @@ -370,6 +365,7 @@ cleanup_lxc ``` **Checklist**: + - [ ] Functions loaded from `$FUNCTIONS_FILE_PATH` - [ ] All installation phases present (deps, tools, app, config, cleanup) - [ ] Using `$STD` for output suppression @@ -437,26 +433,44 @@ $STD apt-get install -y newdependency # 4. Test thoroughly before committing ``` -### Step 3: Update Update Function (if applicable) +### Step 3: The Standard Update Pattern +The `update_script()` function in `ct/appname.sh` should follow a robust pattern: + +1. **Check for updates**: Use `check_for_gh_release` to skip logic if no new version exists. +2. **Stop services**: Stop all relevant services (`systemctl stop appname`). +3. **Backup existing installation**: Move the old folder (e.g., `mv /opt/app /opt/app_bak`). +4. **Deploy new version**: Use `CLEAN_INSTALL=1 fetch_and_deploy_gh_release`. +5. **Restore configuration**: Copy `.env` or config files back from the backup. +6. **Rebuild/Migrate**: Run `npm install`, `composer install`, or DB migrations. +7. **Start services**: Restart services and cleanup the backup. + +**Example from `ct/bookstack.sh`**: ```bash -# Edit: ct/existingapp.sh โ†’ update_script() - -# 1. Update GitHub API URL if repo changed -RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | ...) - -# 2. Update backup/restore logic (if structure changed) -# 3. Update cleanup paths - -# 4. Test update on existing installation -``` - -### Step 4: Document Your Changes - -```bash -# Add comment at top of script -# Co-Author: YourUsername -# Updated: YYYY-MM-DD - Description of changes +function update_script() { + if check_for_gh_release "bookstack" "BookStackApp/BookStack"; then + msg_info "Stopping Services" + systemctl stop apache2 + + msg_info "Backing up data" + mv /opt/bookstack /opt/bookstack-backup + + fetch_and_deploy_gh_release "bookstack" "BookStackApp/BookStack" "tarball" + + msg_info "Restoring backup" + cp /opt/bookstack-backup/.env /opt/bookstack/.env + # ... restore uploads ... + + msg_info "Configuring" + cd /opt/bookstack + $STD composer install --no-dev + $STD php artisan migrate --force + + systemctl start apache2 + rm -rf /opt/bookstack-backup + msg_ok "Updated successfully!" + fi +} ``` --- @@ -656,27 +670,19 @@ shellcheck install/myapp-install.sh # 1. SSH into Proxmox host ssh root@YOUR_PROXMOX_IP -# 2. Download your script -curl -O https://raw.githubusercontent.com/YOUR_USER/ProxmoxVE/feat/myapp/ct/myapp.sh +# 2. Test via curl from your fork (CT script only) +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" +# โฑ๏ธ Wait 10-30 seconds after pushing - GitHub takes time to update -# 3. Make executable -chmod +x myapp.sh - -# 4. UPDATE URLS IN SCRIPT to point to your fork -sed -i 's|community-scripts|YOUR_USER|g' myapp.sh - -# 5. Run script -bash myapp.sh - -# 6. Test interaction: +# 3. Test interaction: # - Select installation mode # - Confirm settings # - Monitor installation -# 7. Verify container created +# 4. Verify container created pct list | grep myapp -# 8. Log into container and verify app +# 5. Log into container and verify app pct exec 100 bash ``` @@ -697,9 +703,9 @@ pct exec 100 bash # Verify script handles gracefully # Test 4: Update function -# Create initial container +# Create initial container (via curl from fork) # Wait for new release -# Run update: bash ct/myapp.sh +# Test update: bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" # Verify it detects and applies update ``` @@ -774,16 +780,19 @@ Use this template: ```markdown ## Description + Brief description of what this PR adds/fixes ## Type of Change + - [ ] New application (ct/AppName.sh + install/appname-install.sh) - [ ] Update existing application - [ ] Bug fix - [ ] Documentation update -- [ ] Other: _______ +- [ ] Other: **\_\_\_** ## Testing + - [ ] Tested on Proxmox VE 8.x - [ ] Container creation successful - [ ] Application installation successful @@ -792,6 +801,7 @@ Brief description of what this PR adds/fixes - [ ] No temporary files left after installation ## Application Details (for new apps only) + - **App Name**: MyApp - **Source**: https://github.com/app/repo - **Default OS**: Debian 12 @@ -800,9 +810,11 @@ Brief description of what this PR adds/fixes - **Access URL**: http://IP:PORT/path ## Checklist + - [ ] My code follows the style guidelines - [ ] I have performed a self-review -- [ ] I have tested the script locally +- [ ] I have tested the script via curl from my fork (after git push) +- [ ] GitHub had time to update (waited 10-30 seconds) - [ ] ShellCheck shows no critical warnings - [ ] Documentation is accurate and complete - [ ] I have added/updated relevant documentation @@ -811,6 +823,7 @@ Brief description of what this PR adds/fixes ### Step 5: Respond to Review Comments **Maintainers may request changes**: + - Fix syntax/style issues - Add better error handling - Optimize resource usage @@ -922,6 +935,7 @@ pct exec CTID netstat -tlnp | grep LISTEN ### Q: Can I test without a Proxmox system? **A**: Partially. You can verify syntax and ShellCheck compliance locally, but real container testing requires Proxmox. Consider using: + - Proxmox in a VM (VirtualBox/KVM) - Test instances on Hetzner/DigitalOcean - Ask maintainers to test for you @@ -929,6 +943,7 @@ pct exec CTID netstat -tlnp | grep LISTEN ### Q: My update function is very complex - is that OK? **A**: Yes! Update functions can be complex if needed. Just ensure: + - Backup user data before updating - Restore user data after update - Test thoroughly before submitting @@ -937,6 +952,7 @@ pct exec CTID netstat -tlnp | grep LISTEN ### Q: Can I add new dependencies to build.func? **A**: Generally no. build.func is the orchestrator and should remain stable. New functions should go in: + - `tools.func` - Tool installation - `core.func` - Utility functions - `install.func` - Container setup @@ -948,11 +964,13 @@ Ask in an issue first if you're unsure. **A**: You have options: **Option 1**: Use Advanced mode (19-step wizard) + ```bash # Extend advanced_settings() if app needs special vars ``` **Option 2**: Create custom setup menu + ```bash function custom_config() { OPTION=$(whiptail --inputbox "Enter database name:" 8 60) @@ -961,6 +979,7 @@ function custom_config() { ``` **Option 3**: Leave as defaults + documentation + ```bash # In success message: echo "Edit /opt/myapp/config.json to customize settings" @@ -969,9 +988,10 @@ echo "Edit /opt/myapp/config.json to customize settings" ### Q: Can I contribute Windows/macOS/ARM support? **A**: + - **Windows**: Not planned (ProxmoxVE is Linux/Proxmox focused) - **macOS**: Can contribute Docker-based alternatives -- **ARM**: Yes! Many apps work on ARM. Add to vm/pimox-*.sh scripts +- **ARM**: Yes! Many apps work on ARM. Add to vm/pimox-\*.sh scripts --- @@ -995,6 +1015,7 @@ echo "Edit /opt/myapp/config.json to customize settings" ### Report Bugs When reporting bugs, include: + - Which application - What happened (error message) - What you expected @@ -1002,6 +1023,7 @@ When reporting bugs, include: - Container OS and version Example: + ``` Title: pihole-install.sh fails on Alpine 3.20 @@ -1025,6 +1047,7 @@ Error Output: ## Contribution Statistics **ProxmoxVE by the Numbers**: + - ๐ŸŽฏ 40+ applications supported - ๐Ÿ‘ฅ 100+ contributors - ๐Ÿ“Š 10,000+ GitHub stars @@ -1038,6 +1061,7 @@ Error Output: ## Code of Conduct By contributing, you agree to: + - โœ… Be respectful and inclusive - โœ… Follow the style guidelines - โœ… Test your changes thoroughly diff --git a/docs/contribution/HELPER_FUNCTIONS.md b/docs/contribution/HELPER_FUNCTIONS.md index 1b52ce7db..d32ab2474 100644 --- a/docs/contribution/HELPER_FUNCTIONS.md +++ b/docs/contribution/HELPER_FUNCTIONS.md @@ -30,61 +30,79 @@ > โš ๏ธ **Both files are ALWAYS required!** The CT script calls the install script automatically during container creation. +Install scripts are **not** run directly by users; they are invoked by the CT script inside the container. + ### Node.js + PostgreSQL **Koel** - Music streaming with PHP + Node.js + PostgreSQL -| File | Link | +| File | Link | | ----------------- | -------------------------------------------------------- | -| CT (update logic) | [ct/koel.sh](../../ct/koel.sh) | -| Install | [install/koel-install.sh](../../install/koel-install.sh) | +| CT (update logic) | [ct/koel.sh](../../ct/koel.sh) | +| Install | [install/koel-install.sh](../../install/koel-install.sh) | **Actual Budget** - Finance app with npm global install -| File | Link | +| File | Link | | ----------------- | ------------------------------------------------------------------------ | -| CT (update logic) | [ct/actualbudget.sh](../../ct/actualbudget.sh) | -| Install | [install/actualbudget-install.sh](../../install/actualbudget-install.sh) | +| CT (update logic) | [ct/actualbudget.sh](../../ct/actualbudget.sh) | +| Install | [install/actualbudget-install.sh](../../install/actualbudget-install.sh) | ### Python + uv **MeTube** - YouTube downloader with Python uv + Node.js + Deno -| File | Link | +| File | Link | | ----------------- | ------------------------------------------------------------ | -| CT (update logic) | [ct/metube.sh](../../ct/metube.sh) | -| Install | [install/metube-install.sh](../../install/metube-install.sh) | +| CT (update logic) | [ct/metube.sh](../../ct/metube.sh) | +| Install | [install/metube-install.sh](../../install/metube-install.sh) | **Endurain** - Fitness tracker with Python uv + PostgreSQL/PostGIS -| File | Link | +| File | Link | | ----------------- | ---------------------------------------------------------------- | -| CT (update logic) | [ct/endurain.sh](../../ct/endurain.sh) | -| Install | [install/endurain-install.sh](../../install/endurain-install.sh) | +| CT (update logic) | [ct/endurain.sh](../../ct/endurain.sh) | +| Install | [install/endurain-install.sh](../../install/endurain-install.sh) | + +### Java + Gradle + +**BookLore** - Book management with Java 21 + Gradle + MariaDB + Nginx +| File | Link | +| ----------------- | -------------------------------------------------------------- | +| CT (update logic) | [ct/booklore.sh](../../ct/booklore.sh) | +| Install | [install/booklore-install.sh](../../install/booklore-install.sh) | + +### Pnpm + Meilisearch + +**KaraKeep** - Bookmark manager with Pnpm + Meilisearch + Puppeteer +| File | Link | +| ----------------- | -------------------------------------------------------------- | +| CT (update logic) | [ct/karakeep.sh](../../ct/karakeep.sh) | +| Install | [install/karakeep-install.sh](../../install/karakeep-install.sh) | ### PHP + MariaDB/MySQL **Wallabag** - Read-it-later with PHP + MariaDB + Redis + Nginx -| File | Link | +| File | Link | | ----------------- | ---------------------------------------------------------------- | -| CT (update logic) | [ct/wallabag.sh](../../ct/wallabag.sh) | -| Install | [install/wallabag-install.sh](../../install/wallabag-install.sh) | +| CT (update logic) | [ct/wallabag.sh](../../ct/wallabag.sh) | +| Install | [install/wallabag-install.sh](../../install/wallabag-install.sh) | **InvoiceNinja** - Invoicing with PHP + MariaDB + Supervisor -| File | Link | +| File | Link | | ----------------- | ------------------------------------------------------------------------ | -| CT (update logic) | [ct/invoiceninja.sh](../../ct/invoiceninja.sh) | -| Install | [install/invoiceninja-install.sh](../../install/invoiceninja-install.sh) | +| CT (update logic) | [ct/invoiceninja.sh](../../ct/invoiceninja.sh) | +| Install | [install/invoiceninja-install.sh](../../install/invoiceninja-install.sh) | **BookStack** - Wiki/Docs with PHP + MariaDB + Apache -| File | Link | +| File | Link | | ----------------- | ------------------------------------------------------------------ | -| CT (update logic) | [ct/bookstack.sh](../../ct/bookstack.sh) | -| Install | [install/bookstack-install.sh](../../install/bookstack-install.sh) | +| CT (update logic) | [ct/bookstack.sh](../../ct/bookstack.sh) | +| Install | [install/bookstack-install.sh](../../install/bookstack-install.sh) | ### PHP + SQLite (Simple) **Speedtest Tracker** - Speedtest with PHP + SQLite + Nginx -| File | Link | +| File | Link | | ----------------- | ---------------------------------------------------------------------------------- | -| CT (update logic) | [ct/speedtest-tracker.sh](../../ct/speedtest-tracker.sh) | -| Install | [install/speedtest-tracker-install.sh](../../install/speedtest-tracker-install.sh) | +| CT (update logic) | [ct/speedtest-tracker.sh](../../ct/speedtest-tracker.sh) | +| Install | [install/speedtest-tracker-install.sh](../../install/speedtest-tracker-install.sh) | --- @@ -95,7 +113,7 @@ Install Node.js from NodeSource repository. ```bash -# Default (Node.js 22) +# Default (Node.js 24) setup_nodejs # Specific version @@ -135,8 +153,12 @@ $STD cargo build --release Install Python uv package manager (fast pip/venv replacement). ```bash +# Default setup_uv +# Install a specific Python version +PYTHON_VERSION="3.12" setup_uv + # Use in script setup_uv cd /opt/myapp @@ -160,7 +182,7 @@ Install PHP with configurable modules and FPM/Apache support. setup_php # Full configuration -PHP_VERSION="8.3" \ +PHP_VERSION="8.4" \ PHP_MODULE="mysqli,gd,curl,mbstring,xml,zip,ldap" \ PHP_FPM="YES" \ PHP_APACHE="YES" \ @@ -168,12 +190,12 @@ setup_php ``` **Environment Variables:** -| Variable | Default | Description | +| Variable | Default | Description | | ------------- | ------- | ------------------------------- | -| `PHP_VERSION` | `8.3` | PHP version to install | -| `PHP_MODULE` | `""` | Comma-separated list of modules | -| `PHP_FPM` | `NO` | Install PHP-FPM | -| `PHP_APACHE` | `NO` | Install Apache module | +| `PHP_VERSION` | `8.4` | PHP version to install | +| `PHP_MODULE` | `""` | Comma-separated list of modules | +| `PHP_FPM` | `NO` | Install PHP-FPM | +| `PHP_APACHE` | `NO` | Install Apache module | ### `setup_composer` @@ -239,12 +261,12 @@ setup_mysql Install PostgreSQL server. ```bash -# Default (PostgreSQL 17) +# Default (PostgreSQL 16) setup_postgresql # Specific version PG_VERSION="16" setup_postgresql -PG_VERSION="17" setup_postgresql +PG_VERSION="16" setup_postgresql ``` ### `setup_postgresql_db` @@ -279,6 +301,43 @@ setup_clickhouse --- +## Advanced Repository Management + +### `setup_deb822_repo` + +The modern standard (Debian 12+) for adding external repositories. Automatically handles GPG keys and sources. + +```bash +setup_deb822_repo \ + "nodejs" \ + "https://deb.nodesource.com/gpgkey/nodesource.gpg.key" \ + "https://deb.nodesource.com/node_22.x" \ + "bookworm" \ + "main" +``` + +### `prepare_repository_setup` + +A high-level helper that performs three critical tasks before adding a new repo: +1. Cleans up old repo files matching the names provided. +2. Removes old GPG keyrings from all standard locations. +3. Ensures APT is in a working state (fixes locks, runs update). + +```bash +# Clean up old mysql/mariadb artifacts before setup +prepare_repository_setup "mariadb" "mysql" +``` + +### `cleanup_tool_keyrings` + +Force-removes GPG keys for specific tools from `/usr/share/keyrings/`, `/etc/apt/keyrings/`, and `/etc/apt/trusted.gpg.d/`. + +```bash +cleanup_tool_keyrings "docker" "kubernetes" +``` + +--- + ## GitHub Release Helpers > **Note**: `fetch_and_deploy_gh_release` is the **preferred method** for downloading GitHub releases. It handles version tracking automatically. Only use `get_latest_github_release` if you need the version number separately. @@ -302,17 +361,17 @@ CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "la ``` **Parameters:** -| Parameter | Default | Description | +| Parameter | Default | Description | | --------------- | ------------- | ----------------------------------------------------------------- | -| `name` | required | App name (for version tracking) | -| `repo` | required | GitHub repo (`owner/repo`) | -| `type` | `tarball` | Release type: `tarball`, `zipball`, `prebuild`, `binary` | -| `version` | `latest` | Version tag or `latest` | -| `dest` | `/opt/[name]` | Destination directory | -| `asset_pattern` | `""` | For `prebuild`: glob pattern to match asset (e.g. `app-*.tar.gz`) | +| `name` | required | App name (for version tracking) | +| `repo` | required | GitHub repo (`owner/repo`) | +| `type` | `tarball` | Release type: `tarball`, `zipball`, `prebuild`, `binary` | +| `version` | `latest` | Version tag or `latest` | +| `dest` | `/opt/[name]` | Destination directory | +| `asset_pattern` | `""` | For `prebuild`: glob pattern to match asset (e.g. `app-*.tar.gz`) | **Environment Variables:** -| Variable | Description | +| Variable | Description | | ----------------- | ------------------------------------------------------------ | | `CLEAN_INSTALL=1` | Remove destination directory before extracting (for updates) | @@ -339,26 +398,21 @@ RELEASE=$(get_latest_github_release "owner/repo") echo "Latest version: $RELEASE" ``` -# Examples - -fetch_and_deploy_gh_release "bookstack" "BookStackApp/BookStack" -fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/myapp" - -```` - -**Parameters:** -| Parameter | Default | Description | -| --------- | ------------- | -------------------------------------------- | -| `name` | required | App name (for version tracking) | -| `repo` | required | GitHub repo (`owner/repo`) | -| `type` | `tarball` | Release type: `tarball`, `zipball`, `binary` | -| `version` | `latest` | Version tag or `latest` | -| `dest` | `/opt/[name]` | Destination directory | - --- ## Tools & Utilities +### `setup_meilisearch` + +Install Meilisearch, a lightning-fast search engine. + +```bash +setup_meilisearch + +# Use in script +$STD php artisan scout:sync-index-settings +``` + ### `setup_yq` Install yq YAML processor. @@ -434,6 +488,15 @@ create_self_signed_cert ## Utility Functions +### `verify_tool_version` + +Validate that the installed major version matches the expected version. Useful during upgrades or troubleshooting. + +```bash +# Verify Node.js is version 22 +verify_tool_version "nodejs" "22" "$(node -v | grep -oP '^v\K[0-9]+')" +``` + ### `get_lxc_ip` Set the `$LOCAL_IP` variable with the container's IP address. @@ -526,7 +589,7 @@ msg_ok "Installed Dependencies" # Setup runtimes and databases FIRST NODE_VERSION="22" setup_nodejs -PG_VERSION="17" setup_postgresql +PG_VERSION="16" setup_postgresql PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db get_lxc_ip diff --git a/docs/contribution/README.md b/docs/contribution/README.md index fa65ca12d..be1231855 100644 --- a/docs/contribution/README.md +++ b/docs/contribution/README.md @@ -17,7 +17,9 @@ Complete guide to contributing to the ProxmoxVE project - from your first fork t ## ๐Ÿš€ Quick Start -### 60 Seconds to Contributing +### 60 Seconds to Contributing (Development) + +When developing and testing **in your fork**: ```bash # 1. Fork on GitHub @@ -27,8 +29,8 @@ Complete guide to contributing to the ProxmoxVE project - from your first fork t git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git cd ProxmoxVE -# 3. Auto-configure your fork -bash docs/contribution/setup-fork.sh +# 3. Auto-configure your fork (IMPORTANT - updates all links!) +bash docs/contribution/setup-fork.sh --full # 4. Create a feature branch git checkout -b feature/my-awesome-app @@ -39,19 +41,73 @@ cat docs/ct/DETAILED_GUIDE.md # For container scripts cat docs/install/DETAILED_GUIDE.md # For install scripts # 6. Create your contribution -cp ct/example.sh ct/myapp.sh -cp install/example-install.sh install/myapp-install.sh +cp docs/contribution/templates_ct/AppName.sh ct/myapp.sh +cp docs/contribution/templates_install/AppName-install.sh install/myapp-install.sh # ... edit files ... -# 7. Test and commit -bash ct/myapp.sh -git add ct/myapp.sh install/myapp-install.sh -git commit -m "feat: add MyApp" +# 7. Push to your fork and test via GitHub +git push origin feature/my-awesome-app +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" +# โฑ๏ธ GitHub may take 10-30 seconds to update files - be patient! + +# 8. Create your JSON metadata file +cp docs/contribution/templates_json/AppName.json frontend/public/json/myapp.json +# Edit metadata: name, slug, categories, description, resources, etc. + +# 9. No direct install-script test +# Install scripts are executed by the CT script inside the container + +# 10. Commit ONLY your new files (see Cherry-Pick section below!) +git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json +git commit -m "feat: add MyApp container and install scripts" git push origin feature/my-awesome-app -# 8. Create Pull Request on GitHub +# 11. Create Pull Request on GitHub ``` +โš ๏ธ **IMPORTANT: After setup-fork.sh, many files are modified!** + +See the **Cherry-Pick: Submitting Only Your Changes** section below to learn how to push ONLY your 3-4 files instead of 600+ modified files! + +### How Users Run Scripts (After Merged) + +Once your script is merged to the main repository, users download and run it from GitHub like this: + +```bash +# โœ… Users run from GitHub (normal usage after PR merged) +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)" + +# Install scripts are called by the CT script and are not run directly by users +``` + +### Development vs. Production Execution + +**During Development (you, in your fork):** + +```bash +# You MUST test via curl from your GitHub fork (not local files!) +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" + +# The script's curl commands are updated by setup-fork.sh to point to YOUR fork +# This ensures you're testing your actual changes +# โฑ๏ธ Wait 10-30 seconds after pushing - GitHub updates slowly +``` + +**After Merge (users, from GitHub):** + +```bash +# Users download the script from upstream via curl +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)" + +# The script's curl commands now point back to upstream (community-scripts) +# This is the stable, tested version +``` + +**Summary:** + +- **Development**: Push to fork, test via curl โ†’ setup-fork.sh changes curl URLs to your fork +- **Production**: curl | bash from upstream โ†’ curl URLs point to community-scripts repo + --- ## ๐Ÿด Setting Up Your Fork @@ -61,14 +117,35 @@ git push origin feature/my-awesome-app When you clone your fork, run the setup script to automatically configure everything: ```bash -bash docs/contribution/setup-fork.sh +bash docs/contribution/setup-fork.sh --full ``` -This will: +**What it does:** -- Auto-detect your GitHub username -- Update all documentation links to point to your fork -- Create `.git-setup-info` with recommended git workflows +- Auto-detects your GitHub username from git config +- Auto-detects your fork repository name +- Updates **ALL** hardcoded links to point to your fork instead of the main repo (`--full`) +- Creates `.git-setup-info` with your configuration +- Allows you to develop and test independently in your fork + +**Why this matters:** + +Without running this script, all links in your fork will still point to the upstream repository (community-scripts). This is a problem when testing because: + +- Installation links will pull from upstream, not your fork +- Updates will target the wrong repository +- Your contributions won't be properly tested + +**After running setup-fork.sh:** + +Your fork is fully configured and ready to develop. You can: + +- Push changes to your fork +- Test via curl: `bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"` +- All links will reference your fork for development +- โฑ๏ธ Wait 10-30 seconds after pushing - GitHub takes time to update +- Commit and push with confidence +- Create a PR to merge into upstream **See**: [FORK_SETUP.md](FORK_SETUP.md) for detailed instructions @@ -81,11 +158,12 @@ If the script doesn't work, manually configure: git config user.name "Your Name" git config user.email "your.email@example.com" -# Add upstream remote for syncing +# Add upstream remote for syncing with main repo git remote add upstream https://github.com/community-scripts/ProxmoxVE.git # Verify remotes git remote -v +# Should show: origin (your fork) and upstream (main repo) ``` --- @@ -102,7 +180,7 @@ All scripts and configurations must follow our coding standards to ensure consis - **[HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md)** - Reference for all tools.func helper functions - **Container Scripts** - `/ct/` templates and guidelines - **Install Scripts** - `/install/` templates and guidelines -- **JSON Configurations** - `/json/` structure and format +- **JSON Configurations** - `frontend/public/json/` structure and format ### Quick Checklist @@ -112,7 +190,7 @@ All scripts and configurations must follow our coding standards to ensure consis - โœ… Include proper shebang: `#!/usr/bin/env bash` - โœ… Add copyright header with author - โœ… Handle errors properly with `msg_error`, `msg_ok`, etc. -- โœ… Test before submitting PR +- โœ… Test before submitting PR (via curl from your fork, not local bash) - โœ… Update documentation if needed --- @@ -133,7 +211,172 @@ Key points: --- -## ๐Ÿ“š Guides & Resources +## ๐Ÿ’ Cherry-Pick: Submitting Only Your Changes + +**Problem**: `setup-fork.sh` modifies 600+ files to update links. You don't want to submit all of those changes - only your new 3-4 files! + +**Solution**: Use git cherry-pick to select only YOUR files. + +### Step-by-Step Cherry-Pick Guide + +#### 1. Check what changed + +```bash +# See all modified files +git status + +# Verify your files are there +git status | grep -E "ct/myapp|install/myapp|json/myapp" +``` + +#### 2. Create a clean feature branch for submission + +```bash +# Go back to upstream main (clean slate) +git fetch upstream +git checkout -b submit/myapp upstream/main + +# Don't use your modified main branch! +``` + +#### 3. Cherry-pick ONLY your files + +Cherry-picking extracts specific changes from commits: + +```bash +# Option A: Cherry-pick commits that added your files +# (if you committed your files separately) +git cherry-pick + +# Option B: Manually copy and commit only your files +# From your work branch, get the file contents +git show feature/my-awesome-app:ct/myapp.sh > /tmp/myapp.sh +git show feature/my-awesome-app:install/myapp-install.sh > /tmp/myapp-install.sh +git show feature/my-awesome-app:frontend/public/json/myapp.json > /tmp/myapp.json + +# Add them to the clean branch +cp /tmp/myapp.sh ct/myapp.sh +cp /tmp/myapp-install.sh install/myapp-install.sh +cp /tmp/myapp.json frontend/public/json/myapp.json + +# Commit +git add ct/myapp.sh install/myapp-install.sh frontend/public/json/myapp.json +git commit -m "feat: add MyApp" +``` + +#### 4. Verify only your files are in the PR + +```bash +# Check git diff against upstream +git diff upstream/main --name-only +# Should show ONLY: +# ct/myapp.sh +# install/myapp-install.sh +# frontend/public/json/myapp.json +``` + +#### 5. Push and create PR + +```bash +# Push your clean submission branch +git push origin submit/myapp + +# Create PR on GitHub from: submit/myapp โ†’ main +``` + +### Why This Matters + +- โœ… Clean PR with only your changes +- โœ… Easier for maintainers to review +- โœ… Faster merge without conflicts +- โŒ Without cherry-pick: PR has 600+ file changes (won't merge!) + +### If You Made a Mistake + +```bash +# Delete the messy branch +git branch -D submit/myapp + +# Go back to clean branch +git checkout -b submit/myapp upstream/main + +# Try cherry-picking again +``` + +--- + +If you're using **Visual Studio Code** with an AI assistant, you can leverage our detailed guidelines to generate high-quality contributions automatically. + +### How to Use AI Assistance + +1. **Open the AI Guidelines** + + ``` + docs/contribution/AI.md + ``` + + This file contains all requirements, patterns, and examples for writing proper scripts. + +2. **Prepare Your Information** + + Before asking the AI to generate code, gather: + - **Repository URL**: e.g., `https://github.com/owner/myapp` + - **Dockerfile/Script**: Paste the app's installation instructions (if available) + - **Dependencies**: What packages does it need? (Node, Python, Java, PostgreSQL, etc.) + - **Ports**: What port does it listen on? (e.g., 3000, 8080, 5000) + - **Configuration**: Any environment variables or config files? + +3. **Tell the AI Assistant** + + Share with the AI: + - The repository URL + - The Dockerfile or install instructions + - Link to [docs/contribution/AI.md](AI.md) with instructions to follow + + **Example prompt:** + + ``` + I want to contribute a container script for MyApp to ProxmoxVE. + Repository: https://github.com/owner/myapp + + Here's the Dockerfile: + [paste Dockerfile content] + + Please follow the guidelines in docs/contribution/AI.md to create: + 1. ct/myapp.sh (container script) + 2. install/myapp-install.sh (installation script) + 3. frontend/public/json/myapp.json (metadata) + ``` + +4. **AI Will Generate** + + The AI will produce scripts that: + - Follow all ProxmoxVE patterns and conventions + - Use helper functions from `tools.func` correctly + - Include proper error handling and messages + - Have correct update mechanisms + - Are ready to submit as a PR + +### Key Points for AI Assistants + +- **Templates Location**: `docs/contribution/templates_ct/AppName.sh`, `templates_install/`, `templates_json/` +- **Guidelines**: Must follow `docs/contribution/AI.md` exactly +- **Helper Functions**: Use only functions from `misc/tools.func` - never write custom ones +- **Testing**: Always test before submission via curl from your fork + ```bash + bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" + # Wait 10-30 seconds after pushing changes + ``` +- **No Docker**: Container scripts must be bare-metal, not Docker-based + +### Benefits + +- **Speed**: AI generates boilerplate in seconds +- **Consistency**: Follows same patterns as 200+ existing scripts +- **Quality**: Less bugs and more maintainable code +- **Learning**: See how your app should be structured + +--- ### Documentation @@ -221,15 +464,15 @@ git push origin feature/my-feature git rebase upstream/main ``` -2. **Test your changes** +2. **Test your changes** (via curl from your fork) ```bash - bash ct/my-app.sh + bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)" # Follow prompts and test the container + # โฑ๏ธ Wait 10-30 seconds after pushing - GitHub takes time to update ``` 3. **Check code standards** - - [ ] Follows template structure - [ ] Proper error handling - [ ] Documentation updated (if needed) @@ -260,23 +503,66 @@ Before opening a PR: ## โ“ FAQ -### How do I test my changes? +### โŒ Why can't I test with `bash ct/myapp.sh` locally? + +You might try: ```bash -# For container scripts -bash ct/my-app.sh - -# For install scripts (runs inside container) -# The ct script will call it automatically - -# For advanced debugging -VERBOSE=yes bash ct/my-app.sh +# โŒ WRONG - This won't test your actual changes! +bash ct/myapp.sh +./ct/myapp.sh +sh ct/myapp.sh ``` +**Why this fails:** + +- `bash ct/myapp.sh` uses the LOCAL clone file +- The LOCAL file doesn't execute the curl commands - it's already on disk +- The curl URLs INSIDE the script are modified by setup-fork.sh, but they're not executed +- So you can't verify if your curl URLs actually work +- Users will get the curl URL version (which may be broken) + +**Solution:** Always test via curl from GitHub: + +```bash +# โœ… CORRECT - Tests the actual GitHub URLs +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)" +``` + +### โ“ How do I test my changes? + +You **cannot** test locally with `bash ct/myapp.sh` from your cloned directory! + +You **must** push to GitHub and test via curl from your fork: + +```bash +# 1. Push your changes to your fork +git push origin feature/my-awesome-app + +# 2. Test via curl (this loads the script from GitHub, not local files) +bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)" + +# 3. For verbose/debug output, pass environment variables +VERBOSE=yes bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)" +DEV_MODE_LOGS=true bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)" +``` + +**Why?** + +- Local `bash ct/myapp.sh` uses local files from your clone +- But the script's INTERNAL curl commands have been modified by setup-fork.sh to point to your fork +- This discrepancy means you're not actually testing the curl URLs +- Testing via curl ensures the script downloads from YOUR fork GitHub URLs +- โฑ๏ธ **Important:** GitHub takes 10-30 seconds to recognize newly pushed files. Wait before testing! + +**What if local bash worked?** + +You'd be testing local files only, not the actual GitHub URLs that users will download. This means broken curl links wouldn't be caught during testing. + ### What if my PR has conflicts? ```bash -# Sync with upstream +# Sync with upstream main repository git fetch upstream git rebase upstream/main @@ -288,17 +574,27 @@ git push -f origin your-branch ### How do I keep my fork updated? -See "Keep Your Fork Updated" section above, or run: +Two ways: + +**Option 1: Run setup script again** ```bash -bash docs/contribution/setup-fork.sh +bash docs/contribution/setup-fork.sh --full +``` + +**Option 2: Manual sync** + +```bash +git fetch upstream +git rebase upstream/main +git push -f origin main ``` ### Where do I ask questions? - **GitHub Issues**: For bugs and feature requests -- **GitHub Discussions**: For general questions -- **Discord**: Community-scripts server +- **GitHub Discussions**: For general questions and ideas +- **Discord**: Community-scripts server for real-time chat --- @@ -307,7 +603,7 @@ bash docs/contribution/setup-fork.sh ### For First-Time Contributors 1. Read: [docs/README.md](../README.md) - Documentation overview -2. Read: [docs/contribution/FORK_SETUP.md](FORK_SETUP.md) - Fork setup guide +2. Read: [CONTRIBUTING.md](CONTRIBUTING.md) - Essential coding standards 3. Choose your path: - Containers โ†’ [docs/ct/DETAILED_GUIDE.md](../ct/DETAILED_GUIDE.md) - Installation โ†’ [docs/install/DETAILED_GUIDE.md](../install/DETAILED_GUIDE.md) @@ -318,21 +614,24 @@ bash docs/contribution/setup-fork.sh 1. Review [CONTRIBUTING.md](CONTRIBUTING.md) - Coding standards 2. Review [CODE_AUDIT.md](CODE_AUDIT.md) - Audit checklist -3. Check templates in `/ct/` and `/install/` -4. Submit PR with confidence +3. Check templates in `/docs/contribution/templates_*/` +4. Use AI assistants with [AI.md](AI.md) for code generation +5. Submit PR with confidence -### For Reviewers/Maintainers +### For Using AI Assistants -1. Use [CODE_AUDIT.md](CODE_AUDIT.md) as review guide -2. Reference [docs/TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md) for architecture -3. Check [docs/EXIT_CODES.md](../EXIT_CODES.md) for error handling +See "Using AI Assistants" section above for: + +- How to structure prompts +- What information to provide +- How to validate AI output --- ## ๐Ÿš€ Ready to Contribute? 1. **Fork** the repository -2. **Clone** your fork and **setup** with `bash docs/contribution/setup-fork.sh` +2. **Clone** your fork and **setup** with `bash docs/contribution/setup-fork.sh --full` 3. **Choose** your contribution type (container, installation, tools, etc.) 4. **Read** the appropriate detailed guide 5. **Create** your feature branch @@ -345,9 +644,9 @@ bash docs/contribution/setup-fork.sh ## ๐Ÿ“ž Contact & Support -- **GitHub**: https://github.com/community-scripts/ProxmoxVE -- **Issues**: https://github.com/community-scripts/ProxmoxVE/issues -- **Discussions**: https://github.com/community-scripts/ProxmoxVE/discussions +- **GitHub**: [community-scripts/ProxmoxVE](https://github.com/community-scripts/ProxmoxVE) +- **Issues**: [GitHub Issues](https://github.com/community-scripts/ProxmoxVE/issues) +- **Discussions**: [GitHub Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) - **Discord**: [Join Server](https://discord.gg/UHrpNWGwkH) --- diff --git a/docs/contribution/setup-fork.sh b/docs/contribution/setup-fork.sh index f140babb9..5ac54b90c 100644 --- a/docs/contribution/setup-fork.sh +++ b/docs/contribution/setup-fork.sh @@ -8,13 +8,15 @@ # Updates all hardcoded links to point to your fork # # Usage: -# ./setup-fork.sh # Auto-detect from git config -# ./setup-fork.sh YOUR_USERNAME # Specify username -# ./setup-fork.sh YOUR_USERNAME REPO_NAME # Specify both +# ./setup-fork.sh # Auto-detect from git config (updates misc/ only) +# ./setup-fork.sh YOUR_USERNAME # Specify username (updates misc/ only) +# ./setup-fork.sh YOUR_USERNAME REPO_NAME # Specify both (updates misc/ only) +# ./setup-fork.sh --full # Update all files including ct/, install/, vm/, etc. # # Examples: -# ./setup-fork.sh john # Uses john/ProxmoxVE -# ./setup-fork.sh john my-fork # Uses john/my-fork +# ./setup-fork.sh john # Uses john/ProxmoxVE, updates misc/ only +# ./setup-fork.sh john my-fork # Uses john/my-fork, updates misc/ only +# ./setup-fork.sh --full # Auto-detect + update all files ################################################################################ set -e @@ -30,131 +32,136 @@ NC='\033[0m' # No Color REPO_NAME="ProxmoxVE" USERNAME="" AUTO_DETECT=true +UPDATE_ALL=false ################################################################################ # FUNCTIONS ################################################################################ print_header() { - echo -e "\n${BLUE}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" - echo -e "${BLUE}โ•‘${NC} ProxmoxVE Fork Setup Script" - echo -e "${BLUE}โ•‘${NC} Configuring for your fork..." - echo -e "${BLUE}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}\n" + echo -e "\n${BLUE}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" + echo -e "${BLUE}โ•‘${NC} ProxmoxVE Fork Setup Script" + echo -e "${BLUE}โ•‘${NC} Configuring for your fork..." + echo -e "${BLUE}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}\n" } print_info() { - echo -e "${BLUE}โ„น${NC} $1" + echo -e "${BLUE}โ„น${NC} $1" } print_success() { - echo -e "${GREEN}โœ“${NC} $1" + echo -e "${GREEN}โœ“${NC} $1" } print_warning() { - echo -e "${YELLOW}โš ${NC} $1" + echo -e "${YELLOW}โš ${NC} $1" } print_error() { - echo -e "${RED}โœ—${NC} $1" + echo -e "${RED}โœ—${NC} $1" } # Detect username from git remote detect_username() { - local remote_url + local remote_url - # Try to get from origin - if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then - return 1 - fi + # Try to get from origin + if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then + return 1 + fi - # Extract username from SSH or HTTPS URL - if [[ $remote_url =~ git@github.com:([^/]+) ]]; then - echo "${BASH_REMATCH[1]}" - elif [[ $remote_url =~ github.com/([^/]+) ]]; then - echo "${BASH_REMATCH[1]}" - else - return 1 - fi + # Extract username from SSH or HTTPS URL + if [[ $remote_url =~ git@github.com:([^/]+) ]]; then + echo "${BASH_REMATCH[1]}" + elif [[ $remote_url =~ github.com/([^/]+) ]]; then + echo "${BASH_REMATCH[1]}" + else + return 1 + fi } # Detect repo name from git remote detect_repo_name() { - local remote_url + local remote_url - if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then - return 1 - fi + if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then + return 1 + fi - # Extract repo name (remove .git if present) - if [[ $remote_url =~ /([^/]+?)(.git)?$ ]]; then - local repo="${BASH_REMATCH[1]}" - echo "${repo%.git}" - else - return 1 - fi + # Extract repo name (remove .git if present) + if [[ $remote_url =~ /([^/]+?)(.git)?$ ]]; then + local repo="${BASH_REMATCH[1]}" + echo "${repo%.git}" + else + return 1 + fi } # Ask user for confirmation confirm() { - local prompt="$1" - local response + local prompt="$1" + local response - read -p "$(echo -e ${YELLOW})$prompt (y/n)${NC} " -r response - [[ $response =~ ^[Yy]$ ]] + echo -ne "${YELLOW}${prompt} (y/n)${NC} " + read -r response + [[ $response =~ ^[Yy]$ ]] } # Update links in files update_links() { - local old_repo="community-scripts" - local old_name="ProxmoxVE" - local new_owner="$1" - local new_repo="$2" - local files_updated=0 + local old_repo="community-scripts" + local old_name="ProxmoxVE" + local new_owner="$1" + local new_repo="$2" + local files_updated=0 - print_info "Scanning for hardcoded links..." + print_info "Scanning for hardcoded links..." - # Find all markdown and shell files - local -a files_to_update=( - "docs/DEFAULTS_SYSTEM_GUIDE.md" - "docs/alpine-install.func.md" - "docs/install.func.md" - "docs/APP-install.md" - "docs/APP-ct.md" - "docs/CONTRIBUTION_GUIDE.md" - "docs/INDEX.md" - "docs/README.md" - "docs/EXIT_CODES.md" - "docs/api/README.md" - ) + # Change to repo root + local repo_root=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - echo "" + # Determine search path + local search_path="$repo_root/misc" + if [[ "$UPDATE_ALL" == "true" ]]; then + search_path="$repo_root" + print_info "Searching all files (--full mode)" + else + print_info "Searching misc/ directory only (core functions)" + fi - for file in "${files_to_update[@]}"; do - if [[ -f "$file" ]]; then - # Count occurrences - local count=$(grep -c "github.com/$old_repo/$old_name" "$file" 2>/dev/null || echo 0) + echo "" - if [[ $count -gt 0 ]]; then - # Backup original - cp "$file" "$file.backup" + # Find all files containing the old repo reference + while IFS= read -r file; do + # Count occurrences + local count=$(grep -c "github.com/$old_repo/$old_name" "$file" 2>/dev/null || echo 0) - # Replace links - sed -i "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file" + if [[ $count -gt 0 ]]; then + # Backup original + cp "$file" "$file.backup" - ((files_updated++)) - print_success "Updated $file ($count links)" - fi - fi - done + # Replace links - use different sed syntax for BSD/macOS vs GNU sed + if sed --version &>/dev/null 2>&1; then + # GNU sed + sed -i "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file" + else + # BSD sed (macOS) + sed -i '' "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file" + fi - return $files_updated + ((files_updated++)) + print_success "Updated $file ($count links)" + fi + done < <(find "$search_path" -type f \( -name "*.md" -o -name "*.sh" -o -name "*.func" -o -name "*.json" \) -not -path "*/.git/*" 2>/dev/null | xargs grep -l "github.com/$old_repo/$old_name" 2>/dev/null) + + return $files_updated } # Create user git config setup info create_git_setup_info() { - local username="$1" + local username="$1" - cat >.git-setup-info <<'EOF' + cat >.git-setup-info <<'EOF' # Git Configuration for ProxmoxVE Development ## Recommended Git Configuration @@ -213,10 +220,10 @@ git merge upstream/main --- -For more help, see: docs/CONTRIBUTION_GUIDE.md +For more help, see: docs/contribution/README.md EOF - print_success "Created .git-setup-info file" + print_success "Created .git-setup-info file" } ################################################################################ @@ -227,65 +234,79 @@ print_header # Parse command line arguments if [[ $# -gt 0 ]]; then + # Check for --full flag + if [[ "$1" == "--full" ]]; then + UPDATE_ALL=true + AUTO_DETECT=true + shift # Remove --full from arguments + fi + + # Process remaining arguments + if [[ $# -gt 0 ]]; then USERNAME="$1" AUTO_DETECT=false if [[ $# -gt 1 ]]; then - REPO_NAME="$2" + REPO_NAME="$2" fi + fi else - # Try auto-detection - if username=$(detect_username); then - USERNAME="$username" - print_success "Detected GitHub username: $USERNAME" - else - print_error "Could not auto-detect GitHub username from git config" - echo -e "${YELLOW}Please run:${NC}" - echo " ./setup-fork.sh YOUR_USERNAME" - exit 1 - fi + # Try auto-detection + if username=$(detect_username); then + USERNAME="$username" + print_success "Detected GitHub username: $USERNAME" + else + print_error "Could not auto-detect GitHub username from git config" + echo -e "${YELLOW}Please run:${NC}" + echo " ./setup-fork.sh YOUR_USERNAME" + exit 1 + fi - if repo_name=$(detect_repo_name); then - REPO_NAME="$repo_name" - if [[ "$REPO_NAME" != "ProxmoxVE" ]]; then - print_info "Detected custom repo name: $REPO_NAME" - else - print_success "Using default repo name: ProxmoxVE" - fi + if repo_name=$(detect_repo_name); then + REPO_NAME="$repo_name" + if [[ "$REPO_NAME" != "ProxmoxVE" ]]; then + print_info "Detected custom repo name: $REPO_NAME" + else + print_success "Using default repo name: ProxmoxVE" fi + fi fi # Validate inputs if [[ -z "$USERNAME" ]]; then - print_error "Username cannot be empty" - exit 1 + print_error "Username cannot be empty" + exit 1 fi if [[ -z "$REPO_NAME" ]]; then - print_error "Repository name cannot be empty" - exit 1 + print_error "Repository name cannot be empty" + exit 1 fi # Show what we'll do echo -e "${BLUE}Configuration Summary:${NC}" echo " Repository URL: https://github.com/$USERNAME/$REPO_NAME" -echo " Files to update: 10 files with documentation" +if [[ "$UPDATE_ALL" == "true" ]]; then + echo " Files to update: ALL files (ct/, install/, vm/, misc/, docs/, etc.)" +else + echo " Files to update: misc/ directory only (core functions)" +fi echo "" # Ask for confirmation if ! confirm "Apply these changes?"; then - print_warning "Setup cancelled" - exit 0 + print_warning "Setup cancelled" + exit 0 fi echo "" # Update all links if update_links "$USERNAME" "$REPO_NAME"; then - links_changed=$? - print_success "Updated $links_changed files" + links_changed=$? + print_success "Updated $links_changed files" else - print_warning "No links needed updating or some files not found" + print_warning "No links needed updating or some files not found" fi # Create git setup info file @@ -307,7 +328,7 @@ echo -e "${BLUE}Next Steps:${NC}" echo " 1. Review the changes: git diff" echo " 2. Check .git-setup-info for recommended git workflow" echo " 3. Start developing: git checkout -b feature/my-app" -echo " 4. Read: docs/CONTRIBUTION_GUIDE.md" +echo " 4. Read: docs/contribution/README.md" echo "" print_success "Happy contributing! ๐Ÿš€" diff --git a/docs/contribution/templates_ct/AppName.md b/docs/contribution/templates_ct/AppName.md index 7759f1dfb..1739b7976 100644 --- a/docs/contribution/templates_ct/AppName.md +++ b/docs/contribution/templates_ct/AppName.md @@ -1,197 +1,189 @@ -# **AppName.sh Scripts** +# CT Container Scripts - Quick Reference - `AppName.sh` scripts found in the `/ct` directory. These scripts are responsible for the installation of the desired application. For this guide we take `/ct/snipeit.sh` as example. - -## Table of Contents - -- [**AppName.sh Scripts**](#appnamesh-scripts) - - [Table of Contents](#table-of-contents) - - [1. **File Header**](#1-file-header) - - [1.1 **Shebang**](#11-shebang) - - [1.2 **Import Functions**](#12-import-functions) - - [1.3 **Metadata**](#13-metadata) - - [2 **Variables and function import**](#2-variables-and-function-import) - - [2.1 **Default Values**](#21-default-values) - - [2.2 **๐Ÿ“‹ App output \& base settings**](#22--app-output--base-settings) - - [2.3 **๐Ÿ›  Core functions**](#23--core-functions) - - [3 **Update function**](#3-update-function) - - [3.1 **Function Header**](#31-function-header) - - [3.2 **Check APP**](#32-check-app) - - [3.3 **Check version**](#33-check-version) - - [3.4 **Verbosity**](#34-verbosity) - - [3.5 **Backups**](#35-backups) - - [3.6 **Cleanup**](#36-cleanup) - - [3.7 **No update function**](#37-no-update-function) - - [4 **End of the script**](#4-end-of-the-script) - - [5. **Contribution checklist**](#5-contribution-checklist) - -## 1. **File Header** - -### 1.1 **Shebang** - -- Use `#!/usr/bin/env bash` as the shebang. - -```bash -#!/usr/bin/env bash -``` - -### 1.2 **Import Functions** - -- Import the build.func file. -- When developing your own script, change the URL to your own repository. - -> [!IMPORTANT] -> You also need to change all apperances of this URL in `misc/build.func` and `misc/install.func` - -Example for development: - -```bash -source <(curl -fsSL https://raw.githubusercontent.com/[USER]/[REPO]/refs/heads/[BRANCH]/misc/build.func) -``` - -Final script: - -```bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) -``` - -> [!CAUTION] -> Before opening a Pull Request, change the URLs to point to the community-scripts repo. - -### 1.3 **Metadata** - -- Add clear comments for script metadata, including author, copyright, and license information. - -Example: - -```bash -# Copyright (c) 2021-2026 community-scripts ORG -# Author: [YourUserName] -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: [SOURCE_URL] -``` - -> [!NOTE]: +> [!WARNING] +> **This is legacy documentation.** Refer to the **modern template** at [templates_ct/AppName.sh](AppName.sh) for best practices. > -> - Add your username and source URL -> - For existing scripts, add "| Co-Author [YourUserName]" after the current author +> Current templates use: +> +> - `tools.func` helpers instead of manual patterns +> - `check_for_gh_release` and `fetch_and_deploy_gh_release` from build.func +> - Automatic setup-fork.sh configuration --- -## 2 **Variables and function import** -> -> [!NOTE] -> You need to have all this set in your script, otherwise it will not work! +## Before Creating a Script -### 2.1 **Default Values** +1. **Fork & Clone:** -- This section sets the default values for the container. -- `APP` needs to be set to the application name and must be equal to the filenames of your scripts. -- `var_tags`: You can set Tags for the CT wich show up in the Proxmox UI. Donยดt overdo it! + ```bash + git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git + cd ProxmoxVE + ``` ->[!NOTE] ->Description for all Default Values -> ->| Variable | Description | Notes | ->|----------|-------------|-------| ->| `APP` | Application name | Must match ct\AppName.sh | ->| `var_tags` | Proxmox display tags without Spaces, only ; | Limit the number | ->| `var_cpu` | CPU cores | Number of cores | ->| `var_ram` | RAM | In MB | ->| `var_disk` | Disk capacity | In GB | ->| `var_os` | Operating system | alpine, debian, ubuntu | ->| `var_version` | OS version | e.g., 3.20, 11, 12, 20.04 | ->| `var_unprivileged` | Container type | 1 = Unprivileged, 0 = Privileged | +2. **Run setup-fork.sh** (updates all curl URLs to your fork): -Example: + ```bash + bash docs/contribution/setup-fork.sh + ``` + +3. **Copy the Modern Template:** + + ```bash + cp templates_ct/AppName.sh ct/MyApp.sh + # Edit ct/MyApp.sh with your app details + ``` + +4. **Test Your Script (via GitHub):** + + โš ๏ธ **Important:** You must push to GitHub and test via curl, not `bash ct/MyApp.sh`! + + ```bash + # Push your changes to your fork first + git push origin feature/my-awesome-app + + # Then test via curl (this loads from YOUR fork, not local files) + bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)" + ``` + + > ๐Ÿ’ก **Why?** The script's curl commands are modified by setup-fork.sh, but local execution uses local files, not the updated GitHub URLs. Testing via curl ensures your script actually works. + > + > โฑ๏ธ **Note:** GitHub sometimes takes 10-30 seconds to update files. If you don't see your changes, wait and try again. + +5. **Cherry-Pick for PR** (submit ONLY your 3-4 files): + - See [Cherry-Pick Guide](../README.md) for step-by-step git commands + +--- + +## Template Structure + +The modern template includes: + +### Header ```bash -APP="SnipeIT" -var_tags="asset-management;foss" +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +# (Note: setup-fork.sh changes this URL to point to YOUR fork during development) +``` + +### Metadata + +```bash +# Copyright (c) 2021-2026 community-scripts ORG +# Author: YourUsername +# License: MIT +APP="MyApp" +var_tags="app-category;foss" var_cpu="2" var_ram="2048" var_disk="4" -var_os="debian" -var_version="12" +var_os="alpine" +var_version="3.20" var_unprivileged="1" ``` -## 2.2 **๐Ÿ“‹ App output & base settings** +### Core Setup ```bash header_info "$APP" -``` -- `header_info`: Generates ASCII header for APP - -## 2.3 **๐Ÿ›  Core functions** - -```bash variables color catch_errors ``` -- `variables`: Processes input and prepares variables -- `color`: Sets icons, colors, and formatting -- `catch_errors`: Enables error handling +### Update Function ---- - -## 3 **Update function** - -### 3.1 **Function Header** - -- If applicable write a function that updates the application and the OS in the container. -- Each update function starts with the same code: +The modern template provides a standard update pattern: ```bash function update_script() { header_info check_container_storage check_container_resources -``` -### 3.2 **Check APP** - -- Before doing anything update-wise, check if the app is installed in the container. - -Example: - -```bash -if [[ ! -d /opt/snipe-it ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi -``` - -### 3.3 **Check version** - -- Before updating, check if a new version exists. - - We use the `${APPLICATION}_version.txt` file created in `/opt` during the install to compare new versions against the currently installed version. - -Example with a Github Release: - -```bash - RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - msg_info "Updating ${APP} to v${RELEASE}" - #DO UPDATE - else - msg_ok "No update required. ${APP} is already at v${RELEASE}." - fi - exit + # Use tools.func helpers: + check_for_gh_release "myapp" "owner/repo" + fetch_and_deploy_gh_release "myapp" "owner/repo" "tarball" "latest" "/opt/myapp" } ``` +--- + +## Key Patterns + +### Check for Updates (App Repository) + +Use `check_for_gh_release` with the **app repo**: + +```bash +check_for_gh_release "myapp" "owner/repo" +``` + +### Deploy External App + +Use `fetch_and_deploy_gh_release` with the **app repo**: + +```bash +fetch_and_deploy_gh_release "myapp" "owner/repo" +``` + +### Avoid Manual Version Checking + +โŒ OLD (manual): + +```bash +RELEASE=$(curl -fsSL https://api.github.com/repos/myapp/myapp/releases/latest | grep tag_name) +``` + +โœ… NEW (use tools.func): + +```bash +fetch_and_deploy_gh_release "myapp" "owner/repo" +``` + +--- + +## Best Practices + +1. **Use tools.func helpers** - Don't manually curl for versions +2. **Only add app-specific dependencies** - Don't add ca-certificates, curl, gnupg (handled by build.func) +3. **Test via curl from your fork** - Push first, then: `bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)"` +4. **Wait for GitHub to update** - Takes 10-30 seconds after git push +5. **Cherry-pick only YOUR files** - Submit only ct/MyApp.sh, install/MyApp-install.sh, frontend/public/json/myapp.json (3 files) +6. **Verify before PR** - Run `git diff upstream/main --name-only` to confirm only your files changed + +--- + +## Common Update Patterns + +See the [modern template](AppName.sh) and [AI.md](../AI.md) for complete working examples. + +Recent reference scripts with good update functions: + +- [Trip](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/trip.sh) +- [Thingsboard](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/thingsboard.sh) +- [UniFi](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/unifi.sh) + +--- + +## Need Help? + +- **[README.md](../README.md)** - Full contribution workflow +- **[AI.md](../AI.md)** - AI-generated script guidelines +- **[FORK_SETUP.md](../FORK_SETUP.md)** - Why setup-fork.sh is important +- **[Slack Community](https://discord.gg/your-link)** - Ask questions + +```` + ### 3.4 **Verbosity** - Use the appropriate flag (**-q** in the examples) for a command to suppress its output. -Example: + Example: ```bash curl -fsSL unzip -q -``` +```` - If a command does not come with this functionality use `$STD` to suppress it's output. @@ -207,8 +199,8 @@ $STD php artisan config:clear - Backup user data if necessary. - Move all user data back in the directory when the update is finished. ->[!NOTE] ->This is not meant to be a permanent backup +> [!NOTE] +> This is not meant to be a permanent backup Example backup: @@ -227,7 +219,7 @@ Example config restore: ### 3.6 **Cleanup** - Do not forget to remove any temporary files/folders such as zip-files or temporary backups. -Example: + Example: ```bash rm -rf /opt/v${RELEASE}.zip @@ -277,7 +269,7 @@ echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}" ## 5. **Contribution checklist** - [ ] Shebang is correctly set (`#!/usr/bin/env bash`). -- [ ] Correct link to *build.func* +- [ ] Correct link to _build.func_ - [ ] Metadata (author, license) is included at the top. - [ ] Variables follow naming conventions. - [ ] Update function exists. diff --git a/docs/contribution/templates_ct/AppName.sh b/docs/contribution/templates_ct/AppName.sh index a7b7e4641..f8c685fd3 100644 --- a/docs/contribution/templates_ct/AppName.sh +++ b/docs/contribution/templates_ct/AppName.sh @@ -5,89 +5,133 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: [SOURCE_URL e.g. https://github.com/example/app] -# App Default Values +# ============================================================================ +# APP CONFIGURATION +# ============================================================================ +# These values are sent to build.func and define default container resources. +# Users can customize these during installation via the interactive prompts. +# ============================================================================ + APP="[AppName]" -var_tags="${var_tags:-[category]}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-4}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -var_unprivileged="${var_unprivileged:-1}" +var_tags="${var_tags:-[category1];[category2]}" # Max 2 tags, semicolon-separated +var_cpu="${var_cpu:-2}" # CPU cores: 1-4 typical +var_ram="${var_ram:-2048}" # RAM in MB: 512, 1024, 2048, etc. +var_disk="${var_disk:-8}" # Disk in GB: 6, 8, 10, 20 typical +var_os="${var_os:-debian}" # OS: debian, ubuntu, alpine +var_version="${var_version:-13}" # OS Version: 13 (Debian), 24.04 (Ubuntu), 3.21 (Alpine) +var_unprivileged="${var_unprivileged:-1}" # 1=unprivileged (secure), 0=privileged (for Docker/Podman) -# ============================================================================= -# CONFIGURATION GUIDE -# ============================================================================= -# 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_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.) +# ============================================================================ +# INITIALIZATION - These are required in all CT scripts +# ============================================================================ +header_info "$APP" # Display app name and setup header +variables # Initialize build.func variables +color # Load color variables for output +catch_errors # Enable error handling with automatic exit on failure -header_info "$APP" -variables -color -catch_errors +# ============================================================================ +# UPDATE SCRIPT - Called when user selects "Update" from web interface +# ============================================================================ +# This function is triggered by the web interface to update the application. +# It should: +# 1. Check if installation exists +# 2. Check for new GitHub releases +# 3. Stop running services +# 4. Backup critical data +# 5. Deploy new version +# 6. Run post-update commands (migrations, config updates, etc.) +# 7. Restore data if needed +# 8. Start services +# +# Exit with `exit` at the end to prevent container restart. +# ============================================================================ function update_script() { header_info check_container_storage check_container_resources - # Check if installation exists + # Step 1: Verify installation exists if [[ ! -d /opt/[appname] ]]; then msg_error "No ${APP} Installation Found!" exit fi - # 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" + # Step 2: Check if update is available + if check_for_gh_release "[appname]" "YourUsername/YourRepo"; then + + # Step 3: Stop services before update + 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" + # Step 4: Backup critical data before overwriting + 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]" + # Step 5: Download and deploy new version + # CLEAN_INSTALL=1 removes old directory before extracting + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "[appname]" "owner/repo" "tarball" "latest" "/opt/[appname]" - # Restore configuration and data + # Step 6: Run post-update commands (uncomment as needed) + # These examples show common patterns - use what applies to your app: + # + # For Node.js apps: + # msg_info "Installing Dependencies" + # cd /opt/[appname] + # $STD npm ci --production + # msg_ok "Installed Dependencies" + # + # For Python apps: + # msg_info "Installing Dependencies" + # cd /opt/[appname] + # $STD uv sync --frozen + # msg_ok "Installed Dependencies" + # + # For database migrations: + # msg_info "Running Database Migrations" + # cd /opt/[appname] + # $STD npm run migrate + # msg_ok "Ran Database Migrations" + # + # For PHP apps: + # msg_info "Installing Dependencies" + # cd /opt/[appname] + # $STD composer install --no-dev + # msg_ok "Installed Dependencies" + + # Step 7: Restore data from backup 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" - - msg_info "Starting Services" + # Step 8: Restart service with new version + msg_info "Starting Service" systemctl start [appname] - msg_ok "Started Services" - + msg_ok "Started Service" msg_ok "Updated successfully!" fi exit } +# ============================================================================ +# MAIN EXECUTION - Container creation flow +# ============================================================================ +# These are called by build.func and handle the full installation process: +# 1. start - Initialize container creation +# 2. build_container - Execute the install script inside container +# 3. description - Display completion info and access details +# ============================================================================ + start build_container description +# ============================================================================ +# COMPLETION MESSAGE +# ============================================================================ 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}" diff --git a/docs/contribution/templates_install/AppName-install.md b/docs/contribution/templates_install/AppName-install.md index a5b21634e..9d8388734 100644 --- a/docs/contribution/templates_install/AppName-install.md +++ b/docs/contribution/templates_install/AppName-install.md @@ -1,54 +1,195 @@ +# Install Scripts - Quick Reference -# **AppName-install.sh Scripts** +> [!WARNING] +> **This is legacy documentation.** Refer to the **modern template** at [templates_install/AppName-install.sh](AppName-install.sh) for best practices. +> +> Current templates use: +> +> - `tools.func` helpers (setup_nodejs, setup_uv, setup_postgresql_db, etc.) +> - Automatic dependency installation via build.func +> - Standardized environment variable patterns - `AppName-install.sh` scripts found in the `/install` directory. These scripts are responsible for the installation of the application. For this guide we take `/install/snipeit-install.sh` as example. +--- -## Table of Contents +## Before Creating a Script -- [**AppName-install.sh Scripts**](#appname-installsh-scripts) - - [Table of Contents](#table-of-contents) - - [1. **File header**](#1-file-header) - - [1.1 **Shebang**](#11-shebang) - - [1.2 **Comments**](#12-comments) - - [1.3 **Variables and function import**](#13-variables-and-function-import) - - [2. **Variable naming and management**](#2-variable-naming-and-management) - - [2.1 **Naming conventions**](#21-naming-conventions) - - [3. **Dependencies**](#3-dependencies) - - [3.1 **Install all at once**](#31-install-all-at-once) - - [3.2 **Collapse dependencies**](#32-collapse-dependencies) - - [4. **Paths to application files**](#4-paths-to-application-files) - - [5. **Version management**](#5-version-management) - - [5.1 **Install the latest release**](#51-install-the-latest-release) - - [5.2 **Save the version for update checks**](#52-save-the-version-for-update-checks) - - [6. **Input and output management**](#6-input-and-output-management) - - [6.1 **User feedback**](#61-user-feedback) - - [6.2 **Verbosity**](#62-verbosity) - - [7. **String/File Manipulation**](#7-stringfile-manipulation) - - [7.1 **File Manipulation**](#71-file-manipulation) - - [8. **Security practices**](#8-security-practices) - - [8.1 **Password generation**](#81-password-generation) - - [8.2 **File permissions**](#82-file-permissions) - - [9. **Service Configuration**](#9-service-configuration) - - [9.1 **Configuration files**](#91-configuration-files) - - [9.2 **Credential management**](#92-credential-management) - - [9.3 **Enviroment files**](#93-enviroment-files) - - [9.4 **Services**](#94-services) - - [10. **Cleanup**](#10-cleanup) - - [10.1 **Remove temporary files**](#101-remove-temporary-files) - - [10.2 **Autoremove and autoclean**](#102-autoremove-and-autoclean) - - [11. **Best Practices Checklist**](#11-best-practices-checklist) - - [Example: High-Level Script Flow](#example-high-level-script-flow) +1. **Copy the Modern Template:** -## 1. **File header** + ```bash + cp templates_install/AppName-install.sh install/MyApp-install.sh + # Edit install/MyApp-install.sh + ``` -### 1.1 **Shebang** +2. **Key Pattern:** + - CT scripts source build.func and call the install script + - Install scripts use sourced FUNCTIONS_FILE_PATH (via build.func) + - Both scripts work together in the container -- Use `#!/usr/bin/env bash` as the shebang. +3. **Test via GitHub:** + + ```bash + # Push your changes to your fork first + git push origin feature/my-awesome-app + + # Test the CT script via curl (it will call the install script) + bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)" + # โฑ๏ธ Wait 10-30 seconds after pushing - GitHub takes time to update + ``` + +--- + +## Template Structure + +### Header ```bash #!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/install.func) +# (setup-fork.sh modifies this URL to point to YOUR fork during development) ``` +### Dependencies (App-Specific Only) + +```bash +# Don't add: ca-certificates, curl, gnupg, wget, git, jq +# These are handled by build.func +msg_info "Installing dependencies" +$STD apt-get install -y app-specific-deps +msg_ok "Installed dependencies" +``` + +### Runtime Setup + +Use tools.func helpers instead of manual installation: + +```bash +# โœ… NEW (use tools.func): +NODE_VERSION="20" +setup_nodejs +# OR +PYTHON_VERSION="3.12" +setup_uv +# OR +PG_DB_NAME="myapp_db" +PG_DB_USER="myapp" +setup_postgresql_db +``` + +### Service Configuration + +```bash +# Create .env file +msg_info "Configuring MyApp" +cat << EOF > /opt/myapp/.env +DEBUG=false +PORT=8080 +DATABASE_URL=postgresql://... +EOF +msg_ok "Configuration complete" + +# Create systemd service +msg_info "Creating systemd service" +cat << EOF > /etc/systemd/system/myapp.service +[Unit] +Description=MyApp +[Service] +ExecStart=/usr/bin/node /opt/myapp/app.js +[Install] +WantedBy=multi-user.target +EOF +msg_ok "Service created" +``` + +### Finalization + +```bash +msg_info "Finalizing MyApp installation" +systemctl enable --now myapp +motd_ssh +customize +msg_ok "MyApp installation complete" +cleanup_lxc +``` + +--- + +## Key Patterns + +### Avoid Manual Version Checking + +โŒ OLD (manual): + +```bash +RELEASE=$(curl -fsSL https://api.github.com/repos/app/repo/releases/latest | grep tag_name) +wget https://github.com/app/repo/releases/download/$RELEASE/app.tar.gz +``` + +โœ… NEW (use tools.func via CT script's fetch_and_deploy_gh_release): + +```bash +# In CT script, not install script: +fetch_and_deploy_gh_release "myapp" "app/repo" "app.tar.gz" "latest" "/opt/myapp" +``` + +### Database Setup + +```bash +# Use setup_postgresql_db, setup_mysql_db, etc. +PG_DB_NAME="myapp" +PG_DB_USER="myapp" +setup_postgresql_db +``` + +### Node.js Setup + +```bash +NODE_VERSION="20" +setup_nodejs +npm install --no-save +``` + +--- + +## Best Practices + +1. **Only add app-specific dependencies** + - Don't add: ca-certificates, curl, gnupg, wget, git, jq + - These are handled by build.func + +2. **Use tools.func helpers** + - setup_nodejs, setup_python, setup_uv, setup_postgresql_db, setup_mysql_db, etc. + +3. **Don't do version checks in install script** + - Version checking happens in CT script's update_script() + - Install script just installs the latest + +4. **Structure:** + - Dependencies + - Runtime setup (tools.func) + - Deployment (fetch from CT script) + - Configuration files + - Systemd service + - Finalization + +--- + +## Reference Scripts + +See working examples: + +- [Trip](https://github.com/community-scripts/ProxmoxVE/blob/main/install/trip-install.sh) +- [Thingsboard](https://github.com/community-scripts/ProxmoxVE/blob/main/install/thingsboard-install.sh) +- [UniFi](https://github.com/community-scripts/ProxmoxVE/blob/main/install/unifi-install.sh) + +--- + +## Need Help? + +- **[Modern Template](AppName-install.sh)** - Start here +- **[CT Template](../templates_ct/AppName.sh)** - How CT scripts work +- **[README.md](../README.md)** - Full contribution workflow +- **[AI.md](../AI.md)** - AI-generated script guidelines + ### 1.2 **Comments** - Add clear comments for script metadata, including author, copyright, and license information. @@ -189,7 +330,7 @@ msg_ok "Installed Dependencies" ### 6.2 **Verbosity** - Use the appropiate flag (**-q** in the examples) for a command to suppres its output -Example: + Example: ```bash curl -fsSL diff --git a/docs/contribution/templates_install/AppName-install.sh b/docs/contribution/templates_install/AppName-install.sh index 10f62ec37..58134a113 100644 --- a/docs/contribution/templates_install/AppName-install.sh +++ b/docs/contribution/templates_install/AppName-install.sh @@ -5,7 +5,6 @@ # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: [SOURCE_URL e.g. https://github.com/example/app] -# Import Functions and Setup source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 @@ -15,48 +14,51 @@ network_check update_os # ============================================================================= -# DEPENDENCIES +# DEPENDENCIES - Only add app-specific dependencies here! +# Don't add: ca-certificates, curl, gnupg, git, build-essential (handled by build.func) # ============================================================================= -# 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 + libharfbuzz0b \ + fontconfig msg_ok "Installed Dependencies" # ============================================================================= -# HELPER FUNCTIONS FROM tools.func +# SETUP RUNTIMES & DATABASES (if needed) # ============================================================================= -# These functions are available via $FUNCTIONS_FILE_PATH (tools.func) -# Call them with optional environment variables for configuration +# Examples (uncomment as needed): # -# --- 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) +# NODE_VERSION="22" setup_nodejs +# NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs # Installs pnpm +# PYTHON_VERSION="3.13" setup_uv +# JAVA_VERSION="21" setup_java +# GO_VERSION="1.22" setup_go +# PHP_VERSION="8.4" PHP_FPM="YES" setup_php +# setup_postgresql # Server only +# setup_mariadb # Server only +# setup_meilisearch # Search engine # -# --- 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" +# Then set up DB and user (sets $[DB]_DB_PASS): +# PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db +# MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db + +# ============================================================================= +# DOWNLOAD & DEPLOY APPLICATION +# ============================================================================= +# fetch_and_deploy_gh_release modes: +# "tarball" - Source tarball (default if omitted) +# "binary" - .deb package (auto-detects amd64/arm64) +# "prebuild" - Pre-built archive (.tar.gz) +# "singlefile" - Single binary file # +# Examples: +# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "tarball" "latest" "/opt/myapp" +# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "binary" "latest" "/tmp" +# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz" + +fetch_and_deploy_gh_release "[appname]" "owner/repo" "tarball" "latest" "/opt/[appname]" + # --- Tools & Utilities --- # get_lxc_ip # Sets $LOCAL_IP variable (call early!) # setup_ffmpeg # Install FFmpeg with codecs @@ -67,8 +69,11 @@ msg_ok "Installed Dependencies" # create_self_signed_cert # Creates cert in /etc/ssl/[appname]/ # ============================================================================= -# EXAMPLE 1: Node.js Application with PostgreSQL +# EXAMPLES # ============================================================================= +# +# EXAMPLE 1: Node.js Application with PostgreSQL +# --------------------------------------------- # NODE_VERSION="22" setup_nodejs # PG_VERSION="17" setup_postgresql # PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db @@ -84,10 +89,9 @@ msg_ok "Installed Dependencies" # PORT=3000 # EOF # msg_ok "Configured MyApp" - -# ============================================================================= +# # EXAMPLE 2: Python Application with uv -# ============================================================================= +# ------------------------------------ # PYTHON_VERSION="3.13" setup_uv # get_lxc_ip # fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp" @@ -141,7 +145,7 @@ fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/ msg_info "Setting up [AppName]" cd /opt/[appname] -$STD npm ci +# $STD npm ci msg_ok "Setup [AppName]" # ============================================================================= @@ -149,14 +153,25 @@ msg_ok "Setup [AppName]" # ============================================================================= msg_info "Configuring [AppName]" +cd /opt/[appname] + +# Install application dependencies (uncomment as needed): +# $STD npm ci --production # Node.js apps +# $STD uv sync --frozen # Python apps +# $STD composer install --no-dev # PHP apps +# $STD cargo build --release # Rust apps + +# Create .env file if needed: cat </opt/[appname]/.env -HOST=${LOCAL_IP} +# Use import_local_ip to get container IP, or hardcode if building on Proxmox +APP_URL=http://localhost PORT=8080 EOF + msg_ok "Configured [AppName]" # ============================================================================= -# SERVICE CREATION +# CREATE SYSTEMD SERVICE # ============================================================================= msg_info "Creating Service" @@ -182,9 +197,11 @@ msg_ok "Created Service" # ============================================================================= # CLEANUP & FINALIZATION # ============================================================================= +# These are called automatically, but shown here for clarity: +# motd_ssh - Displays service info on SSH login +# customize - Enables optional customizations +# cleanup_lxc - Removes temp files, bash history, logs motd_ssh customize - -# cleanup_lxc handles: apt autoremove, autoclean, temp files, bash history cleanup_lxc 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" + } + ] } diff --git a/docs/contribution/templates_json/AppName.md b/docs/contribution/templates_json/AppName.md index 5b61f5e91..1eb4ed61f 100644 --- a/docs/contribution/templates_json/AppName.md +++ b/docs/contribution/templates_json/AppName.md @@ -1,13 +1,165 @@ -# **AppName.json Files** +# JSON Metadata Files - Quick Reference - `AppName.json` files found in the `/json` directory. These files are used to provide informations for the website. For this guide we take `/json/snipeit.json` as example. +The metadata file (`frontend/public/json/myapp.json`) tells the web interface how to display your application. -## Table of Contents +--- -- [**AppName.json Files**](#appnamejson-files) - - [Table of Contents](#table-of-contents) - - [1. JSON Generator](#1-json-generator) +## Quick Start -## 1. JSON Generator +**Use the JSON Generator Tool:** +[https://community-scripts.github.io/ProxmoxVE/json-editor](https://community-scripts.github.io/ProxmoxVE/json-editor) -Use the [JSON Generator](https://community-scripts.github.io/ProxmoxVE/json-editor) to create this file for your application. +1. Enter application details +2. Generator creates `frontend/public/json/myapp.json` +3. Copy the output to your contribution + +--- + +## File Structure + +```json +{ + "name": "MyApp", + "slug": "myapp", + "categories": [1], + "date_created": "2026-01-18", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 3000, + "documentation": "https://docs.example.com/", + "website": "https://example.com/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/myapp.webp", + "config_path": "/opt/myapp/.env", + "description": "Brief description of what MyApp does", + "install_methods": [ + { + "type": "default", + "script": "ct/myapp.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "Debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "Change the default password after first login!", + "type": "warning" + } + ] +} +``` + +--- + +## Field Reference + +| Field | Required | Example | Notes | +| --------------------- | -------- | ----------------- | ---------------------------------------------- | +| `name` | Yes | "MyApp" | Display name | +| `slug` | Yes | "myapp" | URL-friendly identifier (lowercase, no spaces) | +| `categories` | Yes | [1] | One or more category IDs | +| `date_created` | Yes | "2026-01-18" | Format: YYYY-MM-DD | +| `type` | Yes | "ct" | Container type: "ct" or "vm" | +| `interface_port` | Yes | 3000 | Default web interface port | +| `logo` | No | "https://..." | Logo URL (64px x 64px PNG) | +| `config_path` | Yes | "/opt/myapp/.env" | Main config file location | +| `description` | Yes | "App description" | Brief description (100 chars) | +| `install_methods` | Yes | See below | Installation resources (array) | +| `default_credentials` | No | See below | Optional default login | +| `notes` | No | See below | Additional notes (array) | + +--- + +## Install Methods + +Each installation method specifies resource requirements: + +```json +"install_methods": [ + { + "type": "default", + "script": "ct/myapp.sh", + "resources": { + "cpu": 2, + "ram": 2048, + "hdd": 8, + "os": "Debian", + "version": "13" + } + } +] +``` + +**Resource Defaults:** + +- CPU: Cores (1-8) +- RAM: Megabytes (256-4096) +- Disk: Gigabytes (4-50) + +--- + +## Common Categories + +- `0` Miscellaneous +- `1` Proxmox & Virtualization +- `2` Operating Systems +- `3` Containers & Docker +- `4` Network & Firewall +- `5` Adblock & DNS +- `6` Authentication & Security +- `7` Backup & Recovery +- `8` Databases +- `9` Monitoring & Analytics +- `10` Dashboards & Frontends +- `11` Files & Downloads +- `12` Documents & Notes +- `13` Media & Streaming +- `14` \*Arr Suite +- `15` NVR & Cameras +- `16` IoT & Smart Home +- `17` ZigBee, Z-Wave & Matter +- `18` MQTT & Messaging +- `19` Automation & Scheduling +- `20` AI / Coding & Dev-Tools +- `21` Webservers & Proxies +- `22` Bots & ChatOps +- `23` Finance & Budgeting +- `24` Gaming & Leisure +- `25` Business & ERP + +--- + +## Best Practices + +1. **Use the JSON Generator** - It validates structure +2. **Keep descriptions short** - 100 characters max +3. **Use real resource requirements** - Based on your testing +4. **Include sensible defaults** - Pre-filled in install_methods +5. **Slug must be lowercase** - No spaces, use hyphens + +--- + +## Reference Examples + +See actual examples in the repo: + +- [frontend/public/json/trip.json](https://github.com/community-scripts/ProxmoxVE/blob/main/frontend/public/json/trip.json) +- [frontend/public/json/thingsboard.json](https://github.com/community-scripts/ProxmoxVE/blob/main/frontend/public/json/thingsboard.json) +- [frontend/public/json/unifi.json](https://github.com/community-scripts/ProxmoxVE/blob/main/frontend/public/json/unifi.json) + +--- + +## Need Help? + +- **[JSON Generator](https://community-scripts.github.io/ProxmoxVE/json-editor)** - Interactive tool +- **[README.md](../README.md)** - Full contribution workflow +- **[Quick Start](../README.md)** - Step-by-step guide diff --git a/docs/guides/CONFIGURATION_REFERENCE.md b/docs/guides/CONFIGURATION_REFERENCE.md index afc5f6ac7..74728d3b2 100644 --- a/docs/guides/CONFIGURATION_REFERENCE.md +++ b/docs/guides/CONFIGURATION_REFERENCE.md @@ -539,6 +539,69 @@ var_nesting=0 # Nested containers disabled --- +### var_diagnostics + +**Type:** Boolean (yes or no) +**Default:** `yes` +**Description:** Determines if anonymous telemetry and diagnostic data is sent to Community-Scripts API. + +```bash +var_diagnostics=yes # Allow telemetry (helps us improve scripts) +var_diagnostics=no # Disable all telemetry +``` + +**Privacy & Usage:** +- Data is strictly anonymous (random session ID) +- Reports success/failure of installations +- Maps error codes (e.g., APT lock, out of RAM) +- No user-specific data, hostnames, or secret keys are ever sent + +--- + +### var_gpu + +**Type:** Boolean/Toggle +**Options:** `yes` or `no` +**Default:** `no` +**Description:** Enable GPU passthrough for the container. + +```bash +var_gpu=yes # Enable GPU passthrough (auto-detect) +var_gpu=no # Disable GPU passthrough (default) +``` + +**Features enabled:** +- Auto-detects Intel (QuickSync), NVIDIA, and AMD GPUs +- Passes through `/dev/dri` and render nodes +- Configures appropriate container permissions +- Crucial for media servers (Plex, Jellyfin, Immich) + +**Prerequisites:** +- Host drivers installed correctly +- Hardware present and visible to Proxmox +- IOMMU enabled (for some configurations) + +--- + +### var_tun + +**Type:** Boolean/Toggle +**Options:** `yes` or `no` +**Default:** `no` +**Description:** Enable TUN/TAP device support. + +```bash +var_tun=yes # Enable TUN/TAP support +var_tun=no # Disable TUN/TAP support (default) +``` + +**Required for:** +- VPN software (WireGuard, OpenVPN) +- Network tunneling (Tailscale, ZeroTier) +- Custom network bridges + +--- + ### var_keyctl **Type:** Boolean (0 or 1) @@ -560,13 +623,14 @@ var_keyctl=0 # Keyctl disabled ### var_fuse -**Type:** Boolean (0 or 1) -**Default:** `0` +**Type:** Boolean/Toggle +**Options:** `yes` or `no` +**Default:** `no` **Description:** Enable FUSE filesystem support. ```bash -var_fuse=1 # FUSE enabled -var_fuse=0 # FUSE disabled +var_fuse=yes # FUSE enabled +var_fuse=no # FUSE disabled ``` **Required for:** diff --git a/docs/guides/UNATTENDED_DEPLOYMENTS.md b/docs/guides/UNATTENDED_DEPLOYMENTS.md index ff41fbd21..d1b7e7463 100644 --- a/docs/guides/UNATTENDED_DEPLOYMENTS.md +++ b/docs/guides/UNATTENDED_DEPLOYMENTS.md @@ -57,7 +57,7 @@ pveversion ### 2. Network Connectivity ```bash # Test GitHub access -curl -I https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh +curl -I https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh # Test internet connectivity ping -c 1 1.1.1.1 @@ -108,6 +108,8 @@ var_cpu=4 \ var_ram=4096 \ var_disk=30 \ var_hostname=production-app \ +var_os=debian \ +var_version=13 \ var_brg=vmbr0 \ var_net=dhcp \ var_ipv6_method=none \ @@ -117,7 +119,7 @@ var_nesting=1 \ var_tags=production,automated \ var_protection=yes \ var_verbose=no \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)" echo "โœ“ Container deployed successfully" ``` @@ -151,7 +153,7 @@ var_gateway=192.168.1.1 \ **Step 1: Create defaults once (interactive)** ```bash -bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/pihole.sh)" +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/pihole.sh)" # Select "Advanced Settings" โ†’ Configure โ†’ Save as "App Defaults" ``` @@ -161,10 +163,30 @@ bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/Proxmo # deploy-with-defaults.sh # App defaults are loaded automatically -bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/pihole.sh)" +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/pihole.sh)" # Script will use /usr/local/community-scripts/defaults/pihole.vars ``` +### Advanced Configuration Variables + +Beyond the basic resource settings, you can control advanced container features: + +| Variable | Description | Options | +|----------|-------------|---------| +| `var_os` | Operating system template | `debian`, `ubuntu`, `alpine` | +| `var_version` | OS version | `12`, `13` (Debian), `22.04`, `24.04` (Ubuntu) | +| `var_gpu` | Enable GPU passthrough | `yes`, `no` (Default: `no`) | +| `var_tun` | Enable TUN/TAP device | `yes`, `no` (Default: `no`) | +| `var_nesting` | Enable nesting | `1`, `0` (Default: `1`) | + +**Example with GPU and TUN:** +```bash +var_gpu=yes \ +var_tun=yes \ +var_hostname=transcoder \ + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/plex.sh)" +``` + --- ## Batch Deployments @@ -177,14 +199,14 @@ bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/Proxmo #!/bin/bash # batch-deploy-simple.sh -apps=("debian" "ubuntu" "alpine") +apps=("thingsboard" "qui" "flatnotes") for app in "${apps[@]}"; do echo "Deploying $app..." - var_hostname="$app-container" \ + var_hostname="$app-server" \ var_cpu=2 \ var_ram=2048 \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)" echo "โœ“ $app deployed" sleep 5 # Wait between deployments @@ -198,10 +220,10 @@ done # batch-deploy-advanced.sh - Deploy multiple containers with individual configs declare -A CONTAINERS=( - ["pihole"]="2:1024:8:vmbr0:dns,network" - ["homeassistant"]="4:4096:20:vmbr0:automation,ha" - ["docker"]="6:8192:50:vmbr1:containers,docker" - ["nginx"]="2:2048:10:vmbr0:webserver,proxy" + ["beszel"]="1:512:8:vmbr0:monitoring" + ["qui"]="2:1024:10:vmbr0:torrent,ui" + ["thingsboard"]="6:8192:50:vmbr1:iot,industrial" + ["dockge"]="2:2048:10:vmbr0:docker,management" ) for app in "${!CONTAINERS[@]}"; do @@ -228,7 +250,7 @@ for app in "${!CONTAINERS[@]}"; do var_ipv6_method=none \ var_ssh=yes \ var_tags="$tags,automated" \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)" 2>&1 | tee "deploy-${app}.log" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)" 2>&1 | tee "deploy-${app}.log" if [ $? -eq 0 ]; then echo "โœ“ $app deployed successfully" @@ -263,7 +285,7 @@ deploy_container() { var_disk="$disk" \ var_hostname="$app" \ var_net=dhcp \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)" \ + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)" \ &> "deploy-${app}.log" echo "[$app] โœ“ Completed" @@ -294,7 +316,7 @@ echo "All deployments complete!" ```yaml --- # playbook-proxmox.yml -- name: Deploy ProxmoxVED Containers +- name: Deploy ProxmoxVE Containers hosts: proxmox_hosts become: yes tasks: @@ -308,7 +330,7 @@ echo "All deployments complete!" var_net=dhcp \ var_ssh=yes \ var_tags=ansible,automated \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)" args: executable: /bin/bash register: deploy_result @@ -365,7 +387,7 @@ echo "All deployments complete!" var_ssh=yes \ var_ssh_authorized_key="{{ ssh_key }}" \ var_tags="{{ item.tags }},ansible" \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/{{ item.name }}.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/{{ item.name }}.sh)" args: executable: /bin/bash loop: "{{ containers }}" @@ -417,7 +439,7 @@ resource "null_resource" "deploy_container" { "var_disk=${each.value.disk}", "var_hostname=${each.key}", "var_net=dhcp", - "bash -c \"$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${each.value.template}.sh)\"" + "bash -c \"$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${each.value.template}.sh)\"" ] connection { @@ -498,7 +520,7 @@ jobs: var_net=dhcp \ var_ssh=yes \ var_tags=ci-cd,automated \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${{ github.event.inputs.container_type }}.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${{ github.event.inputs.container_type }}.sh)" - name: Notify deployment status if: success() @@ -532,7 +554,7 @@ deploy_container: var_hostname=gitlab-ci-container \ var_net=dhcp \ var_tags=gitlab-ci,automated \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)" EOF only: - main @@ -564,7 +586,7 @@ deploy_container() { var_hostname="$HOSTNAME" \ var_net=dhcp \ var_ssh=yes \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${APP}.sh)" 2>&1 | tee deploy.log + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${APP}.sh)" 2>&1 | tee deploy.log return ${PIPESTATUS[0]} } @@ -656,7 +678,7 @@ deploy() { var_hostname="$HOSTNAME" \ var_cpu=4 \ var_ram=4096 \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${APP}.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${APP}.sh)" return $? } @@ -759,7 +781,7 @@ deploy_secure() { var_protection=yes \ var_tags=production,secure,automated \ var_verbose=no \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${APP}.sh)" 2>&1 | tee -a "$LOG_FILE" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${APP}.sh)" 2>&1 | tee -a "$LOG_FILE" if [ ${PIPESTATUS[0]} -eq 0 ]; then log "โœ“ Deployment successful" @@ -824,7 +846,7 @@ SSH_KEYS=$(load_ssh_keys) var_ssh=yes \ var_ssh_authorized_key="$SSH_KEYS" \ var_hostname=multi-key-server \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)" ``` --- @@ -903,7 +925,7 @@ deploy_from_config() { var_ssh=yes \ var_tags="$tags,automated" \ var_protection=yes \ - bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)" + bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)" if [ $? -eq 0 ]; then log_success "Deployed: $name" diff --git a/docs/contribution/USER_SUBMITTED_GUIDES.md b/docs/guides/USER_SUBMITTED_GUIDES.md similarity index 100% rename from docs/contribution/USER_SUBMITTED_GUIDES.md rename to docs/guides/USER_SUBMITTED_GUIDES.md diff --git a/docs/misc/api.func/API_FUNCTIONS_REFERENCE.md b/docs/misc/api.func/API_FUNCTIONS_REFERENCE.md index 732261f49..98477ad87 100644 --- a/docs/misc/api.func/API_FUNCTIONS_REFERENCE.md +++ b/docs/misc/api.func/API_FUNCTIONS_REFERENCE.md @@ -56,7 +56,7 @@ get_error_description 255 # "Unknown critical error, often due to missing perm - `DIAGNOSTICS` must be set to "yes" - `RANDOM_UUID` must be set and not empty -**API Endpoint**: `http://api.community-scripts.org/dev/upload` +**API Endpoint**: `https://api.community-scripts.org/dev/upload` **JSON Payload Structure**: ```json @@ -110,7 +110,7 @@ post_to_api - `curl` command must be available - `RANDOM_UUID` must be set and not empty -**API Endpoint**: `http://api.community-scripts.org/dev/upload` +**API Endpoint**: `https://api.community-scripts.org/dev/upload` **JSON Payload Structure**: ```json @@ -167,7 +167,7 @@ post_to_api_vm - `RANDOM_UUID` must be set and not empty - POST_UPDATE_DONE must be false (prevents duplicates) -**API Endpoint**: `http://api.community-scripts.org/dev/upload/updatestatus` +**API Endpoint**: `https://api.community-scripts.org/dev/upload/updatestatus` **JSON Payload Structure**: ```json diff --git a/docs/misc/api.func/API_USAGE_EXAMPLES.md b/docs/misc/api.func/API_USAGE_EXAMPLES.md index 616ebc927..c8f6a5cdc 100644 --- a/docs/misc/api.func/API_USAGE_EXAMPLES.md +++ b/docs/misc/api.func/API_USAGE_EXAMPLES.md @@ -461,7 +461,7 @@ check_api_health() { echo "Error description test: $test_error" # Test API connectivity (without sending data) - local api_url="http://api.community-scripts.org/dev/upload" + local api_url="https://api.community-scripts.org/dev/upload" if curl -s --head "$api_url" >/dev/null 2>&1; then echo "API endpoint is reachable" else diff --git a/docs/misc/build.func/BUILD_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/build.func/BUILD_FUNC_FUNCTIONS_REFERENCE.md index 5782ac28b..2e605e085 100644 --- a/docs/misc/build.func/BUILD_FUNC_FUNCTIONS_REFERENCE.md +++ b/docs/misc/build.func/BUILD_FUNC_FUNCTIONS_REFERENCE.md @@ -438,6 +438,34 @@ default_var_settings() # Save global defaults maybe_offer_save_app_defaults() # Save app defaults ``` +### Container Resource & ID Management + +#### `validate_container_id()` +**Purpose**: Validates if a container ID is available for use. +**Parameters**: `ctid` (Integer) +**Returns**: `0` if available, `1` if already in use or invalid. +**Description**: Checks for existing config files in `/etc/pve/lxc/` or `/etc/pve/qemu-server/`, and verifies LVM logical volumes. + +#### `get_valid_container_id()` +**Purpose**: Returns the next available, unused container ID. +**Parameters**: `suggested_id` (Optional) +**Returns**: A valid container ID string. +**Description**: If the suggested ID is taken, it increments until it finds an available one. + +#### `maxkeys_check()` +**Purpose**: Ensures host kernel parameters support high numbers of keys (required for some apps). +**Parameters**: None +**Description**: Checks and optionally updates `kernel.keys.maxkeys` and `kernel.keys.maxbytes`. + +#### `get_current_ip()` +**Purpose**: Retrieves the current IP address of the container. +**Parameters**: `ctid` (Integer) +**Returns**: IP address string. + +#### `update_motd_ip()` +**Purpose**: Updates the Message of the Day (MOTD) file with the container's IP. +**Parameters**: None + ## Function Error Handling ### Validation Functions diff --git a/docs/misc/build.func/BUILD_FUNC_USAGE_EXAMPLES.md b/docs/misc/build.func/BUILD_FUNC_USAGE_EXAMPLES.md index b5ad83d6e..299b2be71 100644 --- a/docs/misc/build.func/BUILD_FUNC_USAGE_EXAMPLES.md +++ b/docs/misc/build.func/BUILD_FUNC_USAGE_EXAMPLES.md @@ -60,10 +60,10 @@ export var_gateway="192.168.1.1" export var_ip="192.168.1.101" export var_vlan="100" export var_mtu="9000" -export var_template_storage="nfs-storage" +export var_template_storage="ssd-storage" export var_container_storage="ssd-storage" -export ENABLE_FUSE="true" -export ENABLE_TUN="true" +export var_fuse="yes" +export var_tun="yes" export SSH="true" # Execute build.func diff --git a/docs/misc/tools.func/TOOLS_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/tools.func/TOOLS_FUNC_FUNCTIONS_REFERENCE.md index 361af06c8..029095568 100644 --- a/docs/misc/tools.func/TOOLS_FUNC_FUNCTIONS_REFERENCE.md +++ b/docs/misc/tools.func/TOOLS_FUNC_FUNCTIONS_REFERENCE.md @@ -20,14 +20,19 @@ Complete alphabetical reference of all functions in tools.func with parameters, - `setup_nodejs(VERSION)` - Install Node.js and npm - `setup_php(VERSION)` - Install PHP-FPM and CLI - `setup_python(VERSION)` - Install Python 3 with pip +- `setup_uv()` - Install Python uv (modern & fast) - `setup_ruby(VERSION)` - Install Ruby with gem - `setup_golang(VERSION)` - Install Go programming language +- `setup_java(VERSION)` - Install OpenJDK (Adoptium) **Databases**: -- `setup_mariadb()` - Install MariaDB server (distro packages by default) +- `setup_mariadb()` - Install MariaDB server +- `setup_mariadb_db()` - Create user/db in MariaDB - `setup_postgresql(VERSION)` - Install PostgreSQL +- `setup_postgresql_db()` - Create user/db in PostgreSQL - `setup_mongodb(VERSION)` - Install MongoDB - `setup_redis(VERSION)` - Install Redis cache +- `setup_meilisearch()` - Install Meilisearch engine **Web Servers**: - `setup_nginx()` - Install Nginx @@ -44,6 +49,7 @@ Complete alphabetical reference of all functions in tools.func with parameters, - `setup_docker_compose()` - Install Docker Compose - `setup_composer()` - Install PHP Composer - `setup_build_tools()` - Install build-essential +- `setup_yq()` - Install mikefarah/yq processor **Monitoring**: - `setup_grafana()` - Install Grafana @@ -60,13 +66,13 @@ Complete alphabetical reference of all functions in tools.func with parameters, ## Core Functions -### pkg_install() +### install_packages_with_retry() -Install one or more packages safely with automatic retry logic and error handling. +Install one or more packages safely with automatic retry logic (3 attempts), APT refresh, and lock handling. **Signature**: ```bash -pkg_install PACKAGE1 [PACKAGE2 ...] +install_packages_with_retry PACKAGE1 [PACKAGE2 ...] ``` **Parameters**: @@ -74,66 +80,122 @@ pkg_install PACKAGE1 [PACKAGE2 ...] **Returns**: - `0` - All packages installed successfully -- `1` - Installation failed after retries +- `1` - Installation failed after all retries + +**Features**: +- Automatically sets `DEBIAN_FRONTEND=noninteractive` +- Handles DPKG lock errors with `dpkg --configure -a` +- Retries on transient network or APT failures + +**Example**: +```bash +install_packages_with_retry curl wget git +``` + +--- + +### upgrade_packages_with_retry() + +Upgrades installed packages with the same robust retry logic as the installation helper. + +**Signature**: +```bash +upgrade_packages_with_retry +``` + +**Returns**: +- `0` - Upgrade successful +- `1` - Upgrade failed + +--- + +### fetch_and_deploy_gh_release() + +The primary tool for downloading and installing software from GitHub Releases. Supports binaries, tarballs, and Debian packages. + +**Signature**: +```bash +fetch_and_deploy_gh_release APPREPO TYPE [VERSION] [DEST] [ASSET_PATTERN] +``` **Environment Variables**: -- `$STD` - Output suppression (`silent` or empty) +- `APPREPO`: GitHub repository (e.g., `owner/repo`) +- `TYPE`: Asset type (`binary`, `tarball`, `prebuild`, `singlefile`) +- `VERSION`: Specific tag or `latest` (Default: `latest`) +- `DEST`: Target directory (Default: `/opt/$APP`) +- `ASSET_PATTERN`: Regex or string pattern to match the release asset (Required for `prebuild` and `singlefile`) + +**Supported Operation Modes**: +- `tarball`: Downloads and extracts the source tarball. +- `binary`: Detects host architecture and installs a `.deb` package using `apt` or `dpkg`. +- `prebuild`: Downloads and extracts a pre-built binary archive (supports `.tar.gz`, `.zip`, `.tgz`, `.txz`). +- `singlefile`: Downloads a single binary file to the destination. + +**Environment Variables**: +- `CLEAN_INSTALL=1`: Removes all contents of the destination directory before extraction. +- `DPKG_FORCE_CONFOLD=1`: Forces `dpkg` to keep old config files during package updates. +- `SYSTEMD_OFFLINE=1`: Used automatically for `.deb` installs to prevent systemd-tmpfiles failures in unprivileged containers. **Example**: ```bash -pkg_install curl wget git +fetch_and_deploy_gh_release "muesli/duf" "binary" "latest" "/opt/duf" "duf_.*_linux_amd64.tar.gz" ``` --- -### pkg_update() +### check_for_gh_release() -Update package lists with automatic retry logic for network failures. +Checks if a newer version is available on GitHub compared to the installed version. **Signature**: ```bash -pkg_update +check_for_gh_release APP REPO ``` -**Parameters**: None - -**Returns**: -- `0` - Package lists updated -- `1` - Failed after 3 retries - **Example**: ```bash -pkg_update +if check_for_gh_release "nodejs" "nodesource/distributions"; then + # update logic +fi ``` --- -### pkg_remove() +### prepare_repository_setup() -Remove packages completely including dependencies. +Performs safe repository preparation by cleaning up old files, keyrings, and ensuring the APT system is in a working state. **Signature**: ```bash -pkg_remove PACKAGE1 [PACKAGE2 ...] +prepare_repository_setup REPO_NAME [REPO_NAME2 ...] ``` -**Parameters**: -- `PACKAGE1, PACKAGE2, ...` - Package names to remove - -**Returns**: -- `0` - Packages removed -- `1` - Removal failed - **Example**: ```bash -pkg_remove old-package outdated-tool +prepare_repository_setup "mariadb" "mysql" +``` + +--- + +### verify_tool_version() + +Validates if the installed major version matches the expected version. + +**Signature**: +```bash +verify_tool_version NAME EXPECTED INSTALLED +``` + +**Example**: +```bash +verify_tool_version "nodejs" "22" "$(node -v | grep -oP '^v\K[0-9]+')" ``` --- ### setup_deb822_repo() -Add repository in modern deb822 format (recommended over legacy format). +Add repository in modern deb822 format. **Signature**: ```bash @@ -188,12 +250,234 @@ cleanup_repo_metadata ## Tool Installation Functions -### setup_nodejs(VERSION) +### setup_nodejs() -Install Node.js and npm from official repositories. +Install Node.js and npm from official repositories. Handles legacy version cleanup (nvm) automatically. **Signature**: ```bash +setup_nodejs +``` + +**Environment Variables**: +- `NODE_VERSION`: Major version to install (e.g. "20", "22", "24"). Default: "24". +- `NODE_MODULE`: Optional npm package to install globally during setup (e.g. "pnpm", "yarn"). + +**Example**: +```bash +NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs +``` + +--- + +### setup_php() + +Install PHP with configurable extensions and FPM/Apache integration. + +**Signature**: +```bash +setup_php +``` + +**Environment Variables**: +- `PHP_VERSION`: Version to install (e.g. "8.3", "8.4"). Default: "8.4". +- `PHP_MODULE`: Comma-separated list of additional extensions. +- `PHP_FPM`: Set to "YES" to install php-fpm. +- `PHP_APACHE`: Set to "YES" to install libapache2-mod-php. + +**Example**: +```bash +PHP_VERSION="8.3" PHP_FPM="YES" PHP_MODULE="mysql,xml,zip" setup_php +``` + +--- + +### setup_mariadb_db() + +Creates a new MariaDB database and a dedicated user with all privileges. Automatically generates a password if not provided and saves it to a credentials file. + +**Environment Variables**: +- `MARIADB_DB_NAME`: Name of the database (required) +- `MARIADB_DB_USER`: Name of the database user (required) +- `MARIADB_DB_PASS`: User password (optional, auto-generated if omitted) + +**Example**: +```bash +MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp_user" setup_mariadb_db +``` + +--- + +### setup_postgresql_db() + +Creates a new PostgreSQL database and a dedicated user/role with all privileges. Automatically generates a password if not provided and saves it to a credentials file. + +**Environment Variables**: +- `PG_DB_NAME`: Name of the database (required) +- `PG_DB_USER`: Name of the database user (required) +- `PG_DB_PASS`: User password (optional, auto-generated if omitted) + +--- + +### setup_java() + +Installs Temurin JDK. + +**Signature**: +```bash +JAVA_VERSION="21" setup_java +``` + +**Parameters**: +- `JAVA_VERSION` - JDK version (e.g., "17", "21") (default: "21") + +**Example**: +```bash +JAVA_VERSION="17" setup_java +``` + +--- + +### setup_uv() + +Installs `uv` (modern Python package manager). + +**Signature**: +```bash +PYTHON_VERSION="3.13" setup_uv +``` + +**Parameters**: +- `PYTHON_VERSION` - Optional Python version to pre-install via uv (e.g., "3.12", "3.13") + +**Example**: +```bash +PYTHON_VERSION="3.13" setup_uv +``` + +--- + +### setup_go() + +Installs Go programming language. + +**Signature**: +```bash +GO_VERSION="1.23" setup_go +``` + +**Parameters**: +- `GO_VERSION` - Go version to install (default: "1.23") + +**Example**: +```bash +GO_VERSION="1.24" setup_go +``` + +--- + +### setup_yq() + +Installs `yq` (YAML processor). + +**Signature**: +```bash +setup_yq +``` + +**Example**: +```bash +setup_yq +``` + +--- + +### setup_composer() + +Installs PHP Composer. + +**Signature**: +```bash +setup_composer +``` + +**Example**: +```bash +setup_composer +``` + +--- + +### setup_meilisearch() + +Install and configure Meilisearch search engine. + +**Environment Variables**: +- `MEILISEARCH_BIND`: Address and port to bind to (Default: "127.0.0.1:7700") +- `MEILISEARCH_ENV`: Environment mode (Default: "production") + +--- + +### setup_yq() + +Install the `mikefarah/yq` YAML processor. Removes existing non-compliant versions. + +**Example**: +```bash +setup_yq +yq eval '.app.version = "1.0.0"' -i config.yaml +``` + +--- + +### setup_composer() + +Install or update the PHP Composer package manager. Handles `COMPOSER_ALLOW_SUPERUSER` automatically and performs self-updates if already installed. + +**Example**: +```bash +setup_php +setup_composer +$STD composer install --no-dev +``` + +--- + +### setup_build_tools() + +Install the `build-essential` package suite for compiling software. + +--- + +### setup_uv() + +Install the modern Python package manager `uv`. Extremely fast replacement for pip/venv. + +**Environment Variables**: +- `PYTHON_VERSION`: Major.Minor version to ensure is installed. + +**Example**: +```bash +PYTHON_VERSION="3.12" setup_uv +uv sync --locked +``` + +--- + +### setup_java() + +Install OpenJDK via the Adoptium repository. + +**Environment Variables**: +- `JAVA_VERSION`: Major version to install (e.g. "17", "21"). Default: "21". + +**Example**: +```bash +JAVA_VERSION="21" setup_java +``` + +--- +```bash setup_nodejs VERSION ``` diff --git a/docs/vm/README.md b/docs/vm/README.md index f0914b1a1..01535b542 100644 --- a/docs/vm/README.md +++ b/docs/vm/README.md @@ -40,14 +40,15 @@ vm/OsName-vm.sh (host-side) See `/vm` directory for all VM creation scripts. Examples: -- `ubuntu2404-vm.sh` - Ubuntu 24.04 VM -- `ubuntu2204-vm.sh` - Ubuntu 22.04 VM -- `debian-vm.sh` - Debian VM -- `debian-13-vm.sh` - Debian 13 VM -- `opnsense-vm.sh` - OPNsense firewall +- `ubuntu2504-vm.sh` - Ubuntu 25.04 VM (Latest) +- `ubuntu2404-vm.sh` - Ubuntu 24.04 VM (LTS) +- `debian-13-vm.sh` - Debian 13 VM (Trixie) +- `archlinux-vm.sh` - Arch Linux VM - `haos-vm.sh` - Home Assistant OS -- `unifi-os-vm.sh` - Unifi Dream Machine -- `k3s-vm.sh` - Kubernetes lightweight +- `mikrotik-routeros.sh` - MikroTik RouterOS +- `openwrt-vm.sh` - OpenWrt VM +- `opnsense-vm.sh` - OPNsense firewall +- `umbrel-os-vm.sh` - Umbrel OS VM - And 10+ more... ## VM vs Container