mirror of
				https://github.com/community-scripts/ProxmoxVE.git
				synced 2025-11-04 02:12:49 +00:00 
			
		
		
		
	Compare commits
	
		
			141 Commits
		
	
	
		
			2025-09-22
			...
			2025-09-30
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8ff82d0c3c | ||
| 
						 | 
					9e39c6cd2b | ||
| 
						 | 
					0bea24888e | ||
| 
						 | 
					70d2be62e9 | ||
| 
						 | 
					fe30e06a48 | ||
| 
						 | 
					193a2ea2df | ||
| 
						 | 
					ffbe0feee1 | ||
| 
						 | 
					107865b06d | ||
| 
						 | 
					0d33b38e29 | ||
| 
						 | 
					11ae7450c7 | ||
| 
						 | 
					598bfd291f | ||
| 
						 | 
					1a38df4c12 | ||
| 
						 | 
					cfc85c1b79 | ||
| 
						 | 
					e7d41fecdc | ||
| 
						 | 
					34ef80ac87 | ||
| 
						 | 
					b18d45631f | ||
| 
						 | 
					efe1e1edb5 | ||
| 
						 | 
					4567505c55 | ||
| 
						 | 
					42c87ba0d4 | ||
| 
						 | 
					b52c252553 | ||
| 
						 | 
					be5ac7153e | ||
| 
						 | 
					07f2849722 | ||
| 
						 | 
					760299283a | ||
| 
						 | 
					0bd2dd7a65 | ||
| 
						 | 
					6591c30e66 | ||
| 
						 | 
					780e5c114c | ||
| 
						 | 
					ba10ec721b | ||
| 
						 | 
					f66dc834bd | ||
| 
						 | 
					be36fc6a94 | ||
| 
						 | 
					65ada6e6f3 | ||
| 
						 | 
					853eb40bba | ||
| 
						 | 
					ace6265895 | ||
| 
						 | 
					639d4f2d53 | ||
| 
						 | 
					d7e77e232c | ||
| 
						 | 
					b850d3f79e | ||
| 
						 | 
					72e5ac5c80 | ||
| 
						 | 
					587579b3a1 | ||
| 
						 | 
					9b4e996d93 | ||
| 
						 | 
					e6f317ede9 | ||
| 
						 | 
					3e4420e357 | ||
| 
						 | 
					38f7e81d8b | ||
| 
						 | 
					8f5d50a9fa | ||
| 
						 | 
					32048cff2d | ||
| 
						 | 
					5775f7cf33 | ||
| 
						 | 
					4d7c004810 | ||
| 
						 | 
					d74131fe6f | ||
| 
						 | 
					87b30f67fa | ||
| 
						 | 
					7ddc50bfe7 | ||
| 
						 | 
					484a46beb1 | ||
| 
						 | 
					b85d1e5062 | ||
| 
						 | 
					05e41f67e1 | ||
| 
						 | 
					bfe6445c64 | ||
| 
						 | 
					ffde3a731c | ||
| 
						 | 
					d5b9da8f5f | ||
| 
						 | 
					1b8d790a14 | ||
| 
						 | 
					175b925ae4 | ||
| 
						 | 
					38a8773d2f | ||
| 
						 | 
					e7dafcbf3e | ||
| 
						 | 
					380fb1cfb7 | ||
| 
						 | 
					10cd6c3f0b | ||
| 
						 | 
					710bd7f4e7 | ||
| 
						 | 
					4d72852e53 | ||
| 
						 | 
					9ad538c2d2 | ||
| 
						 | 
					ee3872e7e1 | ||
| 
						 | 
					f6ca81833e | ||
| 
						 | 
					c41b18f083 | ||
| 
						 | 
					f983f75b30 | ||
| 
						 | 
					137dd647dd | ||
| 
						 | 
					2f5c608f45 | ||
| 
						 | 
					b8e06c05d0 | ||
| 
						 | 
					2beb89055c | ||
| 
						 | 
					308897fdc7 | ||
| 
						 | 
					5b73367c80 | ||
| 
						 | 
					5c0eefa652 | ||
| 
						 | 
					7c5c654dbe | ||
| 
						 | 
					984eeedf31 | ||
| 
						 | 
					7fd08cbe69 | ||
| 
						 | 
					285447b67f | ||
| 
						 | 
					b394cdf6e0 | ||
| 
						 | 
					ab2a6ed38e | ||
| 
						 | 
					f8e109c529 | ||
| 
						 | 
					46e4bc3a04 | ||
| 
						 | 
					d0a1f305c7 | ||
| 
						 | 
					6948e1f695 | ||
| 
						 | 
					8c860da4ed | ||
| 
						 | 
					d32e9fad59 | ||
| 
						 | 
					9096a388c7 | ||
| 
						 | 
					9f0efc27df | ||
| 
						 | 
					06ca6e2087 | ||
| 
						 | 
					8c48ea6718 | ||
| 
						 | 
					b626e705eb | ||
| 
						 | 
					f103d09c09 | ||
| 
						 | 
					82a7d252ab | ||
| 
						 | 
					48af77e928 | ||
| 
						 | 
					d24308a409 | ||
| 
						 | 
					584365fff1 | ||
| 
						 | 
					95c54dccd7 | ||
| 
						 | 
					eb28463d86 | ||
| 
						 | 
					bddde99252 | ||
| 
						 | 
					f1f8c1b279 | ||
| 
						 | 
					37a0a4add9 | ||
| 
						 | 
					02cede3f5d | ||
| 
						 | 
					42a7d57a42 | ||
| 
						 | 
					53b5f0d1fe | ||
| 
						 | 
					4a56d8d9aa | ||
| 
						 | 
					f819188a5e | ||
| 
						 | 
					4d6e3e5977 | ||
| 
						 | 
					d6fc527200 | ||
| 
						 | 
					c103c3b03d | ||
| 
						 | 
					2d290cb27f | ||
| 
						 | 
					883efd1cd2 | ||
| 
						 | 
					1f40670ea0 | ||
| 
						 | 
					cec4e2d5c1 | ||
| 
						 | 
					1fafb3f661 | ||
| 
						 | 
					b56b053e8b | ||
| 
						 | 
					21f98835dc | ||
| 
						 | 
					ab455d7748 | ||
| 
						 | 
					5382fa1dbd | ||
| 
						 | 
					6fa1938360 | ||
| 
						 | 
					2a2df5b5cc | ||
| 
						 | 
					f99d582eb5 | ||
| 
						 | 
					d3f24ae5b2 | ||
| 
						 | 
					25e89f7bac | ||
| 
						 | 
					2686753448 | ||
| 
						 | 
					19678e2534 | ||
| 
						 | 
					1ac8f90281 | ||
| 
						 | 
					7cd3e40f9c | ||
| 
						 | 
					42191bdb5a | ||
| 
						 | 
					aab1a9bce5 | ||
| 
						 | 
					208226065b | ||
| 
						 | 
					54e62749be | ||
| 
						 | 
					2a8e2e62cd | ||
| 
						 | 
					b15d7be4c3 | ||
| 
						 | 
					e208bc110b | ||
| 
						 | 
					b26ad61a33 | ||
| 
						 | 
					5beaec9514 | ||
| 
						 | 
					3a668870b7 | ||
| 
						 | 
					3266962630 | ||
| 
						 | 
					2a3f5d7b47 | ||
| 
						 | 
					fb4c3cf9e9 | ||
| 
						 | 
					e96ea4eb40 | 
							
								
								
									
										38
									
								
								.github/label-priority.json
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								.github/label-priority.json
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,38 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "priorities": {
 | 
			
		||||
    "refactor": 3,
 | 
			
		||||
    "feature": 2,
 | 
			
		||||
    "bugfix": 1,
 | 
			
		||||
    "new script": 3,
 | 
			
		||||
    "update script": 2,
 | 
			
		||||
    "delete script": 2,
 | 
			
		||||
    "json": 3,
 | 
			
		||||
    "website": 2,
 | 
			
		||||
    "maintenance": 1,
 | 
			
		||||
    "documentation": 1,
 | 
			
		||||
    "core": 2,
 | 
			
		||||
    "api": 2,
 | 
			
		||||
    "addon": 2,
 | 
			
		||||
    "pve-tool": 2,
 | 
			
		||||
    "vm": 2,
 | 
			
		||||
    "github": 1
 | 
			
		||||
  },
 | 
			
		||||
  "conflicts": {
 | 
			
		||||
    "bugfix": ["refactor"],
 | 
			
		||||
    "website": ["json"],
 | 
			
		||||
    "update script": ["new script", "delete script"],
 | 
			
		||||
    "new script": ["update script", "delete script"],
 | 
			
		||||
    "delete script": ["new script", "update script"]
 | 
			
		||||
  },
 | 
			
		||||
  "rules": {
 | 
			
		||||
    "always_combine": [
 | 
			
		||||
      "maintenance",
 | 
			
		||||
      "core",
 | 
			
		||||
      "api",
 | 
			
		||||
      "addon",
 | 
			
		||||
      "pve-tool",
 | 
			
		||||
      "vm",
 | 
			
		||||
      "github"
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								.github/workflows/autolabeler.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										116
									
								
								.github/workflows/autolabeler.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -112,119 +112,3 @@ jobs:
 | 
			
		||||
                labels: Array.from(labelsToAdd),
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
  ai-check:
 | 
			
		||||
    needs: autolabeler
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    permissions:
 | 
			
		||||
      pull-requests: write
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - name: Load priority config
 | 
			
		||||
        run: |
 | 
			
		||||
          echo "PRIORITY_JSON=$(jq -c . .github/label-priority.json)" >> $GITHUB_ENV
 | 
			
		||||
 | 
			
		||||
      - name: Fetch PR metadata
 | 
			
		||||
        id: pr
 | 
			
		||||
        uses: actions/github-script@v7
 | 
			
		||||
        with:
 | 
			
		||||
          script: |
 | 
			
		||||
            const pr = context.payload.pull_request;
 | 
			
		||||
            const files = await github.rest.pulls.listFiles({
 | 
			
		||||
              owner: context.repo.owner,
 | 
			
		||||
              repo: context.repo.repo,
 | 
			
		||||
              pull_number: pr.number
 | 
			
		||||
            });
 | 
			
		||||
            const prData = {
 | 
			
		||||
              title: pr.title || "",
 | 
			
		||||
              body: pr.body || "",
 | 
			
		||||
              files: files.data.map(f => f.filename)
 | 
			
		||||
            };
 | 
			
		||||
            require('fs').writeFileSync(process.env.GITHUB_ENV, `PR_DATA=${JSON.stringify(prData)}\n`, {flag: 'a'});
 | 
			
		||||
 | 
			
		||||
      - name: AI Label Review
 | 
			
		||||
        id: ai
 | 
			
		||||
        uses: actions/github-script@v7
 | 
			
		||||
        env:
 | 
			
		||||
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
 | 
			
		||||
        with:
 | 
			
		||||
          script: |
 | 
			
		||||
            const prData = JSON.parse(process.env.PR_DATA);
 | 
			
		||||
 | 
			
		||||
            const prompt = `
 | 
			
		||||
            You are a GitHub labeling bot.
 | 
			
		||||
            Task:
 | 
			
		||||
            - Analyze PR title, body, and file list.
 | 
			
		||||
            - For each possible label, return a confidence score (0–1).
 | 
			
		||||
            - If both bugfix and refactor apply, prefer refactor.
 | 
			
		||||
            - Output JSON: {"labels":[{"name":"bugfix","score":0.9},{"name":"refactor","score":0.6}]}
 | 
			
		||||
 | 
			
		||||
            Valid labels: [new script, update script, delete script, bugfix, feature, maintenance, refactor, website, json, api, core, github, addon, pve-tool, vm].
 | 
			
		||||
 | 
			
		||||
            PR data: ${JSON.stringify(prData)}
 | 
			
		||||
            `;
 | 
			
		||||
 | 
			
		||||
            const response = await fetch("https://api.openai.com/v1/chat/completions", {
 | 
			
		||||
              method: "POST",
 | 
			
		||||
              headers: {
 | 
			
		||||
                "Content-Type": "application/json",
 | 
			
		||||
                "Authorization": "Bearer " + process.env.OPENAI_API_KEY,
 | 
			
		||||
              },
 | 
			
		||||
              body: JSON.stringify({
 | 
			
		||||
                model: "gpt-4.1-mini",
 | 
			
		||||
                messages: [{ role: "user", content: prompt }],
 | 
			
		||||
                temperature: 0
 | 
			
		||||
              })
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const data = await response.json();
 | 
			
		||||
            const labels = JSON.parse(data.choices[0].message.content).labels;
 | 
			
		||||
            core.setOutput("labels", JSON.stringify(labels));
 | 
			
		||||
 | 
			
		||||
      - name: Apply AI Labels
 | 
			
		||||
        uses: actions/github-script@v7
 | 
			
		||||
        with:
 | 
			
		||||
          script: |
 | 
			
		||||
            const raw = JSON.parse('${{ steps.ai.outputs.labels }}');
 | 
			
		||||
            const prNumber = context.payload.pull_request.number;
 | 
			
		||||
            const config = JSON.parse(process.env.PRIORITY_JSON);
 | 
			
		||||
 | 
			
		||||
            let toApply = [];
 | 
			
		||||
            let toSuggest = [];
 | 
			
		||||
 | 
			
		||||
            raw.forEach(l => {
 | 
			
		||||
              if (l.score >= 0.8) {
 | 
			
		||||
                const conflicts = config.conflicts[l.name] || [];
 | 
			
		||||
                const hasStrongerConflict = conflicts.some(c =>
 | 
			
		||||
                  raw.some(x =>
 | 
			
		||||
                    x.name === c &&
 | 
			
		||||
                    x.score >= 0.6 &&
 | 
			
		||||
                    (config.priorities[c] || 0) >= (config.priorities[l.name] || 0)
 | 
			
		||||
                  )
 | 
			
		||||
                );
 | 
			
		||||
                if (!hasStrongerConflict) {
 | 
			
		||||
                  toApply.push(l.name);
 | 
			
		||||
                }
 | 
			
		||||
              } else if (l.score >= 0.5) {
 | 
			
		||||
                toSuggest.push(`${l.name} (${Math.round(l.score*100)}%)`);
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (toApply.length > 0) {
 | 
			
		||||
              await github.rest.issues.addLabels({
 | 
			
		||||
                owner: context.repo.owner,
 | 
			
		||||
                repo: context.repo.repo,
 | 
			
		||||
                issue_number: prNumber,
 | 
			
		||||
                labels: toApply
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (toSuggest.length > 0) {
 | 
			
		||||
              await github.rest.issues.createComment({
 | 
			
		||||
                owner: context.repo.owner,
 | 
			
		||||
                repo: context.repo.repo,
 | 
			
		||||
                issue_number: prNumber,
 | 
			
		||||
                body: `🤖 AI suggests these possible labels (uncertain): ${toSuggest.join(", ")}`
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										153
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -10,8 +10,161 @@
 | 
			
		||||
> [!CAUTION]
 | 
			
		||||
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
 | 
			
		||||
 | 
			
		||||
## 2025-10-01
 | 
			
		||||
 | 
			
		||||
## 2025-09-30
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - caddy: fix typo for setup_go [@MickLesk](https://github.com/MickLesk) ([#8017](https://github.com/community-scripts/ProxmoxVE/pull/8017))
 | 
			
		||||
    - Changedetection: Fix Browserless installation and update process [@h-stoyanov](https://github.com/h-stoyanov) ([#8011](https://github.com/community-scripts/ProxmoxVE/pull/8011))
 | 
			
		||||
    - n8n: Update procedure workaround [@tremor021](https://github.com/tremor021) ([#8004](https://github.com/community-scripts/ProxmoxVE/pull/8004))
 | 
			
		||||
    - Changedetection: Bump nodejs to 24 [@MickLesk](https://github.com/MickLesk) ([#8002](https://github.com/community-scripts/ProxmoxVE/pull/8002))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - Bump Guacamole to Debian 13 [@burgerga](https://github.com/burgerga) ([#8010](https://github.com/community-scripts/ProxmoxVE/pull/8010))
 | 
			
		||||
 | 
			
		||||
## 2025-09-29
 | 
			
		||||
 | 
			
		||||
### 🆕 New Scripts
 | 
			
		||||
 | 
			
		||||
  - Ghostfolio ([#7982](https://github.com/community-scripts/ProxmoxVE/pull/7982))
 | 
			
		||||
- Warracker ([#7977](https://github.com/community-scripts/ProxmoxVE/pull/7977))
 | 
			
		||||
- MyIP ([#7974](https://github.com/community-scripts/ProxmoxVE/pull/7974))
 | 
			
		||||
- Verdaccio ([#7967](https://github.com/community-scripts/ProxmoxVE/pull/7967))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - fix sidebar loading issues and navbar on mobile [@BramSuurdje](https://github.com/BramSuurdje) ([#7991](https://github.com/community-scripts/ProxmoxVE/pull/7991))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - Improve mobile ui: added a hamburger navigation to the mobile view. [@BramSuurdje](https://github.com/BramSuurdje) ([#7987](https://github.com/community-scripts/ProxmoxVE/pull/7987))
 | 
			
		||||
 | 
			
		||||
  - #### 📝 Script Information
 | 
			
		||||
 | 
			
		||||
    - Remove Frigate from Website [@MickLesk](https://github.com/MickLesk) ([#7972](https://github.com/community-scripts/ProxmoxVE/pull/7972))
 | 
			
		||||
 | 
			
		||||
## 2025-09-28
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Metube: remove uv flags [@vhsdream](https://github.com/vhsdream) ([#7962](https://github.com/community-scripts/ProxmoxVE/pull/7962))
 | 
			
		||||
    - freshrss: fix for broken permissions after update [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7953](https://github.com/community-scripts/ProxmoxVE/pull/7953))
 | 
			
		||||
 | 
			
		||||
## 2025-09-27
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - GoAway: Make admin password aquisition more reliable [@tremor021](https://github.com/tremor021) ([#7946](https://github.com/community-scripts/ProxmoxVE/pull/7946))
 | 
			
		||||
    - MeTube: Various fixes [@vhsdream](https://github.com/vhsdream) ([#7936](https://github.com/community-scripts/ProxmoxVE/pull/7936))
 | 
			
		||||
    - Oddo: Fix typo in update procedure [@tremor021](https://github.com/tremor021) ([#7941](https://github.com/community-scripts/ProxmoxVE/pull/7941))
 | 
			
		||||
 | 
			
		||||
## 2025-09-26
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Odoo: Fix missing dependencies [@tremor021](https://github.com/tremor021) ([#7931](https://github.com/community-scripts/ProxmoxVE/pull/7931))
 | 
			
		||||
    - OpenWebUI: Update NODE_OPTIONS to increase memory limit [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#7919](https://github.com/community-scripts/ProxmoxVE/pull/7919))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
  - #### 📝 Script Information
 | 
			
		||||
 | 
			
		||||
    - Clarify descriptions of update scripts [@tremor021](https://github.com/tremor021) ([#7929](https://github.com/community-scripts/ProxmoxVE/pull/7929))
 | 
			
		||||
 | 
			
		||||
## 2025-09-25
 | 
			
		||||
 | 
			
		||||
### 🆕 New Scripts
 | 
			
		||||
 | 
			
		||||
  - GoAway ([#7900](https://github.com/community-scripts/ProxmoxVE/pull/7900))
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - ntfy: bump to debian 13 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7895](https://github.com/community-scripts/ProxmoxVE/pull/7895))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - feat: add menu icons to website [@BramSuurdje](https://github.com/BramSuurdje) ([#7894](https://github.com/community-scripts/ProxmoxVE/pull/7894))
 | 
			
		||||
 | 
			
		||||
## 2025-09-24
 | 
			
		||||
 | 
			
		||||
### 🆕 New Scripts
 | 
			
		||||
 | 
			
		||||
  - Add Script: Joplin Server ([#7879](https://github.com/community-scripts/ProxmoxVE/pull/7879))
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Monica: Fix dependencies [@tremor021](https://github.com/tremor021) ([#7877](https://github.com/community-scripts/ProxmoxVE/pull/7877))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
  - #### 📝 Script Information
 | 
			
		||||
 | 
			
		||||
    - Update name in lxc-delete.json to 'PVE LXC Deletion' [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#7872](https://github.com/community-scripts/ProxmoxVE/pull/7872))
 | 
			
		||||
 | 
			
		||||
## 2025-09-23
 | 
			
		||||
 | 
			
		||||
### 🆕 New Scripts
 | 
			
		||||
 | 
			
		||||
  - UpSnap ([#7825](https://github.com/community-scripts/ProxmoxVE/pull/7825))
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - tools.func: Check for /usr/local/bin in PATH during yq setup [@vhsdream](https://github.com/vhsdream) ([#7856](https://github.com/community-scripts/ProxmoxVE/pull/7856))
 | 
			
		||||
    - BookLore: increase RAM [@vhsdream](https://github.com/vhsdream) ([#7855](https://github.com/community-scripts/ProxmoxVE/pull/7855))
 | 
			
		||||
    - Bump Immich to v1.143.1 [@vhsdream](https://github.com/vhsdream) ([#7864](https://github.com/community-scripts/ProxmoxVE/pull/7864))
 | 
			
		||||
    - zabbix: Remove not exist admin credentials from output [@MickLesk](https://github.com/MickLesk) ([#7849](https://github.com/community-scripts/ProxmoxVE/pull/7849))
 | 
			
		||||
    - Suppress wrong errors from uv shell integration in setup_uv [@MickLesk](https://github.com/MickLesk) ([#7822](https://github.com/community-scripts/ProxmoxVE/pull/7822))
 | 
			
		||||
    - Refactor Caddyfile configuration for headscale-admin [@MickLesk](https://github.com/MickLesk) ([#7821](https://github.com/community-scripts/ProxmoxVE/pull/7821))
 | 
			
		||||
    - Improve subscription element removal (mobile) in post-pve script [@MickLesk](https://github.com/MickLesk) ([#7814](https://github.com/community-scripts/ProxmoxVE/pull/7814))
 | 
			
		||||
    - Blocky: Fix release fetching [@tremor021](https://github.com/tremor021) ([#7807](https://github.com/community-scripts/ProxmoxVE/pull/7807))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - Improve globaleaks install ensuring install can proceed without user … [@evilaliv3](https://github.com/evilaliv3) ([#7860](https://github.com/community-scripts/ProxmoxVE/pull/7860))
 | 
			
		||||
    - Manage My Damn Life: use NodeJS 22 [@vhsdream](https://github.com/vhsdream) ([#7861](https://github.com/community-scripts/ProxmoxVE/pull/7861))
 | 
			
		||||
    - VM: Increase pv & xz functions (HA OS / Umbrel OS) [@MickLesk](https://github.com/MickLesk) ([#7838](https://github.com/community-scripts/ProxmoxVE/pull/7838))
 | 
			
		||||
    - Tandoor: update for newer dependencies (psql) + bump nodejs to 22 [@MickLesk](https://github.com/MickLesk) ([#7826](https://github.com/community-scripts/ProxmoxVE/pull/7826))
 | 
			
		||||
    - Update Monica and Outline to use Node.js 22 [@MickLesk](https://github.com/MickLesk) ([#7833](https://github.com/community-scripts/ProxmoxVE/pull/7833))
 | 
			
		||||
    - Update Zabbix install for Debian 13 and agent selection [@MickLesk](https://github.com/MickLesk) ([#7819](https://github.com/community-scripts/ProxmoxVE/pull/7819))
 | 
			
		||||
    - tracktor: bump to debian 13 | feature bump [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7818](https://github.com/community-scripts/ProxmoxVE/pull/7818))
 | 
			
		||||
    - LiteLLM: Bump to Debian 13 & add deps [@MickLesk](https://github.com/MickLesk) ([#7815](https://github.com/community-scripts/ProxmoxVE/pull/7815))
 | 
			
		||||
    - Immich: bump to v1.143.0 [@vhsdream](https://github.com/vhsdream) ([#7801](https://github.com/community-scripts/ProxmoxVE/pull/7801))
 | 
			
		||||
 | 
			
		||||
### 🧰 Maintenance
 | 
			
		||||
 | 
			
		||||
  - #### 📂 Github
 | 
			
		||||
 | 
			
		||||
    - gh: remove ai autolabel test [@MickLesk](https://github.com/MickLesk) ([#7817](https://github.com/community-scripts/ProxmoxVE/pull/7817))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
  - #### 📝 Script Information
 | 
			
		||||
 | 
			
		||||
    - OpenWebUI: Add information about Ollama [@tremor021](https://github.com/tremor021) ([#7843](https://github.com/community-scripts/ProxmoxVE/pull/7843))
 | 
			
		||||
    - cosmos: add info note for configuration file [@MickLesk](https://github.com/MickLesk) ([#7824](https://github.com/community-scripts/ProxmoxVE/pull/7824))
 | 
			
		||||
    - ElementSynapse: add note for Bridge Install Methods [@MickLesk](https://github.com/MickLesk) ([#7820](https://github.com/community-scripts/ProxmoxVE/pull/7820))
 | 
			
		||||
 | 
			
		||||
## 2025-09-22
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ var_disk="${var_disk:-4}"
 | 
			
		||||
var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_ram="${var_ram:-2048}"
 | 
			
		||||
var_os="${var_os:-debian}"
 | 
			
		||||
var_version="${var_version:-12}"
 | 
			
		||||
var_version="${var_version:-13}"
 | 
			
		||||
var_unprivileged="${var_unprivileged:-1}"
 | 
			
		||||
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
@@ -38,4 +38,4 @@ 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}:8080/guacamole${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080/guacamole${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ function update_script() {
 | 
			
		||||
    rm -rf /opt/blocky
 | 
			
		||||
    msg_ok "Removed Old Version"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "blocky" "0xERR0R/blocky" "prebuild" "latest" "/opt/blocky" "blocky_*_linux_x86_64.tar.gz"
 | 
			
		||||
    fetch_and_deploy_gh_release "blocky" "0xERR0R/blocky" "prebuild" "latest" "/opt/blocky" "blocky_*_Linux_x86_64.tar.gz"
 | 
			
		||||
 | 
			
		||||
    msg_info "Restore Config"
 | 
			
		||||
    mv /opt/config.yml /opt/blocky/config.yml
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
 | 
			
		||||
APP="BookLore"
 | 
			
		||||
var_tags="${var_tags:-books;library}"
 | 
			
		||||
var_cpu="${var_cpu:-3}"
 | 
			
		||||
var_ram="${var_ram:-2048}"
 | 
			
		||||
var_ram="${var_ram:-3072}"
 | 
			
		||||
var_disk="${var_disk:-7}"
 | 
			
		||||
var_os="${var_os:-debian}"
 | 
			
		||||
var_version="${var_version:-12}"
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ function update_script() {
 | 
			
		||||
   msg_ok "Updated $APP LXC"
 | 
			
		||||
 | 
			
		||||
    if command -v xcaddy >/dev/null 2>&1; then
 | 
			
		||||
      install_go
 | 
			
		||||
      setup_go
 | 
			
		||||
      msg_info "Updating xCaddy"
 | 
			
		||||
      cd /opt
 | 
			
		||||
      RELEASE=$(curl -fsSL https://api.github.com/repos/caddyserver/xcaddy/releases/latest | grep "tag_name" | awk -F '"' '{print $4}')
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@ function update_script() {
 | 
			
		||||
    msg_ok "Updated Dependencies"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  NODE_VERSION="24" setup_nodejs
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating ${APP}"
 | 
			
		||||
  $STD pip3 install changedetection.io --upgrade
 | 
			
		||||
  msg_ok "Updated ${APP}"
 | 
			
		||||
@@ -49,6 +51,7 @@ function update_script() {
 | 
			
		||||
    $STD git -C /opt/browserless/ fetch --all
 | 
			
		||||
    $STD git -C /opt/browserless/ reset --hard origin/main
 | 
			
		||||
    $STD npm update --prefix /opt/browserless
 | 
			
		||||
    $STD npm ci --include=optional --include=dev --prefix /opt/browserless
 | 
			
		||||
    $STD /opt/browserless/node_modules/playwright-core/cli.js install --with-deps
 | 
			
		||||
    # Update Chrome separately, as it has to be done with the force option. Otherwise the installation of other browsers will not be done if Chrome is already installed.
 | 
			
		||||
    $STD /opt/browserless/node_modules/playwright-core/cli.js install --force chrome
 | 
			
		||||
 
 | 
			
		||||
@@ -27,8 +27,16 @@ function update_script() {
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    msg_error "FreshRSS should be updated via the user interface."
 | 
			
		||||
    exit
 | 
			
		||||
 | 
			
		||||
    if [ ! -x /opt/freshrss/cli/sensitive-log.sh ]; then
 | 
			
		||||
        msg_info "Fixing wrong permissions"
 | 
			
		||||
        chmod +x /opt/freshrss/cli/sensitive-log.sh
 | 
			
		||||
        systemctl restart apache2
 | 
			
		||||
        msg_ok "Fixed wrong permissions"
 | 
			
		||||
    else
 | 
			
		||||
        msg_error "FreshRSS should be updated via the user interface."
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
@@ -38,4 +46,4 @@ 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}${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										75
									
								
								ct/ghostfolio.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								ct/ghostfolio.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: lucasfell
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://ghostfol.io/
 | 
			
		||||
 | 
			
		||||
APP="Ghostfolio"
 | 
			
		||||
var_tags="${var_tags:-finance;investment}"
 | 
			
		||||
var_cpu="${var_cpu:-2}"
 | 
			
		||||
var_ram="${var_ram:-4096}"
 | 
			
		||||
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 [[ ! -f /opt/ghostfolio/dist/apps/api/main.js ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if check_for_gh_release "ghostfolio" "ghostfolio/ghostfolio"; then
 | 
			
		||||
      msg_info "Stopping Service"
 | 
			
		||||
      systemctl stop ghostfolio
 | 
			
		||||
      msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
      msg_info "Creating Backup"
 | 
			
		||||
      tar -czf "/opt/ghostfolio_backup_$(date +%F).tar.gz" \
 | 
			
		||||
        -C /opt \
 | 
			
		||||
        --exclude="ghostfolio/node_modules" \
 | 
			
		||||
        --exclude="ghostfolio/dist" \
 | 
			
		||||
        ghostfolio
 | 
			
		||||
      mv /opt/ghostfolio/.env /opt/env.backup
 | 
			
		||||
      msg_ok "Backup Created"
 | 
			
		||||
 | 
			
		||||
      CLEAN_INSTALL=1 fetch_and_deploy_gh_release "ghostfolio" "ghostfolio/ghostfolio" "tarball" "latest" "/opt/ghostfolio"
 | 
			
		||||
 | 
			
		||||
      msg_info "Updating Ghostfolio"
 | 
			
		||||
      mv /opt/env.backup /opt/ghostfolio/.env
 | 
			
		||||
      cd /opt/ghostfolio
 | 
			
		||||
      $STD npm ci
 | 
			
		||||
      $STD npm run build:production
 | 
			
		||||
      $STD npx prisma migrate deploy
 | 
			
		||||
      msg_ok "Updated Ghostfolio"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Service"
 | 
			
		||||
    systemctl start ghostfolio
 | 
			
		||||
    msg_ok "Started Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    $STD npm cache clean --force
 | 
			
		||||
    msg_ok "Cleanup Completed"
 | 
			
		||||
    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}:3333${CL}"
 | 
			
		||||
							
								
								
									
										54
									
								
								ct/goaway.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								ct/goaway.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/pommee/goaway
 | 
			
		||||
 | 
			
		||||
APP="GoAway"
 | 
			
		||||
var_tags="${var_tags:-network}"
 | 
			
		||||
var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_ram="${var_ram:-1024}"
 | 
			
		||||
var_disk="${var_disk:-4}"
 | 
			
		||||
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/goaway ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if check_for_gh_release "goaway" "pommee/goaway"; then
 | 
			
		||||
    msg_info "Stopping Services"
 | 
			
		||||
    systemctl stop goaway
 | 
			
		||||
    msg_ok "Stopped Services"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "goaway" "pommee/goaway" "prebuild" "latest" "/opt/goaway" "goaway_*_linux_amd64.tar.gz"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Services"
 | 
			
		||||
    systemctl start goaway
 | 
			
		||||
    msg_ok "Started Services"
 | 
			
		||||
 | 
			
		||||
    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}:8080${CL}"
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/ghostfolio
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/ghostfolio
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
   ________               __  ____      ___     
 | 
			
		||||
  / ____/ /_  ____  _____/ /_/ __/___  / (_)___ 
 | 
			
		||||
 / / __/ __ \/ __ \/ ___/ __/ /_/ __ \/ / / __ \
 | 
			
		||||
/ /_/ / / / / /_/ (__  ) /_/ __/ /_/ / / / /_/ /
 | 
			
		||||
\____/_/ /_/\____/____/\__/_/  \____/_/_/\____/ 
 | 
			
		||||
                                                
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/goaway
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/goaway
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
   ______      ___                      
 | 
			
		||||
  / ____/___  /   |_      ______ ___  __
 | 
			
		||||
 / / __/ __ \/ /| | | /| / / __ `/ / / /
 | 
			
		||||
/ /_/ / /_/ / ___ | |/ |/ / /_/ / /_/ / 
 | 
			
		||||
\____/\____/_/  |_|__/|__/\__,_/\__, /  
 | 
			
		||||
                               /____/   
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/joplin-server
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/joplin-server
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
       __            ___            _____                          
 | 
			
		||||
      / /___  ____  / (_)___       / ___/___  ______   _____  _____
 | 
			
		||||
 __  / / __ \/ __ \/ / / __ \______\__ \/ _ \/ ___/ | / / _ \/ ___/
 | 
			
		||||
/ /_/ / /_/ / /_/ / / / / / /_____/__/ /  __/ /   | |/ /  __/ /    
 | 
			
		||||
\____/\____/ .___/_/_/_/ /_/     /____/\___/_/    |___/\___/_/     
 | 
			
		||||
          /_/                                                      
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/myip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/myip
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
    __  ___      ________ 
 | 
			
		||||
   /  |/  /_  __/  _/ __ \
 | 
			
		||||
  / /|_/ / / / // // /_/ /
 | 
			
		||||
 / /  / / /_/ // // ____/ 
 | 
			
		||||
/_/  /_/\__, /___/_/      
 | 
			
		||||
       /____/             
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/upsnap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/upsnap
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
   __  __     _____                 
 | 
			
		||||
  / / / /___ / ___/____  ____ _____ 
 | 
			
		||||
 / / / / __ \\__ \/ __ \/ __ `/ __ \
 | 
			
		||||
/ /_/ / /_/ /__/ / / / / /_/ / /_/ /
 | 
			
		||||
\____/ .___/____/_/ /_/\__,_/ .___/ 
 | 
			
		||||
    /_/                    /_/      
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/verdaccio
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/verdaccio
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
 _    __              __                _     
 | 
			
		||||
| |  / /__  _________/ /___ ___________(_)___ 
 | 
			
		||||
| | / / _ \/ ___/ __  / __ `/ ___/ ___/ / __ \
 | 
			
		||||
| |/ /  __/ /  / /_/ / /_/ / /__/ /__/ / /_/ /
 | 
			
		||||
|___/\___/_/   \__,_/\__,_/\___/\___/_/\____/ 
 | 
			
		||||
                                              
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/warracker
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/warracker
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
 _       __                           __            
 | 
			
		||||
| |     / /___ _______________ ______/ /_____  _____
 | 
			
		||||
| | /| / / __ `/ ___/ ___/ __ `/ ___/ //_/ _ \/ ___/
 | 
			
		||||
| |/ |/ / /_/ / /  / /  / /_/ / /__/ ,< /  __/ /    
 | 
			
		||||
|__/|__/\__,_/_/  /_/   \__,_/\___/_/|_|\___/_/     
 | 
			
		||||
                                                    
 | 
			
		||||
@@ -53,3 +53,5 @@ 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}Headscale API: ${IP}/api (no Frontend) | headscale-admin: http://${IP}/admin/${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ function update_script() {
 | 
			
		||||
    done
 | 
			
		||||
    msg_ok "Image-processing libraries up to date"
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE="1.142.1"
 | 
			
		||||
  RELEASE="1.143.1"
 | 
			
		||||
  if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
 | 
			
		||||
    msg_info "Stopping Services"
 | 
			
		||||
    systemctl stop immich-web
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										62
									
								
								ct/joplin-server.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								ct/joplin-server.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://joplinapp.org/
 | 
			
		||||
 | 
			
		||||
APP="Joplin-Server"
 | 
			
		||||
var_tags="${var_tags:-notes}"
 | 
			
		||||
var_cpu="${var_cpu:-2}"
 | 
			
		||||
var_ram="${var_ram:-4096}"
 | 
			
		||||
var_disk="${var_disk:-20}"
 | 
			
		||||
var_os="${var_os:-debian}"
 | 
			
		||||
var_version="${var_version:-12}"
 | 
			
		||||
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/joplin-server ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if check_for_gh_release "joplin-server" "laurent22/joplin"; then
 | 
			
		||||
    msg_info "Stopping Services"
 | 
			
		||||
    systemctl stop joplin-server
 | 
			
		||||
    msg_ok "Stopped Services"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball" "latest"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP}"
 | 
			
		||||
    cd /opt/joplin-server
 | 
			
		||||
    sed -i "/onenote-converter/d" packages/lib/package.json
 | 
			
		||||
    $STD yarn config set --home enableTelemetry 0
 | 
			
		||||
    export BUILD_SEQUENCIAL=1
 | 
			
		||||
    $STD yarn install --inline-builds
 | 
			
		||||
    msg_ok "Updated ${APP}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Services"
 | 
			
		||||
    systemctl start joplin-server
 | 
			
		||||
    msg_ok "Started Services"
 | 
			
		||||
 | 
			
		||||
    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}:22300${CL}"
 | 
			
		||||
@@ -11,7 +11,7 @@ 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_version="${var_version:-13}"
 | 
			
		||||
var_unprivileged="${var_unprivileged:-1}"
 | 
			
		||||
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
@@ -29,23 +29,24 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Stopping ${APP}"
 | 
			
		||||
  msg_info "Stopping Service"
 | 
			
		||||
  systemctl stop litellm
 | 
			
		||||
  msg_ok "Stopped ${APP}"
 | 
			
		||||
  msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
  VENV_PATH="/opt/litellm/.venv"
 | 
			
		||||
  PYTHON_VERSION="3.13" setup_uv
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating $APP"
 | 
			
		||||
  msg_info "Updating LiteLLM"
 | 
			
		||||
  $STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
 | 
			
		||||
  msg_ok "LiteLLM updated"
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating DB Schema"
 | 
			
		||||
  $STD uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
 | 
			
		||||
  msg_ok "DB Schema Updated"
 | 
			
		||||
 | 
			
		||||
  msg_info "Starting ${APP}"
 | 
			
		||||
  msg_info "Starting Service"
 | 
			
		||||
  systemctl start litellm
 | 
			
		||||
  msg_ok "Started ${APP}"
 | 
			
		||||
  msg_ok "Started Service"
 | 
			
		||||
  msg_ok "Updated Successfully"
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,12 +35,15 @@ function update_script() {
 | 
			
		||||
 | 
			
		||||
    msg_info "Creating Backup"
 | 
			
		||||
    cp /opt/mmdl/.env /opt/mmdl.env
 | 
			
		||||
    rm -rf /opt/mmdl
 | 
			
		||||
    msg_ok "Backup Created"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "mmdl" "intri-in/manage-my-damn-life-nextjs" "tarball"
 | 
			
		||||
    NODE_VERSION="22" setup_nodejs
 | 
			
		||||
 | 
			
		||||
    msg_info "Configuring ${APP}"
 | 
			
		||||
    cd /opt/mmdl
 | 
			
		||||
    export NEXT_TELEMETRY_DISABLED=1
 | 
			
		||||
    $STD npm install
 | 
			
		||||
    $STD npm run migrate
 | 
			
		||||
    $STD npm run build
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										119
									
								
								ct/metube.sh
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								ct/metube.sh
									
									
									
									
									
								
							@@ -29,59 +29,53 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Stopping ${APP} Service"
 | 
			
		||||
  systemctl stop metube
 | 
			
		||||
  msg_ok "Stopped ${APP} Service"
 | 
			
		||||
 | 
			
		||||
  msg_info "Backing up Old Installation"
 | 
			
		||||
  if [[ -d /opt/metube_bak ]]; then
 | 
			
		||||
    rm -rf /opt/metube_bak
 | 
			
		||||
  if [[ $(echo ":$PATH:" != *":/usr/local/bin:"*) ]]; then
 | 
			
		||||
    echo 'export PATH="/usr/local/bin:$PATH"' >>~/.bashrc
 | 
			
		||||
    source ~/.bashrc
 | 
			
		||||
    if ! command -v deno &>/dev/null; then
 | 
			
		||||
      export DENO_INSTALL="/usr/local"
 | 
			
		||||
      curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
 | 
			
		||||
    else
 | 
			
		||||
      $STD deno upgrade
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
  mv /opt/metube /opt/metube_bak
 | 
			
		||||
  msg_ok "Backup created"
 | 
			
		||||
 | 
			
		||||
  msg_info "Cloning Latest ${APP} Release"
 | 
			
		||||
  $STD git clone https://github.com/alexta69/metube /opt/metube
 | 
			
		||||
  msg_ok "Cloned ${APP}"
 | 
			
		||||
  if check_for_gh_release "metube" "alexta69/metube"; then
 | 
			
		||||
    msg_info "Stopping ${APP} Service"
 | 
			
		||||
    systemctl stop metube
 | 
			
		||||
    msg_ok "Stopped ${APP} Service"
 | 
			
		||||
 | 
			
		||||
  msg_info "Building Frontend"
 | 
			
		||||
  cd /opt/metube/ui
 | 
			
		||||
  $STD npm install
 | 
			
		||||
  $STD node_modules/.bin/ng build
 | 
			
		||||
  msg_ok "Built Frontend"
 | 
			
		||||
    msg_info "Backing up Old Installation"
 | 
			
		||||
    if [[ -d /opt/metube_bak ]]; then
 | 
			
		||||
      rm -rf /opt/metube_bak
 | 
			
		||||
    fi
 | 
			
		||||
    mv /opt/metube /opt/metube_bak
 | 
			
		||||
    msg_ok "Backup created"
 | 
			
		||||
 | 
			
		||||
  PYTHON_VERSION="3.13" setup_uv
 | 
			
		||||
    fetch_and_deploy_gh_release "metube" "alexta69/metube" "tarball" "latest"
 | 
			
		||||
 | 
			
		||||
  msg_info "Setting up Python Environment (uv)"
 | 
			
		||||
  $STD uv venv /opt/metube/.venv
 | 
			
		||||
  $STD /opt/metube/.venv/bin/python -m ensurepip --upgrade
 | 
			
		||||
  $STD /opt/metube/.venv/bin/python -m pip install --upgrade pip
 | 
			
		||||
  $STD /opt/metube/.venv/bin/python -m pip install pipenv
 | 
			
		||||
  msg_ok "Python Environment Ready"
 | 
			
		||||
    msg_info "Building Frontend"
 | 
			
		||||
    cd /opt/metube/ui
 | 
			
		||||
    $STD npm install
 | 
			
		||||
    $STD node_modules/.bin/ng build
 | 
			
		||||
    msg_ok "Built Frontend"
 | 
			
		||||
 | 
			
		||||
  msg_info "Installing Backend Requirements"
 | 
			
		||||
  cd /opt/metube
 | 
			
		||||
  $STD /opt/metube/.venv/bin/pipenv install
 | 
			
		||||
  msg_ok "Installed Backend"
 | 
			
		||||
 | 
			
		||||
  msg_info "Restoring Environment File"
 | 
			
		||||
  if [[ -f /opt/metube_bak/.env ]]; then
 | 
			
		||||
    cp /opt/metube_bak/.env /opt/metube/.env
 | 
			
		||||
  fi
 | 
			
		||||
  msg_ok "Restored .env"
 | 
			
		||||
 | 
			
		||||
  if [[ ! -d /opt/metube/.venv ]]; then
 | 
			
		||||
    msg_info "Migrating to uv-based environment"
 | 
			
		||||
    PYTHON_VERSION="3.13" setup_uv
 | 
			
		||||
    $STD uv venv /opt/metube/.venv
 | 
			
		||||
    $STD /opt/metube/.venv/bin/python -m ensurepip --upgrade
 | 
			
		||||
    $STD /opt/metube/.venv/bin/python -m pip install --upgrade pip
 | 
			
		||||
    $STD /opt/metube/.venv/bin/python -m pip install pipenv
 | 
			
		||||
    $STD /opt/metube/.venv/bin/pipenv install
 | 
			
		||||
    $STD /opt/metube/.venv/bin/pipenv update yt-dlp
 | 
			
		||||
 | 
			
		||||
    msg_info "Patching systemd Service"
 | 
			
		||||
    cat <<EOF >/etc/systemd/system/metube.service
 | 
			
		||||
    msg_info "Installing Backend Requirements"
 | 
			
		||||
    cd /opt/metube
 | 
			
		||||
    $STD uv sync
 | 
			
		||||
    msg_ok "Installed Backend"
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring Environment File"
 | 
			
		||||
    if [[ -f /opt/metube_bak/.env ]]; then
 | 
			
		||||
      cp /opt/metube_bak/.env /opt/metube/.env
 | 
			
		||||
    fi
 | 
			
		||||
    msg_ok "Restored .env"
 | 
			
		||||
 | 
			
		||||
    if grep -q 'pipenv' /etc/systemd/system/metube.service; then
 | 
			
		||||
      msg_info "Patching systemd Service"
 | 
			
		||||
      cat <<EOF >/etc/systemd/system/metube.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Metube - YouTube Downloader
 | 
			
		||||
After=network.target
 | 
			
		||||
@@ -90,30 +84,31 @@ After=network.target
 | 
			
		||||
Type=simple
 | 
			
		||||
WorkingDirectory=/opt/metube
 | 
			
		||||
EnvironmentFile=/opt/metube/.env
 | 
			
		||||
ExecStart=/opt/metube/.venv/bin/pipenv run python3 app/main.py
 | 
			
		||||
ExecStart=/opt/metube/.venv/bin/python3 app/main.py
 | 
			
		||||
Restart=always
 | 
			
		||||
User=root
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
    msg_ok "Patched systemd Service"
 | 
			
		||||
      msg_ok "Patched systemd Service"
 | 
			
		||||
    fi
 | 
			
		||||
    $STD systemctl daemon-reload
 | 
			
		||||
    msg_ok "Service Updated"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning up"
 | 
			
		||||
    rm -rf /opt/metube_bak
 | 
			
		||||
    $STD apt-get -y autoremove
 | 
			
		||||
    $STD apt-get -y autoclean
 | 
			
		||||
    msg_ok "Cleaned Up"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting ${APP} Service"
 | 
			
		||||
    systemctl start metube
 | 
			
		||||
    sleep 1
 | 
			
		||||
    msg_ok "Started ${APP} Service"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Updated Successfully!"
 | 
			
		||||
  fi
 | 
			
		||||
  $STD systemctl daemon-reload
 | 
			
		||||
  msg_ok "Service Updated"
 | 
			
		||||
 | 
			
		||||
  msg_info "Cleaning up"
 | 
			
		||||
  rm -rf /opt/metube_bak
 | 
			
		||||
  $STD apt-get -y autoremove
 | 
			
		||||
  $STD apt-get -y autoclean
 | 
			
		||||
  msg_ok "Cleaned Up"
 | 
			
		||||
 | 
			
		||||
  msg_info "Starting ${APP} Service"
 | 
			
		||||
  systemctl enable -q --now metube
 | 
			
		||||
  sleep 1
 | 
			
		||||
  msg_ok "Started ${APP} Service"
 | 
			
		||||
 | 
			
		||||
  msg_ok "Updated Successfully!"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,9 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
 | 
			
		||||
  if check_for_gh_release "monica" "monicahq/monica"; then
 | 
			
		||||
    msg_info "Stopping Service"
 | 
			
		||||
    systemctl stop apache2
 | 
			
		||||
@@ -43,6 +46,7 @@ function update_script() {
 | 
			
		||||
    cp -r /opt/monica-backup/.env /opt/monica
 | 
			
		||||
    cp -r /opt/monica-backup/storage/* /opt/monica/storage/
 | 
			
		||||
    $STD composer install --no-interaction --no-dev
 | 
			
		||||
    $STD yarn config set ignore-engines true
 | 
			
		||||
    $STD yarn install
 | 
			
		||||
    $STD yarn run production
 | 
			
		||||
    $STD php artisan monica:update --force
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								ct/myip.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ct/myip.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://ipcheck.ing/
 | 
			
		||||
 | 
			
		||||
APP="MyIP"
 | 
			
		||||
var_tags="${var_tags:-network}"
 | 
			
		||||
var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_ram="${var_ram:-512}"
 | 
			
		||||
var_disk="${var_disk:-4}"
 | 
			
		||||
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/myip ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if check_for_gh_release "myip" "jason5ng32/MyIP"; then
 | 
			
		||||
        msg_info "Stopping Services"
 | 
			
		||||
        systemctl stop myip
 | 
			
		||||
        msg_ok "Stopped Services"
 | 
			
		||||
 | 
			
		||||
        cp /opt/myip/.env /opt
 | 
			
		||||
        CLEAN_INSTALL=1 fetch_and_deploy_gh_release "myip" "jason5ng32/MyIP" "tarball"
 | 
			
		||||
        mv /opt/.env /opt/myip
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting Services"
 | 
			
		||||
        systemctl start myip
 | 
			
		||||
        msg_ok "Started Services"
 | 
			
		||||
        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}:18966${CL}"
 | 
			
		||||
@@ -41,7 +41,8 @@ EOF
 | 
			
		||||
  NODE_VERSION="22" setup_nodejs
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating ${APP} LXC"
 | 
			
		||||
  $STD npm update -g n8n
 | 
			
		||||
  rm -rf /usr/lib/node_modules/.n8n-* /usr/lib/node_modules/n8n
 | 
			
		||||
  $STD npm install -g n8n --force
 | 
			
		||||
  systemctl restart n8n
 | 
			
		||||
  msg_ok "Updated Successfully"
 | 
			
		||||
  exit
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								ct/ntfy.sh
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								ct/ntfy.sh
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 tteck
 | 
			
		||||
# Author: tteck (tteckster)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: CrazyWolf13
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://ntfy.sh/
 | 
			
		||||
 | 
			
		||||
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_ram="${var_ram:-512}"
 | 
			
		||||
var_disk="${var_disk:-2}"
 | 
			
		||||
var_os="${var_os:-debian}"
 | 
			
		||||
var_version="${var_version:-12}"
 | 
			
		||||
var_version="${var_version:-13}"
 | 
			
		||||
var_unprivileged="${var_unprivileged:-1}"
 | 
			
		||||
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
@@ -23,13 +23,31 @@ function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
    if [[ ! -d /var ]]; then
 | 
			
		||||
    if [[ ! -d /etc/ntfy ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if [ -f /etc/apt/keyrings/archive.heckel.io.gpg ]; then
 | 
			
		||||
        msg_info "Correcting old Ntfy Repository"
 | 
			
		||||
        rm -f /etc/apt/keyrings/archive.heckel.io.gpg
 | 
			
		||||
        rm -f /etc/apt/sources.list.d/archive.heckel.io.list
 | 
			
		||||
        rm -f /etc/apt/sources.list.d/archive.heckel.io.list.bak
 | 
			
		||||
        rm -f /etc/apt/sources.list.d/archive.heckel.io.sources
 | 
			
		||||
        curl -fsSL -o /etc/apt/keyrings/ntfy.gpg https://archive.ntfy.sh/apt/keyring.gpg
 | 
			
		||||
        cat <<'EOF' >/etc/apt/sources.list.d/ntfy.sources 
 | 
			
		||||
Types: deb
 | 
			
		||||
URIs: https://archive.ntfy.sh/apt/
 | 
			
		||||
Suites: stable
 | 
			
		||||
Components: main
 | 
			
		||||
Signed-By: /etc/apt/keyrings/ntfy.gpg
 | 
			
		||||
EOF
 | 
			
		||||
        msg_ok "Corrected old Ntfy Repository"
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    msg_info "Updating $APP LXC"
 | 
			
		||||
    $STD apt-get update
 | 
			
		||||
    $STD apt-get -y upgrade
 | 
			
		||||
    $STD apt update
 | 
			
		||||
    $STD apt -y upgrade
 | 
			
		||||
    msg_ok "Updated $APP LXC"
 | 
			
		||||
    exit
 | 
			
		||||
}
 | 
			
		||||
@@ -41,4 +59,4 @@ 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}${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,13 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  if ! [[ $(dpkg -s python3-lxml-html-clean 2>/dev/null) ]]; then
 | 
			
		||||
    $STD apt-get install python3-lxml
 | 
			
		||||
    curl -fsSL "http://archive.ubuntu.com/ubuntu/pool/universe/l/lxml-html-clean/python3-lxml-html-clean_0.1.1-1_all.deb" -o /opt/python3-lxml-html-clean.deb
 | 
			
		||||
    $STD dpkg -i /opt/python3-lxml-html-clean.deb
 | 
			
		||||
    rm -f /opt/python3-lxml-html-clean.deb
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://nightly.odoo.com/ | grep -oE 'href="[0-9]+\.[0-9]+/nightly"' | head -n1 | cut -d'"' -f2 | cut -d/ -f1)
 | 
			
		||||
  LATEST_VERSION=$(curl -fsSL "https://nightly.odoo.com/${RELEASE}/nightly/deb/" |
 | 
			
		||||
    grep -oP "odoo_${RELEASE}\.\d+_all\.deb" |
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ function update_script() {
 | 
			
		||||
  fi
 | 
			
		||||
  systemctl stop open-webui.service
 | 
			
		||||
  $STD npm install --force
 | 
			
		||||
  export NODE_OPTIONS="--max-old-space-size=3584"
 | 
			
		||||
  export NODE_OPTIONS="--max-old-space-size=6000"
 | 
			
		||||
  $STD npm run build
 | 
			
		||||
  cd ./backend
 | 
			
		||||
  $STD pip install -r requirements.txt -U
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,8 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
 | 
			
		||||
  if check_for_gh_release "outline" "outline/outline"; then
 | 
			
		||||
    msg_info "Stopping Services"
 | 
			
		||||
    systemctl stop outline
 | 
			
		||||
@@ -37,7 +39,7 @@ function update_script() {
 | 
			
		||||
    cp /opt/outline/.env /opt
 | 
			
		||||
    msg_ok "Backup created"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "outline" "outline/outline" "tarball"
 | 
			
		||||
    CLEAN_INSTALL=1 fetch_and_deploy_gh_release "outline" "outline/outline" "tarball"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP}"
 | 
			
		||||
    cd /opt/outline
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ function update_script() {
 | 
			
		||||
    mv /opt/tandoor /opt/tandoor.bak
 | 
			
		||||
    msg_ok "Backup Created"
 | 
			
		||||
 | 
			
		||||
    NODE_VERSION="20" NODE_MODULE="yarn" setup_nodejs
 | 
			
		||||
    NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
 | 
			
		||||
    PYTHON_VERSION="3.13" setup_uv
 | 
			
		||||
    fetch_and_deploy_gh_release "tandoor" "TandoorRecipes/recipes" "tarball" "latest" "/opt/tandoor"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
 | 
			
		||||
var_ram="${var_ram:-4096}"
 | 
			
		||||
var_disk="${var_disk:-6}"
 | 
			
		||||
var_os="${var_os:-debian}"
 | 
			
		||||
var_version="${var_version:-12}"
 | 
			
		||||
var_version="${var_version:-13}"
 | 
			
		||||
var_unprivileged="${var_unprivileged:-1}"
 | 
			
		||||
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
@@ -33,22 +33,23 @@ function update_script() {
 | 
			
		||||
    systemctl stop tracktor
 | 
			
		||||
    msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Creating Backup"
 | 
			
		||||
    cp /opt/tracktor/app/backend/.env /opt/tracktor.env
 | 
			
		||||
    msg_ok "Created Backup"
 | 
			
		||||
    msg_info "Correcting Services"
 | 
			
		||||
    if [ -f /opt/tracktor/app/backend/.env ]; then
 | 
			
		||||
        mv /opt/tracktor/app/backend/.env /opt/tracktor.env
 | 
			
		||||
        echo 'AUTH_PIN=123456' >> /opt/tracktor.env
 | 
			
		||||
        sed -i 's|^EnvironmentFile=.*|EnvironmentFile=/opt/tracktor.env|' /etc/systemd/system/tracktor.service
 | 
			
		||||
        systemctl daemon-reload
 | 
			
		||||
    fi
 | 
			
		||||
    msg_ok "Corrected Services"
 | 
			
		||||
 | 
			
		||||
    setup_nodejs
 | 
			
		||||
    CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tracktor" "javedh-dev/tracktor" "tarball" "latest" "/opt/tracktor"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP}"
 | 
			
		||||
    msg_info "Updating tracktor"
 | 
			
		||||
    cd /opt/tracktor
 | 
			
		||||
    $STD npm install
 | 
			
		||||
    $STD npm run build
 | 
			
		||||
    msg_ok "Updated $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring Backup"
 | 
			
		||||
    cp /opt/tracktor.env /opt/tracktor/app/backend/.env
 | 
			
		||||
    msg_ok "Restored Backup"
 | 
			
		||||
    msg_ok "Updated tracktor"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Service"
 | 
			
		||||
    systemctl start tracktor
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								ct/upsnap.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								ct/upsnap.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/seriousm4x/UpSnap
 | 
			
		||||
 | 
			
		||||
APP="UpSnap"
 | 
			
		||||
var_tags="${var_tags:-network}"
 | 
			
		||||
var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_ram="${var_ram:-512}"
 | 
			
		||||
var_disk="${var_disk:-2}"
 | 
			
		||||
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/upsnap ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if check_for_gh_release "upsnap" "seriousm4x/UpSnap"; then
 | 
			
		||||
        msg_info "Stopping Services"
 | 
			
		||||
        systemctl stop upsnap
 | 
			
		||||
        msg_ok "Stopped Services"
 | 
			
		||||
 | 
			
		||||
        fetch_and_deploy_gh_release "upsnap" "seriousm4x/UpSnap" "prebuild" "latest" "/opt/upsnap" "UpSnap_*_linux_amd64.zip"
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting Services"
 | 
			
		||||
        systemctl start upsnap
 | 
			
		||||
        msg_ok "Started Services"
 | 
			
		||||
        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}:8090${CL}"
 | 
			
		||||
							
								
								
									
										49
									
								
								ct/verdaccio.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								ct/verdaccio.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: BrynnJKnight
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://verdaccio.org/
 | 
			
		||||
 | 
			
		||||
APP="Verdaccio"
 | 
			
		||||
var_tags="${var_tags:-dev-tools;npm;registry}"
 | 
			
		||||
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 [[ ! -f /etc/systemd/system/verdaccio.service ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating LXC Container"
 | 
			
		||||
  $STD apt update
 | 
			
		||||
  $STD apt -y upgrade
 | 
			
		||||
  msg_ok "Updated LXC Container"
 | 
			
		||||
 | 
			
		||||
  NODE_VERSION="22" NODE_MODULE="verdaccio" setup_nodejs
 | 
			
		||||
  systemctl restart verdaccio
 | 
			
		||||
  msg_ok "Updated Successfully"
 | 
			
		||||
  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}:4873${CL}"
 | 
			
		||||
							
								
								
									
										63
									
								
								ct/warracker.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								ct/warracker.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: BvdBerg01
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/sassanix/Warracker/
 | 
			
		||||
 | 
			
		||||
APP="Warracker"
 | 
			
		||||
var_tags="${var_tags:-warranty}"
 | 
			
		||||
var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_ram="${var_ram:-512}"
 | 
			
		||||
var_disk="${var_disk:-4}"
 | 
			
		||||
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/warracker ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if check_for_gh_release "warracker" "sassanix/Warracker"; then
 | 
			
		||||
        msg_info "Stopping Services"
 | 
			
		||||
        systemctl stop warrackermigration
 | 
			
		||||
        systemctl stop warracker
 | 
			
		||||
        systemctl stop nginx
 | 
			
		||||
        msg_ok "Stopped Services"
 | 
			
		||||
 | 
			
		||||
        fetch_and_deploy_gh_release "warracker" "sassanix/Warracker" "tarball" "latest" "/opt/warracker"
 | 
			
		||||
 | 
			
		||||
        msg_info "Updating Warracker"
 | 
			
		||||
        cd /opt/warracker/backend
 | 
			
		||||
        $STD uv venv .venv
 | 
			
		||||
        $STD source .venv/bin/activate
 | 
			
		||||
        $STD uv pip install -r requirements.txt
 | 
			
		||||
        msg_ok "Updated Warracker"
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting Services"
 | 
			
		||||
        systemctl start warracker
 | 
			
		||||
        systemctl start nginx
 | 
			
		||||
        msg_ok "Started Services"
 | 
			
		||||
        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}${CL}"
 | 
			
		||||
							
								
								
									
										65
									
								
								ct/zabbix.sh
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								ct/zabbix.sh
									
									
									
									
									
								
							@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
 | 
			
		||||
var_ram="${var_ram:-4096}"
 | 
			
		||||
var_disk="${var_disk:-6}"
 | 
			
		||||
var_os="${var_os:-debian}"
 | 
			
		||||
var_version="${var_version:-12}"
 | 
			
		||||
var_version="${var_version:-13}"
 | 
			
		||||
var_unprivileged="${var_unprivileged:-1}"
 | 
			
		||||
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
@@ -23,37 +23,72 @@ function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -f /etc/zabbix/zabbix_server.conf ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  msg_info "Stopping ${APP} Services"
 | 
			
		||||
  systemctl stop zabbix-server zabbix-agent2
 | 
			
		||||
  msg_ok "Stopped ${APP} Services"
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating $APP LXC"
 | 
			
		||||
  . /etc/os-release
 | 
			
		||||
  if [ "$VERSION_CODENAME" != "trixie" ]; then
 | 
			
		||||
    msg_error "Unsupported Debian version: $VERSION_CODENAME – please upgrade to Debian 13 (Trixie) before updating Zabbix."
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if systemctl list-unit-files | grep -q zabbix-agent2.service; then
 | 
			
		||||
    AGENT_SERVICE="zabbix-agent2"
 | 
			
		||||
  else
 | 
			
		||||
    AGENT_SERVICE="zabbix-agent"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Stopping Services"
 | 
			
		||||
  systemctl stop zabbix-server $AGENT_SERVICE
 | 
			
		||||
  msg_ok "Stopped Services"
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating Zabbix"
 | 
			
		||||
  mkdir -p /opt/zabbix-backup/
 | 
			
		||||
  cp /etc/zabbix/zabbix_server.conf /opt/zabbix-backup/
 | 
			
		||||
  cp /etc/apache2/conf-enabled/zabbix.conf /opt/zabbix-backup/
 | 
			
		||||
  cp -R /usr/share/zabbix/ /opt/zabbix-backup/
 | 
			
		||||
  #cp -R /usr/share/zabbix-* /opt/zabbix-backup/ Remove temporary
 | 
			
		||||
 | 
			
		||||
  rm -Rf /etc/apt/sources.list.d/zabbix.list
 | 
			
		||||
  cd /tmp
 | 
			
		||||
  curl -fsSL "$(curl -fsSL https://repo.zabbix.com/zabbix/ |
 | 
			
		||||
    grep -oP '(?<=href=")[0-9]+\.[0-9]+(?=/")' | sort -V | tail -n1 |
 | 
			
		||||
    xargs -I{} echo "https://repo.zabbix.com/zabbix/{}/release/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian12_all.deb")" \
 | 
			
		||||
    -o /tmp/zabbix-release_latest+debian12_all.deb
 | 
			
		||||
  $STD dpkg -i zabbix-release_latest+debian12_all.deb
 | 
			
		||||
  $STD apt-get update
 | 
			
		||||
  $STD apt-get install --only-upgrade zabbix-server-pgsql zabbix-frontend-php zabbix-agent2 zabbix-agent2-plugin-*
 | 
			
		||||
    xargs -I{} echo "https://repo.zabbix.com/zabbix/{}/release/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian13_all.deb")" \
 | 
			
		||||
    -o /tmp/zabbix-release_latest+debian13_all.deb
 | 
			
		||||
  $STD dpkg -i zabbix-release_latest+debian13_all.deb
 | 
			
		||||
  $STD apt update
 | 
			
		||||
 | 
			
		||||
  msg_info "Starting ${APP} Services"
 | 
			
		||||
  systemctl start zabbix-server zabbix-agent2
 | 
			
		||||
  $STD apt install --only-upgrade zabbix-server-pgsql zabbix-frontend-php php8.4-pgsql
 | 
			
		||||
 | 
			
		||||
  if [ "$AGENT_SERVICE" = "zabbix-agent2" ]; then
 | 
			
		||||
    $STD apt install --only-upgrade zabbix-agent2 zabbix-agent2-plugin-postgresql
 | 
			
		||||
    if [ -f /etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf ]; then
 | 
			
		||||
      sed -i 's|^Plugins.NVIDIA.System.Path=.*|# Plugins.NVIDIA.System.Path=/usr/libexec/zabbix/zabbix-agent2-plugin-nvidia-gpu|' \
 | 
			
		||||
        /etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    $STD apt install --only-upgrade zabbix-agent
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if command -v fping >/dev/null 2>&1; then
 | 
			
		||||
    FPING_PATH=$(command -v fping)
 | 
			
		||||
    sed -i "s|^#\?FpingLocation=.*|FpingLocation=$FPING_PATH|" /etc/zabbix/zabbix_server.conf
 | 
			
		||||
  fi
 | 
			
		||||
  if command -v fping6 >/dev/null 2>&1; then
 | 
			
		||||
    FPING6_PATH=$(command -v fping6)
 | 
			
		||||
    sed -i "s|^#\?Fping6Location=.*|Fping6Location=$FPING6_PATH|" /etc/zabbix/zabbix_server.conf
 | 
			
		||||
  fi
 | 
			
		||||
  msg_ok "Updated Zabbix"
 | 
			
		||||
 | 
			
		||||
  msg_info "Starting Services"
 | 
			
		||||
  systemctl start zabbix-server $AGENT_SERVICE
 | 
			
		||||
  systemctl restart apache2
 | 
			
		||||
  msg_ok "Started ${APP} Services"
 | 
			
		||||
  msg_ok "Started Services"
 | 
			
		||||
 | 
			
		||||
  msg_info "Cleaning Up"
 | 
			
		||||
  rm -rf /tmp/zabbix-release_latest+debian12_all.deb
 | 
			
		||||
  rm -rf /tmp/zabbix-release_latest+debian13_all.deb
 | 
			
		||||
  msg_ok "Cleaned"
 | 
			
		||||
  msg_ok "Updated Successfully"
 | 
			
		||||
  exit
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
        "ram": 2048,
 | 
			
		||||
        "hdd": 4,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
      "script": "ct/booklore.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 3,
 | 
			
		||||
        "ram": 2048,
 | 
			
		||||
        "ram": 3072,
 | 
			
		||||
        "hdd": 7,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
 
 | 
			
		||||
@@ -32,5 +32,10 @@
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": []
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "info",
 | 
			
		||||
      "text": "The file `/etc/sysconfig/CosmosCloud` is optional. If you need custom settings, you can create it yourself."
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
  "website": null,
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/proxmox.webp",
 | 
			
		||||
  "config_path": "",
 | 
			
		||||
  "description": "This script will add/remove a crontab schedule that updates all LXCs every Sunday at midnight.",
 | 
			
		||||
  "description": "This script will add/remove a crontab schedule that updates the operating system of all LXCs every Sunday at midnight.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,10 @@
 | 
			
		||||
    {
 | 
			
		||||
      "type": "info",
 | 
			
		||||
      "text": "Synapse-Admin is running on port 5173"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "info",
 | 
			
		||||
      "text": "For bridges Installation methods (WhatsApp, Signal, Discord, etc.), see: ´https://docs.mau.fi/bridges/go/setup.html´"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								frontend/public/json/ghostfolio.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								frontend/public/json/ghostfolio.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Ghostfolio",
 | 
			
		||||
  "slug": "ghostfolio",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    23
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-09-29",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 3333,
 | 
			
		||||
  "documentation": "https://github.com/ghostfolio/ghostfolio?tab=readme-ov-file#self-hosting",
 | 
			
		||||
  "website": "https://ghostfol.io/",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/ghostfolio.webp",
 | 
			
		||||
  "config_path": "/opt/ghostfolio/.env",
 | 
			
		||||
  "description": "Ghostfolio is an open source wealth management software built with web technology. The application empowers busy people to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/ghostfolio.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 2,
 | 
			
		||||
        "ram": 4096,
 | 
			
		||||
        "hdd": 8,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Create your first user account by visiting the web interface and clicking 'Get Started'. The first user will automatically get admin privileges.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Database and Redis credentials: `cat ~/ghostfolio.creds`",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Optional: CoinGecko API keys can be added during installation or later in the .env file for enhanced cryptocurrency data.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Build process requires 4GB RAM (runtime: ~2GB). A temporary swap file will be created automatically if insufficient memory is detected.",
 | 
			
		||||
      "type": "warning"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								frontend/public/json/goaway.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								frontend/public/json/goaway.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "GoAway",
 | 
			
		||||
  "slug": "goaway",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    5
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-09-25",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 8080,
 | 
			
		||||
  "documentation": "https://github.com/pommee/goaway#configuration-file",
 | 
			
		||||
  "config_path": "/opt/goaway/config/settings.yaml",
 | 
			
		||||
  "website": "https://github.com/pommee/goaway",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/goaway.webp",
 | 
			
		||||
  "description": "Lightweight DNS sinkhole written in Go with a modern dashboard client. Very good looking new alternative to Pi-Hole and Adguard Home.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/goaway.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 1,
 | 
			
		||||
        "ram": 1024,
 | 
			
		||||
        "hdd": 4,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Type `cat ~/goaway.creds` to see login credentials.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								frontend/public/json/joplin-server.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								frontend/public/json/joplin-server.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Joplin Server",
 | 
			
		||||
  "slug": "joplin-server",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    12
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-09-24",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 22300,
 | 
			
		||||
  "documentation": "https://joplinapp.org/help/",
 | 
			
		||||
  "config_path": "/opt/joplin-server/.env",
 | 
			
		||||
  "website": "https://joplinapp.org/",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/joplin.webp",
 | 
			
		||||
  "description": "Joplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/joplin-server.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 2,
 | 
			
		||||
        "ram": 4096,
 | 
			
		||||
        "hdd": 20,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": "admin@localhost",
 | 
			
		||||
    "password": "admin"
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Application can take some time to build, depending on your host speed. Please be patient.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
        "ram": 2048,
 | 
			
		||||
        "hdd": 4,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Container LXC Deletion",
 | 
			
		||||
  "name": "PVE LXC Deletion",
 | 
			
		||||
  "slug": "lxc-delete",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    1
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,186 @@
 | 
			
		||||
{
 | 
			
		||||
	"categories": [
 | 
			
		||||
		{ "name": "Proxmox & Virtualization", "id": 1, "sort_order": 1.0, "description": "Tools and scripts to manage Proxmox VE and virtualization platforms effectively." },
 | 
			
		||||
		{ "name": "Operating Systems", "id": 2, "sort_order": 2.0, "description": "Scripts for deploying and managing various operating systems." },
 | 
			
		||||
		{ "name": "Containers & Docker", "id": 3, "sort_order": 3.0, "description": "Solutions for containerization using Docker and related technologies." },
 | 
			
		||||
		{ "name": "Network & Firewall", "id": 4, "sort_order": 4.0, "description": "Enhance network security and configure firewalls with ease." },
 | 
			
		||||
		{ "name": "Adblock & DNS", "id": 5, "sort_order": 5.0, "description": "Optimize your network with DNS and ad-blocking solutions." },
 | 
			
		||||
		{ "name": "Authentication & Security", "id": 6, "sort_order": 6.0, "description": "Secure your infrastructure with authentication and security tools." },
 | 
			
		||||
		{ "name": "Backup & Recovery", "id": 7, "sort_order": 7.0, "description": "Reliable backup and recovery scripts to protect your data." },
 | 
			
		||||
		{ "name": "Databases", "id": 8, "sort_order": 8.0, "description": "Deploy and manage robust database systems with ease." },
 | 
			
		||||
		{ "name": "Monitoring & Analytics", "id": 9, "sort_order": 9.0, "description": "Monitor system performance and analyze data seamlessly." },
 | 
			
		||||
		{ "name": "Dashboards & Frontends", "id": 10, "sort_order": 10.0, "description": "Create interactive dashboards and user-friendly frontends." },
 | 
			
		||||
		{ "name": "Files & Downloads", "id": 11, "sort_order": 11.0, "description": "Manage file sharing and downloading solutions efficiently." },
 | 
			
		||||
		{ "name": "Documents & Notes", "id": 12, "sort_order": 12.0, "description": "Organize and manage documents and note-taking tools." },
 | 
			
		||||
		{ "name": "Media & Streaming", "id": 13, "sort_order": 13.0, "description": "Stream and manage media effortlessly across devices." },
 | 
			
		||||
		{ "name": "*Arr Suite", "id": 14, "sort_order": 14.0, "description": "Automated media management with the popular *Arr suite tools." },
 | 
			
		||||
		{ "name": "NVR & Cameras", "id": 15, "sort_order": 15.0, "description": "Manage network video recorders and camera setups." },
 | 
			
		||||
		{ "name": "IoT & Smart Home", "id": 16, "sort_order": 16.0, "description": "Control and automate IoT devices and smart home systems." },
 | 
			
		||||
		{ "name": "ZigBee, Z-Wave & Matter", "id": 17, "sort_order": 17.0, "description": "Solutions for ZigBee, Z-Wave, and Matter-based device management." },
 | 
			
		||||
		{ "name": "MQTT & Messaging", "id": 18, "sort_order": 18.0, "description": "Set up reliable messaging and MQTT-based communication systems." },
 | 
			
		||||
		{ "name": "Automation & Scheduling", "id": 19, "sort_order": 19.0, "description": "Automate tasks and manage scheduling with powerful tools." },
 | 
			
		||||
		{ "name": "AI / Coding & Dev-Tools", "id": 20, "sort_order": 20.0, "description": "Leverage AI and developer tools for smarter coding workflows." },
 | 
			
		||||
		{ "name": "Webservers & Proxies", "id": 21, "sort_order": 21.0, "description": "Deploy and configure web servers and proxy solutions." },
 | 
			
		||||
		{ "name": "Bots & ChatOps", "id": 22, "sort_order": 22.0, "description": "Enhance collaboration with bots and ChatOps integrations." },
 | 
			
		||||
		{ "name": "Finance & Budgeting", "id": 23, "sort_order": 23.0, "description": "Track expenses and manage budgets efficiently." },
 | 
			
		||||
		{ "name": "Gaming & Leisure", "id": 24, "sort_order": 24.0, "description": "Scripts for gaming servers and leisure-related tools." },
 | 
			
		||||
		{ "name": "Business & ERP", "id": 25, "sort_order": 25.0, "description": "Streamline business operations with ERP and management tools." },
 | 
			
		||||
		{ "name": "Miscellaneous", "id": 0, "sort_order": 99.0, "description": "General scripts and tools that don't fit into other categories." }
 | 
			
		||||
	]
 | 
			
		||||
  "categories": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Proxmox & Virtualization",
 | 
			
		||||
      "id": 1,
 | 
			
		||||
      "sort_order": 1.0,
 | 
			
		||||
      "description": "Tools and scripts to manage Proxmox VE and virtualization platforms effectively.",
 | 
			
		||||
      "icon": "server"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Operating Systems",
 | 
			
		||||
      "id": 2,
 | 
			
		||||
      "sort_order": 2.0,
 | 
			
		||||
      "description": "Scripts for deploying and managing various operating systems.",
 | 
			
		||||
      "icon": "monitor"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Containers & Docker",
 | 
			
		||||
      "id": 3,
 | 
			
		||||
      "sort_order": 3.0,
 | 
			
		||||
      "description": "Solutions for containerization using Docker and related technologies.",
 | 
			
		||||
      "icon": "box"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Network & Firewall",
 | 
			
		||||
      "id": 4,
 | 
			
		||||
      "sort_order": 4.0,
 | 
			
		||||
      "description": "Enhance network security and configure firewalls with ease.",
 | 
			
		||||
      "icon": "shield"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Adblock & DNS",
 | 
			
		||||
      "id": 5,
 | 
			
		||||
      "sort_order": 5.0,
 | 
			
		||||
      "description": "Optimize your network with DNS and ad-blocking solutions.",
 | 
			
		||||
      "icon": "ban"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Authentication & Security",
 | 
			
		||||
      "id": 6,
 | 
			
		||||
      "sort_order": 6.0,
 | 
			
		||||
      "description": "Secure your infrastructure with authentication and security tools.",
 | 
			
		||||
      "icon": "lock"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Backup & Recovery",
 | 
			
		||||
      "id": 7,
 | 
			
		||||
      "sort_order": 7.0,
 | 
			
		||||
      "description": "Reliable backup and recovery scripts to protect your data.",
 | 
			
		||||
      "icon": "archive"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Databases",
 | 
			
		||||
      "id": 8,
 | 
			
		||||
      "sort_order": 8.0,
 | 
			
		||||
      "description": "Deploy and manage robust database systems with ease.",
 | 
			
		||||
      "icon": "database"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Monitoring & Analytics",
 | 
			
		||||
      "id": 9,
 | 
			
		||||
      "sort_order": 9.0,
 | 
			
		||||
      "description": "Monitor system performance and analyze data seamlessly.",
 | 
			
		||||
      "icon": "bar-chart"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Dashboards & Frontends",
 | 
			
		||||
      "id": 10,
 | 
			
		||||
      "sort_order": 10.0,
 | 
			
		||||
      "description": "Create interactive dashboards and user-friendly frontends.",
 | 
			
		||||
      "icon": "layout"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Files & Downloads",
 | 
			
		||||
      "id": 11,
 | 
			
		||||
      "sort_order": 11.0,
 | 
			
		||||
      "description": "Manage file sharing and downloading solutions efficiently.",
 | 
			
		||||
      "icon": "download"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Documents & Notes",
 | 
			
		||||
      "id": 12,
 | 
			
		||||
      "sort_order": 12.0,
 | 
			
		||||
      "description": "Organize and manage documents and note-taking tools.",
 | 
			
		||||
      "icon": "file-text"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Media & Streaming",
 | 
			
		||||
      "id": 13,
 | 
			
		||||
      "sort_order": 13.0,
 | 
			
		||||
      "description": "Stream and manage media effortlessly across devices.",
 | 
			
		||||
      "icon": "play"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "*Arr Suite",
 | 
			
		||||
      "id": 14,
 | 
			
		||||
      "sort_order": 14.0,
 | 
			
		||||
      "description": "Automated media management with the popular *Arr suite tools.",
 | 
			
		||||
      "icon": "tv"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "NVR & Cameras",
 | 
			
		||||
      "id": 15,
 | 
			
		||||
      "sort_order": 15.0,
 | 
			
		||||
      "description": "Manage network video recorders and camera setups.",
 | 
			
		||||
      "icon": "camera"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "IoT & Smart Home",
 | 
			
		||||
      "id": 16,
 | 
			
		||||
      "sort_order": 16.0,
 | 
			
		||||
      "description": "Control and automate IoT devices and smart home systems.",
 | 
			
		||||
      "icon": "home"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "ZigBee, Z-Wave & Matter",
 | 
			
		||||
      "id": 17,
 | 
			
		||||
      "sort_order": 17.0,
 | 
			
		||||
      "description": "Solutions for ZigBee, Z-Wave, and Matter-based device management.",
 | 
			
		||||
      "icon": "radio"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "MQTT & Messaging",
 | 
			
		||||
      "id": 18,
 | 
			
		||||
      "sort_order": 18.0,
 | 
			
		||||
      "description": "Set up reliable messaging and MQTT-based communication systems.",
 | 
			
		||||
      "icon": "message-circle"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Automation & Scheduling",
 | 
			
		||||
      "id": 19,
 | 
			
		||||
      "sort_order": 19.0,
 | 
			
		||||
      "description": "Automate tasks and manage scheduling with powerful tools.",
 | 
			
		||||
      "icon": "clock"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "AI / Coding & Dev-Tools",
 | 
			
		||||
      "id": 20,
 | 
			
		||||
      "sort_order": 20.0,
 | 
			
		||||
      "description": "Leverage AI and developer tools for smarter coding workflows.",
 | 
			
		||||
      "icon": "code"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Webservers & Proxies",
 | 
			
		||||
      "id": 21,
 | 
			
		||||
      "sort_order": 21.0,
 | 
			
		||||
      "description": "Deploy and configure web servers and proxy solutions.",
 | 
			
		||||
      "icon": "globe"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Bots & ChatOps",
 | 
			
		||||
      "id": 22,
 | 
			
		||||
      "sort_order": 22.0,
 | 
			
		||||
      "description": "Enhance collaboration with bots and ChatOps integrations.",
 | 
			
		||||
      "icon": "bot"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Finance & Budgeting",
 | 
			
		||||
      "id": 23,
 | 
			
		||||
      "sort_order": 23.0,
 | 
			
		||||
      "description": "Track expenses and manage budgets efficiently.",
 | 
			
		||||
      "icon": "dollar-sign"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Gaming & Leisure",
 | 
			
		||||
      "id": 24,
 | 
			
		||||
      "sort_order": 24.0,
 | 
			
		||||
      "description": "Scripts for gaming servers and leisure-related tools.",
 | 
			
		||||
      "icon": "gamepad-2"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Business & ERP",
 | 
			
		||||
      "id": 25,
 | 
			
		||||
      "sort_order": 25.0,
 | 
			
		||||
      "description": "Streamline business operations with ERP and management tools.",
 | 
			
		||||
      "icon": "building"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Miscellaneous",
 | 
			
		||||
      "id": 0,
 | 
			
		||||
      "sort_order": 99.0,
 | 
			
		||||
      "description": "General scripts and tools that don't fit into other categories.",
 | 
			
		||||
      "icon": "more-horizontal"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								frontend/public/json/myip.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								frontend/public/json/myip.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "MyIP",
 | 
			
		||||
  "slug": "myip",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    4
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-09-29",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "config_path": "/opt/myip/.env",
 | 
			
		||||
  "interface_port": 18966,
 | 
			
		||||
  "documentation": "https://github.com/jason5ng32/MyIP#-environment-variable",
 | 
			
		||||
  "website": "https://ipcheck.ing/",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/myip.webp",
 | 
			
		||||
  "description": "The best IP Toolbox. Easy to check what's your IPs, IP geolocation, check for DNS leaks, examine WebRTC connections, speed test, ping test, MTR test, check website availability, whois search and more!",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/myip.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 1,
 | 
			
		||||
        "ram": 512,
 | 
			
		||||
        "hdd": 2,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": []
 | 
			
		||||
}
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
        "ram": 512,
 | 
			
		||||
        "hdd": 2,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
 
 | 
			
		||||
@@ -31,5 +31,10 @@
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": []
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Script contains optional installation of Ollama.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 3000,
 | 
			
		||||
  "documentation": "https://tracktor.bytedge.in/introduction.html",
 | 
			
		||||
  "config_path": "/opt/tracktor/app/server/.env",
 | 
			
		||||
  "config_path": "/opt/tracktor.env",
 | 
			
		||||
  "website": "https://tracktor.bytedge.in/",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/tracktor.webp",
 | 
			
		||||
  "description": "Tracktor is an open-source web application for comprehensive vehicle management.\nEasily track fuel consumption, maintenance, insurance, and regulatory documents for all your vehicles in one place.",
 | 
			
		||||
@@ -23,17 +23,17 @@
 | 
			
		||||
        "ram": 1024,
 | 
			
		||||
        "hdd": 6,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
    "password": "123456"
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Please check and update the '/opt/tracktor/app/backend/.env' file if using behind reverse proxy.",
 | 
			
		||||
      "text": "Please check and update the '/opt/tracktor.env' file if using behind reverse proxy.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
  "website": null,
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/linuxcontainers.webp",
 | 
			
		||||
  "config_path": "",
 | 
			
		||||
  "description": "This script has been created to simplify and speed up the process of updating all LXC containers across various Linux distributions, such as Ubuntu, Debian, Devuan, Alpine Linux, CentOS-Rocky-Alma, Fedora, and ArchLinux. It's designed to automatically skip templates and specific containers during the update, enhancing its convenience and usability.",
 | 
			
		||||
  "description": "This script has been created to simplify and speed up the process of updating the operating system running inside LXC containers across various Linux distributions, such as Ubuntu, Debian, Devuan, Alpine Linux, CentOS-Rocky-Alma, Fedora, and ArchLinux. It's designed to automatically skip templates and specific containers during the update, enhancing its convenience and usability.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
@@ -35,6 +35,10 @@
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Execute within the Proxmox shell",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "The script updates only the operating system of the LXC container. It DOES NOT update the application installed within the container!",
 | 
			
		||||
      "type": "warning"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								frontend/public/json/upsnap.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								frontend/public/json/upsnap.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "UpSnap",
 | 
			
		||||
  "slug": "upsnap",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    4
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-09-23",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 8090,
 | 
			
		||||
  "documentation": "https://github.com/seriousm4x/UpSnap/wiki",
 | 
			
		||||
  "config_path": "",
 | 
			
		||||
  "website": "https://github.com/seriousm4x/UpSnap",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/upsnap.webp",
 | 
			
		||||
  "description": "UpSnap is a self-hosted web app that lets you wake up, manage and monitor devices on your network with ease. Built with SvelteKit, Go and PocketBase, it offers a clean dashboard, scheduled wake-ups, device discovery and secure user management.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/upsnap.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 1,
 | 
			
		||||
        "ram": 512,
 | 
			
		||||
        "hdd": 2,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "The first user you register will be the admin user.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								frontend/public/json/verdaccio.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								frontend/public/json/verdaccio.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Verdaccio",
 | 
			
		||||
  "slug": "verdaccio",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    20
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-09-29",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 4873,
 | 
			
		||||
  "documentation": "https://verdaccio.org/docs/what-is-verdaccio",
 | 
			
		||||
  "website": "https://verdaccio.org/",
 | 
			
		||||
  "logo": "https://verdaccio.org/img/logo/symbol/png/verdaccio-tiny.png",
 | 
			
		||||
  "config_path": "/opt/verdaccio/config/config.yaml",
 | 
			
		||||
  "description": "Verdaccio is a lightweight private npm proxy registry built with Node.js. It allows you to host your own npm registry with minimal configuration, providing a private npm repository for your projects. Verdaccio supports npm, yarn, and pnpm, and can cache packages from the public npm registry, allowing for faster installs and protection against npm registry outages. It includes a web interface for browsing packages, authentication and authorization features, and can be easily integrated into your development workflow.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/verdaccio.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 2,
 | 
			
		||||
        "ram": 2048,
 | 
			
		||||
        "hdd": 8,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "To create the first user, run: npm adduser --registry http://<container-ip>:4873",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										40
									
								
								frontend/public/json/warracker.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								frontend/public/json/warracker.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Warracker",
 | 
			
		||||
  "slug": "warracker",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    12
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-09-29",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 80,
 | 
			
		||||
  "documentation": null,
 | 
			
		||||
  "config_path": "/opt/.env",
 | 
			
		||||
  "website": "https://warracker.com/",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/warracker.webp",
 | 
			
		||||
  "description": "Warracker is an open source, self-hostable warranty tracker to monitor expirations, store receipts, files. You own the data, your rules!",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/warracker.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 1,
 | 
			
		||||
        "ram": 512,
 | 
			
		||||
        "hdd": 4,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "The first user you register will be the admin user.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
        "ram": 4096,
 | 
			
		||||
        "hdd": 6,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
        "version": "13"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
@@ -33,11 +33,19 @@
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Database credentials: `cat zabbix.creds`",
 | 
			
		||||
      "text": "Database credentials: `cat ~/zabbix.creds`",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Zabbix agent 2 is used by default",
 | 
			
		||||
      "text": "You can choose between Zabbix agent (classic) and agent2 (modern) during installation",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "For agent2 the PostgreSQL plugin is installed by default; all plugins are optional",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "If agent2 with NVIDIA plugin is installed in an environment without GPU, the installer disables it automatically",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
 
 | 
			
		||||
@@ -103,18 +103,22 @@ export default function RootLayout({
 | 
			
		||||
      <body className={inter.className}>
 | 
			
		||||
        <ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange>
 | 
			
		||||
          <div className="flex w-full flex-col justify-center">
 | 
			
		||||
            <Navbar />
 | 
			
		||||
            <div className="flex min-h-screen flex-col justify-center">
 | 
			
		||||
              <div className="flex w-full justify-center">
 | 
			
		||||
                <div className="w-full max-w-[1440px] ">
 | 
			
		||||
                  <QueryProvider>
 | 
			
		||||
                    <NuqsAdapter>{children}</NuqsAdapter>
 | 
			
		||||
                  </QueryProvider>
 | 
			
		||||
                  <Toaster richColors />
 | 
			
		||||
            <NuqsAdapter>
 | 
			
		||||
              <QueryProvider>
 | 
			
		||||
 | 
			
		||||
                <Navbar />
 | 
			
		||||
                <div className="flex min-h-screen flex-col justify-center">
 | 
			
		||||
                  <div className="flex w-full justify-center">
 | 
			
		||||
                    <div className="w-full max-w-[1440px] ">
 | 
			
		||||
                      {children}
 | 
			
		||||
                      <Toaster richColors />
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <Footer />
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <Footer />
 | 
			
		||||
            </div>
 | 
			
		||||
              </QueryProvider>
 | 
			
		||||
 | 
			
		||||
            </NuqsAdapter>
 | 
			
		||||
          </div>
 | 
			
		||||
        </ThemeProvider>
 | 
			
		||||
      </body>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import { useCallback, useEffect, useRef, useState } from "react";
 | 
			
		||||
import * as Icons from "lucide-react";
 | 
			
		||||
import Image from "next/image";
 | 
			
		||||
import Link from "next/link";
 | 
			
		||||
 | 
			
		||||
@@ -9,18 +10,31 @@ import { formattedBadge } from "@/components/command-menu";
 | 
			
		||||
import { basePath } from "@/config/site-config";
 | 
			
		||||
import { cn } from "@/lib/utils";
 | 
			
		||||
 | 
			
		||||
function getCategoryIcon(iconName: string) {
 | 
			
		||||
  // Convert kebab-case to PascalCase for Lucide icon names
 | 
			
		||||
  const pascalCaseName = iconName
 | 
			
		||||
    .split("-")
 | 
			
		||||
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
 | 
			
		||||
    .join("");
 | 
			
		||||
 | 
			
		||||
  const IconComponent = (Icons as any)[pascalCaseName];
 | 
			
		||||
  return IconComponent ? <IconComponent className="size-4 text-[#0083c3] mr-2" /> : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default function ScriptAccordion({
 | 
			
		||||
  items,
 | 
			
		||||
  selectedScript,
 | 
			
		||||
  setSelectedScript,
 | 
			
		||||
  selectedCategory,
 | 
			
		||||
  setSelectedCategory,
 | 
			
		||||
  onItemSelect,
 | 
			
		||||
}: {
 | 
			
		||||
  items: Category[];
 | 
			
		||||
  selectedScript: string | null;
 | 
			
		||||
  setSelectedScript: (script: string | null) => void;
 | 
			
		||||
  selectedCategory: string | null;
 | 
			
		||||
  setSelectedCategory: (category: string | null) => void;
 | 
			
		||||
  onItemSelect?: () => void;
 | 
			
		||||
}) {
 | 
			
		||||
  const [expandedItem, setExpandedItem] = useState<string | undefined>(undefined);
 | 
			
		||||
  const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({});
 | 
			
		||||
@@ -65,7 +79,7 @@ export default function ScriptAccordion({
 | 
			
		||||
      value={expandedItem}
 | 
			
		||||
      onValueChange={handleAccordionChange}
 | 
			
		||||
      collapsible
 | 
			
		||||
      className="overflow-y-scroll max-h-[calc(100vh-225px)] overflow-x-hidden p-2"
 | 
			
		||||
      className="overflow-y-scroll sm:max-h-[calc(100vh-209px)] overflow-x-hidden p-1"
 | 
			
		||||
    >
 | 
			
		||||
      {items.map(category => (
 | 
			
		||||
        <AccordionItem
 | 
			
		||||
@@ -81,10 +95,13 @@ export default function ScriptAccordion({
 | 
			
		||||
            )}
 | 
			
		||||
          >
 | 
			
		||||
            <div className="mr-2 flex w-full items-center justify-between">
 | 
			
		||||
              <span className="pl-2 text-left">
 | 
			
		||||
                {category.name}
 | 
			
		||||
                {" "}
 | 
			
		||||
              </span>
 | 
			
		||||
              <div className="flex items-center pl-2 text-left">
 | 
			
		||||
                {getCategoryIcon(category.icon)}
 | 
			
		||||
                <span>
 | 
			
		||||
                  {category.name}
 | 
			
		||||
                  {" "}
 | 
			
		||||
                </span>
 | 
			
		||||
              </div>
 | 
			
		||||
              <span className="rounded-full bg-gray-200 px-2 py-1 text-xs text-muted-foreground hover:no-underline dark:bg-blue-800/20">
 | 
			
		||||
                {category.scripts.length}
 | 
			
		||||
              </span>
 | 
			
		||||
@@ -103,14 +120,14 @@ export default function ScriptAccordion({
 | 
			
		||||
                      query: { id: script.slug, category: category.name },
 | 
			
		||||
                    }}
 | 
			
		||||
                    prefetch={false}
 | 
			
		||||
                    className={`flex cursor-pointer items-center justify-between gap-1 px-1 py-1 text-muted-foreground hover:rounded-lg hover:bg-accent/60 hover:dark:bg-accent/20 ${
 | 
			
		||||
                      selectedScript === script.slug
 | 
			
		||||
                        ? "rounded-lg bg-accent font-semibold dark:bg-accent/30 dark:text-white"
 | 
			
		||||
                        : ""
 | 
			
		||||
                    className={`flex cursor-pointer items-center justify-between gap-1 px-1 py-1 text-muted-foreground hover:rounded-lg hover:bg-accent/60 hover:dark:bg-accent/20 ${selectedScript === script.slug
 | 
			
		||||
                      ? "rounded-lg bg-accent font-semibold dark:bg-accent/30 dark:text-white"
 | 
			
		||||
                      : ""
 | 
			
		||||
                    }`}
 | 
			
		||||
                    onClick={() => {
 | 
			
		||||
                      handleSelected(script.slug);
 | 
			
		||||
                      setSelectedCategory(category.name);
 | 
			
		||||
                      onItemSelect?.();
 | 
			
		||||
                    }}
 | 
			
		||||
                    ref={(el) => {
 | 
			
		||||
                      linkRefs.current[script.slug] = el;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,21 +2,29 @@
 | 
			
		||||
 | 
			
		||||
import type { Category, Script } from "@/lib/types";
 | 
			
		||||
 | 
			
		||||
import { cn } from "@/lib/utils";
 | 
			
		||||
 | 
			
		||||
import ScriptAccordion from "./script-accordion";
 | 
			
		||||
 | 
			
		||||
type SidebarProps = {
 | 
			
		||||
  items: Category[];
 | 
			
		||||
  selectedScript: string | null;
 | 
			
		||||
  setSelectedScript: (script: string | null) => void;
 | 
			
		||||
  selectedCategory: string | null;
 | 
			
		||||
  setSelectedCategory: (category: string | null) => void;
 | 
			
		||||
  onItemSelect?: () => void;
 | 
			
		||||
  className?: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function Sidebar({
 | 
			
		||||
  items,
 | 
			
		||||
  selectedScript,
 | 
			
		||||
  setSelectedScript,
 | 
			
		||||
  selectedCategory,
 | 
			
		||||
  setSelectedCategory,
 | 
			
		||||
}: {
 | 
			
		||||
  items: Category[];
 | 
			
		||||
  selectedScript: string | null;
 | 
			
		||||
  setSelectedScript: (script: string | null) => void;
 | 
			
		||||
  selectedCategory: string | null;
 | 
			
		||||
  setSelectedCategory: (category: string | null) => void;
 | 
			
		||||
}) {
 | 
			
		||||
  onItemSelect,
 | 
			
		||||
  className,
 | 
			
		||||
}: SidebarProps) {
 | 
			
		||||
  const uniqueScripts = items.reduce((acc, category) => {
 | 
			
		||||
    for (const script of category.scripts) {
 | 
			
		||||
      if (!acc.some(s => s.name === script.name)) {
 | 
			
		||||
@@ -27,7 +35,7 @@ function Sidebar({
 | 
			
		||||
  }, [] as Script[]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="flex min-w-[350px] flex-col sm:max-w-[350px]">
 | 
			
		||||
    <div className={cn("flex w-full flex-col sm:min-w-[350px] sm:max-w-[350px]", className)}>
 | 
			
		||||
      <div className="flex items-end justify-between pb-4">
 | 
			
		||||
        <h1 className="text-xl font-bold">Categories</h1>
 | 
			
		||||
        <p className="text-xs italic text-muted-foreground">
 | 
			
		||||
@@ -43,6 +51,7 @@ function Sidebar({
 | 
			
		||||
          setSelectedScript={setSelectedScript}
 | 
			
		||||
          selectedCategory={selectedCategory}
 | 
			
		||||
          setSelectedCategory={setSelectedCategory}
 | 
			
		||||
          onItemSelect={onItemSelect}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
"use client";
 | 
			
		||||
import { useEffect, useState } from "react";
 | 
			
		||||
import { Suspense, useEffect, useState } from "react";
 | 
			
		||||
import Image from "next/image";
 | 
			
		||||
import Link from "next/link";
 | 
			
		||||
 | 
			
		||||
@@ -8,6 +8,7 @@ import { navbarLinks } from "@/config/site-config";
 | 
			
		||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
 | 
			
		||||
import { GitHubStarsButton } from "./animate-ui/components/buttons/github-stars";
 | 
			
		||||
import { Button } from "./animate-ui/components/buttons/button";
 | 
			
		||||
import MobileSidebar from "./navigation/mobile-sidebar";
 | 
			
		||||
import { ThemeToggle } from "./ui/theme-toggle";
 | 
			
		||||
import CommandMenu from "./command-menu";
 | 
			
		||||
 | 
			
		||||
@@ -30,39 +31,45 @@ function Navbar() {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <div
 | 
			
		||||
        className={`fixed left-0 top-0 z-50 flex w-screen justify-center px-4 xl:px-0 ${
 | 
			
		||||
          isScrolled ? "glass border-b bg-background/50" : ""
 | 
			
		||||
        className={`fixed left-0 top-0 z-50 flex w-screen justify-center px-4 xl:px-0 ${isScrolled ? "glass border-b bg-background/50" : ""
 | 
			
		||||
        }`}
 | 
			
		||||
      >
 | 
			
		||||
        <div className="flex h-20 w-full max-w-[1440px] items-center justify-between sm:flex-row">
 | 
			
		||||
          <Link
 | 
			
		||||
            href="/"
 | 
			
		||||
            className="flex cursor-pointer w-full justify-center sm:justify-start flex-row-reverse items-center gap-2 font-semibold sm:flex-row"
 | 
			
		||||
            className="cursor-pointer w-full justify-center sm:justify-start flex-row-reverse hidden sm:flex items-center gap-2 font-semibold sm:flex-row"
 | 
			
		||||
          >
 | 
			
		||||
            <Image height={18} unoptimized width={18} alt="logo" src="/ProxmoxVE/logo.png" className="" />
 | 
			
		||||
            <span className="hidden md:block">Proxmox VE Helper-Scripts</span>
 | 
			
		||||
            <span className="">Proxmox VE Helper-Scripts</span>
 | 
			
		||||
          </Link>
 | 
			
		||||
          <div className="flex gap-2">
 | 
			
		||||
            <CommandMenu />
 | 
			
		||||
            <GitHubStarsButton username="community-scripts" repo="ProxmoxVE" />
 | 
			
		||||
            {navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
 | 
			
		||||
              <TooltipProvider key={event}>
 | 
			
		||||
                <Tooltip delayDuration={100}>
 | 
			
		||||
                  <TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
 | 
			
		||||
                    <Button variant="ghost" size="icon" asChild>
 | 
			
		||||
                      <Link target="_blank" href={href} data-umami-event={event}>
 | 
			
		||||
                        {icon}
 | 
			
		||||
                        <span className="sr-only">{text}</span>
 | 
			
		||||
                      </Link>
 | 
			
		||||
                    </Button>
 | 
			
		||||
                  </TooltipTrigger>
 | 
			
		||||
                  <TooltipContent side="bottom" className="text-xs">
 | 
			
		||||
                    {text}
 | 
			
		||||
                  </TooltipContent>
 | 
			
		||||
                </Tooltip>
 | 
			
		||||
              </TooltipProvider>
 | 
			
		||||
            ))}
 | 
			
		||||
            <ThemeToggle />
 | 
			
		||||
          <div className="flex items-center justify-between gap-2 w-full">
 | 
			
		||||
            <div className="flex sm:hidden">
 | 
			
		||||
              <Suspense>
 | 
			
		||||
                <MobileSidebar />
 | 
			
		||||
              </Suspense>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className="flex sm:gap-2">
 | 
			
		||||
              <CommandMenu />
 | 
			
		||||
              <GitHubStarsButton username="community-scripts" repo="ProxmoxVE" className="hidden md:flex" />
 | 
			
		||||
              {navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
 | 
			
		||||
                <TooltipProvider key={event}>
 | 
			
		||||
                  <Tooltip delayDuration={100}>
 | 
			
		||||
                    <TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
 | 
			
		||||
                      <Button variant="ghost" size="icon" asChild>
 | 
			
		||||
                        <Link target="_blank" href={href} data-umami-event={event}>
 | 
			
		||||
                          {icon}
 | 
			
		||||
                          <span className="sr-only">{text}</span>
 | 
			
		||||
                        </Link>
 | 
			
		||||
                      </Button>
 | 
			
		||||
                    </TooltipTrigger>
 | 
			
		||||
                    <TooltipContent side="bottom" className="text-xs">
 | 
			
		||||
                      {text}
 | 
			
		||||
                    </TooltipContent>
 | 
			
		||||
                  </Tooltip>
 | 
			
		||||
                </TooltipProvider>
 | 
			
		||||
              ))}
 | 
			
		||||
              <ThemeToggle />
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										133
									
								
								frontend/src/components/navigation/mobile-sidebar.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								frontend/src/components/navigation/mobile-sidebar.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
"use client";
 | 
			
		||||
 | 
			
		||||
import { useCallback, useEffect, useState } from "react";
 | 
			
		||||
import { usePathname } from "next/navigation";
 | 
			
		||||
import { useQueryState } from "nuqs";
 | 
			
		||||
import { Menu } from "lucide-react";
 | 
			
		||||
 | 
			
		||||
import type { Category, Script } from "@/lib/types";
 | 
			
		||||
 | 
			
		||||
import { ScriptItem } from "@/app/scripts/_components/script-item";
 | 
			
		||||
import Sidebar from "@/app/scripts/_components/sidebar";
 | 
			
		||||
import { fetchCategories } from "@/lib/data";
 | 
			
		||||
 | 
			
		||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "../ui/sheet";
 | 
			
		||||
import { Button } from "../ui/button";
 | 
			
		||||
 | 
			
		||||
function MobileSidebar() {
 | 
			
		||||
  const [isOpen, setIsOpen] = useState(false);
 | 
			
		||||
  const [isLoading, setIsLoading] = useState(false);
 | 
			
		||||
  const [categories, setCategories] = useState<Category[]>([]);
 | 
			
		||||
  const [lastViewedScript, setLastViewedScript] = useState<Script | undefined>(undefined);
 | 
			
		||||
  const pathname = usePathname();
 | 
			
		||||
 | 
			
		||||
  // Always call the hooks (React hooks can't be conditional)
 | 
			
		||||
  const [selectedScript, setSelectedScript] = useQueryState("id");
 | 
			
		||||
  const [selectedCategory, setSelectedCategory] = useQueryState("category");
 | 
			
		||||
 | 
			
		||||
  // For non-scripts pages, we'll manage state locally
 | 
			
		||||
  const [tempSelectedScript, setTempSelectedScript] = useState<string | null>(null);
 | 
			
		||||
  const [tempSelectedCategory, setTempSelectedCategory] = useState<string | null>(null);
 | 
			
		||||
 | 
			
		||||
  const isOnScriptsPage = pathname === "/scripts";
 | 
			
		||||
  const currentSelectedScript = isOnScriptsPage ? selectedScript : tempSelectedScript;
 | 
			
		||||
  const currentSelectedCategory = isOnScriptsPage ? selectedCategory : tempSelectedCategory;
 | 
			
		||||
 | 
			
		||||
  const loadCategories = useCallback(async () => {
 | 
			
		||||
    setIsLoading(true);
 | 
			
		||||
    try {
 | 
			
		||||
      const response = await fetchCategories();
 | 
			
		||||
      setCategories(response);
 | 
			
		||||
    }
 | 
			
		||||
    catch (error) {
 | 
			
		||||
      console.error(error);
 | 
			
		||||
    }
 | 
			
		||||
    finally {
 | 
			
		||||
      setIsLoading(false);
 | 
			
		||||
    }
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    void loadCategories();
 | 
			
		||||
  }, [loadCategories]);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (!currentSelectedScript || categories.length === 0) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const scriptMatch = categories
 | 
			
		||||
      .flatMap(category => category.scripts)
 | 
			
		||||
      .find(script => script.slug === currentSelectedScript);
 | 
			
		||||
 | 
			
		||||
    setLastViewedScript(scriptMatch);
 | 
			
		||||
  }, [currentSelectedScript, categories]);
 | 
			
		||||
 | 
			
		||||
  const handleOpenChange = (openState: boolean) => {
 | 
			
		||||
    setIsOpen(openState);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleItemSelect = () => {
 | 
			
		||||
    setIsOpen(false);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const hasLinks = categories.length > 0;
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Sheet open={isOpen} onOpenChange={handleOpenChange}>
 | 
			
		||||
      <SheetTrigger asChild>
 | 
			
		||||
        <Button
 | 
			
		||||
          variant="ghost"
 | 
			
		||||
          size="icon"
 | 
			
		||||
          aria-label="Open navigation menu"
 | 
			
		||||
          tabIndex={0}
 | 
			
		||||
          onKeyDown={(event) => {
 | 
			
		||||
            if (event.key === "Enter" || event.key === " ") {
 | 
			
		||||
              setIsOpen(true);
 | 
			
		||||
            }
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          <Menu className="size-5" aria-hidden="true" />
 | 
			
		||||
        </Button>
 | 
			
		||||
      </SheetTrigger>
 | 
			
		||||
      <SheetHeader className="border-b border-border px-6 pb-4 pt-2 sr-only">
 | 
			
		||||
        <SheetTitle className="sr-only">Categories</SheetTitle>
 | 
			
		||||
      </SheetHeader>
 | 
			
		||||
      <SheetContent side="left" className="flex w-full max-w-xs flex-col gap-4 overflow-hidden px-0 pb-6">
 | 
			
		||||
        <div className="flex h-full flex-col gap-4 overflow-y-auto">
 | 
			
		||||
          {isLoading && !hasLinks
 | 
			
		||||
            ? (
 | 
			
		||||
                <div className="flex w-full flex-col items-center justify-center gap-2 px-6 py-4 text-sm text-muted-foreground">
 | 
			
		||||
                  Loading categories...
 | 
			
		||||
                </div>
 | 
			
		||||
              )
 | 
			
		||||
            : (
 | 
			
		||||
                <div className="flex flex-col gap-4 px-4">
 | 
			
		||||
                  <Sidebar
 | 
			
		||||
                    items={categories}
 | 
			
		||||
                    selectedScript={currentSelectedScript}
 | 
			
		||||
                    setSelectedScript={isOnScriptsPage ? setSelectedScript : setTempSelectedScript}
 | 
			
		||||
                    selectedCategory={currentSelectedCategory}
 | 
			
		||||
                    setSelectedCategory={isOnScriptsPage ? setSelectedCategory : setTempSelectedCategory}
 | 
			
		||||
                    onItemSelect={handleItemSelect}
 | 
			
		||||
                  />
 | 
			
		||||
                </div>
 | 
			
		||||
              )}
 | 
			
		||||
          {currentSelectedScript && lastViewedScript
 | 
			
		||||
            ? (
 | 
			
		||||
                <div className="flex flex-col gap-3 px-4">
 | 
			
		||||
                  <p className="text-sm font-medium">Last Viewed</p>
 | 
			
		||||
                  <ScriptItem
 | 
			
		||||
                    item={lastViewedScript}
 | 
			
		||||
                    setSelectedScript={isOnScriptsPage ? setSelectedScript : setTempSelectedScript}
 | 
			
		||||
                  />
 | 
			
		||||
                </div>
 | 
			
		||||
              )
 | 
			
		||||
            : null}
 | 
			
		||||
        </div>
 | 
			
		||||
      </SheetContent>
 | 
			
		||||
    </Sheet>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default MobileSidebar;
 | 
			
		||||
@@ -6,7 +6,7 @@ import { Command as CommandPrimitive } from "cmdk";
 | 
			
		||||
import { Search } from "lucide-react";
 | 
			
		||||
import * as React from "react";
 | 
			
		||||
 | 
			
		||||
import { Dialog, DialogContent } from "@/components/ui/dialog";
 | 
			
		||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
 | 
			
		||||
import { cn } from "@/lib/utils";
 | 
			
		||||
 | 
			
		||||
const Command = React.forwardRef<
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import type { Category } from "./types";
 | 
			
		||||
 | 
			
		||||
export async function fetchCategories() {
 | 
			
		||||
  const response = await fetch("api/categories");
 | 
			
		||||
  const response = await fetch(`/ProxmoxVE/api/categories`);
 | 
			
		||||
  if (!response.ok) {
 | 
			
		||||
    throw new Error(`Failed to fetch categories: ${response.statusText}`);
 | 
			
		||||
  }
 | 
			
		||||
@@ -10,7 +10,7 @@ export async function fetchCategories() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function fetchVersions() {
 | 
			
		||||
  const response = await fetch(`api/versions`);
 | 
			
		||||
  const response = await fetch(`/ProxmoxVE/api/versions`);
 | 
			
		||||
  if (!response.ok) {
 | 
			
		||||
    throw new Error(`Failed to fetch versions: ${response.statusText}`);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,8 @@ export type Category = {
 | 
			
		||||
  name: string;
 | 
			
		||||
  id: number;
 | 
			
		||||
  sort_order: number;
 | 
			
		||||
  description: string;
 | 
			
		||||
  icon: string;
 | 
			
		||||
  scripts: Script[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
$STD apt install -y \
 | 
			
		||||
  build-essential \
 | 
			
		||||
  jq \
 | 
			
		||||
  libcairo2-dev \
 | 
			
		||||
@@ -22,7 +22,7 @@ $STD apt-get install -y \
 | 
			
		||||
  libtool-bin \
 | 
			
		||||
  libossp-uuid-dev \
 | 
			
		||||
  libvncserver-dev \
 | 
			
		||||
  freerdp2-dev \
 | 
			
		||||
  freerdp3-dev \
 | 
			
		||||
  libssh2-1-dev \
 | 
			
		||||
  libtelnet-dev \
 | 
			
		||||
  libwebsockets-dev \
 | 
			
		||||
@@ -56,8 +56,9 @@ mkdir -p /etc/guacamole/{extensions,lib}
 | 
			
		||||
RELEASE_SERVER=$(curl -fsSL https://api.github.com/repos/apache/guacamole-server/tags | jq -r '.[].name' | grep -v -- '-RC' | head -n 1)
 | 
			
		||||
curl -fsSL "https://api.github.com/repos/apache/guacamole-server/tarball/refs/tags/${RELEASE_SERVER}" | tar -xz --strip-components=1 -C /opt/apache-guacamole/server
 | 
			
		||||
cd /opt/apache-guacamole/server
 | 
			
		||||
export CPPFLAGS="-Wno-error=deprecated-declarations"
 | 
			
		||||
$STD autoreconf -fi
 | 
			
		||||
$STD ./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots
 | 
			
		||||
$STD ./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots --disable-guaclog
 | 
			
		||||
$STD make
 | 
			
		||||
$STD make install
 | 
			
		||||
$STD ldconfig
 | 
			
		||||
@@ -149,6 +150,6 @@ customize
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf ~/mysql-connector-j-9.3.0{,.tar.gz}
 | 
			
		||||
rm -rf ~/guacamole-auth-jdbc-$RELEASE_SERVER{,.tar.gz}
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "blocky" "0xERR0R/blocky" "prebuild" "latest" "/opt/blocky" "blocky_*_linux_x86_64.tar.gz"
 | 
			
		||||
fetch_and_deploy_gh_release "blocky" "0xERR0R/blocky" "prebuild" "latest" "/opt/blocky" "blocky_*_Linux_x86_64.tar.gz"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Blocky"
 | 
			
		||||
if systemctl is-active systemd-resolved >/dev/null 2>&1; then
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ $STD apt-get install -y \
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
NODE_VERSION="24" setup_nodejs
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Change Detection"
 | 
			
		||||
mkdir /opt/changedetection
 | 
			
		||||
@@ -62,7 +62,7 @@ msg_info "Installing Browserless & Playwright"
 | 
			
		||||
mkdir /opt/browserless
 | 
			
		||||
$STD python3 -m pip install playwright
 | 
			
		||||
$STD git clone https://github.com/browserless/chrome /opt/browserless
 | 
			
		||||
$STD npm install --prefix /opt/browserless
 | 
			
		||||
$STD npm ci --include=optional --include=dev --prefix /opt/browserless
 | 
			
		||||
$STD /opt/browserless/node_modules/playwright-core/cli.js install --with-deps &>/dev/null
 | 
			
		||||
$STD /opt/browserless/node_modules/playwright-core/cli.js install --force chrome &>/dev/null
 | 
			
		||||
$STD /opt/browserless/node_modules/playwright-core/cli.js install chromium firefox webkit &>/dev/null
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										131
									
								
								install/ghostfolio-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								install/ghostfolio-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: lucasfell
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://ghostfol.io/
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
verb_ip6
 | 
			
		||||
catch_errors
 | 
			
		||||
setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt install -y \
 | 
			
		||||
    build-essential \
 | 
			
		||||
    openssl \
 | 
			
		||||
    ca-certificates \
 | 
			
		||||
    redis-server
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PG_VERSION="17" setup_postgresql
 | 
			
		||||
NODE_VERSION="24" setup_nodejs
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Database"
 | 
			
		||||
DB_NAME=ghostfolio
 | 
			
		||||
DB_USER=ghostfolio
 | 
			
		||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
 | 
			
		||||
REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
 | 
			
		||||
ACCESS_TOKEN_SALT=$(openssl rand -base64 32)
 | 
			
		||||
JWT_SECRET_KEY=$(openssl rand -base64 32)
 | 
			
		||||
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;"
 | 
			
		||||
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';"
 | 
			
		||||
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER USER $DB_USER CREATEDB;"
 | 
			
		||||
$STD sudo -u postgres psql -d $DB_NAME -c "GRANT ALL ON SCHEMA public TO $DB_USER;"
 | 
			
		||||
$STD sudo -u postgres psql -d $DB_NAME -c "GRANT CREATE ON SCHEMA public TO $DB_USER;"
 | 
			
		||||
$STD sudo -u postgres psql -d $DB_NAME -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $DB_USER;"
 | 
			
		||||
$STD sudo -u postgres psql -d $DB_NAME -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $DB_USER;"
 | 
			
		||||
{
 | 
			
		||||
    echo "Ghostfolio Credentials"
 | 
			
		||||
    echo "Database User: $DB_USER"
 | 
			
		||||
    echo "Database Password: $DB_PASS"
 | 
			
		||||
    echo "Database Name: $DB_NAME"
 | 
			
		||||
    echo "Redis Password: $REDIS_PASS"
 | 
			
		||||
    echo "Access Token Salt: $ACCESS_TOKEN_SALT"
 | 
			
		||||
    echo "JWT Secret Key: $JWT_SECRET_KEY"
 | 
			
		||||
} >>~/ghostfolio.creds
 | 
			
		||||
msg_ok "Set up Database"
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "ghostfolio" "ghostfolio/ghostfolio" "tarball" "latest" "/opt/ghostfolio"
 | 
			
		||||
 | 
			
		||||
msg_info "Setup Ghostfolio"
 | 
			
		||||
sed -i "s/# requirepass foobared/requirepass $REDIS_PASS/" /etc/redis/redis.conf
 | 
			
		||||
systemctl restart redis-server
 | 
			
		||||
cd /opt/ghostfolio
 | 
			
		||||
$STD npm ci
 | 
			
		||||
$STD npm run build:production
 | 
			
		||||
msg_ok "Built Ghostfolio"
 | 
			
		||||
 | 
			
		||||
msg_ok "Optional CoinGecko API Configuration"
 | 
			
		||||
echo
 | 
			
		||||
echo -e "${YW}CoinGecko API keys are optional but provide better cryptocurrency data.${CL}"
 | 
			
		||||
echo -e "${YW}You can skip this and add them later by editing /opt/ghostfolio/.env${CL}"
 | 
			
		||||
echo
 | 
			
		||||
read -rp "${TAB3}CoinGecko Demo API key (press Enter to skip): " COINGECKO_DEMO_KEY
 | 
			
		||||
read -rp "${TAB3}CoinGecko Pro API key (press Enter to skip): " COINGECKO_PRO_KEY
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Environment"
 | 
			
		||||
cat <<EOF >/opt/ghostfolio/.env
 | 
			
		||||
DATABASE_URL=postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME?connect_timeout=300&sslmode=prefer
 | 
			
		||||
REDIS_HOST=localhost
 | 
			
		||||
REDIS_PORT=6379
 | 
			
		||||
REDIS_PASSWORD=$REDIS_PASS
 | 
			
		||||
ACCESS_TOKEN_SALT=$ACCESS_TOKEN_SALT
 | 
			
		||||
JWT_SECRET_KEY=$JWT_SECRET_KEY
 | 
			
		||||
NODE_ENV=production
 | 
			
		||||
PORT=3333
 | 
			
		||||
HOST=0.0.0.0
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
if [[ -n "${COINGECKO_DEMO_KEY:-}" ]]; then
 | 
			
		||||
    echo "API_KEY_COINGECKO_DEMO=$COINGECKO_DEMO_KEY" >>/opt/ghostfolio/.env
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ -n "${COINGECKO_PRO_KEY:-}" ]]; then
 | 
			
		||||
    echo "API_KEY_COINGECKO_PRO=$COINGECKO_PRO_KEY" >>/opt/ghostfolio/.env
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Set up Environment"
 | 
			
		||||
 | 
			
		||||
msg_info "Running Database Migrations"
 | 
			
		||||
cd /opt/ghostfolio
 | 
			
		||||
$STD npx prisma migrate deploy
 | 
			
		||||
$STD npx prisma db seed
 | 
			
		||||
msg_ok "Database Migrations Complete"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/ghostfolio.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Ghostfolio Investment Tracker
 | 
			
		||||
After=network.target postgresql.service redis-server.service
 | 
			
		||||
Wants=postgresql.service redis-server.service
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
User=root
 | 
			
		||||
WorkingDirectory=/opt/ghostfolio/dist/apps/api
 | 
			
		||||
Environment=NODE_ENV=production
 | 
			
		||||
EnvironmentFile=/opt/ghostfolio/.env
 | 
			
		||||
ExecStart=/usr/bin/node main.js
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=10
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
systemctl enable -q --now ghostfolio
 | 
			
		||||
msg_ok "Created Service"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD npm cache clean --force
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
@@ -18,7 +18,7 @@ curl -fsSL https://deb.globaleaks.org/globaleaks.asc | gpg --dearmor -o /etc/apt
 | 
			
		||||
echo "deb [signed-by=/etc/apt/trusted.gpg.d/globaleaks.gpg] http://deb.globaleaks.org $DISTRO_CODENAME/" >/etc/apt/sources.list.d/globaleaks.list
 | 
			
		||||
echo 'APPARMOR_SANDBOXING=0' >/etc/default/globaleaks
 | 
			
		||||
$STD apt update
 | 
			
		||||
$STD apt -y install globaleaks
 | 
			
		||||
$STD apt -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold install globaleaks
 | 
			
		||||
msg_ok "Setup GlobaLeaks"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										62
									
								
								install/goaway-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								install/goaway-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/pommee/goaway
 | 
			
		||||
 | 
			
		||||
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 net-tools
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "goaway" "pommee/goaway" "prebuild" "latest" "/opt/goaway" "goaway_*_linux_amd64.tar.gz"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/goaway.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=GoAway Service
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
User=root
 | 
			
		||||
WorkingDirectory=/opt/goaway
 | 
			
		||||
ExecStart=/opt/goaway/goaway
 | 
			
		||||
StandardOutput=file:/var/log/goaway.log
 | 
			
		||||
StandardError=inherit
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
RestartSec=5
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
systemctl enable -q --now goaway
 | 
			
		||||
sleep 10
 | 
			
		||||
for i in {1..30}; do
 | 
			
		||||
  ADMIN_PASS=$(awk -F': ' "/Randomly generated admin password:/ {print \$2; exit}" /var/log/goaway.log)
 | 
			
		||||
  [ -n "$ADMIN_PASS" ] && break
 | 
			
		||||
  sleep 1
 | 
			
		||||
done
 | 
			
		||||
{
 | 
			
		||||
  echo "GoAway Credentials"
 | 
			
		||||
  echo "Admin User: admin"
 | 
			
		||||
  echo "Admin Password: $ADMIN_PASS"
 | 
			
		||||
} >>~/goaway.creds
 | 
			
		||||
msg_ok "Service Created"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
@@ -24,26 +24,24 @@ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
 | 
			
		||||
  $STD caddy stop
 | 
			
		||||
  rm /etc/caddy/Caddyfile
 | 
			
		||||
  cat <<'EOF' >/etc/caddy/Caddyfile
 | 
			
		||||
:{$PORT:80}
 | 
			
		||||
:80
 | 
			
		||||
 | 
			
		||||
redir /admin /admin/
 | 
			
		||||
 | 
			
		||||
handle_path /admin* {
 | 
			
		||||
        root * /opt/headscale-admin
 | 
			
		||||
        encode gzip zstd
 | 
			
		||||
    root * /opt/headscale-admin
 | 
			
		||||
    encode gzip zstd
 | 
			
		||||
 | 
			
		||||
        # Correct MIME types for JS/WASM
 | 
			
		||||
        header {
 | 
			
		||||
                @js_files path *.js
 | 
			
		||||
                @wasm_files path *.wasm
 | 
			
		||||
    header {
 | 
			
		||||
        X-Content-Type-Options nosniff
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
                Content-Type @js_files application/javascript
 | 
			
		||||
                Content-Type @wasm_files application/wasm
 | 
			
		||||
    try_files {path} {path}/ /opt/headscale-admin/index.html
 | 
			
		||||
    file_server
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
                X-Content-Type-Options nosniff
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Fallback for SPA routing
 | 
			
		||||
        try_files {path} {path}/ index.html
 | 
			
		||||
        file_server
 | 
			
		||||
handle /api/* {
 | 
			
		||||
    reverse_proxy localhost:8080
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EOF
 | 
			
		||||
 
 | 
			
		||||
@@ -272,7 +272,7 @@ GEO_DIR="${INSTALL_DIR}/geodata"
 | 
			
		||||
mkdir -p "$INSTALL_DIR"
 | 
			
		||||
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v1.142.1" "$SRC_DIR"
 | 
			
		||||
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v1.143.1" "$SRC_DIR"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing ${APPLICATION} (patience)"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										98
									
								
								install/joplin-server-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								install/joplin-server-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://joplinapp.org/
 | 
			
		||||
 | 
			
		||||
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 \
 | 
			
		||||
  git \
 | 
			
		||||
  rsync
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PG_VERSION="17" setup_postgresql
 | 
			
		||||
NODE_VERSION=22 NODE_MODULE="yarn@latest,npm@latest,pm2@latest" setup_nodejs
 | 
			
		||||
mkdir -p /opt/pm2
 | 
			
		||||
export PM2_HOME=/opt/pm2
 | 
			
		||||
$STD pm2 install pm2-logrotate
 | 
			
		||||
$STD pm2 set pm2-logrotate:max_size 100MB
 | 
			
		||||
$STD pm2 set pm2-logrotate:retain 5
 | 
			
		||||
$STD pm2 set pm2-logrotate:compress tr
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up PostgreSQL Database"
 | 
			
		||||
DB_NAME=joplin
 | 
			
		||||
DB_USER=joplin
 | 
			
		||||
DB_PASS="$(openssl rand -base64 18 | 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 $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
 | 
			
		||||
{
 | 
			
		||||
  echo "Joplin-Credentials"
 | 
			
		||||
  echo "Joplin Database User: $DB_USER"
 | 
			
		||||
  echo "Joplin Database Password: $DB_PASS"
 | 
			
		||||
  echo "Joplin Database Name: $DB_NAME"
 | 
			
		||||
} >>~/joplin.creds
 | 
			
		||||
msg_ok "Set up PostgreSQL Database"
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball" "latest"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Joplin Server (Patience)"
 | 
			
		||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
 | 
			
		||||
cd /opt/joplin-server
 | 
			
		||||
sed -i "/onenote-converter/d" packages/lib/package.json
 | 
			
		||||
$STD yarn config set --home enableTelemetry 0
 | 
			
		||||
export BUILD_SEQUENCIAL=1
 | 
			
		||||
$STD yarn install --inline-builds
 | 
			
		||||
 | 
			
		||||
cat <<EOF >/opt/joplin-server/.env
 | 
			
		||||
PM2_HOME=/opt/pm2
 | 
			
		||||
NODE_ENV=production
 | 
			
		||||
APP_BASE_URL=http://$LOCAL_IP:22300
 | 
			
		||||
APP_PORT=22300
 | 
			
		||||
DB_CLIENT=pg
 | 
			
		||||
POSTGRES_PASSWORD=$DB_PASS
 | 
			
		||||
POSTGRES_DATABASE=$DB_NAME
 | 
			
		||||
POSTGRES_USER=$DB_USER
 | 
			
		||||
POSTGRES_PORT=5432
 | 
			
		||||
POSTGRES_HOST=localhost
 | 
			
		||||
EOF
 | 
			
		||||
msg_ok "Setup Joplin Server"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/joplin-server.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Joplin Server Service
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
WorkingDirectory=/opt/joplin-server/packages/server
 | 
			
		||||
EnvironmentFile=/opt/joplin-server/.env
 | 
			
		||||
ExecStart=/usr/bin/yarn start-prod
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
RestartSec=5
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
systemctl enable -q --now joplin-server
 | 
			
		||||
msg_ok "Service Setup"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
@@ -13,6 +13,12 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt install -y \
 | 
			
		||||
  build-essential \
 | 
			
		||||
  python3-dev
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PG_VERSION="17" setup_postgresql
 | 
			
		||||
PYTHON_VERSION="3.13" setup_uv
 | 
			
		||||
 | 
			
		||||
@@ -75,6 +81,7 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ msg_info "Installing dependencies"
 | 
			
		||||
$STD apt-get install --no-install-recommends -y build-essential
 | 
			
		||||
msg_ok "Installed dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="20" setup_nodejs
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
MYSQL_VERSION="8.0" setup_mysql
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Database"
 | 
			
		||||
@@ -48,7 +48,7 @@ sed -i -e 's|db|localhost|' \
 | 
			
		||||
  -e "s|=PASSWORD|=$(openssl rand -base64 40 | tr -dc 'a-zA-Z0-9' | head -c40)|" \
 | 
			
		||||
  /opt/mmdl/.env
 | 
			
		||||
cd /opt/mmdl
 | 
			
		||||
export NEXT_TELEMETRY_DISABLE=1
 | 
			
		||||
export NEXT_TELEMETRY_DISABLED=1
 | 
			
		||||
export CI="true"
 | 
			
		||||
$STD npm install
 | 
			
		||||
$STD npm run migrate
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ $STD apt-get install -y --no-install-recommends \
 | 
			
		||||
  g++ \
 | 
			
		||||
  musl-dev \
 | 
			
		||||
  ffmpeg \
 | 
			
		||||
  git \
 | 
			
		||||
  make \
 | 
			
		||||
  ca-certificates
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
@@ -30,25 +29,29 @@ msg_ok "Installed Dependencies"
 | 
			
		||||
PYTHON_VERSION="3.13" setup_uv
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Deno"
 | 
			
		||||
export DENO_INSTALL="/usr/local"
 | 
			
		||||
curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
 | 
			
		||||
[[ ":$PATH:" != *":/usr/local/bin:"* ]] &&
 | 
			
		||||
  echo 'export PATH="/usr/local/bin:$PATH"' >>~/.bashrc &&
 | 
			
		||||
  source ~/.bashrc
 | 
			
		||||
msg_ok "Installed Deno"
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "metube" "alexta69/metube" "tarball" "latest"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing MeTube"
 | 
			
		||||
$STD git clone https://github.com/alexta69/metube /opt/metube
 | 
			
		||||
cd /opt/metube/ui
 | 
			
		||||
$STD npm install
 | 
			
		||||
$STD node_modules/.bin/ng build
 | 
			
		||||
cd /opt/metube
 | 
			
		||||
$STD uv venv /opt/metube/.venv
 | 
			
		||||
$STD /opt/metube/.venv/bin/python -m ensurepip --upgrade
 | 
			
		||||
$STD /opt/metube/.venv/bin/python -m pip install --upgrade pip
 | 
			
		||||
$STD /opt/metube/.venv/bin/python -m pip install pipenv
 | 
			
		||||
$STD /opt/metube/.venv/bin/pipenv install
 | 
			
		||||
$STD /opt/metube/.venv/bin/pipenv update yt-dlp
 | 
			
		||||
$STD uv sync
 | 
			
		||||
 | 
			
		||||
mkdir -p /opt/metube_downloads /opt/metube_downloads/.metube /opt/metube_downloads/music /opt/metube_downloads/videos
 | 
			
		||||
cat <<EOF >/opt/metube/.env
 | 
			
		||||
DOWNLOAD_DIR=/opt/metube_downloads
 | 
			
		||||
STATE_DIR=/opt/metube_downloads/.metube
 | 
			
		||||
TEMP_DIR=/opt/metube_downloads
 | 
			
		||||
YTDL_OPTIONS={"trim_file_name":10}
 | 
			
		||||
YTDL_OPTIONS={"trim_file_name":10,"extractor_args":{"youtube":{"player_client":["default","-tv_simply"]}}}
 | 
			
		||||
EOF
 | 
			
		||||
msg_ok "Installed MeTube"
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +65,7 @@ After=network.target
 | 
			
		||||
Type=simple
 | 
			
		||||
WorkingDirectory=/opt/metube
 | 
			
		||||
EnvironmentFile=/opt/metube/.env
 | 
			
		||||
ExecStart=/opt/metube/.venv/bin/pipenv run python3 app/main.py
 | 
			
		||||
ExecStart=/opt/metube/.venv/bin/python3 app/main.py
 | 
			
		||||
Restart=always
 | 
			
		||||
User=root
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ update_os
 | 
			
		||||
PHP_VERSION="8.2" PHP_APACHE="YES" PHP_MODULE="dom,gmp,iconv,mysqli,pdo-mysql,redis,tokenizer" setup_php
 | 
			
		||||
setup_composer
 | 
			
		||||
setup_mariadb
 | 
			
		||||
NODE_VERSION="20" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up MariaDB"
 | 
			
		||||
DB_NAME=monica
 | 
			
		||||
@@ -44,6 +44,7 @@ sed -i -e "s|^DB_USERNAME=.*|DB_USERNAME=${DB_USER}|" \
 | 
			
		||||
  -e "s|^HASH_SALT=.*|HASH_SALT=${HASH_SALT}|" \
 | 
			
		||||
  /opt/monica/.env
 | 
			
		||||
$STD composer install --no-dev -o --no-interaction
 | 
			
		||||
$STD yarn config set ignore-engines true
 | 
			
		||||
$STD yarn install
 | 
			
		||||
$STD yarn run production
 | 
			
		||||
$STD php artisan key:generate
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								install/myip-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								install/myip-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://ipcheck.ing/
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
verb_ip6
 | 
			
		||||
catch_errors
 | 
			
		||||
setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
fetch_and_deploy_gh_release "myip" "jason5ng32/MyIP" "tarball"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring MyIP"
 | 
			
		||||
cd /opt/myip
 | 
			
		||||
cp .env.example .env
 | 
			
		||||
$STD npm install
 | 
			
		||||
$STD npm run build
 | 
			
		||||
msg_ok "Configured MyIP"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/myip.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=MyIP Service
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
User=root
 | 
			
		||||
WorkingDirectory=/opt/myip
 | 
			
		||||
ExecStart=/usr/bin/npm start
 | 
			
		||||
EnvironmentFile=/opt/myip/.env
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
RestartSec=5
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
systemctl enable -q --now myip
 | 
			
		||||
msg_ok "Service created"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 tteck
 | 
			
		||||
# Author: tteck (tteckster)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: CrazyWolf13
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://ntfy.sh/
 | 
			
		||||
 | 
			
		||||
@@ -13,17 +13,19 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apt-transport-https
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing ntfy"
 | 
			
		||||
mkdir -p /etc/apt/keyrings
 | 
			
		||||
curl -fsSL https://archive.heckel.io/apt/pubkey.txt | gpg --dearmor -o /etc/apt/keyrings/archive.heckel.io.gpg
 | 
			
		||||
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/archive.heckel.io.gpg] https://archive.heckel.io/apt debian main" >/etc/apt/sources.list.d/archive.heckel.io.list
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y ntfy
 | 
			
		||||
curl -fsSL -o /etc/apt/keyrings/ntfy.gpg https://archive.ntfy.sh/apt/keyring.gpg
 | 
			
		||||
cat <<EOF >/etc/apt/sources.list.d/ntfy.sources 
 | 
			
		||||
Types: deb
 | 
			
		||||
URIs: https://archive.ntfy.sh/apt/
 | 
			
		||||
Suites: stable
 | 
			
		||||
Components: main
 | 
			
		||||
Signed-By: /etc/apt/keyrings/ntfy.gpg
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
$STD apt update
 | 
			
		||||
$STD apt install -y ntfy
 | 
			
		||||
systemctl enable -q --now ntfy
 | 
			
		||||
msg_ok "Installed ntfy"
 | 
			
		||||
 | 
			
		||||
@@ -31,6 +33,7 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,11 +14,13 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  build-essential \
 | 
			
		||||
  make
 | 
			
		||||
$STD apt-get install -y python3-lxml
 | 
			
		||||
curl -fsSL "http://archive.ubuntu.com/ubuntu/pool/universe/l/lxml-html-clean/python3-lxml-html-clean_0.1.1-1_all.deb" -o /opt/python3-lxml-html-clean.deb
 | 
			
		||||
$STD dpkg -i /opt/python3-lxml-html-clean.deb
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PG_VERSION="18" setup_postgresql
 | 
			
		||||
 | 
			
		||||
RELEASE=$(curl -fsSL https://nightly.odoo.com/ | grep -oE 'href="[0-9]+\.[0-9]+/nightly"' | head -n1 | cut -d'"' -f2 | cut -d/ -f1)
 | 
			
		||||
LATEST_VERSION=$(curl -fsSL "https://nightly.odoo.com/${RELEASE}/nightly/deb/" |
 | 
			
		||||
  grep -oP "odoo_${RELEASE}\.\d+_all\.deb" |
 | 
			
		||||
@@ -69,6 +71,7 @@ customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f /opt/odoo.deb
 | 
			
		||||
rm -f /opt/python3-lxml-html-clean.deb
 | 
			
		||||
$STD apt-get autoremove
 | 
			
		||||
$STD apt-get autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ ENABLE_OLLAMA_API=false
 | 
			
		||||
OLLAMA_BASE_URL=http://0.0.0.0:11434
 | 
			
		||||
EOF
 | 
			
		||||
$STD npm install --force
 | 
			
		||||
export NODE_OPTIONS="--max-old-space-size=3584"
 | 
			
		||||
export NODE_OPTIONS="--max-old-space-size=6000"
 | 
			
		||||
$STD npm run build
 | 
			
		||||
msg_ok "Installed Open WebUI"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ $STD apt-get install -y \
 | 
			
		||||
  redis
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="20" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
PG_VERSION="16" setup_postgresql
 | 
			
		||||
 | 
			
		||||
msg_info "Set up PostgreSQL Database"
 | 
			
		||||
 
 | 
			
		||||
@@ -30,9 +30,9 @@ $STD apt-get install -y --no-install-recommends \
 | 
			
		||||
  libxmlsec1-openssl
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="20" NODE_MODULE="yarn" setup_nodejs
 | 
			
		||||
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
 | 
			
		||||
fetch_and_deploy_gh_release "tandoor" "TandoorRecipes/recipes" "tarball" "latest" "/opt/tandoor"
 | 
			
		||||
PG_VERSION="16" setup_postgresql
 | 
			
		||||
PG_VERSION="17" PG_MODULES="contrib" setup_postgresql
 | 
			
		||||
PYTHON_VERSION="3.13" setup_uv
 | 
			
		||||
 | 
			
		||||
msg_info "Set up PostgreSQL Database"
 | 
			
		||||
@@ -45,6 +45,8 @@ $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMP
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
 | 
			
		||||
$STD sudo -u postgres psql -d "$DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS unaccent;"
 | 
			
		||||
$STD sudo -u postgres psql -d "$DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
 | 
			
		||||
{
 | 
			
		||||
  echo "Tandoor-Credentials"
 | 
			
		||||
  echo "Tandoor Database Name: $DB_NAME"
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ $STD npm install
 | 
			
		||||
$STD npm run build
 | 
			
		||||
mkdir /opt/tracktor-data
 | 
			
		||||
HOST_IP=$(hostname -I | awk '{print $1}')
 | 
			
		||||
cat <<EOF >/opt/tracktor/app/backend/.env
 | 
			
		||||
cat <<EOF >/opt/tracktor.env
 | 
			
		||||
NODE_ENV=production
 | 
			
		||||
PUBLIC_DEMO_MODE=false
 | 
			
		||||
DB_PATH=/opt/tracktor-data/tracktor.db
 | 
			
		||||
@@ -31,6 +31,7 @@ PUBLIC_API_BASE_URL=http://$HOST_IP:3000
 | 
			
		||||
# Here add the reverse proxy url as well to avoid cross errors from the app. 
 | 
			
		||||
CORS_ORIGINS=http://$HOST_IP:3000 
 | 
			
		||||
PORT=3000
 | 
			
		||||
AUTH_PIN=123456
 | 
			
		||||
EOF
 | 
			
		||||
msg_ok "Configured Tracktor"
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +44,7 @@ After=network.target
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
WorkingDirectory=/opt/tracktor
 | 
			
		||||
EnvironmentFile=/opt/tracktor/app/backend/.env
 | 
			
		||||
EnvironmentFile=/opt/tracktor.env
 | 
			
		||||
ExecStart=/usr/bin/npm start
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
@@ -56,6 +57,7 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										56
									
								
								install/upsnap-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								install/upsnap-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Slaviša Arežina (tremor021)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/seriousm4x/UpSnap
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
verb_ip6
 | 
			
		||||
catch_errors
 | 
			
		||||
setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt install -y \
 | 
			
		||||
  nmap \
 | 
			
		||||
  samba \
 | 
			
		||||
  samba-common-bin \
 | 
			
		||||
  openssh-client \
 | 
			
		||||
  openssh-server \
 | 
			
		||||
  sshpass
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "upsnap" "seriousm4x/UpSnap" "prebuild" "latest" "/opt/upsnap" "UpSnap_*_linux_amd64.zip"
 | 
			
		||||
setcap 'cap_net_raw=+ep' /opt/upsnap/upsnap
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/upsnap.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=UpSnap Service
 | 
			
		||||
Documentation=https://github.com/seriousm4x/UpSnap/wiki
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
User=root
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
WorkingDirectory=/opt/upsnap
 | 
			
		||||
ExecStart=/opt/upsnap/upsnap serve --http=0.0.0.0:8090
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
systemctl enable -q --now upsnap
 | 
			
		||||
msg_ok "Service Created"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
							
								
								
									
										96
									
								
								install/verdaccio-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								install/verdaccio-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: BrynnJKnight
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://verdaccio.org/
 | 
			
		||||
 | 
			
		||||
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 \
 | 
			
		||||
  ca-certificates \
 | 
			
		||||
  build-essential
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" NODE_MODULE="verdaccio" setup_nodejs
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Verdaccio"
 | 
			
		||||
mkdir -p /opt/verdaccio/config
 | 
			
		||||
mkdir -p /opt/verdaccio/storage
 | 
			
		||||
 | 
			
		||||
cat <<EOF >/opt/verdaccio/config/config.yaml
 | 
			
		||||
# Verdaccio configuration
 | 
			
		||||
storage: /opt/verdaccio/storage
 | 
			
		||||
auth:
 | 
			
		||||
  htpasswd:
 | 
			
		||||
    file: /opt/verdaccio/storage/htpasswd
 | 
			
		||||
    max_users: 1000
 | 
			
		||||
uplinks:
 | 
			
		||||
  npmjs:
 | 
			
		||||
    url: https://registry.npmjs.org/
 | 
			
		||||
packages:
 | 
			
		||||
  '@*/*':
 | 
			
		||||
    access: \$all
 | 
			
		||||
    publish: \$authenticated
 | 
			
		||||
    proxy: npmjs
 | 
			
		||||
  '**':
 | 
			
		||||
    access: \$all
 | 
			
		||||
    publish: \$authenticated
 | 
			
		||||
    proxy: npmjs
 | 
			
		||||
middlewares:
 | 
			
		||||
  audit:
 | 
			
		||||
    enabled: true
 | 
			
		||||
logs:
 | 
			
		||||
  - {type: stdout, format: pretty, level: http}
 | 
			
		||||
listen:
 | 
			
		||||
  - 0.0.0.0:4873
 | 
			
		||||
web:
 | 
			
		||||
  enable: true
 | 
			
		||||
  title: Verdaccio
 | 
			
		||||
  gravatar: true
 | 
			
		||||
  sort_packages: asc
 | 
			
		||||
  login: true
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
chown -R root:root /opt/verdaccio
 | 
			
		||||
chmod -R 755 /opt/verdaccio
 | 
			
		||||
msg_ok "Configured Verdaccio"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/verdaccio.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Verdaccio lightweight private npm proxy registry
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
ExecStart=/usr/bin/verdaccio --config /opt/verdaccio/config/config.yaml
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
StandardOutput=journal
 | 
			
		||||
StandardError=journal
 | 
			
		||||
SyslogIdentifier=verdaccio
 | 
			
		||||
KillMode=control-group
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
systemctl enable -q --now verdaccio
 | 
			
		||||
msg_ok "Created Service"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
							
								
								
									
										119
									
								
								install/warracker-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								install/warracker-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: bvdberg01
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/sassanix/Warracker/
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
verb_ip6
 | 
			
		||||
catch_errors
 | 
			
		||||
setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt install -y \
 | 
			
		||||
    build-essential \
 | 
			
		||||
    libpq-dev \
 | 
			
		||||
    nginx
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PYTHON_VERSION="3.12" setup_uv
 | 
			
		||||
PG_VERSION="17" setup_postgresql
 | 
			
		||||
 | 
			
		||||
msg_info "Setup PostgreSQL"
 | 
			
		||||
DB_NAME="warranty_db"
 | 
			
		||||
DB_USER="warranty_user"
 | 
			
		||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
 | 
			
		||||
DB_ADMIN_USER="warracker_admin"
 | 
			
		||||
DB_ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
 | 
			
		||||
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
 | 
			
		||||
$STD sudo -u postgres psql -c "CREATE USER $DB_ADMIN_USER WITH PASSWORD '$DB_ADMIN_PASS' SUPERUSER;"
 | 
			
		||||
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_ADMIN_USER;"
 | 
			
		||||
$STD sudo -u postgres psql -d "$DB_NAME" -c "GRANT USAGE ON SCHEMA public TO $DB_USER;"
 | 
			
		||||
$STD sudo -u postgres psql -d "$DB_NAME" -c "GRANT CREATE ON SCHEMA public TO $DB_USER;"
 | 
			
		||||
$STD sudo -u postgres psql -d "$DB_NAME" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO $DB_USER;"
 | 
			
		||||
{
 | 
			
		||||
    echo "Application Credentials"
 | 
			
		||||
    echo "DB_NAME: $DB_NAME"
 | 
			
		||||
    echo "DB_USER: $DB_USER"
 | 
			
		||||
    echo "DB_PASS: $DB_PASS"
 | 
			
		||||
    echo "DB_ADMIN_USER: $DB_ADMIN_USER"
 | 
			
		||||
    echo "DB_ADMIN_PASS: $DB_ADMIN_PASS"
 | 
			
		||||
} >>~/warracker.creds
 | 
			
		||||
msg_ok "Setup PostgreSQL"
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "warracker" "sassanix/Warracker" "tarball" "latest" "/opt/warracker"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Warracker"
 | 
			
		||||
cd /opt/warracker/backend
 | 
			
		||||
$STD uv venv .venv
 | 
			
		||||
$STD source .venv/bin/activate
 | 
			
		||||
$STD uv pip install -r requirements.txt
 | 
			
		||||
mv /opt/warracker/env.example /opt/.env
 | 
			
		||||
sed -i \
 | 
			
		||||
    -e "s/your_secure_database_password/$DB_PASS/" \
 | 
			
		||||
    -e "s/your_secure_admin_password/$DB_ADMIN_PASS/" \
 | 
			
		||||
    -e "s|^# DB_PORT=5432$|DB_HOST=127.0.0.1|" \
 | 
			
		||||
    -e "s|your_very_secure_flask_secret_key_change_this_in_production|$(openssl rand -base64 32 | tr -d '\n')|" \
 | 
			
		||||
    /opt/.env
 | 
			
		||||
mkdir -p /data/uploads
 | 
			
		||||
msg_ok "Installed Warracker"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Nginx"
 | 
			
		||||
mv /opt/warracker/nginx.conf /etc/nginx/sites-available/warracker.conf
 | 
			
		||||
sed -i \
 | 
			
		||||
    -e "s|alias /var/www/html/locales/;|alias /opt/warracker/locales/;|" \
 | 
			
		||||
    -e "s|/var/www/html|/opt/warracker/frontend|g" \
 | 
			
		||||
    -e "s/client_max_body_size __NGINX_MAX_BODY_SIZE_CONFIG_VALUE__/client_max_body_size 32M/" \
 | 
			
		||||
    /etc/nginx/sites-available/warracker.conf
 | 
			
		||||
ln -s /etc/nginx/sites-available/warracker.conf /etc/nginx/sites-enabled/warracker.conf
 | 
			
		||||
rm /etc/nginx/sites-enabled/default
 | 
			
		||||
systemctl restart nginx
 | 
			
		||||
 | 
			
		||||
msg_ok "Configured Nginx"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating systemd services"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/warrackermigration.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Warracker Migration Service
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=oneshot
 | 
			
		||||
WorkingDirectory=/opt/warracker/backend/migrations
 | 
			
		||||
EnvironmentFile=/opt/.env
 | 
			
		||||
ExecStart=/opt/warracker/backend/.venv/bin/python apply_migrations.py
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
cat <<EOF >/etc/systemd/system/warracker.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Warracker Service
 | 
			
		||||
After=network.target warrackermigration.service
 | 
			
		||||
Requires=warrackermigration.service
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
WorkingDirectory=/opt/warracker
 | 
			
		||||
EnvironmentFile=/opt/.env
 | 
			
		||||
ExecStart=/opt/warracker/backend/.venv/bin/gunicorn --config /opt/warracker/backend/gunicorn_config.py backend:create_app() --bind 127.0.0.1:5000
 | 
			
		||||
Restart=always
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
systemctl enable -q --now warracker
 | 
			
		||||
msg_ok "Started Warracker Services"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
@@ -13,20 +13,61 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
PG_VERSION="17" setup_postgresql
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Zabbix"
 | 
			
		||||
cd /tmp
 | 
			
		||||
curl -fsSL "$(curl -fsSL https://repo.zabbix.com/zabbix/ |
 | 
			
		||||
  grep -oP '(?<=href=")[0-9]+\.[0-9]+(?=/")' | sort -V | tail -n1 |
 | 
			
		||||
  xargs -I{} echo "https://repo.zabbix.com/zabbix/{}/release/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian12_all.deb")" \
 | 
			
		||||
  -o /tmp/zabbix-release_latest+debian12_all.deb
 | 
			
		||||
$STD dpkg -i /tmp/zabbix-release_latest+debian12_all.deb
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y zabbix-server-pgsql zabbix-frontend-php php8.2-pgsql zabbix-apache-conf zabbix-sql-scripts
 | 
			
		||||
$STD apt-get install -y zabbix-agent2 zabbix-agent2-plugin-*
 | 
			
		||||
  xargs -I{} echo "https://repo.zabbix.com/zabbix/{}/release/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian13_all.deb")" \
 | 
			
		||||
  -o /tmp/zabbix-release_latest+debian13_all.deb
 | 
			
		||||
$STD dpkg -i /tmp/zabbix-release_latest+debian13_all.deb
 | 
			
		||||
$STD apt update
 | 
			
		||||
$STD apt install -y zabbix-server-pgsql zabbix-frontend-php php8.4-pgsql zabbix-apache-conf zabbix-sql-scripts
 | 
			
		||||
msg_ok "Installed Zabbix"
 | 
			
		||||
 | 
			
		||||
while true; do
 | 
			
		||||
  read -rp "Which agent do you want to install? [1=agent (classic), 2=agent2 (modern), default=1]: " AGENT_CHOICE
 | 
			
		||||
  case "$AGENT_CHOICE" in
 | 
			
		||||
  2)
 | 
			
		||||
    AGENT_PKG="zabbix-agent2"
 | 
			
		||||
    break
 | 
			
		||||
    ;;
 | 
			
		||||
  "" | 1)
 | 
			
		||||
    AGENT_PKG="zabbix-agent"
 | 
			
		||||
    break
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    echo "Invalid choice. Please enter 1 or 2."
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
done
 | 
			
		||||
msg_ok "Selected $AGENT_PKG"
 | 
			
		||||
 | 
			
		||||
if [ "$AGENT_PKG" = "zabbix-agent2" ]; then
 | 
			
		||||
  echo "Choose plugins for Zabbix Agent2:"
 | 
			
		||||
  echo "1) PostgreSQL only (default, recommended)"
 | 
			
		||||
  echo "2) All plugins (may cause issues)"
 | 
			
		||||
  read -rp "Choose option [1-2]: " PLUGIN_CHOICE
 | 
			
		||||
 | 
			
		||||
  case "$PLUGIN_CHOICE" in
 | 
			
		||||
  2)
 | 
			
		||||
    $STD apt install -y zabbix-agent2 zabbix-agent2-plugin-*
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    $STD apt install -y zabbix-agent2 zabbix-agent2-plugin-postgresql
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  if [ -f /etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf ]; then
 | 
			
		||||
    sed -i 's|^Plugins.NVIDIA.System.Path=.*|# Plugins.NVIDIA.System.Path=/usr/libexec/zabbix/zabbix-agent2-plugin-nvidia-gpu|' \
 | 
			
		||||
      /etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf
 | 
			
		||||
  fi
 | 
			
		||||
else
 | 
			
		||||
  $STD apt install -y zabbix-agent
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up PostgreSQL"
 | 
			
		||||
$STD apt-get install -y postgresql
 | 
			
		||||
DB_NAME=zabbixdb
 | 
			
		||||
DB_USER=zabbix
 | 
			
		||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
 | 
			
		||||
@@ -35,18 +76,31 @@ $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCO
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
 | 
			
		||||
{
 | 
			
		||||
  echo "Zabbix-Credentials"
 | 
			
		||||
  echo "Zabbix Database User: $DB_USER"
 | 
			
		||||
  echo "Zabbix Database Password: $DB_PASS"
 | 
			
		||||
  echo "Zabbix Database Name: $DB_NAME"
 | 
			
		||||
} >>~/zabbix.creds
 | 
			
		||||
 | 
			
		||||
zcat /usr/share/zabbix/sql-scripts/postgresql/server.sql.gz | sudo -u $DB_USER psql $DB_NAME &>/dev/null
 | 
			
		||||
sed -i "s/^DBName=.*/DBName=$DB_NAME/" /etc/zabbix/zabbix_server.conf
 | 
			
		||||
sed -i "s/^DBUser=.*/DBUser=$DB_USER/" /etc/zabbix/zabbix_server.conf
 | 
			
		||||
sed -i "s/^# DBPassword=.*/DBPassword=$DB_PASS/" /etc/zabbix/zabbix_server.conf
 | 
			
		||||
echo "" >~/zabbix.creds
 | 
			
		||||
echo "zabbix Database Credentials" >>~/zabbix.creds
 | 
			
		||||
echo "" >>~/zabbix.creds
 | 
			
		||||
echo -e "zabbix Database User: \e[32m$DB_USER\e[0m" >>~/zabbix.creds
 | 
			
		||||
echo -e "zabbix Database Password: \e[32m$DB_PASS\e[0m" >>~/zabbix.creds
 | 
			
		||||
echo -e "zabbix Database Name: \e[32m$DB_NAME\e[0m" >>~/zabbix.creds
 | 
			
		||||
msg_ok "Set up PostgreSQL"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Fping"
 | 
			
		||||
if command -v fping >/dev/null 2>&1; then
 | 
			
		||||
  FPING_PATH=$(command -v fping)
 | 
			
		||||
  sed -i "s|^#\?FpingLocation=.*|FpingLocation=$FPING_PATH|" /etc/zabbix/zabbix_server.conf
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if command -v fping6 >/dev/null 2>&1; then
 | 
			
		||||
  FPING6_PATH=$(command -v fping6)
 | 
			
		||||
  sed -i "s|^#\?Fping6Location=.*|Fping6Location=$FPING6_PATH|" /etc/zabbix/zabbix_server.conf
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Configured Fping"
 | 
			
		||||
 | 
			
		||||
msg_info "Starting Services"
 | 
			
		||||
systemctl restart zabbix-server zabbix-agent2 apache2
 | 
			
		||||
systemctl enable -q --now zabbix-server zabbix-agent2 apache2
 | 
			
		||||
@@ -56,7 +110,8 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf /tmp/zabbix-release_latest+debian12_all.deb
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
rm -rf /tmp/zabbix-release_latest+debian13_all.deb
 | 
			
		||||
$STD apt -y autoremove
 | 
			
		||||
$STD apt -y autoclean
 | 
			
		||||
$STD apt -y clean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -1970,9 +1970,8 @@ function setup_uv() {
 | 
			
		||||
    export PATH="/usr/local/bin:$PATH"
 | 
			
		||||
  fi
 | 
			
		||||
  ensure_usr_local_bin_persist
 | 
			
		||||
  if ! $STD uv python update-shell; then
 | 
			
		||||
    msg_error "uv shell integration failed – continuing anyway"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  $STD uv python update-shell >/dev/null 2>&1 || true
 | 
			
		||||
  msg_ok "Setup uv $LATEST_VERSION"
 | 
			
		||||
 | 
			
		||||
  # Optional: install specific Python version
 | 
			
		||||
@@ -2022,6 +2021,8 @@ function setup_yq() {
 | 
			
		||||
    }
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  [[ ":$PATH:" != *":/usr/local/bin:"* ]] && echo 'export PATH="/usr/local/bin:$PATH"' >>~/.bashrc && source ~/.bashrc
 | 
			
		||||
 | 
			
		||||
  if command -v yq &>/dev/null; then
 | 
			
		||||
    if ! yq --version 2>&1 | grep -q 'mikefarah'; then
 | 
			
		||||
      rm -f "$(command -v yq)"
 | 
			
		||||
 
 | 
			
		||||
@@ -532,20 +532,28 @@ if [ -f "$MOBILE_TPL" ] && ! grep -q "$MARKER" "$MOBILE_TPL"; then
 | 
			
		||||
      "$MARKER" \
 | 
			
		||||
      "<script>" \
 | 
			
		||||
      "  function removeSubscriptionElements() {" \
 | 
			
		||||
      "    // --- Remove subscription dialogs ---" \
 | 
			
		||||
      "    const dialogs = document.querySelectorAll('dialog.pwt-outer-dialog');" \
 | 
			
		||||
      "    dialogs.forEach(dialog => {" \
 | 
			
		||||
      "      const closeButton = dialog.querySelector('.fa-close');" \
 | 
			
		||||
      "      const exclamationIcon = dialog.querySelector('.fa-exclamation-triangle');" \
 | 
			
		||||
      "      const continueButton = dialog.querySelector('button');" \
 | 
			
		||||
      "      if (closeButton && exclamationIcon && continueButton) { dialog.remove(); console.log('Removed subscription dialog'); }" \
 | 
			
		||||
      "      const text = (dialog.textContent || '').toLowerCase();" \
 | 
			
		||||
      "      if (text.includes('subscription')) {" \
 | 
			
		||||
      "        dialog.remove();" \
 | 
			
		||||
      "        console.log('Removed subscription dialog');" \
 | 
			
		||||
      "      }" \
 | 
			
		||||
      "    });" \
 | 
			
		||||
      "" \
 | 
			
		||||
      "    // --- Remove subscription cards, but keep Reboot/Shutdown/Console ---" \
 | 
			
		||||
      "    const cards = document.querySelectorAll('.pwt-card.pwt-p-2.pwt-d-flex.pwt-interactive.pwt-justify-content-center');" \
 | 
			
		||||
      "    cards.forEach(card => {" \
 | 
			
		||||
      "      const hasInteractiveElements = card.querySelector('button, input, a');" \
 | 
			
		||||
      "      const hasComplexStructure = card.querySelector('.pwt-grid, .pwt-flex, .pwt-button');" \
 | 
			
		||||
      "      if (!hasInteractiveElements && !hasComplexStructure) { card.remove(); console.log('Removed subscription card'); }" \
 | 
			
		||||
      "      const text = (card.textContent || '').toLowerCase();" \
 | 
			
		||||
      "      const hasButton = card.querySelector('button');" \
 | 
			
		||||
      "      if (!hasButton && text.includes('subscription')) {" \
 | 
			
		||||
      "        card.remove();" \
 | 
			
		||||
      "        console.log('Removed subscription card');" \
 | 
			
		||||
      "      }" \
 | 
			
		||||
      "    });" \
 | 
			
		||||
      "  }" \
 | 
			
		||||
      "" \
 | 
			
		||||
      "  const observer = new MutationObserver(removeSubscriptionElements);" \
 | 
			
		||||
      "  observer.observe(document.body, { childList: true, subtree: true });" \
 | 
			
		||||
      "  removeSubscriptionElements();" \
 | 
			
		||||
@@ -555,9 +563,8 @@ if [ -f "$MOBILE_TPL" ] && ! grep -q "$MARKER" "$MOBILE_TPL"; then
 | 
			
		||||
      "" >> "$MOBILE_TPL"
 | 
			
		||||
fi
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
    chmod 755 /usr/local/bin/pve-remove-nag.sh
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    cat >/etc/apt/apt.conf.d/no-nag-script <<'EOF'
 | 
			
		||||
DPkg::Post-Invoke { "/usr/local/bin/pve-remove-nag.sh"; };
 | 
			
		||||
EOF
 | 
			
		||||
 
 | 
			
		||||
@@ -205,15 +205,69 @@ function exit-script() {
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Ensure pv is installed or abort with instructions
 | 
			
		||||
function ensure_pv() {
 | 
			
		||||
  if ! command -v pv &>/dev/null; then
 | 
			
		||||
    msg_info "Installing required package: pv"
 | 
			
		||||
    apt-get update -qq &>/dev/null
 | 
			
		||||
    apt-get install -y pv &>/dev/null
 | 
			
		||||
    if ! apt-get update -qq &>/dev/null || ! apt-get install -y pv &>/dev/null; then
 | 
			
		||||
      msg_error "Failed to install pv automatically."
 | 
			
		||||
      echo -e "\nPlease run manually on the Proxmox host:\n  apt install pv\n"
 | 
			
		||||
      exit 1
 | 
			
		||||
    fi
 | 
			
		||||
    msg_ok "Installed pv"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Download an .xz file and validate it
 | 
			
		||||
# Args: $1=url $2=cache_file
 | 
			
		||||
function download_and_validate_xz() {
 | 
			
		||||
  local url="$1"
 | 
			
		||||
  local file="$2"
 | 
			
		||||
 | 
			
		||||
  # If file exists, check validity
 | 
			
		||||
  if [[ -s "$file" ]]; then
 | 
			
		||||
    if xz -t "$file" &>/dev/null; then
 | 
			
		||||
      msg_ok "Using cached image $(basename "$file")"
 | 
			
		||||
      return 0
 | 
			
		||||
    else
 | 
			
		||||
      msg_error "Cached file $(basename "$file") is corrupted. Deleting and retrying download..."
 | 
			
		||||
      rm -f "$file"
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Download fresh file
 | 
			
		||||
  msg_info "Downloading image: $(basename "$file")"
 | 
			
		||||
  if ! curl -fSL -o "$file" "$url"; then
 | 
			
		||||
    msg_error "Download failed: $url"
 | 
			
		||||
    rm -f "$file"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Validate again
 | 
			
		||||
  if ! xz -t "$file" &>/dev/null; then
 | 
			
		||||
    msg_error "Downloaded file $(basename "$file") is corrupted. Please try again later."
 | 
			
		||||
    rm -f "$file"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  msg_ok "Downloaded and validated $(basename "$file")"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Extract .xz with pv
 | 
			
		||||
# Args: $1=cache_file $2=target_img
 | 
			
		||||
function extract_xz_with_pv() {
 | 
			
		||||
  set -o pipefail
 | 
			
		||||
  local file="$1"
 | 
			
		||||
  local target="$2"
 | 
			
		||||
 | 
			
		||||
  msg_info "Decompressing $(basename "$file") to $target"
 | 
			
		||||
  if ! xz -dc "$file" | pv -N "Extracting" >"$target"; then
 | 
			
		||||
    msg_error "Failed to extract $file"
 | 
			
		||||
    rm -f "$target"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  msg_ok "Decompressed to $target"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function default_settings() {
 | 
			
		||||
  BRANCH="$stable"
 | 
			
		||||
  VMID=$(get_valid_nextid)
 | 
			
		||||
@@ -507,23 +561,15 @@ FILE_IMG="/var/lib/vz/template/tmp/${CACHE_FILE##*/%.xz}" # .qcow2
 | 
			
		||||
mkdir -p "$CACHE_DIR" "$(dirname "$FILE_IMG")"
 | 
			
		||||
msg_ok "${CL}${BL}${URL}${CL}"
 | 
			
		||||
 | 
			
		||||
if [[ ! -s "$CACHE_FILE" ]]; then
 | 
			
		||||
  curl -f#SL -o "$CACHE_FILE" "$URL"
 | 
			
		||||
  msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
 | 
			
		||||
else
 | 
			
		||||
  msg_ok "Using cached image ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
 | 
			
		||||
fi
 | 
			
		||||
download_and_validate_xz "$URL" "$CACHE_FILE"
 | 
			
		||||
 | 
			
		||||
set -o pipefail
 | 
			
		||||
msg_info "Creating Home Assistant OS VM shell"
 | 
			
		||||
qm create "$VMID" -machine q35 -bios ovmf -agent 1 -tablet 0 -localtime 1 ${CPU_TYPE} \
 | 
			
		||||
  -cores "$CORE_COUNT" -memory "$RAM_SIZE" -name "$HN" -tags community-script \
 | 
			
		||||
  -net0 "virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU" -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null
 | 
			
		||||
msg_ok "Created VM shell"
 | 
			
		||||
 | 
			
		||||
msg_info "Decompressing $(basename "$CACHE_FILE") to $FILE_IMG"
 | 
			
		||||
xz -dc "$CACHE_FILE" | pv -N "Extracting" >"$FILE_IMG"
 | 
			
		||||
msg_ok "Decompressed to $FILE_IMG"
 | 
			
		||||
extract_xz_with_pv "$CACHE_FILE" "$FILE_IMG"
 | 
			
		||||
 | 
			
		||||
msg_info "Importing disk into storage ($STORAGE)"
 | 
			
		||||
if qm disk import --help >/dev/null 2>&1; then
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,6 @@ GN=$(echo "\033[1;92m")
 | 
			
		||||
DGN=$(echo "\033[32m")
 | 
			
		||||
CL=$(echo "\033[m")
 | 
			
		||||
 | 
			
		||||
CL=$(echo "\033[m")
 | 
			
		||||
BOLD=$(echo "\033[1m")
 | 
			
		||||
BFR="\\r\\033[K"
 | 
			
		||||
HOLD=" "
 | 
			
		||||
@@ -201,15 +200,69 @@ function exit-script() {
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Ensure pv is installed or abort with instructions
 | 
			
		||||
function ensure_pv() {
 | 
			
		||||
  if ! command -v pv &>/dev/null; then
 | 
			
		||||
    msg_info "Installing required package: pv"
 | 
			
		||||
    apt-get update -qq &>/dev/null
 | 
			
		||||
    apt-get install -y pv &>/dev/null
 | 
			
		||||
    if ! apt-get update -qq &>/dev/null || ! apt-get install -y pv &>/dev/null; then
 | 
			
		||||
      msg_error "Failed to install pv automatically."
 | 
			
		||||
      echo -e "\nPlease run manually on the Proxmox host:\n  apt install pv\n"
 | 
			
		||||
      exit 1
 | 
			
		||||
    fi
 | 
			
		||||
    msg_ok "Installed pv"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Download an .xz file and validate it
 | 
			
		||||
# Args: $1=url $2=cache_file
 | 
			
		||||
function download_and_validate_xz() {
 | 
			
		||||
  local url="$1"
 | 
			
		||||
  local file="$2"
 | 
			
		||||
 | 
			
		||||
  # If file exists, check validity
 | 
			
		||||
  if [[ -s "$file" ]]; then
 | 
			
		||||
    if xz -t "$file" &>/dev/null; then
 | 
			
		||||
      msg_ok "Using cached image $(basename "$file")"
 | 
			
		||||
      return 0
 | 
			
		||||
    else
 | 
			
		||||
      msg_error "Cached file $(basename "$file") is corrupted. Deleting and retrying download..."
 | 
			
		||||
      rm -f "$file"
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Download fresh file
 | 
			
		||||
  msg_info "Downloading image: $(basename "$file")"
 | 
			
		||||
  if ! curl -fSL -o "$file" "$url"; then
 | 
			
		||||
    msg_error "Download failed: $url"
 | 
			
		||||
    rm -f "$file"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Validate again
 | 
			
		||||
  if ! xz -t "$file" &>/dev/null; then
 | 
			
		||||
    msg_error "Downloaded file $(basename "$file") is corrupted. Please try again later."
 | 
			
		||||
    rm -f "$file"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  msg_ok "Downloaded and validated $(basename "$file")"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Extract .xz with pv
 | 
			
		||||
# Args: $1=cache_file $2=target_img
 | 
			
		||||
function extract_xz_with_pv() {
 | 
			
		||||
  set -o pipefail
 | 
			
		||||
  local file="$1"
 | 
			
		||||
  local target="$2"
 | 
			
		||||
 | 
			
		||||
  msg_info "Decompressing $(basename "$file") to $target"
 | 
			
		||||
  if ! xz -dc "$file" | pv -N "Extracting" >"$target"; then
 | 
			
		||||
    msg_error "Failed to extract $file"
 | 
			
		||||
    rm -f "$target"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  msg_ok "Decompressed to $target"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function default_settings() {
 | 
			
		||||
  VMID=$(get_valid_nextid)
 | 
			
		||||
  MACHINE="q35"
 | 
			
		||||
@@ -475,19 +528,13 @@ FILE_IMG="/var/lib/vz/template/tmp/${CACHE_FILE##*/%.xz}"
 | 
			
		||||
 | 
			
		||||
mkdir -p "$CACHE_DIR" "$(dirname "$FILE_IMG")"
 | 
			
		||||
 | 
			
		||||
if [[ ! -s "$CACHE_FILE" ]]; then
 | 
			
		||||
  msg_ok "Downloading Umbrel OS image"
 | 
			
		||||
  curl -f#SL -o "$CACHE_FILE" "$URL"
 | 
			
		||||
else
 | 
			
		||||
  msg_ok "Using cached Umbrel OS image"
 | 
			
		||||
fi
 | 
			
		||||
download_and_validate_xz "$URL" "$CACHE_FILE"
 | 
			
		||||
 | 
			
		||||
set -o pipefail
 | 
			
		||||
qm create "$VMID" -machine q35 -bios ovmf -agent 1 -tablet 0 -localtime 1 ${CPU_TYPE} \
 | 
			
		||||
  -cores "$CORE_COUNT" -memory "$RAM_SIZE" -name "$HN" -tags community-script \
 | 
			
		||||
  -net0 "virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU" -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null
 | 
			
		||||
 | 
			
		||||
xz -dc "$CACHE_FILE" | pv -N "Extracting" >"$FILE_IMG"
 | 
			
		||||
extract_xz_with_pv "$CACHE_FILE" "$FILE_IMG"
 | 
			
		||||
 | 
			
		||||
if qm disk import --help >/dev/null 2>&1; then
 | 
			
		||||
  IMPORT_CMD=(qm disk import)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user