mirror of
				https://github.com/community-scripts/ProxmoxVE.git
				synced 2025-11-04 02:12:49 +00:00 
			
		
		
		
	Compare commits
	
		
			129 Commits
		
	
	
		
			2025-07-06
			...
			2025-07-11
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					ee5cd20915 | ||
| 
						 | 
					5dcd39231f | ||
| 
						 | 
					8f79823c95 | ||
| 
						 | 
					ba00a1d3f0 | ||
| 
						 | 
					599d65768e | ||
| 
						 | 
					471e2f758f | ||
| 
						 | 
					f3a4bd461d | ||
| 
						 | 
					b115fe9120 | ||
| 
						 | 
					f9429ecf5a | ||
| 
						 | 
					ebea43f299 | ||
| 
						 | 
					d693c9361b | ||
| 
						 | 
					3ca53067a7 | ||
| 
						 | 
					93e204850b | ||
| 
						 | 
					8595d48cec | ||
| 
						 | 
					6fcca2bfdb | ||
| 
						 | 
					295b419fbc | ||
| 
						 | 
					b9ac02e74f | ||
| 
						 | 
					66d2f96b16 | ||
| 
						 | 
					1a66ca2683 | ||
| 
						 | 
					b865be5e45 | ||
| 
						 | 
					edb8ee5980 | ||
| 
						 | 
					d30c0718da | ||
| 
						 | 
					90b6712453 | ||
| 
						 | 
					3140438b2f | ||
| 
						 | 
					bb00b9f545 | ||
| 
						 | 
					12b9e163bc | ||
| 
						 | 
					ee182fe867 | ||
| 
						 | 
					5c6573152d | ||
| 
						 | 
					1c05a843bb | ||
| 
						 | 
					ce5b17e210 | ||
| 
						 | 
					787d749340 | ||
| 
						 | 
					cd98fddc05 | ||
| 
						 | 
					043ca11732 | ||
| 
						 | 
					d596ced793 | ||
| 
						 | 
					4f08b4609b | ||
| 
						 | 
					2e4c185ee1 | ||
| 
						 | 
					64fac95a03 | ||
| 
						 | 
					786c9178f9 | ||
| 
						 | 
					7b380253ee | ||
| 
						 | 
					3914c0f7b9 | ||
| 
						 | 
					1a53b749da | ||
| 
						 | 
					f01046133e | ||
| 
						 | 
					e8aa450d06 | ||
| 
						 | 
					6acf854f3e | ||
| 
						 | 
					b565048985 | ||
| 
						 | 
					24eff9dbbd | ||
| 
						 | 
					24be3b43b1 | ||
| 
						 | 
					54d534a5d2 | ||
| 
						 | 
					5bad80e148 | ||
| 
						 | 
					89498f4205 | ||
| 
						 | 
					661a58ae29 | ||
| 
						 | 
					acc500fe9d | ||
| 
						 | 
					0a37d1b004 | ||
| 
						 | 
					8c09216691 | ||
| 
						 | 
					54cd7dd669 | ||
| 
						 | 
					2ff778db9a | ||
| 
						 | 
					5d1f0ab13e | ||
| 
						 | 
					b306a31235 | ||
| 
						 | 
					c8797ba135 | ||
| 
						 | 
					b9ec651a8b | ||
| 
						 | 
					475c666eb0 | ||
| 
						 | 
					8d419616a6 | ||
| 
						 | 
					d087719571 | ||
| 
						 | 
					df52a2d057 | ||
| 
						 | 
					4886196cfa | ||
| 
						 | 
					1f37fbb83e | ||
| 
						 | 
					387f2c7bd1 | ||
| 
						 | 
					0b949c8151 | ||
| 
						 | 
					fd248e072c | ||
| 
						 | 
					e58e50fc15 | ||
| 
						 | 
					5b869b61fc | ||
| 
						 | 
					0e2c793f92 | ||
| 
						 | 
					96a8f9df89 | ||
| 
						 | 
					4f569c67eb | ||
| 
						 | 
					e856b36306 | ||
| 
						 | 
					42e8623f39 | ||
| 
						 | 
					3b7036ae58 | ||
| 
						 | 
					4412b39d21 | ||
| 
						 | 
					0faf06f4e2 | ||
| 
						 | 
					0b300fb9ab | ||
| 
						 | 
					08b89eb285 | ||
| 
						 | 
					9cbcf4435a | ||
| 
						 | 
					e4252a58ee | ||
| 
						 | 
					08eb914e3c | ||
| 
						 | 
					000b7d4a85 | ||
| 
						 | 
					bb33002c2a | ||
| 
						 | 
					7bafa864d0 | ||
| 
						 | 
					396e0c6523 | ||
| 
						 | 
					1530e52108 | ||
| 
						 | 
					451f6aff8e | ||
| 
						 | 
					046acc75db | ||
| 
						 | 
					f40218aa07 | ||
| 
						 | 
					c5e831dadc | ||
| 
						 | 
					16786a8304 | ||
| 
						 | 
					fc728bcca7 | ||
| 
						 | 
					5516aa493d | ||
| 
						 | 
					54f2f98193 | ||
| 
						 | 
					137a41f67c | ||
| 
						 | 
					26365561dc | ||
| 
						 | 
					9dc0fc80b9 | ||
| 
						 | 
					722f7e14d7 | ||
| 
						 | 
					b2a8a9bd00 | ||
| 
						 | 
					12bd6754ab | ||
| 
						 | 
					74166f97f9 | ||
| 
						 | 
					b2bccd9501 | ||
| 
						 | 
					c567b75aa7 | ||
| 
						 | 
					2d77790b64 | ||
| 
						 | 
					37d466103d | ||
| 
						 | 
					d59aa0527a | ||
| 
						 | 
					9ddf10f82e | ||
| 
						 | 
					69d2835c73 | ||
| 
						 | 
					59f99a27d2 | ||
| 
						 | 
					372b52f64d | ||
| 
						 | 
					2586c9f385 | ||
| 
						 | 
					5c5d5d52ce | ||
| 
						 | 
					c2a7e990bd | ||
| 
						 | 
					3847442ca5 | ||
| 
						 | 
					6996111473 | ||
| 
						 | 
					3336f6a6f5 | ||
| 
						 | 
					be6a63cd03 | ||
| 
						 | 
					160846e98b | ||
| 
						 | 
					e63128625e | ||
| 
						 | 
					e58ad9237a | ||
| 
						 | 
					2ce64b5004 | ||
| 
						 | 
					9893379eef | ||
| 
						 | 
					9ae95d1eb5 | ||
| 
						 | 
					8a178b6f45 | ||
| 
						 | 
					f0b645c894 | ||
| 
						 | 
					2be5d83a6d | 
							
								
								
									
										42
									
								
								.github/autolabeler-config.json
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								.github/autolabeler-config.json
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,6 +4,7 @@
 | 
			
		||||
      "fileStatus": "added",
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "ct/**",
 | 
			
		||||
        "tools/**",
 | 
			
		||||
        "install/**",
 | 
			
		||||
        "misc/**",
 | 
			
		||||
        "turnkey/**",
 | 
			
		||||
@@ -17,16 +18,13 @@
 | 
			
		||||
      "fileStatus": "modified",
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "ct/**",
 | 
			
		||||
        "tools/**",
 | 
			
		||||
        "install/**",
 | 
			
		||||
        "misc/**",
 | 
			
		||||
        "turnkey/**",
 | 
			
		||||
        "vm/**"
 | 
			
		||||
      ],
 | 
			
		||||
      "excludeGlobs": [
 | 
			
		||||
        "misc/build.func",
 | 
			
		||||
        "misc/install.func",
 | 
			
		||||
        "misc/api.func"
 | 
			
		||||
      ]
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "delete script": [
 | 
			
		||||
@@ -34,6 +32,7 @@
 | 
			
		||||
      "fileStatus": "removed",
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "ct/**",
 | 
			
		||||
        "tools/**",
 | 
			
		||||
        "install/**",
 | 
			
		||||
        "misc/**",
 | 
			
		||||
        "turnkey/**",
 | 
			
		||||
@@ -46,11 +45,7 @@
 | 
			
		||||
    {
 | 
			
		||||
      "fileStatus": null,
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "*.md",
 | 
			
		||||
        ".github/**",
 | 
			
		||||
        "misc/*.func",
 | 
			
		||||
        "misc/create_lxc.sh",
 | 
			
		||||
        "api/**"
 | 
			
		||||
        "*.md"
 | 
			
		||||
      ],
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
    }
 | 
			
		||||
@@ -62,7 +57,9 @@
 | 
			
		||||
        "misc/*.func",
 | 
			
		||||
        "misc/create_lxc.sh"
 | 
			
		||||
      ],
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
      "excludeGlobs": [
 | 
			
		||||
        "misc/api.func"
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "website": [
 | 
			
		||||
@@ -71,7 +68,9 @@
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "frontend/**"
 | 
			
		||||
      ],
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
      "excludeGlobs": [
 | 
			
		||||
        "frontend/public/json/**"
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "api": [
 | 
			
		||||
@@ -102,22 +101,29 @@
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "high risk": [
 | 
			
		||||
  "addon": [
 | 
			
		||||
    {
 | 
			
		||||
      "fileStatus": null,
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "misc/build.func",
 | 
			
		||||
        "misc/install.func",
 | 
			
		||||
        "misc/create_lxc.sh"
 | 
			
		||||
        "tools/addon/**"
 | 
			
		||||
      ],
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "documentation": [
 | 
			
		||||
  "pve-tool": [
 | 
			
		||||
    {
 | 
			
		||||
      "fileStatus": null,
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "*.md"
 | 
			
		||||
        "tools/pve/**"
 | 
			
		||||
      ],
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "vm": [
 | 
			
		||||
    {
 | 
			
		||||
      "fileStatus": null,
 | 
			
		||||
      "includeGlobs": [
 | 
			
		||||
        "vm/**"
 | 
			
		||||
      ],
 | 
			
		||||
      "excludeGlobs": []
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										120
									
								
								.github/changelog-pr-config.json
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										120
									
								
								.github/changelog-pr-config.json
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,112 +1,148 @@
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "title": "🆕 New Scripts",
 | 
			
		||||
    "labels": ["new script"]
 | 
			
		||||
    "labels": [
 | 
			
		||||
      "new script"
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "title": "🚀 Updated Scripts",
 | 
			
		||||
    "labels": ["update script"],
 | 
			
		||||
    "labels": [
 | 
			
		||||
      "update script"
 | 
			
		||||
    ],
 | 
			
		||||
    "subCategories": [
 | 
			
		||||
      {
 | 
			
		||||
        "title": "🐞 Bug Fixes",
 | 
			
		||||
        "labels": ["bugfix"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "bugfix"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "✨ New Features",
 | 
			
		||||
        "labels": ["feature"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "feature"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "💥 Breaking Changes",
 | 
			
		||||
        "labels": ["breaking change"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "breaking change"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "🔧 Refactor",
 | 
			
		||||
        "labels": ["refactor"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "refactor"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "title": "🧰 Maintenance",
 | 
			
		||||
    "labels": ["maintenance"],
 | 
			
		||||
    "labels": [
 | 
			
		||||
      "maintenance"
 | 
			
		||||
    ],
 | 
			
		||||
    "subCategories": [
 | 
			
		||||
      {
 | 
			
		||||
        "title": "🐞 Bug Fixes",
 | 
			
		||||
        "labels": ["bugfix"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "bugfix"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "✨ New Features",
 | 
			
		||||
        "labels": ["feature"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "feature"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "💥 Breaking Changes",
 | 
			
		||||
        "labels": ["breaking change"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "breaking change"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "📡 API",
 | 
			
		||||
        "labels": ["api"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "api"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "💾 Core",
 | 
			
		||||
        "labels": ["core"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "core"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "📂 Github",
 | 
			
		||||
        "labels": ["github"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "github"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title" :"📝 Documentation",
 | 
			
		||||
        "labels": ["documentation"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "title": "📝 Documentation",
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "maintenance"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title" :"🔧 Refactor",
 | 
			
		||||
        "labels": ["refactor"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "title": "🔧 Refactor",
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "refactor"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "title": "🌐 Website",
 | 
			
		||||
    "labels": ["website"],
 | 
			
		||||
    "labels": [
 | 
			
		||||
      "website"
 | 
			
		||||
    ],
 | 
			
		||||
    "subCategories": [
 | 
			
		||||
      {
 | 
			
		||||
        "title": "🐞 Bug Fixes",
 | 
			
		||||
        "labels": ["bugfix"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "bugfix"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "✨ New Features",
 | 
			
		||||
        "labels": ["feature"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "feature"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "💥 Breaking Changes",
 | 
			
		||||
        "labels": ["breaking change"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "breaking change"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "title": "📝 Script Information",
 | 
			
		||||
        "labels": ["json"],
 | 
			
		||||
        "notes" : []
 | 
			
		||||
        "labels": [
 | 
			
		||||
          "json"
 | 
			
		||||
        ],
 | 
			
		||||
        "notes": []
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "title": "❔ Unlabelled",
 | 
			
		||||
    "labels": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "title": "💥 Breaking Changes",
 | 
			
		||||
    "labels": ["breaking change"]
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										73
									
								
								.github/workflows/autolabeler.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										73
									
								
								.github/workflows/autolabeler.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,7 @@
 | 
			
		||||
name: Auto Label Pull Requests
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
  pull_request_target:
 | 
			
		||||
    branches: ["main"]
 | 
			
		||||
    types: [opened, synchronize, reopened, edited]
 | 
			
		||||
@@ -19,7 +20,7 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: npm install minimatch
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      - name: Label PR based on file changes and PR template
 | 
			
		||||
        uses: actions/github-script@v7
 | 
			
		||||
        with:
 | 
			
		||||
@@ -33,7 +34,7 @@ jobs:
 | 
			
		||||
            const autolabelerConfig = JSON.parse(fileContent);
 | 
			
		||||
 | 
			
		||||
            const prNumber = context.payload.pull_request.number;
 | 
			
		||||
            const prBody = context.payload.pull_request.body.toLowerCase();
 | 
			
		||||
            const prBody = context.payload.pull_request.body || "";
 | 
			
		||||
 | 
			
		||||
            let labelsToAdd = new Set();
 | 
			
		||||
 | 
			
		||||
@@ -43,51 +44,67 @@ jobs:
 | 
			
		||||
              pull_number: prNumber,
 | 
			
		||||
            });
 | 
			
		||||
            const prFiles = prListFilesResponse.data;
 | 
			
		||||
           
 | 
			
		||||
 | 
			
		||||
          
 | 
			
		||||
            // Apply labels based on file changes
 | 
			
		||||
            for (const [label, rules] of Object.entries(autolabelerConfig)) {
 | 
			
		||||
              const shouldAddLabel = prFiles.some((prFile) => {
 | 
			
		||||
                return rules.some((rule) => {
 | 
			
		||||
                  const isFileStatusMatch = rule.fileStatus ? rule.fileStatus === prFile.status : true;
 | 
			
		||||
                  const isIncludeGlobMatch = rule.includeGlobs.some((glob) => minimatch(prFile.filename, glob));
 | 
			
		||||
                  const isExcludeGlobMatch = rule.excludeGlobs.some((glob) => minimatch(prFile.filename, glob));
 | 
			
		||||
 | 
			
		||||
                  return isFileStatusMatch && isIncludeGlobMatch && !isExcludeGlobMatch;
 | 
			
		||||
                });
 | 
			
		||||
              });
 | 
			
		||||
 | 
			
		||||
              if (shouldAddLabel) {
 | 
			
		||||
                labelsToAdd.add(label);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            //if two labels or more are added, return
 | 
			
		||||
              if (labelsToAdd.size < 2) {
 | 
			
		||||
                const templateLabelMappings = {
 | 
			
		||||
                "🐞 **Bug fix**": "bugfix",
 | 
			
		||||
                "✨ **New feature**": "feature",
 | 
			
		||||
                "💥 **Breaking change**": "breaking change",
 | 
			
		||||
                "🔧 **Refactoring / Code Cleanup**": "refactor",
 | 
			
		||||
              };
 | 
			
		||||
 | 
			
		||||
              for (const [checkbox, label] of Object.entries(templateLabelMappings)) {
 | 
			
		||||
                const escapedCheckbox = checkbox.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
 | 
			
		||||
                const regex = new RegExp(`- \\[(x|X)\\]\\s*.*${escapedCheckbox}`, "i");
 | 
			
		||||
                const match = prBody.match(regex);              
 | 
			
		||||
                if (match) {
 | 
			
		||||
                  console.log(`Match: ${match}`);
 | 
			
		||||
                  labelsToAdd.add(label);
 | 
			
		||||
                if (label === "update script") {
 | 
			
		||||
                  for (const prFile of prFiles) {
 | 
			
		||||
                    const filename = prFile.filename;
 | 
			
		||||
                    if (filename.startsWith("vm/")) labelsToAdd.add("vm");
 | 
			
		||||
                    if (filename.startsWith("tools/addon/")) labelsToAdd.add("addon");
 | 
			
		||||
                    if (filename.startsWith("tools/pve/")) labelsToAdd.add("pve-tool");
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
            
 | 
			
		||||
            console.log(`Labels to add: ${Array.from(labelsToAdd).join(", ")}`);
 | 
			
		||||
            if (labelsToAdd.size < 2) {
 | 
			
		||||
              const templateLabelMappings = {
 | 
			
		||||
                "🐞 **Bug fix**": "bugfix",
 | 
			
		||||
                "✨ **New feature**": "feature",
 | 
			
		||||
                "💥 **Breaking change**": "breaking change",
 | 
			
		||||
                "🆕 **New script**": "new script",
 | 
			
		||||
                "🌍 **Website update**": "website", // handled special
 | 
			
		||||
                "🔧 **Refactoring / Code Cleanup**": "refactor",
 | 
			
		||||
                "📝 **Documentation update**": "documentation" // mapped to maintenance
 | 
			
		||||
              };
 | 
			
		||||
 | 
			
		||||
              for (const [checkbox, label] of Object.entries(templateLabelMappings)) {
 | 
			
		||||
                const escapedCheckbox = checkbox.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1");
 | 
			
		||||
                const regex = new RegExp(`- \\[(x|X)\\]\\s*${escapedCheckbox}`, "i");
 | 
			
		||||
 | 
			
		||||
                if (regex.test(prBody)) {
 | 
			
		||||
                  if (label === "website") {
 | 
			
		||||
                    const hasJson = prFiles.some((f) => f.filename.startsWith("frontend/public/json/"));
 | 
			
		||||
                    const hasUpdateScript = labelsToAdd.has("update script");
 | 
			
		||||
                    const hasContentLabel = ["bugfix", "feature", "refactor"].some((l) => labelsToAdd.has(l));
 | 
			
		||||
 | 
			
		||||
                    if (!(hasUpdateScript && hasContentLabel)) {
 | 
			
		||||
                      labelsToAdd.add(hasJson ? "json" : "website");
 | 
			
		||||
                    }
 | 
			
		||||
                  } else if (label === "documentation") {
 | 
			
		||||
                    labelsToAdd.add("maintenance");
 | 
			
		||||
                  } else {
 | 
			
		||||
                    labelsToAdd.add(label);
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            if (labelsToAdd.size === 0) {
 | 
			
		||||
              labelsToAdd.add("needs triage");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (labelsToAdd.size > 0) {
 | 
			
		||||
              console.log(`Adding labels ${Array.from(labelsToAdd).join(", ")} to PR ${prNumber}`);
 | 
			
		||||
              await github.rest.issues.addLabels({
 | 
			
		||||
                owner: context.repo.owner,
 | 
			
		||||
                repo: context.repo.repo,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/changelog-pr.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/changelog-pr.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -80,7 +80,7 @@ jobs:
 | 
			
		||||
                    { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
 | 
			
		||||
                    { title: "📡 API", labels: ["api"], notes: [] },
 | 
			
		||||
                    { title: "Github", labels: ["github"], notes: [] },
 | 
			
		||||
                    { title: "📝 Documentation", labels: ["documentation"], notes: [] },
 | 
			
		||||
                    { title: "📝 Documentation", labels: ["maintenance"], notes: [] },
 | 
			
		||||
                    { title: "🔧 Refactor", labels: ["refactor"], notes: [] }
 | 
			
		||||
                  ] :
 | 
			
		||||
                  obj.labels.includes("website") ? [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										121
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -10,12 +10,129 @@
 | 
			
		||||
> [!CAUTION]
 | 
			
		||||
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
 | 
			
		||||
 | 
			
		||||
> [!NOTE]
 | 
			
		||||
All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment.
 | 
			
		||||
## 2025-07-12
 | 
			
		||||
 | 
			
		||||
## 2025-07-11
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - immich: hotfix #5921 [@vhsdream](https://github.com/vhsdream) ([#5938](https://github.com/community-scripts/ProxmoxVE/pull/5938))
 | 
			
		||||
    - bookstack: add setup_composer in update [@MickLesk](https://github.com/MickLesk) ([#5935](https://github.com/community-scripts/ProxmoxVE/pull/5935))
 | 
			
		||||
    - Quickfix: Immich: revert install sequence [@vhsdream](https://github.com/vhsdream) ([#5932](https://github.com/community-scripts/ProxmoxVE/pull/5932))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - Refactor & Function Bump: Docker [@MickLesk](https://github.com/MickLesk) ([#5889](https://github.com/community-scripts/ProxmoxVE/pull/5889))
 | 
			
		||||
 | 
			
		||||
  - #### 🔧 Refactor
 | 
			
		||||
 | 
			
		||||
    - Immich: handle custom library dependency updates; other fixes [@vhsdream](https://github.com/vhsdream) ([#5896](https://github.com/community-scripts/ProxmoxVE/pull/5896))
 | 
			
		||||
 | 
			
		||||
## 2025-07-10
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - Refactor: Habitica [@MickLesk](https://github.com/MickLesk) ([#5911](https://github.com/community-scripts/ProxmoxVE/pull/5911))
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - core: fix breaking re-download of lxc containers  [@MickLesk](https://github.com/MickLesk) ([#5906](https://github.com/community-scripts/ProxmoxVE/pull/5906))
 | 
			
		||||
    - PLANKA: Fix paths to application directory [@tremor021](https://github.com/tremor021) ([#5900](https://github.com/community-scripts/ProxmoxVE/pull/5900))
 | 
			
		||||
 | 
			
		||||
  - #### 🔧 Refactor
 | 
			
		||||
 | 
			
		||||
    - Refactor: EMQX + Update-Function + Improved NodeJS Crawling [@MickLesk](https://github.com/MickLesk) ([#5907](https://github.com/community-scripts/ProxmoxVE/pull/5907))
 | 
			
		||||
 | 
			
		||||
## 2025-07-09
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Omada Update: add missing exit  [@MickLesk](https://github.com/MickLesk) ([#5894](https://github.com/community-scripts/ProxmoxVE/pull/5894))
 | 
			
		||||
    - FreshRSS: fix needed php modules [@MickLesk](https://github.com/MickLesk) ([#5886](https://github.com/community-scripts/ProxmoxVE/pull/5886))
 | 
			
		||||
    - core: Fix VAAPI passthrough for unprivileged LXC containers via devX  [@MickLesk](https://github.com/MickLesk) ([#5875](https://github.com/community-scripts/ProxmoxVE/pull/5875))
 | 
			
		||||
    - tools.func: fix an bug while php libapache2-mod breaks [@MickLesk](https://github.com/MickLesk) ([#5857](https://github.com/community-scripts/ProxmoxVE/pull/5857))
 | 
			
		||||
    - BabyBuddy: fix path issues for update [@MickLesk](https://github.com/MickLesk) ([#5856](https://github.com/community-scripts/ProxmoxVE/pull/5856))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - tools.func: strip leading folders for prebuild assets [@MickLesk](https://github.com/MickLesk) ([#5865](https://github.com/community-scripts/ProxmoxVE/pull/5865))
 | 
			
		||||
 | 
			
		||||
  - #### 💥 Breaking Changes
 | 
			
		||||
 | 
			
		||||
    - Refactor: Stirling-PDF [@MickLesk](https://github.com/MickLesk) ([#5872](https://github.com/community-scripts/ProxmoxVE/pull/5872))
 | 
			
		||||
 | 
			
		||||
  - #### 🔧 Refactor
 | 
			
		||||
 | 
			
		||||
    - Refactor: EMQX [@tremor021](https://github.com/tremor021) ([#5840](https://github.com/community-scripts/ProxmoxVE/pull/5840))
 | 
			
		||||
    - Refactor: Excalidraw [@tremor021](https://github.com/tremor021) ([#5841](https://github.com/community-scripts/ProxmoxVE/pull/5841))
 | 
			
		||||
    - Refactor: Firefly [@tremor021](https://github.com/tremor021) ([#5844](https://github.com/community-scripts/ProxmoxVE/pull/5844))
 | 
			
		||||
    - Refactor: gatus [@tremor021](https://github.com/tremor021) ([#5849](https://github.com/community-scripts/ProxmoxVE/pull/5849))
 | 
			
		||||
    - Refactor: FreshRSS [@tremor021](https://github.com/tremor021) ([#5847](https://github.com/community-scripts/ProxmoxVE/pull/5847))
 | 
			
		||||
    - Refactor: Fluid-Calendar [@tremor021](https://github.com/tremor021) ([#5846](https://github.com/community-scripts/ProxmoxVE/pull/5846))
 | 
			
		||||
    - Refactor: Commafeed [@tremor021](https://github.com/tremor021) ([#5802](https://github.com/community-scripts/ProxmoxVE/pull/5802))
 | 
			
		||||
    - Refactor: FlareSolverr [@tremor021](https://github.com/tremor021) ([#5845](https://github.com/community-scripts/ProxmoxVE/pull/5845))
 | 
			
		||||
    - Refactor: Glance [@tremor021](https://github.com/tremor021) ([#5874](https://github.com/community-scripts/ProxmoxVE/pull/5874))
 | 
			
		||||
    - Refactor: Gitea [@tremor021](https://github.com/tremor021) ([#5876](https://github.com/community-scripts/ProxmoxVE/pull/5876))
 | 
			
		||||
    - Refactor: Ghost (use now MySQL)  [@MickLesk](https://github.com/MickLesk) ([#5871](https://github.com/community-scripts/ProxmoxVE/pull/5871))
 | 
			
		||||
 | 
			
		||||
### 🧰 Maintenance
 | 
			
		||||
 | 
			
		||||
  - #### 📂 Github
 | 
			
		||||
 | 
			
		||||
    - Github: AutoLabler | ChangeLog (Refactor) [@MickLesk](https://github.com/MickLesk) ([#5868](https://github.com/community-scripts/ProxmoxVE/pull/5868))
 | 
			
		||||
 | 
			
		||||
## 2025-07-08
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - Refactor: Emby [@tremor021](https://github.com/tremor021) ([#5839](https://github.com/community-scripts/ProxmoxVE/pull/5839))
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Ollama: fix update script [@lucacome](https://github.com/lucacome) ([#5819](https://github.com/community-scripts/ProxmoxVE/pull/5819))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - tools.func: add ffmpeg + minor improvement [@MickLesk](https://github.com/MickLesk) ([#5834](https://github.com/community-scripts/ProxmoxVE/pull/5834))
 | 
			
		||||
 | 
			
		||||
  - #### 🔧 Refactor
 | 
			
		||||
 | 
			
		||||
    - Refactor: ErsatzTV [@MickLesk](https://github.com/MickLesk) ([#5835](https://github.com/community-scripts/ProxmoxVE/pull/5835))
 | 
			
		||||
 | 
			
		||||
## 2025-07-07
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Fix/stirling pdf script [@JcMinarro](https://github.com/JcMinarro) ([#5803](https://github.com/community-scripts/ProxmoxVE/pull/5803))
 | 
			
		||||
    - gitea-mirror: update repo-url [@CrazyWolf13](https://github.com/CrazyWolf13) ([#5794](https://github.com/community-scripts/ProxmoxVE/pull/5794))
 | 
			
		||||
    - Fix unbound var in pulse.sh [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#5807](https://github.com/community-scripts/ProxmoxVE/pull/5807))
 | 
			
		||||
    - Bookstack: Fix PHP Issue & Bump to PHP 8.3 [@MickLesk](https://github.com/MickLesk) ([#5779](https://github.com/community-scripts/ProxmoxVE/pull/5779))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - Refactor: Threadfin (+ updatable) [@MickLesk](https://github.com/MickLesk) ([#5783](https://github.com/community-scripts/ProxmoxVE/pull/5783))
 | 
			
		||||
    - tools.func: better handling when unpacking tarfiles in prebuild mode [@MickLesk](https://github.com/MickLesk) ([#5781](https://github.com/community-scripts/ProxmoxVE/pull/5781))
 | 
			
		||||
    - tools.func: add AVX check for MongoDB [@MickLesk](https://github.com/MickLesk) ([#5780](https://github.com/community-scripts/ProxmoxVE/pull/5780))
 | 
			
		||||
 | 
			
		||||
  - #### 🔧 Refactor
 | 
			
		||||
 | 
			
		||||
    - Refactor: Docmost [@tremor021](https://github.com/tremor021) ([#5806](https://github.com/community-scripts/ProxmoxVE/pull/5806))
 | 
			
		||||
    - Refactor: Baby Buddy [@tremor021](https://github.com/tremor021) ([#5769](https://github.com/community-scripts/ProxmoxVE/pull/5769))
 | 
			
		||||
    - Refactor: Changed the way we install BunkerWeb by leveraging the brand new install-bunkerweb.sh [@TheophileDiot](https://github.com/TheophileDiot) ([#5707](https://github.com/community-scripts/ProxmoxVE/pull/5707))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
  - #### 📝 Script Information
 | 
			
		||||
 | 
			
		||||
    - PBS: add hint for advanced installs [@MickLesk](https://github.com/MickLesk) ([#5788](https://github.com/community-scripts/ProxmoxVE/pull/5788))
 | 
			
		||||
    - EMQX: Add warning to website [@tremor021](https://github.com/tremor021) ([#5770](https://github.com/community-scripts/ProxmoxVE/pull/5770))
 | 
			
		||||
 | 
			
		||||
## 2025-07-06
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<div align="center">
 | 
			
		||||
  <p align="center">
 | 
			
		||||
    <a href="#">
 | 
			
		||||
      <img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo.png" height="100px" />
 | 
			
		||||
      <img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png" height="100px" />
 | 
			
		||||
    </a>
 | 
			
		||||
  </p>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ function update_script() {
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/babybuddy/babybuddy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/babybuddy_version.txt)" ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.babybuddy 2>/dev/null)" ]] || [[ ! -f ~/.babybuddy ]]; then
 | 
			
		||||
    setup_uv
 | 
			
		||||
 | 
			
		||||
    msg_info "Stopping Services"
 | 
			
		||||
@@ -38,21 +38,18 @@ function update_script() {
 | 
			
		||||
    msg_ok "Services Stopped"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning old files"
 | 
			
		||||
    cp babybuddy/settings/production.py /tmp/production.py.bak
 | 
			
		||||
    cp /opt/babybuddy/babybuddy/settings/production.py /tmp/production.py.bak
 | 
			
		||||
    find . -mindepth 1 -maxdepth 1 ! -name '.venv' -exec rm -rf {} +
 | 
			
		||||
    msg_ok "Cleaned old files"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "babybuddy" "babybuddy/babybuddy"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    temp_file=$(mktemp)
 | 
			
		||||
    curl -fsSL "https://github.com/babybuddy/babybuddy/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
    cd /opt/babybuddy
 | 
			
		||||
    tar zxf "$temp_file" --strip-components=1 -C /opt/babybuddy
 | 
			
		||||
    mv /tmp/production.py.bak babybuddy/settings/production.py
 | 
			
		||||
    cd /opt/babybuddy
 | 
			
		||||
    mv /tmp/production.py.bak /opt/babybuddy/babybuddy/settings/production.py
 | 
			
		||||
    source .venv/bin/activate
 | 
			
		||||
    $STD uv pip install -r requirements.txt
 | 
			
		||||
    $STD python manage.py migrate
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ${APP} to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Fixing permissions"
 | 
			
		||||
@@ -66,9 +63,6 @@ function update_script() {
 | 
			
		||||
    systemctl start nginx
 | 
			
		||||
    msg_ok "Services Started"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning up"
 | 
			
		||||
    rm -f "$temp_file"
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,8 @@ function update_script() {
 | 
			
		||||
    msg_ok "Backup finished"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "bookstack" "BookStackApp/BookStack"
 | 
			
		||||
    PHP_MODULE="ldap,tidy,bz2,mysqli" PHP_FPM="YES" PHP_APACHE="YES" PHP_VERSION="8.3" setup_php
 | 
			
		||||
    setup_composer
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring backup"
 | 
			
		||||
    cp /opt/bookstack-backup/.env /opt/bookstack/.env
 | 
			
		||||
 
 | 
			
		||||
@@ -37,8 +37,8 @@ Pin: version ${RELEASE}
 | 
			
		||||
Pin-Priority: 1001
 | 
			
		||||
EOF
 | 
			
		||||
    apt-get update
 | 
			
		||||
    apt-get install -y nginx=1.26.3*
 | 
			
		||||
    apt-get install -y bunkerweb=${RELEASE}
 | 
			
		||||
    apt-mark unhold bunkerweb nginx
 | 
			
		||||
    apt-get install -y --allow-downgrades bunkerweb=${RELEASE}
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ${APP} to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,12 +23,13 @@ function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -d /opt/commafeed ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/Athou/commafeed/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
 | 
			
		||||
  if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.commafeed 2>/dev/null)" ]] || [[ ! -f ~/.commafeed ]]; then
 | 
			
		||||
    msg_info "Stopping ${APP}"
 | 
			
		||||
    systemctl stop commafeed
 | 
			
		||||
    msg_ok "Stopped ${APP}"
 | 
			
		||||
@@ -39,13 +40,15 @@ function update_script() {
 | 
			
		||||
      $STD apt-get install -y rsync
 | 
			
		||||
      msg_ok "Installed Dependencies"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if [ -d /opt/commafeed/data ] && [ "$(ls -A /opt/commafeed/data)" ]; then
 | 
			
		||||
      mv /opt/commafeed/data /opt/data.bak
 | 
			
		||||
    fi
 | 
			
		||||
    fetch_and_deploy_gh_release "commafeed" "Athou/commafeed" "prebuild" "latest" "/opt/commafeed" "commafeed-*-h2-jvm.zip"
 | 
			
		||||
    
 | 
			
		||||
    msg_info "Updating ${APP} to ${RELEASE}"
 | 
			
		||||
    curl -fsSL "https://github.com/Athou/commafeed/releases/download/${RELEASE}/commafeed-${RELEASE}-h2-jvm.zip" -o $(basename "https://github.com/Athou/commafeed/releases/download/${RELEASE}/commafeed-${RELEASE}-h2-jvm.zip")
 | 
			
		||||
    $STD unzip commafeed-"${RELEASE}"-h2-jvm.zip
 | 
			
		||||
    rsync -a --exclude 'data/' commafeed-"${RELEASE}"-h2/ /opt/commafeed/
 | 
			
		||||
    rm -rf commafeed-"${RELEASE}"-h2 commafeed-"${RELEASE}"-h2-jvm.zip
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    if [ -d /opt/commafeed/data.bak ] && [ "$(ls -A /opt/commafeed/data.bak)" ]; then
 | 
			
		||||
      mv /opt/commafeed/data.bak /opt/commafeed/data
 | 
			
		||||
    fi
 | 
			
		||||
    msg_ok "Updated ${APP} to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting ${APP}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								ct/docker.sh
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								ct/docker.sh
									
									
									
									
									
								
							@@ -20,18 +20,68 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
    if [[ ! -d /var ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    msg_info "Updating ${APP} LXC"
 | 
			
		||||
    $STD apt-get update
 | 
			
		||||
    $STD apt-get -y upgrade
 | 
			
		||||
    msg_ok "Updated ${APP} LXC"
 | 
			
		||||
    exit
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  get_latest_release() {
 | 
			
		||||
    curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating base system"
 | 
			
		||||
  $STD apt-get update
 | 
			
		||||
  $STD apt-get -y upgrade
 | 
			
		||||
  msg_ok "Base system updated"
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating Docker Engine"
 | 
			
		||||
  $STD apt-get install --only-upgrade -y docker-ce docker-ce-cli containerd.io
 | 
			
		||||
  msg_ok "Docker Engine updated"
 | 
			
		||||
 | 
			
		||||
  if [[ -f /usr/local/lib/docker/cli-plugins/docker-compose ]]; then
 | 
			
		||||
    COMPOSE_BIN="/usr/local/lib/docker/cli-plugins/docker-compose"
 | 
			
		||||
    COMPOSE_NEW_VERSION=$(get_latest_release "docker/compose")
 | 
			
		||||
    msg_info "Updating Docker Compose to $COMPOSE_NEW_VERSION"
 | 
			
		||||
    curl -fsSL "https://github.com/docker/compose/releases/download/${COMPOSE_NEW_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
 | 
			
		||||
      -o "$COMPOSE_BIN"
 | 
			
		||||
    chmod +x "$COMPOSE_BIN"
 | 
			
		||||
    msg_ok "Docker Compose updated"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if docker ps -a --format '{{.Names}}' | grep -q '^portainer$'; then
 | 
			
		||||
    msg_info "Updating Portainer"
 | 
			
		||||
    $STD docker pull portainer/portainer-ce:latest
 | 
			
		||||
    $STD docker stop portainer && docker rm portainer
 | 
			
		||||
    $STD docker volume create portainer_data >/dev/null 2>&1
 | 
			
		||||
    $STD docker run -d \
 | 
			
		||||
      -p 8000:8000 \
 | 
			
		||||
      -p 9443:9443 \
 | 
			
		||||
      --name=portainer \
 | 
			
		||||
      --restart=always \
 | 
			
		||||
      -v /var/run/docker.sock:/var/run/docker.sock \
 | 
			
		||||
      -v portainer_data:/data \
 | 
			
		||||
      portainer/portainer-ce:latest
 | 
			
		||||
    msg_ok "Updated Portainer"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then
 | 
			
		||||
    msg_info "Updating Portainer Agent"
 | 
			
		||||
    $STD docker pull portainer/agent:latest
 | 
			
		||||
    $STD docker stop portainer_agent && docker rm portainer_agent
 | 
			
		||||
    $STD docker run -d \
 | 
			
		||||
      -p 9001:9001 \
 | 
			
		||||
      --name=portainer_agent \
 | 
			
		||||
      --restart=always \
 | 
			
		||||
      -v /var/run/docker.sock:/var/run/docker.sock \
 | 
			
		||||
      -v /var/lib/docker/volumes:/var/lib/docker/volumes \
 | 
			
		||||
      portainer/agent
 | 
			
		||||
    msg_ok "Updated Portainer Agent"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Cleaning up"
 | 
			
		||||
  $STD apt-get -y autoremove
 | 
			
		||||
  $STD apt-get -y autoclean
 | 
			
		||||
  msg_ok "Cleanup complete"
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
@@ -39,4 +89,4 @@ build_container
 | 
			
		||||
description
 | 
			
		||||
 | 
			
		||||
msg_ok "Completed Successfully!\n"
 | 
			
		||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
 | 
			
		||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -27,48 +27,35 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  if ! command -v node >/dev/null || [[ "$(/usr/bin/env node -v | grep -oP '^v\K[0-9]+')" != "22" ]]; then
 | 
			
		||||
    msg_info "Installing Node.js 22"
 | 
			
		||||
    $STD apt-get purge -y nodejs
 | 
			
		||||
    rm -f /etc/apt/sources.list.d/nodesource.list
 | 
			
		||||
    rm -f /etc/apt/keyrings/nodesource.gpg
 | 
			
		||||
    mkdir -p /etc/apt/keyrings
 | 
			
		||||
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
 | 
			
		||||
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" >/etc/apt/sources.list.d/nodesource.list
 | 
			
		||||
    $STD apt-get update
 | 
			
		||||
    $STD apt-get install -y nodejs
 | 
			
		||||
    $STD npm install -g pnpm@10.4.0
 | 
			
		||||
    msg_ok "Node.js 22 installed"
 | 
			
		||||
    NODE_VERSION="22" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs
 | 
			
		||||
  fi
 | 
			
		||||
  export NODE_OPTIONS="--max_old_space_size=4096"
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/docmost/docmost/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.docmost 2>/dev/null)" ]] || [[ ! -f ~/.docmost ]]; then
 | 
			
		||||
    msg_info "Stopping ${APP}"
 | 
			
		||||
    systemctl stop docmost
 | 
			
		||||
    msg_ok "${APP} Stopped"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    msg_info "Backing up data"
 | 
			
		||||
    cp /opt/docmost/.env /opt/
 | 
			
		||||
    cp -r /opt/docmost/data /opt/
 | 
			
		||||
    rm -rf /opt/docmost
 | 
			
		||||
    temp_file=$(mktemp)
 | 
			
		||||
    curl -fsSL "https://github.com/docmost/docmost/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
    tar -xzf "$temp_file"
 | 
			
		||||
    mv docmost-${RELEASE} /opt/docmost
 | 
			
		||||
    msg_ok "Data backed up"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "docmost" "docmost/docmost"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt/docmost
 | 
			
		||||
    mv /opt/.env /opt/docmost/.env
 | 
			
		||||
    mv /opt/data /opt/docmost/data
 | 
			
		||||
    $STD pnpm install --force
 | 
			
		||||
    $STD pnpm build
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ${APP}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting ${APP}"
 | 
			
		||||
    systemctl start docmost
 | 
			
		||||
    msg_ok "Started ${APP}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    rm -f ${temp_file}
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								ct/emby.sh
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								ct/emby.sh
									
									
									
									
									
								
							@@ -23,26 +23,26 @@ function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -d /opt/emby-server ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  LATEST=$(curl -fsSL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
 | 
			
		||||
  msg_info "Stopping ${APP}"
 | 
			
		||||
  systemctl stop emby-server
 | 
			
		||||
  msg_ok "Stopped ${APP}"
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.emby 2>/dev/null)" ]] || [[ ! -f ~/.emby ]]; then
 | 
			
		||||
    msg_info "Stopping ${APP}"
 | 
			
		||||
    systemctl stop emby-server
 | 
			
		||||
    msg_ok "Stopped ${APP}"
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating ${APP}"
 | 
			
		||||
  $STD curl -fsSL "https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb" -o "emby-server-deb_${LATEST}_amd64.deb"
 | 
			
		||||
  $STD dpkg -i "emby-server-deb_${LATEST}_amd64.deb"
 | 
			
		||||
  rm "emby-server-deb_${LATEST}_amd64.deb"
 | 
			
		||||
  msg_ok "Updated ${APP}"
 | 
			
		||||
    fetch_and_deploy_gh_release "emby" "MediaBrowser/Emby.Releases" "binary"
 | 
			
		||||
 | 
			
		||||
  msg_info "Starting ${APP}"
 | 
			
		||||
  systemctl start emby-server
 | 
			
		||||
  msg_ok "Started ${APP}"
 | 
			
		||||
  msg_ok "Updated Successfully"
 | 
			
		||||
  exit
 | 
			
		||||
    msg_info "Starting ${APP}"
 | 
			
		||||
    systemctl start emby-server
 | 
			
		||||
    msg_ok "Started ${APP}"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								ct/emqx.sh
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								ct/emqx.sh
									
									
									
									
									
								
							@@ -20,18 +20,39 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
    if [[ ! -d /var ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    msg_info "Updating $APP LXC"
 | 
			
		||||
    $STD apt-get update
 | 
			
		||||
    $STD apt-get -y upgrade
 | 
			
		||||
    msg_ok "Updated $APP LXC"
 | 
			
		||||
    exit
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://www.emqx.com/en/downloads/enterprise | grep -oP '/en/downloads/enterprise/v\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n1)
 | 
			
		||||
  if [[ "$RELEASE" != "$(cat ~/.emqx 2>/dev/null)" ]] || [[ ! -f ~/.emqx ]]; then
 | 
			
		||||
    msg_info "Stopping EMQX"
 | 
			
		||||
    systemctl stop emqx
 | 
			
		||||
    msg_ok "Stopped EMQX"
 | 
			
		||||
 | 
			
		||||
    msg_info "Downloading EMQX v${RELEASE}"
 | 
			
		||||
    DEB_FILE="/tmp/emqx-enterprise-${RELEASE}-debian12-amd64.deb"
 | 
			
		||||
    curl -fsSL -o "$DEB_FILE" "https://www.emqx.com/en/downloads/enterprise/v${RELEASE}/emqx-enterprise-${RELEASE}-debian12-amd64.deb"
 | 
			
		||||
    msg_ok "Downloaded EMQX"
 | 
			
		||||
 | 
			
		||||
    msg_info "Installing EMQX"
 | 
			
		||||
    $STD apt-get install -y "$DEB_FILE"
 | 
			
		||||
    msg_ok "Installed EMQX v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting EMQX"
 | 
			
		||||
    systemctl start emqx
 | 
			
		||||
    echo "$RELEASE" >~/.emqx
 | 
			
		||||
    msg_ok "Started EMQX"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    rm -f "$DEB_FILE"
 | 
			
		||||
    msg_ok "Cleanup Completed"
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. EMQX is already at v${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
@@ -41,4 +62,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}:18083${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:18083${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
 | 
			
		||||
 | 
			
		||||
APP="ErsatzTV"
 | 
			
		||||
var_tags="${var_tags:-iptv}"
 | 
			
		||||
var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_cpu="${var_cpu:-2}"
 | 
			
		||||
var_ram="${var_ram:-1024}"
 | 
			
		||||
var_disk="${var_disk:-5}"
 | 
			
		||||
var_os="${var_os:-debian}"
 | 
			
		||||
@@ -27,31 +27,18 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1)
 | 
			
		||||
  if [[ ! -f /opt/${APP}_version.txt && $(echo "x.x.x" >/opt/${APP}_version.txt) || "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.ersatztv 2>/dev/null)" ]] || [[ ! -f ~/.ersatztv ]]; then
 | 
			
		||||
    msg_info "Stopping ErsatzTV"
 | 
			
		||||
    systemctl stop ersatzTV
 | 
			
		||||
    msg_ok "Stopped ErsatzTV"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ErsatzTV"
 | 
			
		||||
    cp -R /opt/ErsatzTV/ ErsatzTV-backup
 | 
			
		||||
    rm ErsatzTV-backup/ErsatzTV
 | 
			
		||||
    rm -rf /opt/ErsatzTV
 | 
			
		||||
    temp_file=$(mktemp)
 | 
			
		||||
    curl -fsSL "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz" -o "$temp_file"
 | 
			
		||||
    tar -xzf "$temp_file"
 | 
			
		||||
    mv ErsatzTV-${RELEASE}-linux-x64 /opt/ErsatzTV
 | 
			
		||||
    cp -R ErsatzTV-backup/* /opt/ErsatzTV/
 | 
			
		||||
    rm -rf ErsatzTV-backup
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ErsatzTV"
 | 
			
		||||
    FFMPEG_VERSION="latest" FFMPEG_TYPE="medium" setup_ffmpeg
 | 
			
		||||
    fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting ErsatzTV"
 | 
			
		||||
    systemctl start ersatzTV
 | 
			
		||||
    msg_ok "Started ErsatzTV"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    rm -f ${temp_file}
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
 
 | 
			
		||||
@@ -28,20 +28,16 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/excalidraw/excalidraw/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat /opt/excalidraw_version.txt)" ]] || [[ ! -f /opt/excalidraw_version.txt ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.excalidraw 2>/dev/null)" ]] || [[ ! -f ~/.excalidraw ]]; then
 | 
			
		||||
    msg_info "Stopping $APP"
 | 
			
		||||
    systemctl stop excalidraw
 | 
			
		||||
    msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating $APP to v${RELEASE}"
 | 
			
		||||
    cd /tmp
 | 
			
		||||
    temp_file=$(mktemp)
 | 
			
		||||
    curl -fsSL "https://github.com/excalidraw/excalidraw/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
    tar xzf $temp_file
 | 
			
		||||
    rm -rf /opt/excalidraw
 | 
			
		||||
    mv excalidraw-${RELEASE} /opt/excalidraw
 | 
			
		||||
    fetch_and_deploy_gh_release "excalidraw" "excalidraw/excalidraw"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating $APP to v${RELEASE}"
 | 
			
		||||
    cd /opt/excalidraw
 | 
			
		||||
    $STD yarn
 | 
			
		||||
    msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
@@ -50,11 +46,6 @@ function update_script() {
 | 
			
		||||
    systemctl start excalidraw
 | 
			
		||||
    msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    rm -rf $temp_file
 | 
			
		||||
    msg_ok "Cleanup Completed"
 | 
			
		||||
 | 
			
		||||
    echo "${RELEASE}" >/opt/excalidraw_version.txt
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
 
 | 
			
		||||
@@ -29,17 +29,20 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/firefly-iii/firefly-iii/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}')
 | 
			
		||||
  if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.firefly 2>/dev/null)" ]] || [[ ! -f ~/.firefly ]]; then
 | 
			
		||||
    msg_info "Stopping Apache2"
 | 
			
		||||
    systemctl stop apache2
 | 
			
		||||
    msg_ok "Stopped Apache2"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    msg_info "Backing up data"
 | 
			
		||||
    cp /opt/firefly/.env /opt/.env
 | 
			
		||||
    cp -r /opt/firefly/storage /opt/storage
 | 
			
		||||
    cd /opt
 | 
			
		||||
    curl -fsSL "https://github.com/firefly-iii/firefly-iii/releases/download/v${RELEASE}/FireflyIII-v${RELEASE}.tar.gz" -o $(basename "https://github.com/firefly-iii/firefly-iii/releases/download/v${RELEASE}/FireflyIII-v${RELEASE}.tar.gz")
 | 
			
		||||
    tar -xzf FireflyIII-v${RELEASE}.tar.gz -C /opt/firefly --exclude='storage'
 | 
			
		||||
    msg_ok "Backed up data"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "firefly" "firefly-iii/firefly-iii"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    rm -rf /opt/firefly/storage
 | 
			
		||||
    cp /opt/.env /opt/firefly/.env
 | 
			
		||||
    cp -r /opt/storage /opt/firefly/storage
 | 
			
		||||
    cd /opt/firefly
 | 
			
		||||
@@ -50,16 +53,12 @@ function update_script() {
 | 
			
		||||
    $STD php artisan view:clear
 | 
			
		||||
    $STD php artisan firefly-iii:upgrade-database
 | 
			
		||||
    $STD php artisan firefly-iii:laravel-passport-keys
 | 
			
		||||
    echo "${RELEASE}" >"/opt/${APP}_version.txt"
 | 
			
		||||
    msg_ok "Updated ${APP} to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Apache2"
 | 
			
		||||
    systemctl start apache2
 | 
			
		||||
    msg_ok "Started Apache2"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning up"
 | 
			
		||||
    rm -rf /opt/FireflyIII-v${RELEASE}.tar.gz
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}."
 | 
			
		||||
 
 | 
			
		||||
@@ -23,20 +23,23 @@ function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://github.com/FlareSolverr/FlareSolverr/releases/latest | grep "title>Release" | cut -d " " -f 4)
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
 | 
			
		||||
    msg_info "Updating $APP LXC"
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/FlareSolverr/FlareSolverr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.flaresolverr 2>/dev/null)" ]] || [[ ! -f ~/.flaresolverr ]]; then
 | 
			
		||||
    msg_info "Stopping service"
 | 
			
		||||
    systemctl stop flaresolverr
 | 
			
		||||
    curl -fsSL "https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz" -o $(basename "https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz")
 | 
			
		||||
    tar -xzf flaresolverr_linux_x64.tar.gz -C /opt
 | 
			
		||||
    rm flaresolverr_linux_x64.tar.gz
 | 
			
		||||
    msg_ok "Stopped service"
 | 
			
		||||
 | 
			
		||||
    rm -rf /opt/flaresolverr
 | 
			
		||||
    fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting service"
 | 
			
		||||
    systemctl start flaresolverr
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated $APP LXC"
 | 
			
		||||
    msg_ok "Started service"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
 
 | 
			
		||||
@@ -20,51 +20,43 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
    if [[ ! -d /opt/fluid-calendar ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    RELEASE=$(curl -fsSL https://api.github.com/repos/dotnetfactory/fluid-calendar/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
    if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
 | 
			
		||||
        msg_info "Stopping $APP"
 | 
			
		||||
        systemctl stop fluid-calendar.service
 | 
			
		||||
        msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
        msg_info "Updating $APP to v${RELEASE}"
 | 
			
		||||
        cp /opt/fluid-calendar/.env /opt/fluid.env
 | 
			
		||||
        rm -rf /opt/fluid-calendar
 | 
			
		||||
        tmp_file=$(mktemp)
 | 
			
		||||
        curl -fsSL "https://github.com/dotnetfactory/fluid-calendar/archive/refs/tags/v${RELEASE}.zip" -o "$tmp_file"
 | 
			
		||||
        $STD unzip $tmp_file
 | 
			
		||||
        mv ${APP}-${RELEASE}/ /opt/fluid-calendar
 | 
			
		||||
        mv /opt/fluid.env /opt/fluid-calendar/.env
 | 
			
		||||
        cd /opt/fluid-calendar
 | 
			
		||||
        export NEXT_TELEMETRY_DISABLED=1
 | 
			
		||||
        $STD npm install --legacy-peer-deps
 | 
			
		||||
        $STD npm run prisma:generate
 | 
			
		||||
        $STD npx prisma migrate deploy
 | 
			
		||||
        $STD npm run build:os
 | 
			
		||||
        msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting $APP"
 | 
			
		||||
        systemctl start fluid-calendar.service
 | 
			
		||||
        msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
        msg_info "Cleaning Up"
 | 
			
		||||
        rm -rf $tmp_file
 | 
			
		||||
        msg_ok "Cleanup Completed"
 | 
			
		||||
 | 
			
		||||
        echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
        msg_ok "Update Successful"
 | 
			
		||||
    else
 | 
			
		||||
        msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
    fi
 | 
			
		||||
  if [[ ! -d /opt/fluid-calendar ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/dotnetfactory/fluid-calendar/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.fluid-calendar 2>/dev/null)" ]] || [[ ! -f ~/.fluid-calendar ]]; then
 | 
			
		||||
    msg_info "Stopping $APP"
 | 
			
		||||
    systemctl stop fluid-calendar
 | 
			
		||||
    msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
    cp /opt/fluid-calendar/.env /opt/fluid.env
 | 
			
		||||
    rm -rf /opt/fluid-calendar
 | 
			
		||||
    fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating $APP to v${RELEASE}"
 | 
			
		||||
    mv /opt/fluid.env /opt/fluid-calendar/.env
 | 
			
		||||
    cd /opt/fluid-calendar
 | 
			
		||||
    export NEXT_TELEMETRY_DISABLED=1
 | 
			
		||||
    $STD npm install --legacy-peer-deps
 | 
			
		||||
    $STD npm run prisma:generate
 | 
			
		||||
    $STD npx prisma migrate deploy
 | 
			
		||||
    $STD npm run build:os
 | 
			
		||||
    msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting $APP"
 | 
			
		||||
    systemctl start fluid-calendar
 | 
			
		||||
    msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								ct/gatus.sh
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								ct/gatus.sh
									
									
									
									
									
								
							@@ -29,35 +29,29 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -s https://api.github.com/repos/TwiN/gatus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.gatus 2>/dev/null)" ]] || [[ ! -f ~/.gatus ]]; then
 | 
			
		||||
    msg_info "Updating $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Stopping $APP"
 | 
			
		||||
    systemctl stop gatus
 | 
			
		||||
    msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating $APP to v${RELEASE}"
 | 
			
		||||
    mv /opt/gatus/config/config.yaml /opt
 | 
			
		||||
    rm -rf /opt/gatus/*
 | 
			
		||||
    temp_file=$(mktemp)
 | 
			
		||||
    curl -fsSL "https://github.com/TwiN/gatus/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
    tar zxf "$temp_file" --strip-components=1 -C /opt/gatus
 | 
			
		||||
    rm -rf /opt/gatus
 | 
			
		||||
    fetch_and_deploy_gh_release "gatus" "TwiN/gatus"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating $APP to v${RELEASE}"
 | 
			
		||||
    cd /opt/gatus
 | 
			
		||||
    $STD go mod tidy
 | 
			
		||||
    CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gatus .
 | 
			
		||||
    setcap CAP_NET_RAW+ep gatus
 | 
			
		||||
    mv /opt/config.yaml config
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting $APP"
 | 
			
		||||
    systemctl start gatus
 | 
			
		||||
    msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    rm -f "$temp_file"
 | 
			
		||||
    msg_ok "Cleanup Completed"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								ct/ghost.sh
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								ct/ghost.sh
									
									
									
									
									
								
							@@ -20,26 +20,31 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
    msg_info "Updating ${APP} LXC"
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
    if command -v ghost &>/dev/null; then
 | 
			
		||||
        current_version=$(ghost version | grep 'Ghost-CLI version' | awk '{print $3}')
 | 
			
		||||
        latest_version=$(npm show ghost-cli version)
 | 
			
		||||
        if [ "$current_version" != "$latest_version" ]; then
 | 
			
		||||
            msg_info "Updating ${APP} from version v${current_version} to v${latest_version}"
 | 
			
		||||
            $STD npm install -g ghost-cli@latest
 | 
			
		||||
            msg_ok "Updated Successfully"
 | 
			
		||||
        else
 | 
			
		||||
            msg_ok "${APP} is already at v${current_version}"
 | 
			
		||||
        fi
 | 
			
		||||
  if ! dpkg-query -W -f='${Status}' mariadb-server 2>/dev/null | grep -q "install ok installed"; then
 | 
			
		||||
    setup_mysql
 | 
			
		||||
  fi
 | 
			
		||||
  NODE_VERSION="22" setup_nodejs
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating ${APP} LXC"
 | 
			
		||||
  if command -v ghost &>/dev/null; then
 | 
			
		||||
    current_version=$(ghost version | grep 'Ghost-CLI version' | awk '{print $3}')
 | 
			
		||||
    latest_version=$(npm show ghost-cli version)
 | 
			
		||||
    if [ "$current_version" != "$latest_version" ]; then
 | 
			
		||||
      msg_info "Updating ${APP} from version v${current_version} to v${latest_version}"
 | 
			
		||||
      $STD npm install -g ghost-cli@latest
 | 
			
		||||
      msg_ok "Updated Successfully"
 | 
			
		||||
    else
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
      msg_ok "${APP} is already at v${current_version}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
@@ -49,4 +54,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}:2368${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:2368${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: CrazyWolf13
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/arunavo4/gitea-mirror
 | 
			
		||||
# Source: https://github.com/RayLabsHQ/gitea-mirror
 | 
			
		||||
 | 
			
		||||
APP="gitea-mirror"
 | 
			
		||||
var_tags="${var_tags:-mirror;gitea}"
 | 
			
		||||
@@ -28,7 +28,7 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/arunavo4/gitea-mirror/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/RayLabsHQ/gitea-mirror/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.${APP} 2>/dev/null || cat /opt/${APP}_version.txt 2>/dev/null)" ]]; then
 | 
			
		||||
 | 
			
		||||
    msg_info "Stopping Services"
 | 
			
		||||
@@ -48,7 +48,7 @@ function update_script() {
 | 
			
		||||
    msg_ok "Installed Bun"
 | 
			
		||||
 | 
			
		||||
    rm -rf /opt/gitea-mirror
 | 
			
		||||
    fetch_and_deploy_gh_release "gitea-mirror" "arunavo4/gitea-mirror"
 | 
			
		||||
    fetch_and_deploy_gh_release "gitea-mirror" "RayLabsHQ/gitea-mirror"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating and rebuilding ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt/gitea-mirror
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								ct/gitea.sh
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								ct/gitea.sh
									
									
									
									
									
								
							@@ -20,24 +20,33 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
   header_info
 | 
			
		||||
   check_container_storage
 | 
			
		||||
   check_container_resources
 | 
			
		||||
   if [[ ! -f /usr/local/bin/gitea ]]; then
 | 
			
		||||
      msg_error "No ${APP} Installation Found!"
 | 
			
		||||
      exit
 | 
			
		||||
   fi
 | 
			
		||||
   RELEASE=$(curl -fsSL https://github.com/go-gitea/gitea/releases/latest | grep "title>Release" | cut -d " " -f 4 | sed 's/^v//')
 | 
			
		||||
   msg_info "Updating $APP to ${RELEASE}"
 | 
			
		||||
   FILENAME="gitea-$RELEASE-linux-amd64"
 | 
			
		||||
   curl -fsSL "https://github.com/go-gitea/gitea/releases/download/v$RELEASE/gitea-$RELEASE-linux-amd64" -o $FILENAME
 | 
			
		||||
   systemctl stop gitea
 | 
			
		||||
   rm -rf /usr/local/bin/gitea
 | 
			
		||||
   mv $FILENAME /usr/local/bin/gitea
 | 
			
		||||
   chmod +x /usr/local/bin/gitea
 | 
			
		||||
   systemctl start gitea
 | 
			
		||||
   msg_ok "Updated $APP Successfully"
 | 
			
		||||
   exit
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -f /usr/local/bin/gitea ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://github.com/go-gitea/gitea/releases/latest | grep "title>Release" | cut -d " " -f 4 | sed 's/^v//')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.gitea 2>/dev/null)" ]] || [[ ! -f ~/.gitea ]]; then
 | 
			
		||||
    msg_info "Stopping service"
 | 
			
		||||
    systemctl stop gitea
 | 
			
		||||
    msg_ok "Service stopped"
 | 
			
		||||
 | 
			
		||||
    rm -rf /usr/local/bin/gitea
 | 
			
		||||
    fetch_and_deploy_gh_release "gitea" "go-gitea/gitea" "singlefile" "latest" "/usr/local/bin" "gitea-*-linux-amd64"
 | 
			
		||||
    chmod +x /usr/local/bin/gitea
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting service"
 | 
			
		||||
    systemctl start gitea
 | 
			
		||||
    msg_ok "Started service"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								ct/glance.sh
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								ct/glance.sh
									
									
									
									
									
								
							@@ -28,28 +28,19 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/glanceapp/glance/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.glance 2>/dev/null)" ]] || [[ ! -f ~/.glance ]]; then
 | 
			
		||||
    msg_info "Stopping Service"
 | 
			
		||||
    systemctl stop glance
 | 
			
		||||
    msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt
 | 
			
		||||
    curl -fsSL "https://github.com/glanceapp/glance/releases/download/v${RELEASE}/glance-linux-amd64.tar.gz" -o $(basename "https://github.com/glanceapp/glance/releases/download/v${RELEASE}/glance-linux-amd64.tar.gz")
 | 
			
		||||
    rm -rf /opt/glance/glance
 | 
			
		||||
    tar -xzf glance-linux-amd64.tar.gz -C /opt/glance
 | 
			
		||||
    echo "${RELEASE}" >"/opt/${APP}_version.txt"
 | 
			
		||||
    msg_ok "Updated ${APP} to v${RELEASE}"
 | 
			
		||||
    rm -f /opt/glance/glance
 | 
			
		||||
    fetch_and_deploy_gh_release "glance" "glanceapp/glance" "prebuild" "latest" "/opt/glance" "glance-linux-amd64.tar.gz"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Service"
 | 
			
		||||
    systemctl start glance
 | 
			
		||||
    msg_ok "Started Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning up"
 | 
			
		||||
    rm -rf /opt/glance-linux-amd64.tar.gz
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}."
 | 
			
		||||
 
 | 
			
		||||
@@ -20,48 +20,61 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
    if [[ ! -d "/opt/habitica" ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    RELEASE=$(curl -fsSL https://api.github.com/repos/HabitRPG/habitica/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
    if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
 | 
			
		||||
        msg_info "Stopping $APP"
 | 
			
		||||
        systemctl stop habitica-mongodb
 | 
			
		||||
        systemctl stop habitica
 | 
			
		||||
        systemctl stop habitica-client
 | 
			
		||||
        msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
        msg_info "Updating $APP to ${RELEASE}"
 | 
			
		||||
        temp_file=$(mktemp)
 | 
			
		||||
curl -fsSL "https://github.com/HabitRPG/habitica/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
        tar zxf $temp_file
 | 
			
		||||
        cp -rf habitica-${RELEASE}/* /opt/habitica
 | 
			
		||||
        cd /opt/habitica
 | 
			
		||||
        $STD npm i
 | 
			
		||||
        echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
        msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting $APP"
 | 
			
		||||
        systemctl start habitica-mongodb
 | 
			
		||||
        systemctl start habitica
 | 
			
		||||
        systemctl start habitica-client
 | 
			
		||||
        msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
        msg_info "Cleaning Up"
 | 
			
		||||
        rm -f $temp_file
 | 
			
		||||
        rm -rf ~/habitica-${RELEASE}
 | 
			
		||||
        msg_ok "Cleanup Completed"
 | 
			
		||||
 | 
			
		||||
        msg_ok "Update Successful"
 | 
			
		||||
    else
 | 
			
		||||
        msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
    fi
 | 
			
		||||
  if [[ ! -d "/opt/habitica" ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  NODE_VERSION="20" NODE_MODULE="gulp-cli,mocha" setup_nodejs
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/HabitRPG/habitica/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.habitica 2>/dev/null)" ]] || [[ ! -f ~/.habitica ]]; then
 | 
			
		||||
 | 
			
		||||
    msg_info "Stopping $APP"
 | 
			
		||||
    systemctl stop habitica-mongodb
 | 
			
		||||
    systemctl stop habitica
 | 
			
		||||
    systemctl stop habitica-client
 | 
			
		||||
    msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Save configuration"
 | 
			
		||||
    if [[ -f /opt/habitica/config.json ]]; then
 | 
			
		||||
      cp /opt/habitica/config.json ~/config.json
 | 
			
		||||
      msg_ok "Saved configuration"
 | 
			
		||||
    else
 | 
			
		||||
      msg_warn "No configuration file found, skipping save"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "habitica" "HabitRPG/habitica" "tarball" "latest" "/opt/habitica"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating $APP to ${RELEASE}"
 | 
			
		||||
    cd /opt/habitica
 | 
			
		||||
    $STD npm i
 | 
			
		||||
    $STD npm run postinstall
 | 
			
		||||
    $STD npm run client:build
 | 
			
		||||
    $STD gulp build:prod
 | 
			
		||||
    msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring configuration"
 | 
			
		||||
    if [[ -f ~/config.json ]]; then
 | 
			
		||||
      cp ~/config.json /opt/habitica/config.json
 | 
			
		||||
      msg_ok "Restored configuration"
 | 
			
		||||
    else
 | 
			
		||||
      msg_warn "No configuration file found to restore"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting $APP"
 | 
			
		||||
    systemctl start habitica-mongodb
 | 
			
		||||
    systemctl start habitica
 | 
			
		||||
    systemctl start habitica-client
 | 
			
		||||
    msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
@@ -71,4 +84,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${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										278
									
								
								ct/immich.sh
									
									
									
									
									
								
							
							
						
						
									
										278
									
								
								ct/immich.sh
									
									
									
									
									
								
							@@ -51,134 +51,12 @@ function update_script() {
 | 
			
		||||
  fi
 | 
			
		||||
  if [[ -f ~/.immich_library_revisions ]]; then
 | 
			
		||||
    libraries=("libjxl" "libheif" "libraw" "imagemagick" "libvips")
 | 
			
		||||
    readarray -d '' NEW_REVISIONS < <(for library in "${libraries[@]}"; do
 | 
			
		||||
      echo "$library: $(curl -fsSL https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/sources/"$library".json | jq -cr '.revision' -)"
 | 
			
		||||
    done)
 | 
			
		||||
    UPDATED_REVISIONS="$(comm -13 <(sort ~/.immich_library_revisions) <(echo -n "${NEW_REVISIONS[@]}" | sort))"
 | 
			
		||||
    if [[ "$UPDATED_REVISIONS" ]]; then
 | 
			
		||||
      readarray -t NAMES < <(echo "$UPDATED_REVISIONS" | awk -F ':' '{print $1}')
 | 
			
		||||
      rm -rf "$SOURCE_DIR"
 | 
			
		||||
      mkdir -p "$SOURCE_DIR"
 | 
			
		||||
      cd "$BASE_DIR"
 | 
			
		||||
      $STD git pull
 | 
			
		||||
      cd "$STAGING_DIR"
 | 
			
		||||
      for name in "${NAMES[@]}"; do
 | 
			
		||||
        if [[ "$name" == "libjxl" ]]; then
 | 
			
		||||
          msg_info "Recompiling libjxl"
 | 
			
		||||
          SOURCE=${SOURCE_DIR}/libjxl
 | 
			
		||||
          JPEGLI_LIBJPEG_LIBRARY_SOVERSION="62"
 | 
			
		||||
          JPEGLI_LIBJPEG_LIBRARY_VERSION="62.3.0"
 | 
			
		||||
          : "${LIBJXL_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libjxl.json)}"
 | 
			
		||||
          $STD git clone https://github.com/libjxl/libjxl.git "$SOURCE"
 | 
			
		||||
          cd "$SOURCE"
 | 
			
		||||
          $STD git reset --hard "$LIBJXL_REVISION"
 | 
			
		||||
          $STD git submodule update --init --recursive --depth 1 --recommend-shallow
 | 
			
		||||
          $STD git apply "$BASE_DIR"/server/sources/libjxl-patches/jpegli-empty-dht-marker.patch
 | 
			
		||||
          $STD git apply "$BASE_DIR"/server/sources/libjxl-patches/jpegli-icc-warning.patch
 | 
			
		||||
          mkdir build
 | 
			
		||||
          cd build
 | 
			
		||||
          $STD cmake \
 | 
			
		||||
            -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
            -DBUILD_TESTING=OFF \
 | 
			
		||||
            -DJPEGXL_ENABLE_DOXYGEN=OFF \
 | 
			
		||||
            -DJPEGXL_ENABLE_MANPAGES=OFF \
 | 
			
		||||
            -DJPEGXL_ENABLE_PLUGIN_GIMP210=OFF \
 | 
			
		||||
            -DJPEGXL_ENABLE_BENCHMARK=OFF \
 | 
			
		||||
            -DJPEGXL_ENABLE_EXAMPLES=OFF \
 | 
			
		||||
            -DJPEGXL_FORCE_SYSTEM_BROTLI=ON \
 | 
			
		||||
            -DJPEGXL_FORCE_SYSTEM_HWY=ON \
 | 
			
		||||
            -DJPEGXL_ENABLE_JPEGLI=ON \
 | 
			
		||||
            -DJPEGXL_ENABLE_JPEGLI_LIBJPEG=ON \
 | 
			
		||||
            -DJPEGXL_INSTALL_JPEGLI_LIBJPEG=ON \
 | 
			
		||||
            -DJPEGXL_ENABLE_PLUGINS=ON \
 | 
			
		||||
            -DJPEGLI_LIBJPEG_LIBRARY_SOVERSION="$JPEGLI_LIBJPEG_LIBRARY_SOVERSION" \
 | 
			
		||||
            -DJPEGLI_LIBJPEG_LIBRARY_VERSION="$JPEGLI_LIBJPEG_LIBRARY_VERSION" \
 | 
			
		||||
            -DLIBJPEG_TURBO_VERSION_NUMBER=2001005 \
 | 
			
		||||
            ..
 | 
			
		||||
          $STD cmake --build . -- -j"$(nproc)"
 | 
			
		||||
          $STD cmake --install .
 | 
			
		||||
          ldconfig /usr/local/lib
 | 
			
		||||
          $STD make clean
 | 
			
		||||
          cd "$STAGING_DIR"
 | 
			
		||||
          rm -rf "$SOURCE"/{build,third_party}
 | 
			
		||||
          msg_ok "Recompiled libjxl"
 | 
			
		||||
        fi
 | 
			
		||||
        if [[ "$name" == "libheif" ]]; then
 | 
			
		||||
          msg_info "Recompiling libheif"
 | 
			
		||||
          SOURCE=${SOURCE_DIR}/libheif
 | 
			
		||||
          : "${LIBHEIF_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libheif.json)}"
 | 
			
		||||
          $STD git clone https://github.com/strukturag/libheif.git "$SOURCE"
 | 
			
		||||
          cd "$SOURCE"
 | 
			
		||||
          $STD git reset --hard "$LIBHEIF_REVISION"
 | 
			
		||||
          mkdir build
 | 
			
		||||
          cd build
 | 
			
		||||
          $STD cmake --preset=release-noplugins \
 | 
			
		||||
            -DWITH_DAV1D=ON \
 | 
			
		||||
            -DENABLE_PARALLEL_TILE_DECODING=ON \
 | 
			
		||||
            -DWITH_LIBSHARPYUV=ON \
 | 
			
		||||
            -DWITH_LIBDE265=ON \
 | 
			
		||||
            -DWITH_AOM_DECODER=OFF \
 | 
			
		||||
            -DWITH_AOM_ENCODER=OFF \
 | 
			
		||||
            -DWITH_X265=OFF \
 | 
			
		||||
            -DWITH_EXAMPLES=OFF \
 | 
			
		||||
            ..
 | 
			
		||||
          $STD make install -j "$(nproc)"
 | 
			
		||||
          ldconfig /usr/local/lib
 | 
			
		||||
          $STD make clean
 | 
			
		||||
          cd "$STAGING_DIR"
 | 
			
		||||
          rm -rf "$SOURCE"/build
 | 
			
		||||
          msg_ok "Recompiled libheif"
 | 
			
		||||
        fi
 | 
			
		||||
        if [[ "$name" == "libraw" ]]; then
 | 
			
		||||
          msg_info "Recompiling libraw"
 | 
			
		||||
          SOURCE=${SOURCE_DIR}/libraw
 | 
			
		||||
          : "${LIBRAW_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libraw.json)}"
 | 
			
		||||
          $STD git clone https://github.com/libraw/libraw.git "$SOURCE"
 | 
			
		||||
          cd "$SOURCE"
 | 
			
		||||
          $STD git reset --hard "$LIBRAW_REVISION"
 | 
			
		||||
          $STD autoreconf --install
 | 
			
		||||
          $STD ./configure
 | 
			
		||||
          $STD make -j"$(nproc)"
 | 
			
		||||
          $STD make install
 | 
			
		||||
          ldconfig /usr/local/lib
 | 
			
		||||
          $STD make clean
 | 
			
		||||
          cd "$STAGING_DIR"
 | 
			
		||||
          msg_ok "Recompiled libraw"
 | 
			
		||||
        fi
 | 
			
		||||
        if [[ "$name" == "imagemagick" ]]; then
 | 
			
		||||
          msg_info "Recompiling ImageMagick"
 | 
			
		||||
          SOURCE=$SOURCE_DIR/imagemagick
 | 
			
		||||
          : "${IMAGEMAGICK_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/imagemagick.json)}"
 | 
			
		||||
          $STD git clone https://github.com/ImageMagick/ImageMagick.git "$SOURCE"
 | 
			
		||||
          cd "$SOURCE"
 | 
			
		||||
          $STD git reset --hard "$IMAGEMAGICK_REVISION"
 | 
			
		||||
          $STD ./configure --with-modules
 | 
			
		||||
          $STD make -j"$(nproc)"
 | 
			
		||||
          $STD make install
 | 
			
		||||
          ldconfig /usr/local/lib
 | 
			
		||||
          $STD make clean
 | 
			
		||||
          cd "$STAGING_DIR"
 | 
			
		||||
          msg_ok "Recompiled ImageMagick"
 | 
			
		||||
        fi
 | 
			
		||||
        if [[ "$name" == "libvips" ]]; then
 | 
			
		||||
          msg_info "Recompiling libvips"
 | 
			
		||||
          SOURCE=$SOURCE_DIR/libvips
 | 
			
		||||
          : "${LIBVIPS_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libvips.json)}"
 | 
			
		||||
          $STD git clone https://github.com/libvips/libvips.git "$SOURCE"
 | 
			
		||||
          cd "$SOURCE"
 | 
			
		||||
          $STD git reset --hard "$LIBVIPS_REVISION"
 | 
			
		||||
          $STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
 | 
			
		||||
          cd build
 | 
			
		||||
          $STD ninja install
 | 
			
		||||
          ldconfig /usr/local/lib
 | 
			
		||||
          cd "$STAGING_DIR"
 | 
			
		||||
          rm -rf "$SOURCE"/build
 | 
			
		||||
          msg_ok "Recompiled libvips"
 | 
			
		||||
        fi
 | 
			
		||||
      done
 | 
			
		||||
      echo -n "${NEW_REVISIONS[@]}" >~/.immich_library_revisions
 | 
			
		||||
      msg_ok "Image-processing libraries compiled"
 | 
			
		||||
    fi
 | 
			
		||||
    cd "$BASE_DIR"
 | 
			
		||||
    $STD git pull
 | 
			
		||||
    for library in "${libraries[@]}"; do
 | 
			
		||||
      compile_"$library"
 | 
			
		||||
    done
 | 
			
		||||
    msg_ok "Image-processing libraries updated"
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/immich-app/immich/releases?per_page=1 | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ -f ~/.immich && "$RELEASE" == "$(cat ~/.immich)" ]]; then
 | 
			
		||||
@@ -245,6 +123,10 @@ function update_script() {
 | 
			
		||||
  cp -a server/{node_modules,dist,bin,resources,package.json,package-lock.json,start*.sh} "$APP_DIR"/
 | 
			
		||||
  cp -a web/build "$APP_DIR"/www
 | 
			
		||||
  cp LICENSE "$APP_DIR"
 | 
			
		||||
  cd "$APP_DIR"
 | 
			
		||||
  export SHARP_FORCE_GLOBAL_LIBVIPS=true
 | 
			
		||||
  $STD npm install sharp
 | 
			
		||||
  rm -rf "$APP_DIR"/node_modules/@img/sharp-{libvips*,linuxmusl-x64}
 | 
			
		||||
  msg_ok "Updated ${APP} web and microservices"
 | 
			
		||||
 | 
			
		||||
  cd "$SRC_DIR"/machine-learning
 | 
			
		||||
@@ -276,8 +158,6 @@ function update_script() {
 | 
			
		||||
  ln -s "$GEO_DIR" "$APP_DIR"
 | 
			
		||||
 | 
			
		||||
  msg_info "Updating Immich CLI"
 | 
			
		||||
  $STD npm install --build-from-source sharp
 | 
			
		||||
  rm -rf "$APP_DIR"/node_modules/@img/sharp-{libvips*,linuxmusl-x64}
 | 
			
		||||
  $STD npm i -g @immich/cli
 | 
			
		||||
  msg_ok "Updated Immich CLI"
 | 
			
		||||
 | 
			
		||||
@@ -293,6 +173,144 @@ function update_script() {
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function compile_libjxl() {
 | 
			
		||||
  SOURCE=${SOURCE_DIR}/libjxl
 | 
			
		||||
  JPEGLI_LIBJPEG_LIBRARY_SOVERSION="62"
 | 
			
		||||
  JPEGLI_LIBJPEG_LIBRARY_VERSION="62.3.0"
 | 
			
		||||
  : "${LIBJXL_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libjxl.json)}"
 | 
			
		||||
  if [[ "${update:-}" ]] || [[ "$LIBJXL_REVISION" != "$(grep 'libjxl' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
 | 
			
		||||
    msg_info "Recompiling libjxl"
 | 
			
		||||
    if [[ -d "$SOURCE" ]]; then rm -rf "$SOURCE"; fi
 | 
			
		||||
    $STD git clone https://github.com/libjxl/libjxl.git "$SOURCE"
 | 
			
		||||
    cd "$SOURCE"
 | 
			
		||||
    $STD git reset --hard "$LIBJXL_REVISION"
 | 
			
		||||
    $STD git submodule update --init --recursive --depth 1 --recommend-shallow
 | 
			
		||||
    $STD git apply "$BASE_DIR"/server/sources/libjxl-patches/jpegli-empty-dht-marker.patch
 | 
			
		||||
    $STD git apply "$BASE_DIR"/server/sources/libjxl-patches/jpegli-icc-warning.patch
 | 
			
		||||
    mkdir build
 | 
			
		||||
    cd build
 | 
			
		||||
    $STD cmake \
 | 
			
		||||
      -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
      -DBUILD_TESTING=OFF \
 | 
			
		||||
      -DJPEGXL_ENABLE_DOXYGEN=OFF \
 | 
			
		||||
      -DJPEGXL_ENABLE_MANPAGES=OFF \
 | 
			
		||||
      -DJPEGXL_ENABLE_PLUGIN_GIMP210=OFF \
 | 
			
		||||
      -DJPEGXL_ENABLE_BENCHMARK=OFF \
 | 
			
		||||
      -DJPEGXL_ENABLE_EXAMPLES=OFF \
 | 
			
		||||
      -DJPEGXL_FORCE_SYSTEM_BROTLI=ON \
 | 
			
		||||
      -DJPEGXL_FORCE_SYSTEM_HWY=ON \
 | 
			
		||||
      -DJPEGXL_ENABLE_JPEGLI=ON \
 | 
			
		||||
      -DJPEGXL_ENABLE_JPEGLI_LIBJPEG=ON \
 | 
			
		||||
      -DJPEGXL_INSTALL_JPEGLI_LIBJPEG=ON \
 | 
			
		||||
      -DJPEGXL_ENABLE_PLUGINS=ON \
 | 
			
		||||
      -DJPEGLI_LIBJPEG_LIBRARY_SOVERSION="$JPEGLI_LIBJPEG_LIBRARY_SOVERSION" \
 | 
			
		||||
      -DJPEGLI_LIBJPEG_LIBRARY_VERSION="$JPEGLI_LIBJPEG_LIBRARY_VERSION" \
 | 
			
		||||
      -DLIBJPEG_TURBO_VERSION_NUMBER=2001005 \
 | 
			
		||||
      ..
 | 
			
		||||
    $STD cmake --build . -- -j"$(nproc)"
 | 
			
		||||
    $STD cmake --install .
 | 
			
		||||
    ldconfig /usr/local/lib
 | 
			
		||||
    $STD make clean
 | 
			
		||||
    cd "$STAGING_DIR"
 | 
			
		||||
    rm -rf "$SOURCE"/{build,third_party}
 | 
			
		||||
    msg_ok "Recompiled libjxl"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function compile_libheif() {
 | 
			
		||||
  SOURCE=${SOURCE_DIR}/libheif
 | 
			
		||||
  if ! dpkg -l | grep -q libaom; then
 | 
			
		||||
    $STD apt-get install -y libaom-dev
 | 
			
		||||
    local update="required"
 | 
			
		||||
  fi
 | 
			
		||||
  : "${LIBHEIF_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libheif.json)}"
 | 
			
		||||
  if [[ "${update:-}" ]] || [[ "$LIBHEIF_REVISION" != "$(grep 'libheif' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
 | 
			
		||||
    msg_info "Recompiling libheif"
 | 
			
		||||
    if [[ -d "$SOURCE" ]]; then rm -rf "$SOURCE"; fi
 | 
			
		||||
    $STD git clone https://github.com/strukturag/libheif.git "$SOURCE"
 | 
			
		||||
    cd "$SOURCE"
 | 
			
		||||
    $STD git reset --hard "$LIBHEIF_REVISION"
 | 
			
		||||
    mkdir build
 | 
			
		||||
    cd build
 | 
			
		||||
    $STD cmake --preset=release-noplugins \
 | 
			
		||||
      -DWITH_DAV1D=ON \
 | 
			
		||||
      -DENABLE_PARALLEL_TILE_DECODING=ON \
 | 
			
		||||
      -DWITH_LIBSHARPYUV=ON \
 | 
			
		||||
      -DWITH_LIBDE265=ON \
 | 
			
		||||
      -DWITH_AOM_DECODER=OFF \
 | 
			
		||||
      -DWITH_AOM_ENCODER=ON \
 | 
			
		||||
      -DWITH_X265=OFF \
 | 
			
		||||
      -DWITH_EXAMPLES=OFF \
 | 
			
		||||
      ..
 | 
			
		||||
    $STD make install -j "$(nproc)"
 | 
			
		||||
    ldconfig /usr/local/lib
 | 
			
		||||
    $STD make clean
 | 
			
		||||
    cd "$STAGING_DIR"
 | 
			
		||||
    rm -rf "$SOURCE"/build
 | 
			
		||||
    msg_ok "Recompiled libheif"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function compile_libraw() {
 | 
			
		||||
  SOURCE=${SOURCE_DIR}/libraw
 | 
			
		||||
  local update
 | 
			
		||||
  : "${LIBRAW_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libraw.json)}"
 | 
			
		||||
  if [[ "${update:-}" ]] || [[ "$LIBRAW_REVISION" != "$(grep 'libraw' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
 | 
			
		||||
    msg_info "Recompiling libraw"
 | 
			
		||||
    if [[ -d "$SOURCE" ]]; then rm -rf "$SOURCE"; fi
 | 
			
		||||
    $STD git clone https://github.com/libraw/libraw.git "$SOURCE"
 | 
			
		||||
    cd "$SOURCE"
 | 
			
		||||
    $STD git reset --hard "$LIBRAW_REVISION"
 | 
			
		||||
    $STD autoreconf --install
 | 
			
		||||
    $STD ./configure
 | 
			
		||||
    $STD make -j"$(nproc)"
 | 
			
		||||
    $STD make install
 | 
			
		||||
    ldconfig /usr/local/lib
 | 
			
		||||
    $STD make clean
 | 
			
		||||
    cd "$STAGING_DIR"
 | 
			
		||||
    msg_ok "Recompiled libraw"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function compile_imagemagick() {
 | 
			
		||||
  SOURCE=$SOURCE_DIR/imagemagick
 | 
			
		||||
  : "${IMAGEMAGICK_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/imagemagick.json)}"
 | 
			
		||||
  if [[ "${update:-}" ]] || [[ "$IMAGEMAGICK_REVISION" != "$(grep 'imagemagick' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
 | 
			
		||||
    msg_info "Recompiling ImageMagick"
 | 
			
		||||
    if [[ -d "$SOURCE" ]]; then rm -rf "$SOURCE"; fi
 | 
			
		||||
    $STD git clone https://github.com/ImageMagick/ImageMagick.git "$SOURCE"
 | 
			
		||||
    cd "$SOURCE"
 | 
			
		||||
    $STD git reset --hard "$IMAGEMAGICK_REVISION"
 | 
			
		||||
    $STD ./configure --with-modules
 | 
			
		||||
    $STD make -j"$(nproc)"
 | 
			
		||||
    $STD make install
 | 
			
		||||
    ldconfig /usr/local/lib
 | 
			
		||||
    $STD make clean
 | 
			
		||||
    cd "$STAGING_DIR"
 | 
			
		||||
    msg_ok "Recompiled ImageMagick"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function compile_libvips() {
 | 
			
		||||
  SOURCE=$SOURCE_DIR/libvips
 | 
			
		||||
  # : "${LIBVIPS_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libvips.json)}"
 | 
			
		||||
  : "${LIBVIPS_REVISION:=8fa37a64547e392d3808eed8d72adab7e02b3d00}"
 | 
			
		||||
  if [[ "${update:-}" ]] || [[ "$LIBVIPS_REVISION" != "$(grep 'libvips' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
 | 
			
		||||
    msg_info "Recompiling libvips"
 | 
			
		||||
    if [[ -d "$SOURCE" ]]; then rm -rf "$SOURCE"; fi
 | 
			
		||||
    $STD git clone https://github.com/libvips/libvips.git "$SOURCE"
 | 
			
		||||
    cd "$SOURCE"
 | 
			
		||||
    $STD git reset --hard "$LIBVIPS_REVISION"
 | 
			
		||||
    $STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
 | 
			
		||||
    cd build
 | 
			
		||||
    $STD ninja install
 | 
			
		||||
    ldconfig /usr/local/lib
 | 
			
		||||
    cd "$STAGING_DIR"
 | 
			
		||||
    rm -rf "$SOURCE"/build
 | 
			
		||||
    msg_ok "Recompiled libvips"
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
build_container
 | 
			
		||||
description
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,7 @@ function update_script() {
 | 
			
		||||
    msg_info "Updating Ollama to ${RELEASE}"
 | 
			
		||||
    rm -rf /usr/local/lib/ollama
 | 
			
		||||
    rm -rf /usr/local/bin/ollama
 | 
			
		||||
    mkdir -p /usr/local/lib/ollama
 | 
			
		||||
    tar -xzf "${TMP_TAR}" -C /usr/local/lib/ollama
 | 
			
		||||
    ln -sf /usr/local/lib/ollama/bin/ollama /usr/local/bin/ollama
 | 
			
		||||
    echo "${RELEASE}" >/opt/Ollama_version.txt
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,7 @@ function update_script() {
 | 
			
		||||
  $STD dpkg -i "$OMADA_PKG"
 | 
			
		||||
  rm -f "$OMADA_PKG"
 | 
			
		||||
  msg_ok "Updated Omada Controller"
 | 
			
		||||
  exit 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								ct/planka.sh
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								ct/planka.sh
									
									
									
									
									
								
							@@ -40,20 +40,20 @@ function update_script() {
 | 
			
		||||
    mkdir -p /opt/planka-backup/user-avatars
 | 
			
		||||
    mkdir -p /opt/planka-backup/background-images
 | 
			
		||||
    mkdir -p /opt/planka-backup/attachments
 | 
			
		||||
    mv /opt/planka/planka/.env /opt/planka-backup
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/planka/public/favicons 2>/dev/null)" ] && mv /opt/planka/planka/public/favicons/* /opt/planka-backup/favicons/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/planka/public/user-avatars 2>/dev/null)" ] && mv /opt/planka/planka/public/user-avatars/* /opt/planka-backup/user-avatars/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/planka/public/background-images 2>/dev/null)" ] && mv /opt/planka/planka/public/background-images/* /opt/planka-backup/background-images/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/planka/private/attachments 2>/dev/null)" ] && mv /opt/planka/planka/private/attachments/* /opt/planka-backup/attachments/
 | 
			
		||||
    mv /opt/planka/.env /opt/planka-backup
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/public/favicons 2>/dev/null)" ] && mv /opt/planka/public/favicons/* /opt/planka-backup/favicons/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/public/user-avatars 2>/dev/null)" ] && mv /opt/planka/public/user-avatars/* /opt/planka-backup/user-avatars/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/public/background-images 2>/dev/null)" ] && mv /opt/planka/public/background-images/* /opt/planka-backup/background-images/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka/private/attachments 2>/dev/null)" ] && mv /opt/planka/private/attachments/* /opt/planka-backup/attachments/
 | 
			
		||||
    rm -rf /opt/planka
 | 
			
		||||
    fetch_and_deploy_gh_release "planka" "plankanban/planka" "prebuild" "latest" "/opt/planka" "planka-prebuild.zip"
 | 
			
		||||
    cd /opt/planka/planka
 | 
			
		||||
    cd /opt/planka
 | 
			
		||||
    $STD npm install
 | 
			
		||||
    mv /opt/planka-backup/.env /opt/planka/planka/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/favicons 2>/dev/null)" ] && mv /opt/planka-backup/favicons/* /opt/planka/planka/public/favicons/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/user-avatars 2>/dev/null)" ] && mv /opt/planka-backup/user-avatars/* /opt/planka/planka/public/user-avatars/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/background-images 2>/dev/null)" ] && mv /opt/planka-backup/background-images/* /opt/planka/planka/public/background-images/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/attachments 2>/dev/null)" ] && mv /opt/planka-backup/attachments/* /opt/planka/planka/private/attachments/
 | 
			
		||||
    mv /opt/planka-backup/.env /opt/planka/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/favicons 2>/dev/null)" ] && mv /opt/planka-backup/favicons/* /opt/planka/public/favicons/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/user-avatars 2>/dev/null)" ] && mv /opt/planka-backup/user-avatars/* /opt/planka/public/user-avatars/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/background-images 2>/dev/null)" ] && mv /opt/planka-backup/background-images/* /opt/planka/public/background-images/
 | 
			
		||||
    [ -n "$(ls -A /opt/planka-backup/attachments 2>/dev/null)" ] && mv /opt/planka-backup/attachments/* /opt/planka/private/attachments/
 | 
			
		||||
    msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting $APP"
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,7 @@ function update_script() {
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}."
 | 
			
		||||
  fi
 | 
			
		||||
  exit  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
@@ -27,29 +27,41 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  msg_info "Updating ${APP}"
 | 
			
		||||
  systemctl stop stirlingpdf
 | 
			
		||||
  if [[ -n $(dpkg -l | grep -w ocrmypdf) ]] && [[ -z $(dpkg -l | grep -w qpdf) ]]; then
 | 
			
		||||
    $STD apt-get remove -y ocrmypdf
 | 
			
		||||
    $STD apt-get install -y qpdf
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.stirling-pdf 2>/dev/null)" ]] || [[ ! -f ~/.stirling-pdf ]]; then
 | 
			
		||||
    if [[ ! -f /etc/systemd/system/unoserver.service ]]; then
 | 
			
		||||
      msg_custom "⚠️ " "\e[33m" "Legacy installation detected – please recreate the container using the latest install script."
 | 
			
		||||
      exit 0
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    PYTHON_VERSION="3.12" setup_uv
 | 
			
		||||
    JAVA_VERSION="21" setup_java
 | 
			
		||||
 | 
			
		||||
    msg_info "Stopping Services"
 | 
			
		||||
    systemctl stop stirlingpdf libreoffice-listener unoserver
 | 
			
		||||
    msg_ok "Stopped Services"
 | 
			
		||||
 | 
			
		||||
    if [[ -f ~/.Stirling-PDF-login ]]; then
 | 
			
		||||
      USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar"
 | 
			
		||||
      mv /opt/Stirling-PDF/Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar
 | 
			
		||||
    else
 | 
			
		||||
      USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    msg_info "Refreshing Font Cache"
 | 
			
		||||
    $STD fc-cache -fv
 | 
			
		||||
    msg_ok "Font Cache Updated"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Services"
 | 
			
		||||
    systemctl start stirlingpdf libreoffice-listener unoserver
 | 
			
		||||
    msg_ok "Started Services"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  curl -fsSL "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz" -o $(basename "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz")
 | 
			
		||||
  tar -xzf v$RELEASE.tar.gz
 | 
			
		||||
  cd Stirling-PDF-$RELEASE
 | 
			
		||||
  chmod +x ./gradlew
 | 
			
		||||
  $STD ./gradlew build
 | 
			
		||||
  rm -rf /opt/Stirling-PDF/Stirling-PDF-*.jar
 | 
			
		||||
  cp -r ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/
 | 
			
		||||
  cp -r scripts /opt/Stirling-PDF/
 | 
			
		||||
  cd ~
 | 
			
		||||
  rm -rf Stirling-PDF-$RELEASE v$RELEASE.tar.gz
 | 
			
		||||
  ln -sf /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar
 | 
			
		||||
  systemctl start stirlingpdf
 | 
			
		||||
  msg_ok "Updated ${APP} to v$RELEASE"
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
build_container
 | 
			
		||||
description
 | 
			
		||||
 
 | 
			
		||||
@@ -27,12 +27,24 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  msg_info "Updating $APP"
 | 
			
		||||
  systemctl stop threadfin.service
 | 
			
		||||
  curl -fsSL "https://github.com/Threadfin/Threadfin/releases/latest/download/Threadfin_linux_amd64" -o "/opt/threadfin/threadfin"
 | 
			
		||||
  chmod +x /opt/threadfin/threadfin
 | 
			
		||||
  systemctl start threadfin.service
 | 
			
		||||
  msg_ok "Updated $APP"
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/threadfin/threadfin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.threadfin 2>/dev/null)" ]] || [[ ! -f ~/.threadfin ]]; then
 | 
			
		||||
 | 
			
		||||
    msg_info "Stopping $APP"
 | 
			
		||||
    systemctl stop threadfin
 | 
			
		||||
    msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "threadfin" "threadfin/threadfin" "singlefile" "latest" "/opt/threadfin" "Threadfin_linux_amd64"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting $APP"
 | 
			
		||||
    systemctl start threadfin
 | 
			
		||||
    msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								frontend/public/json/add-iptag.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								frontend/public/json/add-iptag.json
									
									
									
										generated
									
									
									
								
							@@ -37,12 +37,16 @@
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Configuration: `nano /opt/iptag/iptag.conf`. iptag.service must be restarted after change.",
 | 
			
		||||
      "text": "Configuration: `nano /opt/iptag/iptag.conf`. iptag Service must be restarted after change. See here for full documentation: `https://github.com/community-scripts/ProxmoxVE/discussions/5790`",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "The Proxmox Node must contain ipcalc and net-tools. `apt-get install -y ipcalc net-tools`",
 | 
			
		||||
      "type": "warning"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "You can execute the ip tool manually with `iptag-run`",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								frontend/public/json/bunkerweb.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								frontend/public/json/bunkerweb.json
									
									
									
										generated
									
									
									
								
							@@ -31,5 +31,10 @@
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": []
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.",
 | 
			
		||||
      "type": "warning"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								frontend/public/json/dockge.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								frontend/public/json/dockge.json
									
									
									
										generated
									
									
									
								
							@@ -6,7 +6,7 @@
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2024-05-02",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": false,
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 5001,
 | 
			
		||||
  "documentation": null,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								frontend/public/json/docmost.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								frontend/public/json/docmost.json
									
									
									
										generated
									
									
									
								
							@@ -31,5 +31,10 @@
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": []
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Use `cat ~/docmost.creds` to see database credentials.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								frontend/public/json/emqx.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								frontend/public/json/emqx.json
									
									
									
										generated
									
									
									
								
							@@ -6,7 +6,7 @@
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2024-05-02",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": false,
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 18083,
 | 
			
		||||
  "documentation": "https://docs.emqx.com/en/emqx/latest/",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								frontend/public/json/ersatztv.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								frontend/public/json/ersatztv.json
									
									
									
										generated
									
									
									
								
							@@ -19,7 +19,7 @@
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/ersatztv.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 1,
 | 
			
		||||
        "cpu": 2,
 | 
			
		||||
        "ram": 1024,
 | 
			
		||||
        "hdd": 5,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								frontend/public/json/gitea-mirror.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								frontend/public/json/gitea-mirror.json
									
									
									
										generated
									
									
									
								
							@@ -9,9 +9,9 @@
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 4321,
 | 
			
		||||
  "documentation": "https://github.com/arunavo4/gitea-mirror/",
 | 
			
		||||
  "documentation": "https://github.com/RayLabsHQ/gitea-mirror/",
 | 
			
		||||
  "config_path": "/etc/systemd/system/gitea-mirror.service",
 | 
			
		||||
  "website": "https://github.com/arunavo4/gitea-mirror/",
 | 
			
		||||
  "website": "https://github.com/RayLabsHQ/gitea-mirror/",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/gitea-mirror.webp",
 | 
			
		||||
  "description": "Gitea Mirror auto-syncs GitHub repos to your self-hosted Gitea, with a sleek Web UI and easy Docker deployment. ",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								frontend/public/json/habitica.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								frontend/public/json/habitica.json
									
									
									
										generated
									
									
									
								
							@@ -8,7 +8,7 @@
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 8080,
 | 
			
		||||
  "interface_port": 3000,
 | 
			
		||||
  "documentation": "https://github.com/HabitRPG/habitica/wiki",
 | 
			
		||||
  "website": "https://habitica.com/",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/habitica.webp",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								frontend/public/json/proxmox-backup-server.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								frontend/public/json/proxmox-backup-server.json
									
									
									
										generated
									
									
									
								
							@@ -35,6 +35,10 @@
 | 
			
		||||
        {
 | 
			
		||||
            "text": "Set a root password if using autologin. This will be the PBS password. `passwd root`",
 | 
			
		||||
            "type": "warning"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "text": "Advanced Install is only possible without root password and root SSH access, you can configure this after installation.",
 | 
			
		||||
            "type": "warning"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								frontend/public/json/stirling-pdf.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										66
									
								
								frontend/public/json/stirling-pdf.json
									
									
									
										generated
									
									
									
								
							@@ -1,35 +1,35 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "Stirling-PDF",
 | 
			
		||||
    "slug": "stirling-pdf",
 | 
			
		||||
    "categories": [
 | 
			
		||||
        12
 | 
			
		||||
    ],
 | 
			
		||||
    "date_created": "2024-05-02",
 | 
			
		||||
    "type": "ct",
 | 
			
		||||
    "updateable": true,
 | 
			
		||||
    "privileged": false,
 | 
			
		||||
    "interface_port": 8080,
 | 
			
		||||
    "documentation": null,
 | 
			
		||||
    "website": "https://github.com/Stirling-Tools/Stirling-PDF",
 | 
			
		||||
    "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/stirling-pdf.webp",
 | 
			
		||||
    "config_path": "/opt/Stirling-PDF/.env",
 | 
			
		||||
    "description": "Stirling-PDF is a powerful locally hosted web based PDF manipulation tool that allows you to perform various operations on PDF files, such as splitting merging, converting, reorganizing, adding images, rotating, compressing, and more.",
 | 
			
		||||
    "install_methods": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "default",
 | 
			
		||||
            "script": "ct/stirling-pdf.sh",
 | 
			
		||||
            "resources": {
 | 
			
		||||
                "cpu": 2,
 | 
			
		||||
                "ram": 2048,
 | 
			
		||||
                "hdd": 8,
 | 
			
		||||
                "os": "debian",
 | 
			
		||||
                "version": "12"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "default_credentials": {
 | 
			
		||||
        "username": null,
 | 
			
		||||
        "password": null
 | 
			
		||||
    },
 | 
			
		||||
    "notes": []
 | 
			
		||||
  "name": "Stirling-PDF",
 | 
			
		||||
  "slug": "stirling-pdf",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    12
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2024-05-02",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 8080,
 | 
			
		||||
  "documentation": null,
 | 
			
		||||
  "website": "https://github.com/Stirling-Tools/Stirling-PDF",
 | 
			
		||||
  "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/stirling-pdf.webp",
 | 
			
		||||
  "config_path": "/opt/Stirling-PDF/.env",
 | 
			
		||||
  "description": "Stirling-PDF is a powerful locally hosted web based PDF manipulation tool that allows you to perform various operations on PDF files, such as splitting merging, converting, reorganizing, adding images, rotating, compressing, and more.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/stirling-pdf.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 2,
 | 
			
		||||
        "ram": 2048,
 | 
			
		||||
        "hdd": 8,
 | 
			
		||||
        "os": "debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": "admin",
 | 
			
		||||
    "password": "stirling"
 | 
			
		||||
  },
 | 
			
		||||
  "notes": []
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								frontend/public/json/threadfin.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								frontend/public/json/threadfin.json
									
									
									
										generated
									
									
									
								
							@@ -6,7 +6,7 @@
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2024-06-12",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": false,
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 34400,
 | 
			
		||||
  "documentation": null,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										636
									
								
								frontend/public/json/versions.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										636
									
								
								frontend/public/json/versions.json
									
									
									
										generated
									
									
									
								
							@@ -1,4 +1,319 @@
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Ombi-app/Ombi",
 | 
			
		||||
    "version": "v4.47.1",
 | 
			
		||||
    "date": "2025-01-05T21:14:23Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "eclipse-mosquitto/mosquitto",
 | 
			
		||||
    "version": "v2.0.22",
 | 
			
		||||
    "date": "2025-07-11T21:34:20Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "steveiliop56/tinyauth",
 | 
			
		||||
    "version": "v3.6.0",
 | 
			
		||||
    "date": "2025-07-09T23:15:25Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "mongodb/mongo",
 | 
			
		||||
    "version": "r8.2.0-alpha0",
 | 
			
		||||
    "date": "2025-07-11T21:06:26Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "duplicati/duplicati",
 | 
			
		||||
    "version": "v2.1.0.124-2.1.0.124_canary_2025-07-11",
 | 
			
		||||
    "date": "2025-07-11T20:09:08Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "TandoorRecipes/recipes",
 | 
			
		||||
    "version": "1.5.35",
 | 
			
		||||
    "date": "2025-06-22T08:30:10Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "MediaBrowser/Emby.Releases",
 | 
			
		||||
    "version": "4.9.1.2",
 | 
			
		||||
    "date": "2025-06-26T22:08:00Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "homarr-labs/homarr",
 | 
			
		||||
    "version": "v1.28.0",
 | 
			
		||||
    "date": "2025-07-11T19:16:26Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "n8n-io/n8n",
 | 
			
		||||
    "version": "n8n@1.101.2",
 | 
			
		||||
    "date": "2025-07-11T12:03:41Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "FlowiseAI/Flowise",
 | 
			
		||||
    "version": "flowise@3.0.4",
 | 
			
		||||
    "date": "2025-07-11T13:26:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zwave-js/zwave-js-ui",
 | 
			
		||||
    "version": "v10.9.0",
 | 
			
		||||
    "date": "2025-07-11T12:57:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zitadel/zitadel",
 | 
			
		||||
    "version": "v3.3.1",
 | 
			
		||||
    "date": "2025-07-11T11:51:48Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "prometheus/prometheus",
 | 
			
		||||
    "version": "v2.53.5",
 | 
			
		||||
    "date": "2025-06-30T11:01:12Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Paymenter/Paymenter",
 | 
			
		||||
    "version": "v1.2.2",
 | 
			
		||||
    "date": "2025-07-11T10:09:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "traefik/traefik",
 | 
			
		||||
    "version": "v3.4.4",
 | 
			
		||||
    "date": "2025-07-11T08:41:34Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "mattermost/mattermost",
 | 
			
		||||
    "version": "preview-v0.1",
 | 
			
		||||
    "date": "2025-06-27T14:35:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Jackett/Jackett",
 | 
			
		||||
    "version": "v0.22.2145",
 | 
			
		||||
    "date": "2025-07-11T05:49:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "documenso/documenso",
 | 
			
		||||
    "version": "v1.12.2-rc.1",
 | 
			
		||||
    "date": "2025-07-11T02:55:56Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "outline/outline",
 | 
			
		||||
    "version": "v0.85.1",
 | 
			
		||||
    "date": "2025-07-11T01:17:53Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "jenkinsci/jenkins",
 | 
			
		||||
    "version": "jenkins-2.518",
 | 
			
		||||
    "date": "2025-07-08T13:52:55Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "rcourtman/Pulse",
 | 
			
		||||
    "version": "v3.41.1",
 | 
			
		||||
    "date": "2025-07-10T17:10:46Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "LibreTranslate/LibreTranslate",
 | 
			
		||||
    "version": "v1.7.2",
 | 
			
		||||
    "date": "2025-07-10T19:29:26Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "binwiederhier/ntfy",
 | 
			
		||||
    "version": "v2.13.0",
 | 
			
		||||
    "date": "2025-07-10T19:27:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "ollama/ollama",
 | 
			
		||||
    "version": "v0.9.6",
 | 
			
		||||
    "date": "2025-07-08T01:26:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "keycloak/keycloak",
 | 
			
		||||
    "version": "26.3.1",
 | 
			
		||||
    "date": "2025-07-09T15:41:43Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "msgbyte/tianji",
 | 
			
		||||
    "version": "v1.23.4",
 | 
			
		||||
    "date": "2025-07-10T18:13:38Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "forgejo/forgejo",
 | 
			
		||||
    "version": "v11.0.3",
 | 
			
		||||
    "date": "2025-07-10T13:12:00Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "crowdsecurity/crowdsec",
 | 
			
		||||
    "version": "v1.6.10",
 | 
			
		||||
    "date": "2025-07-10T12:04:30Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "neo4j/neo4j",
 | 
			
		||||
    "version": "5.26.9",
 | 
			
		||||
    "date": "2025-07-10T10:04:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "meilisearch/meilisearch",
 | 
			
		||||
    "version": "prototype-incremental-vector-store-3",
 | 
			
		||||
    "date": "2025-07-07T10:27:19Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "firefly-iii/firefly-iii",
 | 
			
		||||
    "version": "v6.2.20",
 | 
			
		||||
    "date": "2025-07-02T04:03:37Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pocket-id/pocket-id",
 | 
			
		||||
    "version": "v1.6.2",
 | 
			
		||||
    "date": "2025-07-09T22:14:10Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "NginxProxyManager/nginx-proxy-manager",
 | 
			
		||||
    "version": "v2.12.6",
 | 
			
		||||
    "date": "2025-07-09T21:52:15Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "apache/tika",
 | 
			
		||||
    "version": "3.2.1",
 | 
			
		||||
    "date": "2025-07-09T20:47:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "sabnzbd/sabnzbd",
 | 
			
		||||
    "version": "4.5.2",
 | 
			
		||||
    "date": "2025-07-09T19:08:28Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "raydak-labs/configarr",
 | 
			
		||||
    "version": "v1.13.6",
 | 
			
		||||
    "date": "2025-07-09T17:23:01Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "hargata/lubelog",
 | 
			
		||||
    "version": "v1.4.9",
 | 
			
		||||
    "date": "2025-07-09T16:27:46Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nicolargo/glances",
 | 
			
		||||
    "version": "v4.3.3",
 | 
			
		||||
    "date": "2025-07-09T15:35:44Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "rclone/rclone",
 | 
			
		||||
    "version": "v1.70.3",
 | 
			
		||||
    "date": "2025-07-09T15:06:31Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "home-assistant/operating-system",
 | 
			
		||||
    "version": "16.0",
 | 
			
		||||
    "date": "2025-07-09T13:28:43Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "element-hq/synapse",
 | 
			
		||||
    "version": "v1.133.0",
 | 
			
		||||
    "date": "2025-07-01T15:13:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "AdguardTeam/AdGuardHome",
 | 
			
		||||
    "version": "v0.107.63",
 | 
			
		||||
    "date": "2025-06-26T14:34:19Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "fuma-nama/fumadocs",
 | 
			
		||||
    "version": "fumadocs-ui@15.6.3",
 | 
			
		||||
    "date": "2025-07-09T09:28:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "cockpit-project/cockpit",
 | 
			
		||||
    "version": "342",
 | 
			
		||||
    "date": "2025-07-09T08:48:21Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "esphome/esphome",
 | 
			
		||||
    "version": "2025.6.3",
 | 
			
		||||
    "date": "2025-07-03T01:07:26Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "henrygd/beszel",
 | 
			
		||||
    "version": "v0.11.1",
 | 
			
		||||
    "date": "2025-04-29T01:14:35Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Prowlarr/Prowlarr",
 | 
			
		||||
    "version": "v1.37.0.5076",
 | 
			
		||||
    "date": "2025-06-04T11:04:53Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Radarr/Radarr",
 | 
			
		||||
    "version": "v5.26.2.10099",
 | 
			
		||||
    "date": "2025-06-11T20:10:39Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "ipfs/kubo",
 | 
			
		||||
    "version": "v0.35.0",
 | 
			
		||||
    "date": "2025-05-21T18:00:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "grokability/snipe-it",
 | 
			
		||||
    "version": "v8.1.18",
 | 
			
		||||
    "date": "2025-07-08T20:36:37Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Stirling-Tools/Stirling-PDF",
 | 
			
		||||
    "version": "v1.0.2",
 | 
			
		||||
    "date": "2025-07-08T19:14:31Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "TwiN/gatus",
 | 
			
		||||
    "version": "v5.20.0",
 | 
			
		||||
    "date": "2025-07-08T16:27:11Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "bunkerity/bunkerweb",
 | 
			
		||||
    "version": "v1.6.2",
 | 
			
		||||
    "date": "2025-07-08T13:52:33Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "wazuh/wazuh",
 | 
			
		||||
    "version": "coverity-w28-4.13.0",
 | 
			
		||||
    "date": "2025-07-08T11:25:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "docker/compose",
 | 
			
		||||
    "version": "v2.38.2",
 | 
			
		||||
    "date": "2025-07-08T09:35:14Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Checkmk/checkmk",
 | 
			
		||||
    "version": "v2.4.0p7",
 | 
			
		||||
    "date": "2025-07-08T05:51:08Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "VictoriaMetrics/VictoriaMetrics",
 | 
			
		||||
    "version": "pmm-6401-v1.121.0",
 | 
			
		||||
    "date": "2025-07-07T16:16:13Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "photoprism/photoprism",
 | 
			
		||||
    "version": "250707-d28b3101e",
 | 
			
		||||
    "date": "2025-07-07T15:15:21Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "traccar/traccar",
 | 
			
		||||
    "version": "v6.8.1",
 | 
			
		||||
    "date": "2025-07-07T14:40:11Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "BookStackApp/BookStack",
 | 
			
		||||
    "version": "v25.05.2",
 | 
			
		||||
    "date": "2025-07-07T14:08:25Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nzbgetcom/nzbget",
 | 
			
		||||
    "version": "v25.2",
 | 
			
		||||
    "date": "2025-07-04T08:21:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "morpheus65535/bazarr",
 | 
			
		||||
    "version": "v1.5.2",
 | 
			
		||||
    "date": "2025-05-11T16:40:55Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "slskd/slskd",
 | 
			
		||||
    "version": "0.23.1",
 | 
			
		||||
    "date": "2025-07-06T23:57:52Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pelican-dev/panel",
 | 
			
		||||
    "version": "v1.0.0-beta22",
 | 
			
		||||
@@ -9,11 +324,6 @@
 | 
			
		||||
    "version": "v1.0.0-beta14",
 | 
			
		||||
    "date": "2025-07-06T21:07:07Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pocket-id/pocket-id",
 | 
			
		||||
    "version": "v1.6.1",
 | 
			
		||||
    "date": "2025-07-06T20:59:34Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Luligu/matterbridge",
 | 
			
		||||
    "version": "3.1.2",
 | 
			
		||||
@@ -29,26 +339,6 @@
 | 
			
		||||
    "version": "v1.30.0",
 | 
			
		||||
    "date": "2025-07-01T11:29:11Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "traccar/traccar",
 | 
			
		||||
    "version": "v6.8.0",
 | 
			
		||||
    "date": "2025-07-06T18:19:05Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "firefly-iii/firefly-iii",
 | 
			
		||||
    "version": "v6.2.20",
 | 
			
		||||
    "date": "2025-07-02T04:03:37Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "msgbyte/tianji",
 | 
			
		||||
    "version": "v1.23.0",
 | 
			
		||||
    "date": "2025-07-06T16:01:58Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "TandoorRecipes/recipes",
 | 
			
		||||
    "version": "1.5.35",
 | 
			
		||||
    "date": "2025-06-22T08:30:10Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Part-DB/Part-DB-server",
 | 
			
		||||
    "version": "v1.17.2",
 | 
			
		||||
@@ -59,11 +349,6 @@
 | 
			
		||||
    "version": "8.0.3",
 | 
			
		||||
    "date": "2025-07-06T12:19:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Jackett/Jackett",
 | 
			
		||||
    "version": "v0.22.2123",
 | 
			
		||||
    "date": "2025-07-06T06:01:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "fallenbagel/jellyseerr",
 | 
			
		||||
    "version": "preview-OIDC",
 | 
			
		||||
@@ -74,16 +359,6 @@
 | 
			
		||||
    "version": "2.1.1",
 | 
			
		||||
    "date": "2025-06-14T17:45:06Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "steveiliop56/tinyauth",
 | 
			
		||||
    "version": "v3.4.1",
 | 
			
		||||
    "date": "2025-06-11T07:53:44Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "slskd/slskd",
 | 
			
		||||
    "version": "0.23.0",
 | 
			
		||||
    "date": "2025-07-06T00:02:35Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Kareadita/Kavita",
 | 
			
		||||
    "version": "v0.8.7",
 | 
			
		||||
@@ -94,31 +369,16 @@
 | 
			
		||||
    "version": "v6.12.7",
 | 
			
		||||
    "date": "2025-06-18T03:44:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nicolargo/glances",
 | 
			
		||||
    "version": "v4.3.2",
 | 
			
		||||
    "date": "2025-07-05T16:00:15Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "runtipi/runtipi",
 | 
			
		||||
    "version": "v4.3.0",
 | 
			
		||||
    "date": "2025-07-05T12:14:52Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "fuma-nama/fumadocs",
 | 
			
		||||
    "version": "fumadocs-openapi@9.0.18",
 | 
			
		||||
    "date": "2025-07-05T09:36:45Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "theonedev/onedev",
 | 
			
		||||
    "version": "v11.11.4",
 | 
			
		||||
    "date": "2025-07-05T09:23:25Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Paymenter/Paymenter",
 | 
			
		||||
    "version": "v1.2.0",
 | 
			
		||||
    "date": "2025-07-05T08:58:05Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "linkwarden/linkwarden",
 | 
			
		||||
    "version": "v2.11.3",
 | 
			
		||||
@@ -130,60 +390,20 @@
 | 
			
		||||
    "date": "2025-07-04T20:02:52Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "homarr-labs/homarr",
 | 
			
		||||
    "version": "v1.27.0",
 | 
			
		||||
    "date": "2025-07-04T19:16:16Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zitadel/zitadel",
 | 
			
		||||
    "version": "v3.3.0",
 | 
			
		||||
    "date": "2025-06-12T06:54:48Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "bunkerity/bunkerweb",
 | 
			
		||||
    "version": "v1.6.2",
 | 
			
		||||
    "date": "2025-07-04T15:21:18Z"
 | 
			
		||||
    "name": "emqx/emqx",
 | 
			
		||||
    "version": "e6.0.0-M1.202507-alpha.1",
 | 
			
		||||
    "date": "2025-07-04T14:58:23Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "kimai/kimai",
 | 
			
		||||
    "version": "2.37.0",
 | 
			
		||||
    "date": "2025-07-04T14:49:43Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "keycloak/keycloak",
 | 
			
		||||
    "version": "26.3.0",
 | 
			
		||||
    "date": "2025-07-02T12:26:44Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Graylog2/graylog2-server",
 | 
			
		||||
    "version": "6.3.1",
 | 
			
		||||
    "date": "2025-07-04T11:20:48Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "mattermost/mattermost",
 | 
			
		||||
    "version": "preview-v0.1",
 | 
			
		||||
    "date": "2025-06-27T14:35:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nzbgetcom/nzbget",
 | 
			
		||||
    "version": "v25.2",
 | 
			
		||||
    "date": "2025-07-04T08:21:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Checkmk/checkmk",
 | 
			
		||||
    "version": "v2.2.0p44",
 | 
			
		||||
    "date": "2025-07-04T06:44:06Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "outline/outline",
 | 
			
		||||
    "version": "v0.85.0",
 | 
			
		||||
    "date": "2025-07-04T00:06:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "home-assistant/operating-system",
 | 
			
		||||
    "version": "15.2",
 | 
			
		||||
    "date": "2025-04-14T15:37:12Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "cloudflare/cloudflared",
 | 
			
		||||
    "version": "2025.7.0",
 | 
			
		||||
@@ -199,66 +419,21 @@
 | 
			
		||||
    "version": "v3.2.1",
 | 
			
		||||
    "date": "2025-07-03T16:09:19Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "cockpit-project/cockpit",
 | 
			
		||||
    "version": "310.5",
 | 
			
		||||
    "date": "2025-07-03T14:05:25Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "n8n-io/n8n",
 | 
			
		||||
    "version": "n8n@1.100.0",
 | 
			
		||||
    "date": "2025-06-23T12:48:35Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Dolibarr/dolibarr",
 | 
			
		||||
    "version": "18.0.7",
 | 
			
		||||
    "date": "2025-07-03T08:57:21Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "esphome/esphome",
 | 
			
		||||
    "version": "2025.6.3",
 | 
			
		||||
    "date": "2025-07-03T01:07:26Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "actualbudget/actual",
 | 
			
		||||
    "version": "v25.7.1",
 | 
			
		||||
    "date": "2025-07-03T01:03:18Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "mongodb/mongo",
 | 
			
		||||
    "version": "r6.0.25-rc0",
 | 
			
		||||
    "date": "2025-07-03T00:44:52Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "documenso/documenso",
 | 
			
		||||
    "version": "v1.12.2-rc.0",
 | 
			
		||||
    "date": "2025-07-03T00:31:22Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "emqx/emqx",
 | 
			
		||||
    "version": "v5.8.7",
 | 
			
		||||
    "date": "2025-07-02T21:54:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "hargata/lubelog",
 | 
			
		||||
    "version": "v1.4.8",
 | 
			
		||||
    "date": "2025-07-02T21:15:13Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Koenkk/zigbee2mqtt",
 | 
			
		||||
    "version": "2.5.1",
 | 
			
		||||
    "date": "2025-07-02T19:38:06Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "ollama/ollama",
 | 
			
		||||
    "version": "v0.9.5",
 | 
			
		||||
    "date": "2025-07-02T18:39:28Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "wazuh/wazuh",
 | 
			
		||||
    "version": "coverity-w27-4.13.0",
 | 
			
		||||
    "date": "2025-07-01T03:17:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "glpi-project/glpi",
 | 
			
		||||
    "version": "10.0.18",
 | 
			
		||||
@@ -289,11 +464,6 @@
 | 
			
		||||
    "version": "1.2.35",
 | 
			
		||||
    "date": "2025-07-01T21:37:20Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "TwiN/gatus",
 | 
			
		||||
    "version": "v5.19.0",
 | 
			
		||||
    "date": "2025-07-01T19:59:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "hivemq/hivemq-community-edition",
 | 
			
		||||
    "version": "2025.4",
 | 
			
		||||
@@ -309,21 +479,6 @@
 | 
			
		||||
    "version": "v0.57.0",
 | 
			
		||||
    "date": "2025-07-01T16:47:46Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "jenkinsci/jenkins",
 | 
			
		||||
    "version": "jenkins-2.517",
 | 
			
		||||
    "date": "2025-07-01T16:08:23Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "element-hq/synapse",
 | 
			
		||||
    "version": "v1.133.0",
 | 
			
		||||
    "date": "2025-07-01T15:13:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "rcourtman/Pulse",
 | 
			
		||||
    "version": "v99.99.99",
 | 
			
		||||
    "date": "2025-07-01T08:26:41Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zabbix/zabbix",
 | 
			
		||||
    "version": "7.4.0",
 | 
			
		||||
@@ -334,41 +489,21 @@
 | 
			
		||||
    "version": "v0.15.0-rc3",
 | 
			
		||||
    "date": "2025-07-01T04:09:37Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "NginxProxyManager/nginx-proxy-manager",
 | 
			
		||||
    "version": "v2.12.4",
 | 
			
		||||
    "date": "2025-07-01T01:45:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "MagicMirrorOrg/MagicMirror",
 | 
			
		||||
    "version": "v2.32.0",
 | 
			
		||||
    "date": "2025-06-30T22:12:48Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "docker/compose",
 | 
			
		||||
    "version": "v2.38.1",
 | 
			
		||||
    "date": "2025-06-30T20:07:35Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "jhuckaby/Cronicle",
 | 
			
		||||
    "version": "v0.9.81",
 | 
			
		||||
    "date": "2025-06-30T16:40:33Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "prometheus/prometheus",
 | 
			
		||||
    "version": "v2.53.5",
 | 
			
		||||
    "date": "2025-06-30T11:01:12Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "jupyter/notebook",
 | 
			
		||||
    "version": "v7.4.4",
 | 
			
		||||
    "date": "2025-06-30T13:04:22Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "grokability/snipe-it",
 | 
			
		||||
    "version": "v8.1.17",
 | 
			
		||||
    "date": "2025-06-30T11:26:27Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "PrivateBin/PrivateBin",
 | 
			
		||||
    "version": "1.7.8",
 | 
			
		||||
@@ -399,56 +534,16 @@
 | 
			
		||||
    "version": "version/2025.6.3",
 | 
			
		||||
    "date": "2025-06-27T14:01:06Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "rclone/rclone",
 | 
			
		||||
    "version": "v1.70.2",
 | 
			
		||||
    "date": "2025-06-27T13:21:17Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "sabnzbd/sabnzbd",
 | 
			
		||||
    "version": "4.5.1",
 | 
			
		||||
    "date": "2025-04-11T09:57:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "FlowiseAI/Flowise",
 | 
			
		||||
    "version": "flowise@3.0.3",
 | 
			
		||||
    "date": "2025-06-27T09:53:57Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "MediaBrowser/Emby.Releases",
 | 
			
		||||
    "version": "4.9.1.2",
 | 
			
		||||
    "date": "2025-06-26T22:08:00Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "netbox-community/netbox",
 | 
			
		||||
    "version": "v4.3.3",
 | 
			
		||||
    "date": "2025-06-26T18:42:56Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "apache/tika",
 | 
			
		||||
    "version": "3.2.1-rc2",
 | 
			
		||||
    "date": "2025-06-26T17:10:25Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "tailscale/tailscale",
 | 
			
		||||
    "version": "v1.84.3",
 | 
			
		||||
    "date": "2025-06-26T16:31:57Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "traefik/traefik",
 | 
			
		||||
    "version": "v3.5.0-rc1",
 | 
			
		||||
    "date": "2025-06-26T15:08:43Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "meilisearch/meilisearch",
 | 
			
		||||
    "version": "prototype-no-simd-x86-arroy-0",
 | 
			
		||||
    "date": "2025-06-26T14:54:18Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "AdguardTeam/AdGuardHome",
 | 
			
		||||
    "version": "v0.107.63",
 | 
			
		||||
    "date": "2025-06-26T14:34:19Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "node-red/node-red",
 | 
			
		||||
    "version": "4.1.0-beta.2",
 | 
			
		||||
@@ -474,11 +569,6 @@
 | 
			
		||||
    "version": "v1.18.4",
 | 
			
		||||
    "date": "2025-06-25T00:06:56Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "duplicati/duplicati",
 | 
			
		||||
    "version": "v2.1.0.120-2.1.0.120_canary_2025-06-24",
 | 
			
		||||
    "date": "2025-06-24T22:39:50Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "evcc-io/evcc",
 | 
			
		||||
    "version": "0.204.5",
 | 
			
		||||
@@ -499,11 +589,6 @@
 | 
			
		||||
    "version": "RELEASE.2025-06-13T11-33-47Z",
 | 
			
		||||
    "date": "2025-06-23T20:58:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "VictoriaMetrics/VictoriaMetrics",
 | 
			
		||||
    "version": "pmm-6401-v1.120.0",
 | 
			
		||||
    "date": "2025-06-23T15:12:12Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "gotson/komga",
 | 
			
		||||
    "version": "1.22.0",
 | 
			
		||||
@@ -564,11 +649,6 @@
 | 
			
		||||
    "version": "v0.21.0",
 | 
			
		||||
    "date": "2025-06-19T11:54:59Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "neo4j/neo4j",
 | 
			
		||||
    "version": "2025.05.1",
 | 
			
		||||
    "date": "2025-06-19T11:28:36Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "prometheus-pve/prometheus-pve-exporter",
 | 
			
		||||
    "version": "v3.5.5",
 | 
			
		||||
@@ -579,11 +659,6 @@
 | 
			
		||||
    "version": "v0.21.0",
 | 
			
		||||
    "date": "2025-06-18T21:43:27Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "ipfs/kubo",
 | 
			
		||||
    "version": "v0.35.0",
 | 
			
		||||
    "date": "2025-05-21T18:00:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pterodactyl/panel",
 | 
			
		||||
    "version": "v1.11.11",
 | 
			
		||||
@@ -604,16 +679,6 @@
 | 
			
		||||
    "version": "v5.6.0",
 | 
			
		||||
    "date": "2025-06-18T12:19:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zwave-js/zwave-js-ui",
 | 
			
		||||
    "version": "v10.7.0",
 | 
			
		||||
    "date": "2025-06-18T11:57:05Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "forgejo/forgejo",
 | 
			
		||||
    "version": "v11.0.2",
 | 
			
		||||
    "date": "2025-06-18T09:38:19Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "silverbulletmd/silverbullet",
 | 
			
		||||
    "version": "2.0.0-pre3",
 | 
			
		||||
@@ -629,21 +694,6 @@
 | 
			
		||||
    "version": "v2.1.5",
 | 
			
		||||
    "date": "2025-06-17T18:04:11Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "BookStackApp/BookStack",
 | 
			
		||||
    "version": "v25.05.1",
 | 
			
		||||
    "date": "2025-06-17T14:38:04Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "crowdsecurity/crowdsec",
 | 
			
		||||
    "version": "v1.6.9",
 | 
			
		||||
    "date": "2025-06-17T11:54:50Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "morpheus65535/bazarr",
 | 
			
		||||
    "version": "v1.5.2",
 | 
			
		||||
    "date": "2025-05-11T16:40:55Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "donaldzou/WGDashboard",
 | 
			
		||||
    "version": "v4.2.4",
 | 
			
		||||
@@ -679,11 +729,6 @@
 | 
			
		||||
    "version": "cli/v0.25.0",
 | 
			
		||||
    "date": "2025-06-15T17:48:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Prowlarr/Prowlarr",
 | 
			
		||||
    "version": "v1.37.0.5076",
 | 
			
		||||
    "date": "2025-06-04T11:04:53Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Readarr/Readarr",
 | 
			
		||||
    "version": "v2.0.0.4645",
 | 
			
		||||
@@ -694,11 +739,6 @@
 | 
			
		||||
    "version": "v2.12.4.4658",
 | 
			
		||||
    "date": "2025-06-09T17:27:45Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Radarr/Radarr",
 | 
			
		||||
    "version": "v5.26.2.10099",
 | 
			
		||||
    "date": "2025-06-11T20:10:39Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "advplyr/audiobookshelf",
 | 
			
		||||
    "version": "v2.25.1",
 | 
			
		||||
@@ -829,11 +869,6 @@
 | 
			
		||||
    "version": "v0.14.1",
 | 
			
		||||
    "date": "2024-08-29T22:32:51Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "binwiederhier/ntfy",
 | 
			
		||||
    "version": "v2.12.0",
 | 
			
		||||
    "date": "2025-05-30T00:26:27Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "release-argus/Argus",
 | 
			
		||||
    "version": "0.26.3",
 | 
			
		||||
@@ -884,11 +919,6 @@
 | 
			
		||||
    "version": "0.5",
 | 
			
		||||
    "date": "2025-05-21T20:19:14Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Stirling-Tools/Stirling-PDF",
 | 
			
		||||
    "version": "v0.46.2",
 | 
			
		||||
    "date": "2025-05-20T11:21:04Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "sbondCo/Watcharr",
 | 
			
		||||
    "version": "v2.1.0",
 | 
			
		||||
@@ -909,11 +939,6 @@
 | 
			
		||||
    "version": "v25.05.2",
 | 
			
		||||
    "date": "2025-05-17T12:53:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Ombi-app/Ombi",
 | 
			
		||||
    "version": "v4.47.1",
 | 
			
		||||
    "date": "2025-01-05T21:14:23Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "motioneye-project/motioneye",
 | 
			
		||||
    "version": "0.42.1",
 | 
			
		||||
@@ -959,21 +984,11 @@
 | 
			
		||||
    "version": "3.5.0",
 | 
			
		||||
    "date": "2025-05-05T16:28:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "raydak-labs/configarr",
 | 
			
		||||
    "version": "v1.13.5",
 | 
			
		||||
    "date": "2025-05-03T09:48:44Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "WordPress/WordPress",
 | 
			
		||||
    "version": "6.8.1",
 | 
			
		||||
    "date": "2025-04-30T16:44:16Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "henrygd/beszel",
 | 
			
		||||
    "version": "v0.11.1",
 | 
			
		||||
    "date": "2025-04-29T01:14:35Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "deluge-torrent/deluge",
 | 
			
		||||
    "version": "deluge-2.2.0",
 | 
			
		||||
@@ -989,11 +1004,6 @@
 | 
			
		||||
    "version": "v2.6.3",
 | 
			
		||||
    "date": "2025-04-27T09:05:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "photoprism/photoprism",
 | 
			
		||||
    "version": "250426-27ec7a128",
 | 
			
		||||
    "date": "2025-04-26T11:51:39Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "TechnitiumSoftware/DnsServer",
 | 
			
		||||
    "version": "v13.6.0",
 | 
			
		||||
@@ -1099,11 +1109,6 @@
 | 
			
		||||
    "version": "v1.34.0",
 | 
			
		||||
    "date": "2025-03-26T08:48:34Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "LibreTranslate/LibreTranslate",
 | 
			
		||||
    "version": "v1.6.5",
 | 
			
		||||
    "date": "2025-03-25T20:27:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nextcloud/nextcloudpi",
 | 
			
		||||
    "version": "v1.55.4",
 | 
			
		||||
@@ -1154,11 +1159,6 @@
 | 
			
		||||
    "version": "v0.28.1",
 | 
			
		||||
    "date": "2025-03-07T15:41:35Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "eclipse-mosquitto/mosquitto",
 | 
			
		||||
    "version": "v2.0.21",
 | 
			
		||||
    "date": "2025-03-06T16:24:56Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "toniebox-reverse-engineering/teddycloud",
 | 
			
		||||
    "version": "tc_v0.6.4",
 | 
			
		||||
 
 | 
			
		||||
@@ -24,13 +24,13 @@ RELEASE=$(curl -s https://api.github.com/repos/steveiliop56/tinyauth/releases/la
 | 
			
		||||
curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth
 | 
			
		||||
chmod +x /opt/tinyauth/tinyauth
 | 
			
		||||
 | 
			
		||||
PASSWORD=$(openssl rand -base64 8 | tr -dc 'a-zA-Z0-9' | head -c 8)
 | 
			
		||||
USER=$(htpasswd -Bbn "tinyauth" "${PASSWORD}")
 | 
			
		||||
PASS=$(openssl rand -base64 8 | tr -dc 'a-zA-Z0-9' | head -c 8)
 | 
			
		||||
USER=$(htpasswd -Bbn "tinyauth" "${PASS}")
 | 
			
		||||
 | 
			
		||||
cat <<EOF > /opt/tinyauth/credentials.txt
 | 
			
		||||
cat <<EOF >/opt/tinyauth/credentials.txt
 | 
			
		||||
Tinyauth Credentials
 | 
			
		||||
Username: tinyauth
 | 
			
		||||
Password: ${PASSWORD}
 | 
			
		||||
Password: ${PASS}
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
echo "${RELEASE}" >/opt/tinyauth_version.txt
 | 
			
		||||
 
 | 
			
		||||
@@ -24,13 +24,10 @@ $STD apt-get install -y \
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
setup_uv
 | 
			
		||||
fetch_and_deploy_gh_release "babybuddy" "babybuddy/babybuddy"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Babybuddy"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/babybuddy/babybuddy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
mkdir -p /opt/{babybuddy,data}
 | 
			
		||||
curl -fsSL "https://github.com/babybuddy/babybuddy/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
tar zxf "$temp_file" --strip-components=1 -C /opt/babybuddy
 | 
			
		||||
mkdir -p /opt/data
 | 
			
		||||
cd /opt/babybuddy
 | 
			
		||||
$STD uv venv .venv
 | 
			
		||||
$STD source .venv/bin/activate
 | 
			
		||||
@@ -102,7 +99,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f "$temp_file"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,12 +13,8 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y apache2
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PG_VERSION="16" setup_postgresql
 | 
			
		||||
PHP_APACHE="YES" PHP_MODULE="pgsql, dom" PHP_VERSION="8.2" setup_php
 | 
			
		||||
PHP_APACHE="YES" PHP_MODULE="pgsql" PHP_VERSION="8.2" setup_php
 | 
			
		||||
fetch_and_deploy_gh_release "baikal" "sabre-io/Baikal"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up PostgreSQL Database"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,12 +14,10 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apache2 \
 | 
			
		||||
  redis
 | 
			
		||||
$STD apt-get install -y redis
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PHP_VERSION="8.2" PHP_APACHE="YES" PHP_MODULE="date, json, redis, sqlite3, sockets" setup_php
 | 
			
		||||
PHP_VERSION="8.2" PHP_APACHE="YES" PHP_MODULE="redis, sqlite3" setup_php
 | 
			
		||||
fetch_and_deploy_gh_release "barcodebuddy" "Forceu/barcodebuddy"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring barcodebuddy"
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,8 @@ $STD apt-get install -y \
 | 
			
		||||
  make
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PHP_MODULE="fpm, ldap, tidy, bz2, mysql" PHP_FPM="YES" PHP_APACHE="YES" PHP_VERSION="8.2" setup_php
 | 
			
		||||
PHP_MODULE="ldap,tidy,bz2,mysqli" PHP_FPM="YES" PHP_APACHE="YES" PHP_VERSION="8.3" setup_php
 | 
			
		||||
 | 
			
		||||
setup_composer
 | 
			
		||||
setup_mariadb
 | 
			
		||||
 | 
			
		||||
@@ -56,7 +57,7 @@ chmod -R 755 /opt/bookstack /opt/bookstack/bootstrap/cache /opt/bookstack/public
 | 
			
		||||
chmod -R 775 /opt/bookstack/storage /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads
 | 
			
		||||
chmod -R 640 /opt/bookstack/.env
 | 
			
		||||
$STD a2enmod rewrite
 | 
			
		||||
$STD a2enmod php8.2
 | 
			
		||||
$STD a2enmod php8.3
 | 
			
		||||
msg_ok "Configured Bookstack"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
 
 | 
			
		||||
@@ -18,19 +18,12 @@ $STD apt-get install -y apt-transport-https
 | 
			
		||||
$STD apt-get install -y lsb-release
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Nginx"
 | 
			
		||||
curl -fsSL "https://nginx.org/keys/nginx_signing.key" | gpg --dearmor >/usr/share/keyrings/nginx-archive-keyring.gpg
 | 
			
		||||
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian $(lsb_release -cs) nginx" >/etc/apt/sources.list.d/nginx.list
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y nginx=1.26.3*
 | 
			
		||||
msg_ok "Installed Nginx"
 | 
			
		||||
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
msg_info "Installing BunkerWeb v${RELEASE} (Patience)"
 | 
			
		||||
curl -fsSL "https://repo.bunkerweb.io/bunkerity/bunkerweb/gpgkey" | gpg --dearmor >/etc/apt/keyrings/bunkerity_bunkerweb-archive-keyring.gpg
 | 
			
		||||
echo "deb [signed-by=/etc/apt/keyrings/bunkerity_bunkerweb-archive-keyring.gpg] https://repo.bunkerweb.io/bunkerity/bunkerweb/debian/ bookworm main" >/etc/apt/sources.list.d/bunkerity_bunkerweb.list
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y bunkerweb=${RELEASE}
 | 
			
		||||
curl -fsSL -o install-bunkerweb.sh https://github.com/bunkerity/bunkerweb/raw/v${RELEASE}/misc/install-bunkerweb.sh
 | 
			
		||||
chmod +x install-bunkerweb.sh
 | 
			
		||||
$STD ./install-bunkerweb.sh --yes
 | 
			
		||||
$STD apt-mark unhold bunkerweb nginx
 | 
			
		||||
cat <<EOF >/etc/apt/preferences.d/bunkerweb
 | 
			
		||||
Package: bunkerweb
 | 
			
		||||
Pin: version ${RELEASE}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,22 +17,8 @@ msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y rsync
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Azul Zulu"
 | 
			
		||||
curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" -o "/etc/apt/trusted.gpg.d/zulu-repo.asc"
 | 
			
		||||
curl -fsSL "https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb" -o "zulu-repo_1.0.0-3_all.deb"
 | 
			
		||||
$STD dpkg -i zulu-repo_1.0.0-3_all.deb
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get -y install zulu17-jdk
 | 
			
		||||
msg_ok "Installed Azul Zulu"
 | 
			
		||||
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/Athou/commafeed/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
 | 
			
		||||
msg_info "Installing CommaFeed ${RELEASE}"
 | 
			
		||||
mkdir /opt/commafeed
 | 
			
		||||
curl -fsSL "https://github.com/Athou/commafeed/releases/download/${RELEASE}/commafeed-${RELEASE}-h2-jvm.zip" -o "commafeed-${RELEASE}-h2-jvm.zip"
 | 
			
		||||
$STD unzip commafeed-${RELEASE}-h2-jvm.zip
 | 
			
		||||
mv commafeed-${RELEASE}-h2/* /opt/commafeed/
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Installed CommaFeed ${RELEASE}"
 | 
			
		||||
JAVA_VERSION="17" setup_java
 | 
			
		||||
fetch_and_deploy_gh_release "commafeed" "Athou/commafeed" "prebuild" "latest" "/opt/commafeed" "commafeed-*-h2-jvm.zip"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/commafeed.service
 | 
			
		||||
@@ -55,7 +41,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf commafeed-${RELEASE}-h2 commafeed-${RELEASE}-h2-jvm.zip zulu-repo_1.0.0-3_all.deb
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,17 @@ echo -e '{\n  "log-driver": "journald"\n}' >/etc/docker/daemon.json
 | 
			
		||||
$STD sh <(curl -fsSL https://get.docker.com)
 | 
			
		||||
msg_ok "Installed Docker $DOCKER_LATEST_VERSION"
 | 
			
		||||
 | 
			
		||||
read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt
 | 
			
		||||
read -r -p "${TAB3}Install Docker Compose v2 plugin? <y/N> " prompt_compose
 | 
			
		||||
if [[ ${prompt_compose,,} =~ ^(y|yes)$ ]]; then
 | 
			
		||||
  msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
 | 
			
		||||
  mkdir -p /usr/local/lib/docker/cli-plugins
 | 
			
		||||
  curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_LATEST_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
 | 
			
		||||
    -o /usr/local/lib/docker/cli-plugins/docker-compose
 | 
			
		||||
  chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
 | 
			
		||||
  msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
read -r -p "${TAB3}Would you like to add Portainer (UI)? <y/N> " prompt
 | 
			
		||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
 | 
			
		||||
  msg_info "Installing Portainer $PORTAINER_LATEST_VERSION"
 | 
			
		||||
  docker volume create portainer_data >/dev/null
 | 
			
		||||
@@ -43,9 +53,9 @@ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
 | 
			
		||||
    portainer/portainer-ce:latest
 | 
			
		||||
  msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION"
 | 
			
		||||
else
 | 
			
		||||
  read -r -p "${TAB3}Would you like to add the Portainer Agent? <y/N> " prompt
 | 
			
		||||
  if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
 | 
			
		||||
    msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION"
 | 
			
		||||
  read -r -p "${TAB3}Would you like to install the Portainer Agent (for remote management)? <y/N> " prompt_agent
 | 
			
		||||
  if [[ ${prompt_agent,,} =~ ^(y|yes)$ ]]; then
 | 
			
		||||
    msg_info "Installing Portainer Agent $PORTAINER_AGENT_LATEST_VERSION"
 | 
			
		||||
    $STD docker run -d \
 | 
			
		||||
      -p 9001:9001 \
 | 
			
		||||
      --name portainer_agent \
 | 
			
		||||
@@ -57,13 +67,42 @@ else
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
read -r -p "${TAB3}Would you like to expose the Docker TCP socket? <y/N> " prompt
 | 
			
		||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
 | 
			
		||||
  msg_info "Exposing Docker TCP socket"
 | 
			
		||||
  $STD mkdir -p /etc/docker
 | 
			
		||||
  $STD echo '{ "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"] }' > /etc/docker/daemon.json
 | 
			
		||||
  $STD rc-service docker restart
 | 
			
		||||
  msg_ok "Exposed Docker TCP socket at tcp://+:2375"
 | 
			
		||||
read -r -p "${TAB3}Expose Docker TCP socket (insecure) ? [n = No, l = Local only (127.0.0.1), a = All interfaces (0.0.0.0)] <n/l/a>: " socket_choice
 | 
			
		||||
case "${socket_choice,,}" in
 | 
			
		||||
  l)
 | 
			
		||||
    socket="tcp://127.0.0.1:2375"
 | 
			
		||||
    ;;
 | 
			
		||||
  a)
 | 
			
		||||
    socket="tcp://0.0.0.0:2375"
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    socket=""
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
if [[ -n "$socket" ]]; then
 | 
			
		||||
  msg_info "Enabling Docker TCP socket on $socket"
 | 
			
		||||
  $STD apt-get install -y jq
 | 
			
		||||
 | 
			
		||||
  tmpfile=$(mktemp)
 | 
			
		||||
  jq --arg sock "$socket" '. + { "hosts": ["unix:///var/run/docker.sock", $sock] }' /etc/docker/daemon.json > "$tmpfile" && mv "$tmpfile" /etc/docker/daemon.json
 | 
			
		||||
 | 
			
		||||
  mkdir -p /etc/systemd/system/docker.service.d
 | 
			
		||||
  cat <<EOF > /etc/systemd/system/docker.service.d/override.conf
 | 
			
		||||
[Service]
 | 
			
		||||
ExecStart=
 | 
			
		||||
ExecStart=/usr/bin/dockerd
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
  $STD systemctl daemon-reexec
 | 
			
		||||
  $STD systemctl daemon-reload
 | 
			
		||||
 | 
			
		||||
  if systemctl restart docker; then
 | 
			
		||||
    msg_ok "Docker TCP socket available on $socket"
 | 
			
		||||
  else
 | 
			
		||||
    msg_error "Docker failed to restart. Check journalctl -xeu docker.service"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs
 | 
			
		||||
PG_VERSION="16" setup_postgresql
 | 
			
		||||
fetch_and_deploy_gh_release "docmost" "docmost/docmost"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up PostgreSQL"
 | 
			
		||||
DB_NAME="docmost_db"
 | 
			
		||||
@@ -40,12 +41,7 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
 | 
			
		||||
} >>~/docmost.creds
 | 
			
		||||
msg_ok "Set up PostgreSQL"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Docmost (Patience)"
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/docmost/docmost/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
curl -fsSL "https://github.com/docmost/docmost/archive/refs/tags/v${RELEASE}.tar.gz" -o ""$temp_file""
 | 
			
		||||
tar -xzf "$temp_file"
 | 
			
		||||
mv docmost-${RELEASE} /opt/docmost
 | 
			
		||||
msg_info "Configuring Docmost (Patience)"
 | 
			
		||||
cd /opt/docmost
 | 
			
		||||
mv .env.example .env
 | 
			
		||||
mkdir data
 | 
			
		||||
@@ -56,8 +52,7 @@ sed -i -e "s|APP_SECRET=.*|APP_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z
 | 
			
		||||
export NODE_OPTIONS="--max-old-space-size=2048"
 | 
			
		||||
$STD pnpm install
 | 
			
		||||
$STD pnpm build
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed Docmost"
 | 
			
		||||
msg_ok "Configured Docmost"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/docmost.service
 | 
			
		||||
@@ -81,7 +76,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f "$temp_file"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -24,17 +24,15 @@ if [[ "$CTTYPE" == "0" ]]; then
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Set Up Hardware Acceleration"
 | 
			
		||||
 | 
			
		||||
LATEST=$(curl -fsSL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
 | 
			
		||||
fetch_and_deploy_gh_release "emby" "MediaBrowser/Emby.Releases" "binary"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Emby"
 | 
			
		||||
curl -fsSL "https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb" -o "emby-server-deb_${LATEST}_amd64.deb"
 | 
			
		||||
$STD dpkg -i emby-server-deb_${LATEST}_amd64.deb
 | 
			
		||||
msg_info "Configuring Emby"
 | 
			
		||||
if [[ "$CTTYPE" == "0" ]]; then
 | 
			
		||||
  sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,emby/' -e 's/^render:x:108:root,emby$/ssl-cert:x:108:/' /etc/group
 | 
			
		||||
else
 | 
			
		||||
  sed -i -e 's/^ssl-cert:x:104:$/render:x:104:emby/' -e 's/^render:x:108:emby$/ssl-cert:x:108:/' /etc/group
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Installed Emby"
 | 
			
		||||
msg_ok "Configured Emby"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
@@ -42,5 +40,4 @@ customize
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
rm emby-server-deb_${LATEST}_amd64.deb
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,16 +13,39 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing dependencies"
 | 
			
		||||
$STD apt-get install -y ca-certificates
 | 
			
		||||
msg_ok "Installed dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Fetching latest EMQX Enterprise version"
 | 
			
		||||
LATEST_VERSION=$(curl -fsSL https://www.emqx.com/en/downloads/enterprise | grep -oP '/en/downloads/enterprise/v\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n1)
 | 
			
		||||
if [[ -z "$LATEST_VERSION" ]]; then
 | 
			
		||||
  msg_error "Failed to determine latest EMQX version"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Latest version: v$LATEST_VERSION"
 | 
			
		||||
 | 
			
		||||
DOWNLOAD_URL="https://www.emqx.com/en/downloads/enterprise/v$LATEST_VERSION/emqx-enterprise-${LATEST_VERSION}-debian12-amd64.deb"
 | 
			
		||||
DEB_FILE="/tmp/emqx-enterprise-${LATEST_VERSION}-debian12-amd64.deb"
 | 
			
		||||
 | 
			
		||||
msg_info "Downloading EMQX v$LATEST_VERSION"
 | 
			
		||||
$STD curl -fsSL -o "$DEB_FILE" "$DOWNLOAD_URL"
 | 
			
		||||
msg_ok "Downloaded EMQX"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing EMQX"
 | 
			
		||||
$STD bash <(curl -fsSL https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh)
 | 
			
		||||
$STD apt-get install -y emqx
 | 
			
		||||
$STD systemctl enable --now emqx
 | 
			
		||||
$STD apt-get install -y "$DEB_FILE"
 | 
			
		||||
echo "$LATEST_VERSION" >~/.emqx
 | 
			
		||||
msg_ok "Installed EMQX"
 | 
			
		||||
 | 
			
		||||
msg_info "Starting EMQX service"
 | 
			
		||||
$STD systemctl enable -q --now emqx
 | 
			
		||||
msg_ok "Enabled EMQX service"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
apt-get autoremove >/dev/null
 | 
			
		||||
apt-get autoclean >/dev/null
 | 
			
		||||
rm -f "$DEB_FILE"
 | 
			
		||||
$STD apt-get autoremove
 | 
			
		||||
$STD apt-get autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,15 +13,7 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing FFmpeg (Patience)"
 | 
			
		||||
cd /usr/local/bin
 | 
			
		||||
curl -fsSL "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz" -o "ffmpeg-release-amd64-static.tar.xz"
 | 
			
		||||
$STD tar -xvf ffmpeg-release-amd64-static.tar.xz
 | 
			
		||||
rm -f ffmpeg-*.tar.xz
 | 
			
		||||
cd ffmpeg-*
 | 
			
		||||
mv ffmpeg ffprobe /usr/local/bin/
 | 
			
		||||
rm -rf /usr/local/bin/ffmpeg-*
 | 
			
		||||
msg_ok "Installed FFmpeg"
 | 
			
		||||
FFMPEG_VERSION="latest" FFMPEG_TYPE="medium" setup_ffmpeg
 | 
			
		||||
 | 
			
		||||
msg_info "Setting Up Hardware Acceleration"
 | 
			
		||||
$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
 | 
			
		||||
@@ -34,15 +26,7 @@ if [[ "$CTTYPE" == "0" ]]; then
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Set Up Hardware Acceleration"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing ErsatzTV"
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
cd /opt
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1)
 | 
			
		||||
curl -fsSL "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz" -o "$temp_file"
 | 
			
		||||
tar -xzf "$temp_file"
 | 
			
		||||
mv /opt/ErsatzTV-${RELEASE}-linux-x64 /opt/ErsatzTV
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed ErsatzTV"
 | 
			
		||||
fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/ersatzTV.service
 | 
			
		||||
@@ -53,8 +37,8 @@ After=multi-user.target
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
User=root
 | 
			
		||||
WorkingDirectory=/opt/ErsatzTV 
 | 
			
		||||
ExecStart=/opt/ErsatzTV/ErsatzTV  
 | 
			
		||||
WorkingDirectory=/opt/ErsatzTV
 | 
			
		||||
ExecStart=/opt/ErsatzTV/ErsatzTV
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=30
 | 
			
		||||
 | 
			
		||||
@@ -68,7 +52,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f ${temp_file}
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,21 +14,15 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  xdg-utils
 | 
			
		||||
$STD apt-get install -y xdg-utils
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
fetch_and_deploy_gh_release "excalidraw" "excalidraw/excalidraw"
 | 
			
		||||
 | 
			
		||||
msg_info "Setup Excalidraw"
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/excalidraw/excalidraw/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
curl -fsSL "https://github.com/excalidraw/excalidraw/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
tar xzf $temp_file
 | 
			
		||||
mv excalidraw-${RELEASE} /opt/excalidraw
 | 
			
		||||
msg_info "Configuring Excalidraw"
 | 
			
		||||
cd /opt/excalidraw
 | 
			
		||||
$STD yarn
 | 
			
		||||
echo "${RELEASE}" >/opt/excalidraw_version.txt
 | 
			
		||||
msg_ok "Setup Excalidraw"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
@@ -53,7 +47,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f $temp_file
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,17 +14,14 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
curl -fsSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
 | 
			
		||||
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bookworm main" >/etc/apt/sources.list.d/php.list
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apache2 \
 | 
			
		||||
  libapache2-mod-php8.4 \
 | 
			
		||||
  php8.4-{bcmath,cli,intl,curl,zip,gd,xml,mbstring,mysql} \
 | 
			
		||||
  composer
 | 
			
		||||
$STD apt-get install -y apache2
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="mysql" setup_php
 | 
			
		||||
setup_composer
 | 
			
		||||
setup_mariadb
 | 
			
		||||
fetch_and_deploy_gh_release "firefly" "firefly-iii/firefly-iii"
 | 
			
		||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up database"
 | 
			
		||||
DB_NAME=firefly
 | 
			
		||||
@@ -41,13 +38,7 @@ mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRI
 | 
			
		||||
} >>~/firefly.creds
 | 
			
		||||
msg_ok "Set up database"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Firefly III (Patience)"
 | 
			
		||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/firefly-iii/firefly-iii/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}')
 | 
			
		||||
cd /opt
 | 
			
		||||
curl -fsSL "https://github.com/firefly-iii/firefly-iii/releases/download/v${RELEASE}/FireflyIII-v${RELEASE}.tar.gz" -o "FireflyIII-v${RELEASE}.tar.gz"
 | 
			
		||||
mkdir -p /opt/firefly
 | 
			
		||||
tar -xzf FireflyIII-v${RELEASE}.tar.gz -C /opt/firefly
 | 
			
		||||
msg_info "Configuring Firefly III (Patience)"
 | 
			
		||||
chown -R www-data:www-data /opt/firefly
 | 
			
		||||
chmod -R 775 /opt/firefly/storage
 | 
			
		||||
cd /opt/firefly
 | 
			
		||||
@@ -69,8 +60,7 @@ tar -xzf "DataImporter-v${IMPORTER_RELEASE}.tar.gz" -C /opt/firefly/dataimporter
 | 
			
		||||
cp /opt/firefly/dataimporter/.env.example /opt/firefly/dataimporter/.env
 | 
			
		||||
sed -i "s#FIREFLY_III_URL=#FIREFLY_III_URL=http://${LOCAL_IP}#g" /opt/firefly/dataimporter/.env
 | 
			
		||||
chown -R www-data:www-data /opt/firefly
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed Firefly III"
 | 
			
		||||
msg_ok "Configured Firefly III"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/apache2/sites-available/firefly.conf
 | 
			
		||||
@@ -112,7 +102,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf "/opt/FireflyIII-v${RELEASE}.tar.gz"
 | 
			
		||||
rm -rf "/opt/DataImporter-v${IMPORTER_RELEASE}.tar.gz"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,9 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y apt-transport-https
 | 
			
		||||
$STD apt-get install -y xvfb
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apt-transport-https \
 | 
			
		||||
  xvfb
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Chrome"
 | 
			
		||||
@@ -26,13 +27,7 @@ $STD apt update
 | 
			
		||||
$STD apt install -y google-chrome-stable
 | 
			
		||||
msg_ok "Installed Chrome"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing FlareSolverr"
 | 
			
		||||
RELEASE=$(curl -fsSL https://github.com/FlareSolverr/FlareSolverr/releases/latest | grep "title>Release" | cut -d " " -f 4)
 | 
			
		||||
$STD curl -fsSL "https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz" -o "flaresolverr_linux_x64.tar.gz"
 | 
			
		||||
$STD tar -xzf flaresolverr_linux_x64.tar.gz -C /opt
 | 
			
		||||
$STD rm flaresolverr_linux_x64.tar.gz
 | 
			
		||||
echo "${RELEASE}" >/opt/"${APPLICATION}"_version.txt
 | 
			
		||||
msg_ok "Installed FlareSolverr"
 | 
			
		||||
fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/flaresolverr.service
 | 
			
		||||
 
 | 
			
		||||
@@ -14,17 +14,11 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  zip \
 | 
			
		||||
  postgresql-common
 | 
			
		||||
$STD apt-get install -y zip
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Additional Dependencies"
 | 
			
		||||
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
 | 
			
		||||
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list
 | 
			
		||||
echo "YES" | /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh &>/dev/null
 | 
			
		||||
$STD apt-get install -y postgresql-17 nodejs
 | 
			
		||||
msg_ok "Installed Additional Dependencies"
 | 
			
		||||
PG_VERSION="17" setup_postgresql
 | 
			
		||||
NODE_VERSION="20" setup_nodejs
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Postgresql Database"
 | 
			
		||||
DB_NAME="fluiddb"
 | 
			
		||||
@@ -44,14 +38,9 @@ $STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;"
 | 
			
		||||
} >>~/$APPLICATION.creds
 | 
			
		||||
msg_ok "Set up Postgresql Database"
 | 
			
		||||
 | 
			
		||||
msg_info "Setup ${APPLICATION}"
 | 
			
		||||
tmp_file=$(mktemp)
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/dotnetfactory/fluid-calendar/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
curl -fsSL "https://github.com/dotnetfactory/fluid-calendar/archive/refs/tags/v${RELEASE}.zip" -o "$tmp_file"
 | 
			
		||||
$STD unzip $tmp_file
 | 
			
		||||
mv ${APPLICATION}-${RELEASE}/ /opt/${APPLICATION}
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
fetch_and_deploy_gh_release "fluid-calendar" "dotnetfactory/fluid-calendar"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring ${APPLICATION}"
 | 
			
		||||
cat <<EOF >/opt/fluid-calendar/.env
 | 
			
		||||
DATABASE_URL="postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}"
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +61,7 @@ $STD npm install --legacy-peer-deps
 | 
			
		||||
$STD npm run prisma:generate
 | 
			
		||||
$STD npx prisma migrate deploy
 | 
			
		||||
$STD npm run build:os
 | 
			
		||||
msg_ok "Setup ${APPLICATION}"
 | 
			
		||||
msg_ok "Configuring ${APPLICATION}"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/fluid-calendar.service
 | 
			
		||||
@@ -95,7 +84,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f $tmp_file
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,13 +13,7 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apache2 \
 | 
			
		||||
  php-{curl,dom,json,ctype,pgsql,gmp,mbstring,iconv,zip} \
 | 
			
		||||
  libapache2-mod-php
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PHP_VERSION="8.2" PHP_MODULE="curl,xml,mbstring,intl,zip,pgsql,gmp" PHP_APACHE="YES" setup_php
 | 
			
		||||
PG_VERSION="16" setup_postgresql
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up PostgreSQL"
 | 
			
		||||
@@ -36,17 +30,14 @@ $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMP
 | 
			
		||||
} >>~/freshrss.creds
 | 
			
		||||
msg_ok "Set up PostgreSQL"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing FreshRSS"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/FreshRSS/FreshRSS/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
cd /opt
 | 
			
		||||
curl -fsSL "https://github.com/FreshRSS/FreshRSS/archive/refs/tags/${RELEASE}.zip" -o "${RELEASE}.zip"
 | 
			
		||||
$STD unzip "${RELEASE}.zip"
 | 
			
		||||
mv "/opt/FreshRSS-${RELEASE}" /opt/freshrss
 | 
			
		||||
fetch_and_deploy_gh_release "freshrss" "FreshRSS/FreshRSS"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring FreshRSS"
 | 
			
		||||
cd /opt/freshrss
 | 
			
		||||
chown -R www-data:www-data /opt/freshrss
 | 
			
		||||
chmod -R g+rX /opt/freshrss
 | 
			
		||||
chmod -R g+w /opt/freshrss/data/
 | 
			
		||||
msg_ok "Installed FreshRSS"
 | 
			
		||||
msg_ok "Configured FreshRSS"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up cron job for feed refresh"
 | 
			
		||||
cat <<EOF >/etc/cron.d/freshrss-actualize
 | 
			
		||||
@@ -83,7 +74,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf "/opt/${RELEASE}.zip"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -20,20 +20,15 @@ $STD apt-get install -y \
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
setup_go
 | 
			
		||||
fetch_and_deploy_gh_release "gatus" "TwiN/gatus"
 | 
			
		||||
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/TwiN/gatus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
msg_info "Setting up gatus v${RELEASE}"
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
mkdir -p /opt/gatus
 | 
			
		||||
curl -fsSL "https://github.com/TwiN/gatus/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
tar zxf "$temp_file" --strip-components=1 -C /opt/gatus
 | 
			
		||||
msg_info "Configuring gatus"
 | 
			
		||||
cd /opt/gatus
 | 
			
		||||
$STD go mod tidy
 | 
			
		||||
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gatus .
 | 
			
		||||
setcap CAP_NET_RAW+ep gatus
 | 
			
		||||
mv config.yaml config
 | 
			
		||||
echo "${RELEASE}" >/opt/gatus_version.txt
 | 
			
		||||
msg_ok "Done setting up gatus"
 | 
			
		||||
msg_ok "Configured gatus"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/gatus.service
 | 
			
		||||
@@ -58,10 +53,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f "$temp_file"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 
 | 
			
		||||
@@ -16,19 +16,19 @@ update_os
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  nginx \
 | 
			
		||||
  ca-certificates
 | 
			
		||||
  ca-certificates \
 | 
			
		||||
  libjemalloc2
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
setup_mariadb
 | 
			
		||||
setup_mysql
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Database"
 | 
			
		||||
DB_NAME=ghost
 | 
			
		||||
DB_USER=ghostuser
 | 
			
		||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
 | 
			
		||||
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME;"
 | 
			
		||||
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
 | 
			
		||||
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
 | 
			
		||||
 | 
			
		||||
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
 | 
			
		||||
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
 | 
			
		||||
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
 | 
			
		||||
{
 | 
			
		||||
  echo "Ghost-Credentials"
 | 
			
		||||
  echo "Ghost Database User: $DB_USER"
 | 
			
		||||
@@ -37,7 +37,7 @@ $STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUS
 | 
			
		||||
} >>~/ghost.creds
 | 
			
		||||
msg_ok "Configured MySQL"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="20" setup_nodejs
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Ghost CLI"
 | 
			
		||||
$STD npm install ghost-cli@latest -g
 | 
			
		||||
 
 | 
			
		||||
@@ -19,10 +19,9 @@ $STD apt-get install -y git
 | 
			
		||||
$STD apt-get install -y sqlite3
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Gitea"
 | 
			
		||||
RELEASE=$(curl -fsSL https://github.com/go-gitea/gitea/releases/latest | grep "title>Release" | cut -d " " -f 4 | sed 's/^v//')
 | 
			
		||||
curl -fsSL "https://github.com/go-gitea/gitea/releases/download/v$RELEASE/gitea-$RELEASE-linux-amd64" -o "gitea-$RELEASE-linux-amd64"
 | 
			
		||||
mv gitea* /usr/local/bin/gitea
 | 
			
		||||
fetch_and_deploy_gh_release "gitea" "go-gitea/gitea" "singlefile" "latest" "/usr/local/bin" "gitea-*-linux-amd64"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Gitea"
 | 
			
		||||
chmod +x /usr/local/bin/gitea
 | 
			
		||||
adduser --system --group --disabled-password --shell /bin/bash --home /etc/gitea gitea >/dev/null
 | 
			
		||||
mkdir -p /var/lib/gitea/{custom,data,log}
 | 
			
		||||
@@ -31,7 +30,7 @@ chmod -R 750 /var/lib/gitea/
 | 
			
		||||
chown root:gitea /etc/gitea
 | 
			
		||||
chmod 770 /etc/gitea
 | 
			
		||||
sudo -u gitea ln -s /var/lib/gitea/data/.ssh/ /etc/gitea/.ssh
 | 
			
		||||
msg_ok "Installed Gitea"
 | 
			
		||||
msg_ok "Configured Gitea"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/gitea.service
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: CrazyWolf13
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/arunavo4/gitea-mirror
 | 
			
		||||
# Source: https://github.com/RayLabsHQ/gitea-mirror
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
@@ -28,7 +28,7 @@ ln -sf /opt/bun/bin/bun /usr/local/bin/bun
 | 
			
		||||
ln -sf /opt/bun/bin/bun /usr/local/bin/bunx
 | 
			
		||||
msg_ok "Installed Bun"
 | 
			
		||||
 | 
			
		||||
fetch_and_deploy_gh_release "gitea-mirror" "arunavo4/gitea-mirror"
 | 
			
		||||
fetch_and_deploy_gh_release "gitea-mirror" "RayLabsHQ/gitea-mirror"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing gitea-mirror"
 | 
			
		||||
cd /opt/gitea-mirror
 | 
			
		||||
 
 | 
			
		||||
@@ -13,12 +13,9 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Glance"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/glanceapp/glance/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
cd /opt
 | 
			
		||||
curl -fsSL "https://github.com/glanceapp/glance/releases/download/v${RELEASE}/glance-linux-amd64.tar.gz" -o "glance-linux-amd64.tar.gz"
 | 
			
		||||
mkdir -p /opt/glance
 | 
			
		||||
tar -xzf glance-linux-amd64.tar.gz -C /opt/glance
 | 
			
		||||
fetch_and_deploy_gh_release "glance" "glanceapp/glance" "prebuild" "latest" "/opt/glance" "glance-linux-amd64.tar.gz"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Glance"
 | 
			
		||||
cat <<EOF >/opt/glance/glance.yml
 | 
			
		||||
pages:
 | 
			
		||||
  - name: Startpage
 | 
			
		||||
@@ -39,9 +36,7 @@ pages:
 | 
			
		||||
                  - title: Helper Scripts
 | 
			
		||||
                    url: https://github.com/community-scripts/ProxmoxVE
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed Glance"
 | 
			
		||||
msg_ok "Configured Glance"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
service_path="/etc/systemd/system/glance.service"
 | 
			
		||||
@@ -67,7 +62,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf /opt/glance-linux-amd64.tar.gz
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -22,18 +22,16 @@ curl -fsSL "http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1
 | 
			
		||||
$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="20" setup_nodejs
 | 
			
		||||
NODE_VERSION="20" NODE_MODULE="gulp-cli,mocha" setup_nodejs
 | 
			
		||||
fetch_and_deploy_gh_release "habitica" "HabitRPG/habitica" "tarball" "latest" "/opt/habitica"
 | 
			
		||||
 | 
			
		||||
msg_info "Setup ${APPLICATION}"
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/HabitRPG/habitica/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
curl -fsSL "https://github.com/HabitRPG/habitica/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
tar zxf $temp_file
 | 
			
		||||
mv habitica-${RELEASE}/ /opt/habitica
 | 
			
		||||
cd /opt/habitica
 | 
			
		||||
$STD npm i
 | 
			
		||||
$STD npm run postinstall
 | 
			
		||||
$STD npm run client:build
 | 
			
		||||
$STD gulp build:prod
 | 
			
		||||
cp config.json.example config.json
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Setup ${APPLICATION}"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
@@ -91,7 +89,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f $temp_file
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,7 @@ $STD apt-get install --no-install-recommends -y \
 | 
			
		||||
  mesa-vulkan-drivers \
 | 
			
		||||
  ocl-icd-libopencl1 \
 | 
			
		||||
  tini \
 | 
			
		||||
  libaom-dev \
 | 
			
		||||
  zlib1g
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  libgdk-pixbuf-2.0-dev librsvg2-dev libtool
 | 
			
		||||
@@ -153,7 +154,6 @@ if [[ -f ~/.openvino ]]; then
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Packages from Testing Repo Installed"
 | 
			
		||||
 | 
			
		||||
# Fix default DB collation issue after libc update
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER DATABASE postgres REFRESH COLLATION VERSION;"
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER DATABASE $DB_NAME REFRESH COLLATION VERSION;"
 | 
			
		||||
 | 
			
		||||
@@ -218,7 +218,7 @@ $STD cmake --preset=release-noplugins \
 | 
			
		||||
  -DWITH_LIBSHARPYUV=ON \
 | 
			
		||||
  -DWITH_LIBDE265=ON \
 | 
			
		||||
  -DWITH_AOM_DECODER=OFF \
 | 
			
		||||
  -DWITH_AOM_ENCODER=OFF \
 | 
			
		||||
  -DWITH_AOM_ENCODER=ON \
 | 
			
		||||
  -DWITH_X265=OFF \
 | 
			
		||||
  -DWITH_EXAMPLES=OFF \
 | 
			
		||||
  ..
 | 
			
		||||
@@ -254,7 +254,8 @@ $STD make clean
 | 
			
		||||
cd "$STAGING_DIR"
 | 
			
		||||
 | 
			
		||||
SOURCE=$SOURCE_DIR/libvips
 | 
			
		||||
: "${LIBVIPS_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libvips.json)}"
 | 
			
		||||
# : "${LIBVIPS_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libvips.json)}"
 | 
			
		||||
: "${LIBVIPS_REVISION:=8fa37a64547e392d3808eed8d72adab7e02b3d00}"
 | 
			
		||||
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
 | 
			
		||||
cd "$SOURCE"
 | 
			
		||||
$STD git reset --hard "$LIBVIPS_REVISION"
 | 
			
		||||
@@ -301,6 +302,10 @@ cd "$SRC_DIR"
 | 
			
		||||
cp -a server/{node_modules,dist,bin,resources,package.json,package-lock.json,start*.sh} "$APP_DIR"/
 | 
			
		||||
cp -a web/build "$APP_DIR"/www
 | 
			
		||||
cp LICENSE "$APP_DIR"
 | 
			
		||||
cd "$APP_DIR"
 | 
			
		||||
export SHARP_FORCE_GLOBAL_LIBVIPS=true
 | 
			
		||||
$STD npm install sharp
 | 
			
		||||
rm -rf "$APP_DIR"/node_modules/@img/sharp-{libvips*,linuxmusl-x64}
 | 
			
		||||
msg_ok "Installed Immich Web Components"
 | 
			
		||||
 | 
			
		||||
cd "$SRC_DIR"/machine-learning
 | 
			
		||||
@@ -331,8 +336,6 @@ ln -s "$UPLOAD_DIR" "$APP_DIR"/upload
 | 
			
		||||
ln -s "$UPLOAD_DIR" "$ML_DIR"/upload
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Immich CLI"
 | 
			
		||||
$STD npm install --build-from-source sharp
 | 
			
		||||
rm -rf "$APP_DIR"/node_modules/@img/sharp-{libvips*,linuxmusl-x64}
 | 
			
		||||
$STD npm i -g @immich/cli
 | 
			
		||||
msg_ok "Installed Immich CLI"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -45,12 +45,12 @@ fetch_and_deploy_gh_release "planka" "plankanban/planka" "prebuild" "latest" "/o
 | 
			
		||||
msg_info "Configuring PLANKA"
 | 
			
		||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
 | 
			
		||||
SECRET_KEY=$(openssl rand -hex 64)
 | 
			
		||||
cd /opt/planka/planka
 | 
			
		||||
cd /opt/planka
 | 
			
		||||
$STD npm install
 | 
			
		||||
cp .env.sample .env
 | 
			
		||||
sed -i "s#http://localhost:1337#http://$LOCAL_IP:1337#g" /opt/planka/planka/.env
 | 
			
		||||
sed -i "s#postgres@localhost#planka:$DB_PASS@localhost#g" /opt/planka/planka/.env
 | 
			
		||||
sed -i "s#notsecretkey#$SECRET_KEY#g" /opt/planka/planka/.env
 | 
			
		||||
sed -i "s#http://localhost:1337#http://$LOCAL_IP:1337#g" /opt/planka/.env
 | 
			
		||||
sed -i "s#postgres@localhost#planka:$DB_PASS@localhost#g" /opt/planka/.env
 | 
			
		||||
sed -i "s#notsecretkey#$SECRET_KEY#g" /opt/planka/.env
 | 
			
		||||
$STD npm run db:init
 | 
			
		||||
msg_ok "Configured PLANKA"
 | 
			
		||||
 | 
			
		||||
@@ -84,7 +84,7 @@ Description=planka Service
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
WorkingDirectory=/opt/planka/planka
 | 
			
		||||
WorkingDirectory=/opt/planka
 | 
			
		||||
ExecStart=/usr/bin/npm start --prod
 | 
			
		||||
Restart=always
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies (Patience)"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  git \
 | 
			
		||||
  automake \
 | 
			
		||||
  autoconf \
 | 
			
		||||
  libtool \
 | 
			
		||||
@@ -25,10 +24,26 @@ $STD apt-get install -y \
 | 
			
		||||
  make \
 | 
			
		||||
  g++ \
 | 
			
		||||
  unpaper \
 | 
			
		||||
  fonts-urw-base35 \
 | 
			
		||||
  qpdf \
 | 
			
		||||
  poppler-utils
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PYTHON_VERSION="3.12" setup_uv
 | 
			
		||||
JAVA_VERSION="21" setup_java
 | 
			
		||||
 | 
			
		||||
read -r -p "${TAB3}Do you want to Stirling-PDF with Login? (no/n = without Login) [Y/n] " response
 | 
			
		||||
response=${response,,} # Convert to lowercase
 | 
			
		||||
login_mode="false"
 | 
			
		||||
if [[ "$response" == "y" || "$response" == "yes" || -z "$response" ]]; then
 | 
			
		||||
  USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar"
 | 
			
		||||
  mv /opt/Stirling-PDF/Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar
 | 
			
		||||
  touch ~/.Stirling-PDF-login
 | 
			
		||||
  login_mode="true"
 | 
			
		||||
else
 | 
			
		||||
  USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF.jar"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
msg_info "Installing LibreOffice Components"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  libreoffice-writer \
 | 
			
		||||
@@ -37,32 +52,35 @@ $STD apt-get install -y \
 | 
			
		||||
  libreoffice-core \
 | 
			
		||||
  libreoffice-common \
 | 
			
		||||
  libreoffice-base-core \
 | 
			
		||||
  python3-uno
 | 
			
		||||
  libreoffice-script-provider-python \
 | 
			
		||||
  libreoffice-java-common \
 | 
			
		||||
  unoconv \
 | 
			
		||||
  pngquant \
 | 
			
		||||
  weasyprint
 | 
			
		||||
msg_ok "Installed LibreOffice Components"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Python Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
$STD pip3 install \
 | 
			
		||||
  uno \
 | 
			
		||||
mkdir -p /tmp/stirling-pdf
 | 
			
		||||
$STD uv venv /opt/.venv
 | 
			
		||||
export PATH="/opt/.venv/bin:$PATH"
 | 
			
		||||
source /opt/.venv/bin/activate
 | 
			
		||||
$STD uv pip install --upgrade pip
 | 
			
		||||
$STD uv pip install \
 | 
			
		||||
  opencv-python-headless \
 | 
			
		||||
  unoconv \
 | 
			
		||||
  pngquant \
 | 
			
		||||
  WeasyPrint
 | 
			
		||||
  ocrmypdf \
 | 
			
		||||
  pillow \
 | 
			
		||||
  pdf2image
 | 
			
		||||
 | 
			
		||||
$STD apt-get install -y python3-uno python3-pip
 | 
			
		||||
$STD pip3 install --break-system-packages unoserver
 | 
			
		||||
ln -sf /opt/.venv/bin/python3 /usr/local/bin/python3
 | 
			
		||||
ln -sf /opt/.venv/bin/pip /usr/local/bin/pip
 | 
			
		||||
msg_ok "Installed Python Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Azul Zulu"
 | 
			
		||||
curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9" -o "/etc/apt/trusted.gpg.d/zulu-repo.asc"
 | 
			
		||||
curl -fsSL "https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb" -o "/zulu-repo_1.0.0-3_all.deb"
 | 
			
		||||
$STD dpkg -i zulu-repo_1.0.0-3_all.deb
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get -y install zulu17-jdk
 | 
			
		||||
msg_ok "Installed Azul Zulu"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing JBIG2"
 | 
			
		||||
$STD git clone https://github.com/agl/jbig2enc /opt/jbig2enc
 | 
			
		||||
$STD curl -fsSL -o /tmp/jbig2enc.tar.gz https://github.com/agl/jbig2enc/archive/refs/tags/0.30.tar.gz
 | 
			
		||||
mkdir -p /opt/jbig2enc
 | 
			
		||||
tar -xzf /tmp/jbig2enc.tar.gz -C /opt/jbig2enc --strip-components=1
 | 
			
		||||
cd /opt/jbig2enc
 | 
			
		||||
$STD bash ./autogen.sh
 | 
			
		||||
$STD bash ./configure
 | 
			
		||||
@@ -74,23 +92,46 @@ msg_info "Installing Language Packs (Patience)"
 | 
			
		||||
$STD apt-get install -y 'tesseract-ocr-*'
 | 
			
		||||
msg_ok "Installed Language Packs"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Stirling-PDF (Additional Patience)"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
curl -fsSL "https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v${RELEASE}.tar.gz" -o "v${RELEASE}.tar.gz"
 | 
			
		||||
tar -xzf v${RELEASE}.tar.gz
 | 
			
		||||
cd Stirling-PDF-$RELEASE
 | 
			
		||||
chmod +x ./gradlew
 | 
			
		||||
$STD ./gradlew build
 | 
			
		||||
mkdir -p /opt/Stirling-PDF
 | 
			
		||||
touch /opt/Stirling-PDF/.env
 | 
			
		||||
mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/
 | 
			
		||||
mv scripts /opt/Stirling-PDF/
 | 
			
		||||
ln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar
 | 
			
		||||
ln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata
 | 
			
		||||
msg_ok "Installed Stirling-PDF"
 | 
			
		||||
msg_info "Creating Environment Variables"
 | 
			
		||||
cat <<EOF >/opt/Stirling-PDF/.env
 | 
			
		||||
# Java tuning
 | 
			
		||||
JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70"
 | 
			
		||||
JAVA_CUSTOM_OPTS=""
 | 
			
		||||
 | 
			
		||||
# LibreOffice
 | 
			
		||||
PATH=/opt/.venv/bin:/usr/lib/libreoffice/program:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 | 
			
		||||
UNO_PATH=/usr/lib/libreoffice/program
 | 
			
		||||
URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc
 | 
			
		||||
PYTHONPATH=/usr/lib/libreoffice/program:/opt/.venv/lib/python3.12/site-packages
 | 
			
		||||
LD_LIBRARY_PATH=/usr/lib/libreoffice/program
 | 
			
		||||
 | 
			
		||||
STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf
 | 
			
		||||
TMPDIR=/tmp/stirling-pdf
 | 
			
		||||
TEMP=/tmp/stirling-pdf
 | 
			
		||||
TMP=/tmp/stirling-pdf
 | 
			
		||||
 | 
			
		||||
# Paths
 | 
			
		||||
PATH=/opt/.venv/bin:/usr/lib/libreoffice/program:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
if [[ "$login_mode" == "true" ]]; then
 | 
			
		||||
  cat <<EOF >>/opt/Stirling-PDF/.env
 | 
			
		||||
# activate Login
 | 
			
		||||
DISABLE_ADDITIONAL_FEATURES=false
 | 
			
		||||
SECURITY_ENABLELOGIN=true
 | 
			
		||||
 | 
			
		||||
# login credentials
 | 
			
		||||
SECURITY_INITIALLOGIN_USERNAME=admin
 | 
			
		||||
SECURITY_INITIALLOGIN_PASSWORD=stirling
 | 
			
		||||
EOF
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Created Environment Variables"
 | 
			
		||||
 | 
			
		||||
msg_info "Refreshing Font Cache"
 | 
			
		||||
$STD fc-cache -fv
 | 
			
		||||
msg_ok "Font Cache Updated"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
# Create LibreOffice listener service
 | 
			
		||||
cat <<EOF >/etc/systemd/system/libreoffice-listener.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=LibreOffice Headless Listener Service
 | 
			
		||||
@@ -107,14 +148,6 @@ Restart=always
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
# Set up environment variables
 | 
			
		||||
cat <<EOF >/opt/Stirling-PDF/.env
 | 
			
		||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/libreoffice/program
 | 
			
		||||
UNO_PATH=/usr/lib/libreoffice/program
 | 
			
		||||
PYTHONPATH=/usr/lib/python3/dist-packages:/usr/lib/libreoffice/program
 | 
			
		||||
LD_LIBRARY_PATH=/usr/lib/libreoffice/program
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
cat <<EOF >/etc/systemd/system/stirlingpdf.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Stirling-PDF service
 | 
			
		||||
@@ -137,16 +170,32 @@ RestartSec=10
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
# Enable and start services
 | 
			
		||||
cat <<EOF >/etc/systemd/system/unoserver.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=UnoServer RPC Interface
 | 
			
		||||
After=libreoffice-listener.service
 | 
			
		||||
Requires=libreoffice-listener.service
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
ExecStart=/usr/local/bin/unoserver --port 2003 --interface 127.0.0.1
 | 
			
		||||
Restart=always
 | 
			
		||||
EnvironmentFile=/opt/Stirling-PDF/.env
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
systemctl enable -q --now libreoffice-listener
 | 
			
		||||
systemctl enable -q --now stirlingpdf
 | 
			
		||||
systemctl enable -q --now unoserver
 | 
			
		||||
msg_ok "Created Service"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf v${RELEASE}.tar.gz /zulu-repo_1.0.0-3_all.deb
 | 
			
		||||
rm -f /tmp/jbig2enc.tar.gz
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,16 +14,12 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y ffmpeg
 | 
			
		||||
$STD apt-get install -y vlc
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  ffmpeg \
 | 
			
		||||
  vlc
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Threadfin"
 | 
			
		||||
mkdir -p /opt/threadfin
 | 
			
		||||
curl -fsSL "https://github.com/Threadfin/Threadfin/releases/latest/download/Threadfin_linux_amd64" -o "/opt/threadfin/threadfin"
 | 
			
		||||
chmod +x /opt/threadfin/threadfin
 | 
			
		||||
 | 
			
		||||
msg_ok "Installed Threadfin"
 | 
			
		||||
fetch_and_deploy_gh_release "threadfin" "threadfin/threadfin" "singlefile" "latest" "/opt/threadfin" "Threadfin_linux_amd64"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/threadfin.service
 | 
			
		||||
 
 | 
			
		||||
@@ -1142,64 +1142,48 @@ EOF
 | 
			
		||||
 | 
			
		||||
    echo ""
 | 
			
		||||
    msg_custom "⚙️ " "\e[96m" "Configuring VAAPI passthrough for LXC container"
 | 
			
		||||
 | 
			
		||||
    if [ "$CT_TYPE" != "0" ]; then
 | 
			
		||||
      msg_custom "⚠️ " "\e[33m" "Container is unprivileged – VAAPI passthrough may not work without additional host configuration (e.g., idmap)."
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    msg_custom "ℹ️ " "\e[96m" "VAAPI enables GPU hardware acceleration (e.g., for video transcoding in Jellyfin or Plex)."
 | 
			
		||||
 | 
			
		||||
    echo ""
 | 
			
		||||
    read -rp "➤ Automatically mount all available VAAPI devices? [Y/n]: " VAAPI_ALL
 | 
			
		||||
 | 
			
		||||
    if [[ "$VAAPI_ALL" =~ ^[Yy]$|^$ ]]; then
 | 
			
		||||
      # Mount all devices automatically
 | 
			
		||||
      if [[ -e /dev/dri/renderD128 ]]; then
 | 
			
		||||
        echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG"
 | 
			
		||||
        echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG"
 | 
			
		||||
      fi
 | 
			
		||||
      if [[ -e /dev/dri/card0 ]]; then
 | 
			
		||||
        echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG"
 | 
			
		||||
 | 
			
		||||
        echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG"
 | 
			
		||||
      fi
 | 
			
		||||
      if [[ -e /dev/fb0 ]]; then
 | 
			
		||||
        echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG"
 | 
			
		||||
        echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG"
 | 
			
		||||
      fi
 | 
			
		||||
      if [[ -d /dev/dri ]]; then
 | 
			
		||||
        echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG"
 | 
			
		||||
      fi
 | 
			
		||||
    else
 | 
			
		||||
      # Manual selection per device
 | 
			
		||||
      if [[ -e /dev/dri/renderD128 ]]; then
 | 
			
		||||
        read -rp "➤ Mount /dev/dri/renderD128 (GPU rendering)? [y/N]: " MOUNT_D128
 | 
			
		||||
        if [[ "$MOUNT_D128" =~ ^[Yy]$ ]]; then
 | 
			
		||||
      if [ "$CT_TYPE" == "0" ]; then
 | 
			
		||||
        # PRV Container → alles zulässig
 | 
			
		||||
        [[ -e /dev/dri/renderD128 ]] && {
 | 
			
		||||
          echo "lxc.cgroup2.devices.allow: c 226:128 rwm" >>"$LXC_CONFIG"
 | 
			
		||||
          echo "lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file" >>"$LXC_CONFIG"
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      if [[ -e /dev/dri/card0 ]]; then
 | 
			
		||||
        read -rp "➤ Mount /dev/dri/card0 (GPU hardware interface)? [y/N]: " MOUNT_CARD0
 | 
			
		||||
        if [[ "$MOUNT_CARD0" =~ ^[Yy]$ ]]; then
 | 
			
		||||
        }
 | 
			
		||||
        [[ -e /dev/dri/card0 ]] && {
 | 
			
		||||
          echo "lxc.cgroup2.devices.allow: c 226:0 rwm" >>"$LXC_CONFIG"
 | 
			
		||||
          echo "lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file" >>"$LXC_CONFIG"
 | 
			
		||||
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      if [[ -e /dev/fb0 ]]; then
 | 
			
		||||
        read -rp "➤ Mount /dev/fb0 (Framebuffer, GUI)? [y/N]: " MOUNT_FB0
 | 
			
		||||
        if [[ "$MOUNT_FB0" =~ ^[Yy]$ ]]; then
 | 
			
		||||
        }
 | 
			
		||||
        [[ -e /dev/fb0 ]] && {
 | 
			
		||||
          echo "lxc.cgroup2.devices.allow: c 29:0 rwm" >>"$LXC_CONFIG"
 | 
			
		||||
          echo "lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file" >>"$LXC_CONFIG"
 | 
			
		||||
        fi
 | 
			
		||||
        }
 | 
			
		||||
        [[ -d /dev/dri ]] && {
 | 
			
		||||
          echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG"
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        # UNPRV Container → nur devX für UI
 | 
			
		||||
        [[ -e /dev/dri/card0 ]] && echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG"
 | 
			
		||||
        [[ -e /dev/dri/card1 ]] && echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG"
 | 
			
		||||
        [[ -e /dev/dri/renderD128 ]] && echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG"
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
      if [[ -d /dev/dri ]]; then
 | 
			
		||||
        echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG"
 | 
			
		||||
      fi
 | 
			
		||||
  fi
 | 
			
		||||
  if [ "$CT_TYPE" == "1" ] && [ "$is_vaapi_app" == "true" ]; then
 | 
			
		||||
    if [[ -e /dev/dri/card0 ]]; then
 | 
			
		||||
      echo "dev0: /dev/dri/card0,gid=44" >>"$LXC_CONFIG"
 | 
			
		||||
    elif [[ -e /dev/dri/card1 ]]; then
 | 
			
		||||
      echo "dev0: /dev/dri/card1,gid=44" >>"$LXC_CONFIG"
 | 
			
		||||
    fi
 | 
			
		||||
    if [[ -e /dev/dri/renderD128 ]]; then
 | 
			
		||||
      echo "dev1: /dev/dri/renderD128,gid=104" >>"$LXC_CONFIG"
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -355,7 +355,6 @@ msg_custom() {
 | 
			
		||||
  [[ -z "$msg" ]] && return
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}"
 | 
			
		||||
  printf "\r\033[K\e[?25h\n"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
run_container_safe() {
 | 
			
		||||
 
 | 
			
		||||
@@ -253,7 +253,7 @@ fi
 | 
			
		||||
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating LXC Template List"
 | 
			
		||||
if ! timeout 15 pveam update >/dev/null 2>&1; then
 | 
			
		||||
if ! pveam update >/dev/null 2>&1; then
 | 
			
		||||
  TEMPLATE_FALLBACK=$(pveam list "$TEMPLATE_STORAGE" | awk "/$TEMPLATE_SEARCH/ {print \$2}" | sort -t - -k 2 -V | tail -n1)
 | 
			
		||||
  if [[ -z "$TEMPLATE_FALLBACK" ]]; then
 | 
			
		||||
    msg_error "Failed to update LXC template list and no local template matching '$TEMPLATE_SEARCH' found."
 | 
			
		||||
@@ -284,7 +284,7 @@ if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLAT
 | 
			
		||||
  for attempt in {1..3}; do
 | 
			
		||||
    msg_info "Attempt $attempt: Downloading LXC template..."
 | 
			
		||||
 | 
			
		||||
    if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then
 | 
			
		||||
    if pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then
 | 
			
		||||
      msg_ok "Template download successful."
 | 
			
		||||
      break
 | 
			
		||||
    fi
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										247
									
								
								misc/tools.func
									
									
									
									
									
								
							
							
						
						
									
										247
									
								
								misc/tools.func
									
									
									
									
									
								
							@@ -54,9 +54,14 @@ function setup_nodejs() {
 | 
			
		||||
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" \
 | 
			
		||||
      >/etc/apt/sources.list.d/nodesource.list
 | 
			
		||||
 | 
			
		||||
    sleep 2
 | 
			
		||||
    if ! apt-get update >/dev/null 2>&1; then
 | 
			
		||||
      msg_error "Failed to update APT repositories after adding NodeSource"
 | 
			
		||||
      exit 1
 | 
			
		||||
      msg_warn "APT update failed – retrying in 5s"
 | 
			
		||||
      sleep 5
 | 
			
		||||
      if ! apt-get update >/dev/null 2>&1; then
 | 
			
		||||
        msg_error "Failed to update APT repositories after adding NodeSource"
 | 
			
		||||
        exit 1
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! apt-get install -y nodejs >/dev/null 2>&1; then
 | 
			
		||||
@@ -368,25 +373,6 @@ function setup_mysql() {
 | 
			
		||||
#   PHP_MAX_EXECUTION_TIME     - (default: 300)
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
# Installs PHP with selected modules and configures Apache/FPM support.
 | 
			
		||||
#
 | 
			
		||||
# Description:
 | 
			
		||||
#   - Adds Sury PHP repo if needed
 | 
			
		||||
#   - Installs default and user-defined modules
 | 
			
		||||
#   - Patches php.ini for CLI, Apache, and FPM as needed
 | 
			
		||||
#
 | 
			
		||||
# Variables:
 | 
			
		||||
#   PHP_VERSION                - PHP version to install (default: 8.4)
 | 
			
		||||
#   PHP_MODULE                 - Additional comma-separated modules
 | 
			
		||||
#   PHP_APACHE                 - Set YES to enable PHP with Apache
 | 
			
		||||
#   PHP_FPM                    - Set YES to enable PHP-FPM
 | 
			
		||||
#   PHP_MEMORY_LIMIT           - (default: 512M)
 | 
			
		||||
#   PHP_UPLOAD_MAX_FILESIZE    - (default: 128M)
 | 
			
		||||
#   PHP_POST_MAX_SIZE          - (default: 128M)
 | 
			
		||||
#   PHP_MAX_EXECUTION_TIME     - (default: 300)
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
function setup_php() {
 | 
			
		||||
  local PHP_VERSION="${PHP_VERSION:-8.4}"
 | 
			
		||||
  local PHP_MODULE="${PHP_MODULE:-}"
 | 
			
		||||
@@ -435,6 +421,13 @@ function setup_php() {
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  local MODULE_LIST="php${PHP_VERSION}"
 | 
			
		||||
  for pkg in $MODULE_LIST; do
 | 
			
		||||
    if ! apt-cache show "$pkg" >/dev/null 2>&1; then
 | 
			
		||||
      msg_error "Package not found: $pkg"
 | 
			
		||||
      exit 1
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  IFS=',' read -ra MODULES <<<"$COMBINED_MODULES"
 | 
			
		||||
  for mod in "${MODULES[@]}"; do
 | 
			
		||||
    MODULE_LIST+=" php${PHP_VERSION}-${mod}"
 | 
			
		||||
@@ -443,11 +436,17 @@ function setup_php() {
 | 
			
		||||
  if [[ "$PHP_FPM" == "YES" ]]; then
 | 
			
		||||
    MODULE_LIST+=" php${PHP_VERSION}-fpm"
 | 
			
		||||
  fi
 | 
			
		||||
  if [[ "$PHP_APACHE" == "YES" ]]; then
 | 
			
		||||
    $STD apt-get install -y apache2 libapache2-mod-php${PHP_VERSION}
 | 
			
		||||
    $STD systemctl restart apache2 || true
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [[ "$PHP_APACHE" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then
 | 
			
		||||
    if [[ -f /etc/apache2/mods-enabled/php${CURRENT_PHP}.load ]]; then
 | 
			
		||||
      $STD a2dismod php${CURRENT_PHP} || true
 | 
			
		||||
    fi
 | 
			
		||||
    $STD a2enmod php${PHP_VERSION}
 | 
			
		||||
    $STD systemctl restart apache2 || true
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [[ "$PHP_FPM" == "YES" ]] && [[ -n "$CURRENT_PHP" ]]; then
 | 
			
		||||
@@ -458,10 +457,6 @@ function setup_php() {
 | 
			
		||||
  $STD apt-get install -y $MODULE_LIST
 | 
			
		||||
  msg_ok "Setup PHP $PHP_VERSION"
 | 
			
		||||
 | 
			
		||||
  if [[ "$PHP_APACHE" == "YES" ]]; then
 | 
			
		||||
    $STD systemctl restart apache2 || true
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [[ "$PHP_FPM" == "YES" ]]; then
 | 
			
		||||
    $STD systemctl enable php${PHP_VERSION}-fpm
 | 
			
		||||
    $STD systemctl restart php${PHP_VERSION}-fpm
 | 
			
		||||
@@ -651,6 +646,15 @@ function setup_mongodb() {
 | 
			
		||||
  DISTRO_ID=$(awk -F= '/^ID=/{ gsub(/"/,"",$2); print $2 }' /etc/os-release)
 | 
			
		||||
  DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{ print $2 }' /etc/os-release)
 | 
			
		||||
 | 
			
		||||
  # Check AVX support
 | 
			
		||||
  if ! grep -qm1 'avx[^ ]*' /proc/cpuinfo; then
 | 
			
		||||
    local major="${MONGO_VERSION%%.*}"
 | 
			
		||||
    if ((major > 5)); then
 | 
			
		||||
      msg_error "MongoDB ${MONGO_VERSION} requires AVX support, which is not available on this system."
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  case "$DISTRO_ID" in
 | 
			
		||||
  ubuntu)
 | 
			
		||||
    MONGO_BASE_URL="https://repo.mongodb.org/apt/ubuntu"
 | 
			
		||||
@@ -899,7 +903,7 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ### Prebuild Mode ###
 | 
			
		||||
  ### Prebuild Mode ###
 | 
			
		||||
  elif [[ "$mode" == "prebuild" ]]; then
 | 
			
		||||
    local pattern="${6%\"}"
 | 
			
		||||
    pattern="${pattern#\"}"
 | 
			
		||||
@@ -918,7 +922,6 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
        break
 | 
			
		||||
        ;;
 | 
			
		||||
      esac
 | 
			
		||||
 | 
			
		||||
    done
 | 
			
		||||
 | 
			
		||||
    [[ -z "$asset_url" ]] && {
 | 
			
		||||
@@ -934,20 +937,42 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
      return 1
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    local unpack_tmp
 | 
			
		||||
    unpack_tmp=$(mktemp -d)
 | 
			
		||||
    mkdir -p "$target"
 | 
			
		||||
 | 
			
		||||
    if [[ "$filename" == *.zip ]]; then
 | 
			
		||||
      if ! command -v unzip &>/dev/null; then
 | 
			
		||||
        $STD apt-get install -y unzip
 | 
			
		||||
      fi
 | 
			
		||||
      $STD unzip "$tmpdir/$filename" -d "$target"
 | 
			
		||||
      unzip -q "$tmpdir/$filename" -d "$unpack_tmp"
 | 
			
		||||
    elif [[ "$filename" == *.tar.* ]]; then
 | 
			
		||||
      tar --strip-components=1 -xf "$tmpdir/$filename" -C "$target"
 | 
			
		||||
      tar -xf "$tmpdir/$filename" -C "$unpack_tmp"
 | 
			
		||||
    else
 | 
			
		||||
      msg_error "Unsupported archive format: $filename"
 | 
			
		||||
      rm -rf "$tmpdir"
 | 
			
		||||
      rm -rf "$tmpdir" "$unpack_tmp"
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    local top_dirs
 | 
			
		||||
    top_dirs=$(find "$unpack_tmp" -mindepth 1 -maxdepth 1 -type d | wc -l)
 | 
			
		||||
 | 
			
		||||
    if [[ "$top_dirs" -eq 1 ]]; then
 | 
			
		||||
      # Strip leading folder
 | 
			
		||||
      local inner_dir
 | 
			
		||||
      inner_dir=$(find "$unpack_tmp" -mindepth 1 -maxdepth 1 -type d)
 | 
			
		||||
      shopt -s dotglob nullglob
 | 
			
		||||
      cp -r "$inner_dir"/* "$target/"
 | 
			
		||||
      shopt -u dotglob nullglob
 | 
			
		||||
    else
 | 
			
		||||
      # Copy all contents
 | 
			
		||||
      shopt -s dotglob nullglob
 | 
			
		||||
      cp -r "$unpack_tmp"/* "$target/"
 | 
			
		||||
      shopt -u dotglob nullglob
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    rm -rf "$unpack_tmp"
 | 
			
		||||
 | 
			
		||||
    ### Singlefile Mode ###
 | 
			
		||||
  elif [[ "$mode" == "singlefile" ]]; then
 | 
			
		||||
    local pattern="${6%\"}"
 | 
			
		||||
@@ -977,13 +1002,20 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
 | 
			
		||||
    filename="${asset_url##*/}"
 | 
			
		||||
    mkdir -p "$target"
 | 
			
		||||
    curl $download_timeout -fsSL -o "$target/$app" "$asset_url" || {
 | 
			
		||||
 | 
			
		||||
    local use_filename="${USE_ORIGINAL_FILENAME:-false}"
 | 
			
		||||
    local target_file="$app"
 | 
			
		||||
    [[ "$use_filename" == "true" ]] && target_file="$filename"
 | 
			
		||||
 | 
			
		||||
    curl $download_timeout -fsSL -o "$target/$target_file" "$asset_url" || {
 | 
			
		||||
      msg_error "Download failed: $asset_url"
 | 
			
		||||
      rm -rf "$tmpdir"
 | 
			
		||||
      return 1
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    chmod +x "$target/$app"
 | 
			
		||||
    if [[ "$target_file" != *.jar && -f "$target/$target_file" ]]; then
 | 
			
		||||
      chmod +x "$target/$target_file"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
  else
 | 
			
		||||
    msg_error "Unknown mode: $mode"
 | 
			
		||||
@@ -1662,3 +1694,154 @@ function setup_imagemagick() {
 | 
			
		||||
  ensure_usr_local_bin_persist
 | 
			
		||||
  msg_ok "Setup ImageMagick $VERSION"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
# Installs FFmpeg from source or prebuilt binary (Debian/Ubuntu only).
 | 
			
		||||
#
 | 
			
		||||
# Description:
 | 
			
		||||
#   - Downloads and builds FFmpeg from GitHub (https://github.com/FFmpeg/FFmpeg)
 | 
			
		||||
#   - Supports specific version override via FFMPEG_VERSION (e.g. n7.1.1)
 | 
			
		||||
#   - Supports build profile via FFMPEG_TYPE:
 | 
			
		||||
#       - minimal : x264, vpx, mp3 only
 | 
			
		||||
#       - medium  : adds subtitles, fonts, opus, vorbis
 | 
			
		||||
#       - full    : adds dav1d, svt-av1, zlib, numa
 | 
			
		||||
#       - binary  : downloads static build (johnvansickle.com)
 | 
			
		||||
#   - Defaults to latest stable version and full feature set
 | 
			
		||||
#
 | 
			
		||||
# Notes:
 | 
			
		||||
#   - Requires: curl, jq, build-essential, and matching codec libraries
 | 
			
		||||
#   - Result is installed to /usr/local/bin/ffmpeg
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
function setup_ffmpeg() {
 | 
			
		||||
  local TMP_DIR
 | 
			
		||||
  TMP_DIR=$(mktemp -d)
 | 
			
		||||
  local GITHUB_REPO="FFmpeg/FFmpeg"
 | 
			
		||||
  local VERSION="${FFMPEG_VERSION:-latest}"
 | 
			
		||||
  local TYPE="${FFMPEG_TYPE:-full}"
 | 
			
		||||
  local BIN_PATH="/usr/local/bin/ffmpeg"
 | 
			
		||||
 | 
			
		||||
  # Binary fallback mode
 | 
			
		||||
  if [[ "$TYPE" == "binary" ]]; then
 | 
			
		||||
    msg_info "Installing FFmpeg (static binary)"
 | 
			
		||||
    curl -fsSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o "$TMP_DIR/ffmpeg.tar.xz"
 | 
			
		||||
    tar -xf "$TMP_DIR/ffmpeg.tar.xz" -C "$TMP_DIR"
 | 
			
		||||
    local EXTRACTED_DIR
 | 
			
		||||
    EXTRACTED_DIR=$(find "$TMP_DIR" -maxdepth 1 -type d -name "ffmpeg-*")
 | 
			
		||||
    cp "$EXTRACTED_DIR/ffmpeg" "$BIN_PATH"
 | 
			
		||||
    cp "$EXTRACTED_DIR/ffprobe" /usr/local/bin/ffprobe
 | 
			
		||||
    chmod +x "$BIN_PATH" /usr/local/bin/ffprobe
 | 
			
		||||
    rm -rf "$TMP_DIR"
 | 
			
		||||
    msg_ok "Installed FFmpeg binary ($($BIN_PATH -version | head -n1))"
 | 
			
		||||
    return
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if ! command -v jq &>/dev/null; then
 | 
			
		||||
    $STD apt-get update
 | 
			
		||||
    $STD apt-get install -y jq
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Auto-detect latest stable version if none specified
 | 
			
		||||
  if [[ "$VERSION" == "latest" || -z "$VERSION" ]]; then
 | 
			
		||||
    msg_info "Resolving latest FFmpeg tag"
 | 
			
		||||
    VERSION=$(curl -fsSL "https://api.github.com/repos/${GITHUB_REPO}/tags" |
 | 
			
		||||
      jq -r '.[].name' |
 | 
			
		||||
      grep -E '^n[0-9]+\.[0-9]+\.[0-9]+$' |
 | 
			
		||||
      sort -V | tail -n1)
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [[ -z "$VERSION" ]]; then
 | 
			
		||||
    msg_error "Could not determine FFmpeg version"
 | 
			
		||||
    rm -rf "$TMP_DIR"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Installing FFmpeg ${VERSION} ($TYPE)"
 | 
			
		||||
 | 
			
		||||
  # Dependency selection
 | 
			
		||||
  local DEPS=(build-essential yasm nasm pkg-config)
 | 
			
		||||
  case "$TYPE" in
 | 
			
		||||
  minimal)
 | 
			
		||||
    DEPS+=(libx264-dev libvpx-dev libmp3lame-dev)
 | 
			
		||||
    ;;
 | 
			
		||||
  medium)
 | 
			
		||||
    DEPS+=(libx264-dev libvpx-dev libmp3lame-dev libfreetype6-dev libass-dev libopus-dev libvorbis-dev)
 | 
			
		||||
    ;;
 | 
			
		||||
  full)
 | 
			
		||||
    DEPS+=(
 | 
			
		||||
      libx264-dev libx265-dev libvpx-dev libmp3lame-dev
 | 
			
		||||
      libfreetype6-dev libass-dev libopus-dev libvorbis-dev
 | 
			
		||||
      libdav1d-dev libsvtav1-dev zlib1g-dev libnuma-dev
 | 
			
		||||
    )
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    msg_error "Invalid FFMPEG_TYPE: $TYPE"
 | 
			
		||||
    rm -rf "$TMP_DIR"
 | 
			
		||||
    return 1
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  $STD apt-get update
 | 
			
		||||
  $STD apt-get install -y "${DEPS[@]}"
 | 
			
		||||
 | 
			
		||||
  curl -fsSL "https://github.com/${GITHUB_REPO}/archive/refs/tags/${VERSION}.tar.gz" -o "$TMP_DIR/ffmpeg.tar.gz"
 | 
			
		||||
  tar -xzf "$TMP_DIR/ffmpeg.tar.gz" -C "$TMP_DIR"
 | 
			
		||||
  cd "$TMP_DIR/FFmpeg-"* || {
 | 
			
		||||
    msg_error "Source extraction failed"
 | 
			
		||||
    rm -rf "$TMP_DIR"
 | 
			
		||||
    return 1
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  local args=(
 | 
			
		||||
    --enable-gpl
 | 
			
		||||
    --enable-shared
 | 
			
		||||
    --enable-nonfree
 | 
			
		||||
    --disable-static
 | 
			
		||||
    --enable-libx264
 | 
			
		||||
    --enable-libvpx
 | 
			
		||||
    --enable-libmp3lame
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  if [[ "$TYPE" != "minimal" ]]; then
 | 
			
		||||
    args+=(--enable-libfreetype --enable-libass --enable-libopus --enable-libvorbis)
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [[ "$TYPE" == "full" ]]; then
 | 
			
		||||
    args+=(--enable-libx265 --enable-libdav1d --enable-zlib)
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [[ ${#args[@]} -eq 0 ]]; then
 | 
			
		||||
    msg_error "FFmpeg configure args array is empty – aborting."
 | 
			
		||||
    rm -rf "$TMP_DIR"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  ./configure "${args[@]}" >"$TMP_DIR/configure.log" 2>&1 || {
 | 
			
		||||
    msg_error "FFmpeg ./configure failed (see $TMP_DIR/configure.log)"
 | 
			
		||||
    cat "$TMP_DIR/configure.log" | tail -n 20
 | 
			
		||||
    rm -rf "$TMP_DIR"
 | 
			
		||||
    return 1
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  $STD make -j"$(nproc)"
 | 
			
		||||
  $STD make install
 | 
			
		||||
  echo "/usr/local/lib" >/etc/ld.so.conf.d/ffmpeg.conf
 | 
			
		||||
  ldconfig
 | 
			
		||||
 | 
			
		||||
  ldconfig -p | grep libavdevice >/dev/null || {
 | 
			
		||||
    msg_error "libavdevice not registered with dynamic linker"
 | 
			
		||||
    return 1
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ! command -v ffmpeg &>/dev/null; then
 | 
			
		||||
    msg_error "FFmpeg installation failed"
 | 
			
		||||
    rm -rf "$TMP_DIR"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  local FINAL_VERSION
 | 
			
		||||
  FINAL_VERSION=$(ffmpeg -version | head -n1 | awk '{print $3}')
 | 
			
		||||
  rm -rf "$TMP_DIR"
 | 
			
		||||
  ensure_usr_local_bin_persist
 | 
			
		||||
  msg_ok "Setup FFmpeg $FINAL_VERSION"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -162,6 +162,21 @@ update_installation() {
 | 
			
		||||
  generate_service >/lib/systemd/system/iptag.service
 | 
			
		||||
  msg_ok "Updated service file"
 | 
			
		||||
 | 
			
		||||
  msg_info "Creating manual run command"
 | 
			
		||||
  cat <<'EOF' >/usr/local/bin/iptag-run
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
CONFIG_FILE="/opt/iptag/iptag.conf"
 | 
			
		||||
SCRIPT_FILE="/opt/iptag/iptag"
 | 
			
		||||
if [[ ! -f "$SCRIPT_FILE" ]]; then
 | 
			
		||||
  echo "❌ Main script not found: $SCRIPT_FILE"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
export FORCE_SINGLE_RUN=true
 | 
			
		||||
exec "$SCRIPT_FILE"
 | 
			
		||||
EOF
 | 
			
		||||
  chmod +x /usr/local/bin/iptag-run
 | 
			
		||||
  msg_ok "Created iptag-run executable - You can execute this manually by entering “iptag-run” in the Proxmox host, so the script is executed by hand."
 | 
			
		||||
 | 
			
		||||
  msg_info "Restarting service"
 | 
			
		||||
  systemctl daemon-reload &>/dev/null
 | 
			
		||||
  systemctl enable -q --now iptag.service &>/dev/null
 | 
			
		||||
@@ -194,18 +209,19 @@ LXC_STATUS_CHECK_INTERVAL=300
 | 
			
		||||
FORCE_UPDATE_INTERVAL=7200
 | 
			
		||||
 | 
			
		||||
# Performance optimizations
 | 
			
		||||
VM_IP_CACHE_TTL=120
 | 
			
		||||
MAX_PARALLEL_VM_CHECKS=5
 | 
			
		||||
VM_IP_CACHE_TTL=300
 | 
			
		||||
MAX_PARALLEL_VM_CHECKS=1
 | 
			
		||||
 | 
			
		||||
# LXC performance optimizations  
 | 
			
		||||
LXC_IP_CACHE_TTL=0
 | 
			
		||||
MAX_PARALLEL_LXC_CHECKS=7
 | 
			
		||||
LXC_IP_CACHE_TTL=300
 | 
			
		||||
MAX_PARALLEL_LXC_CHECKS=2
 | 
			
		||||
 | 
			
		||||
# Extreme LXC optimizations
 | 
			
		||||
LXC_BATCH_SIZE=20
 | 
			
		||||
LXC_STATUS_CACHE_TTL=30
 | 
			
		||||
LXC_BATCH_SIZE=3
 | 
			
		||||
LXC_STATUS_CACHE_TTL=300
 | 
			
		||||
LXC_AGGRESSIVE_CACHING=true
 | 
			
		||||
LXC_SKIP_SLOW_METHODS=true
 | 
			
		||||
LXC_ALLOW_FORCED_COMMANDS=false
 | 
			
		||||
 | 
			
		||||
# Debug settings (set to true to enable debugging)
 | 
			
		||||
DEBUG=false
 | 
			
		||||
@@ -222,8 +238,8 @@ After=network.target
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
ExecStart=/opt/iptag/iptag
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=1
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
RestartSec=10
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
@@ -576,7 +592,9 @@ update_tags() {
 | 
			
		||||
 | 
			
		||||
    if [[ "$type" == "lxc" ]]; then
 | 
			
		||||
        current_ips_full=$(get_lxc_ips "${vmid}")
 | 
			
		||||
        local current_tags_raw=$(pct config "${vmid}" 2>/dev/null | grep tags | awk '{print $2}')
 | 
			
		||||
        while IFS= read -r line; do
 | 
			
		||||
          [[ "$line" == tags:* ]] && current_tags_raw="${line#tags: }" && break
 | 
			
		||||
        done < <(pct config "$vmid" 2>/dev/null)
 | 
			
		||||
    else
 | 
			
		||||
        current_ips_full=$(get_vm_ips "${vmid}")
 | 
			
		||||
        local vm_config="/etc/pve/qemu-server/${vmid}.conf"
 | 
			
		||||
@@ -789,7 +807,10 @@ check_status_changed() {
 | 
			
		||||
check() {
 | 
			
		||||
    local current_time changes_detected=false
 | 
			
		||||
    current_time=$(date +%s)
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    local update_lxc=false
 | 
			
		||||
    local update_vm=false
 | 
			
		||||
 | 
			
		||||
    # Periodic cache cleanup (every 10 minutes)
 | 
			
		||||
    local time_since_last_cleanup=$((current_time - ${last_cleanup_time:-0}))
 | 
			
		||||
    if [[ $time_since_last_cleanup -ge 600 ]]; then
 | 
			
		||||
@@ -801,60 +822,56 @@ check() {
 | 
			
		||||
    # Check LXC status
 | 
			
		||||
    local time_since_last_lxc_check=$((current_time - last_lxc_status_check_time))
 | 
			
		||||
    if [[ "${LXC_STATUS_CHECK_INTERVAL:-60}" -gt 0 ]] && \
 | 
			
		||||
       [[ "${time_since_last_lxc_check}" -ge "${LXC_STATUS_CHECK_INTERVAL:-60}" ]]; then
 | 
			
		||||
        last_lxc_status_check_time=${current_time}
 | 
			
		||||
       [[ "$time_since_last_lxc_check" -ge "${LXC_STATUS_CHECK_INTERVAL:-60}" ]]; then
 | 
			
		||||
        last_lxc_status_check_time=$current_time
 | 
			
		||||
        if check_status_changed "lxc"; then
 | 
			
		||||
            changes_detected=true
 | 
			
		||||
            log_warning "LXC status changes detected, updating tags"
 | 
			
		||||
            update_all_tags "lxc"
 | 
			
		||||
            last_update_lxc_time=${current_time}
 | 
			
		||||
            update_lxc=true
 | 
			
		||||
            log_warning "LXC status changes detected"
 | 
			
		||||
        fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    # Check VM status
 | 
			
		||||
    local time_since_last_vm_check=$((current_time - last_vm_status_check_time))
 | 
			
		||||
    if [[ "${VM_STATUS_CHECK_INTERVAL:-60}" -gt 0 ]] && \
 | 
			
		||||
       [[ "${time_since_last_vm_check}" -ge "${VM_STATUS_CHECK_INTERVAL:-60}" ]]; then
 | 
			
		||||
        last_vm_status_check_time=${current_time}
 | 
			
		||||
       [[ "$time_since_last_vm_check" -ge "${VM_STATUS_CHECK_INTERVAL:-60}" ]]; then
 | 
			
		||||
        last_vm_status_check_time=$current_time
 | 
			
		||||
        if check_status_changed "vm"; then
 | 
			
		||||
            changes_detected=true
 | 
			
		||||
            log_warning "VM status changes detected, updating tags"
 | 
			
		||||
            update_all_tags "vm"
 | 
			
		||||
            last_update_vm_time=${current_time}
 | 
			
		||||
            update_vm=true
 | 
			
		||||
            log_warning "VM status changes detected"
 | 
			
		||||
        fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    # Check network interface changes
 | 
			
		||||
    local time_since_last_fw_check=$((current_time - last_fw_net_interface_check_time))
 | 
			
		||||
    if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL:-60}" -gt 0 ]] && \
 | 
			
		||||
       [[ "${time_since_last_fw_check}" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL:-60}" ]]; then
 | 
			
		||||
        last_fw_net_interface_check_time=${current_time}
 | 
			
		||||
       [[ "$time_since_last_fw_check" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL:-60}" ]]; then
 | 
			
		||||
        last_fw_net_interface_check_time=$current_time
 | 
			
		||||
        if check_status_changed "fw"; then
 | 
			
		||||
            changes_detected=true
 | 
			
		||||
            log_warning "Network interface changes detected, updating all tags"
 | 
			
		||||
            update_all_tags "lxc"
 | 
			
		||||
            update_all_tags "vm"
 | 
			
		||||
            last_update_lxc_time=${current_time}
 | 
			
		||||
            last_update_vm_time=${current_time}
 | 
			
		||||
            update_lxc=true
 | 
			
		||||
            update_vm=true
 | 
			
		||||
            log_warning "Network interface changes detected"
 | 
			
		||||
        fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    # Force update if needed
 | 
			
		||||
    # Force update if interval exceeded
 | 
			
		||||
    for type in "lxc" "vm"; do
 | 
			
		||||
        local last_update_var="last_update_${type}_time"
 | 
			
		||||
        local time_since_last_update=$((current_time - ${!last_update_var}))
 | 
			
		||||
        if [[ ${time_since_last_update} -ge ${FORCE_UPDATE_INTERVAL:-1800} ]]; then
 | 
			
		||||
            changes_detected=true
 | 
			
		||||
            local minutes=$((${FORCE_UPDATE_INTERVAL:-1800} / 60))
 | 
			
		||||
        if [[ $time_since_last_update -ge ${FORCE_UPDATE_INTERVAL:-1800} ]]; then
 | 
			
		||||
            if [[ "$type" == "lxc" ]]; then
 | 
			
		||||
                log_info "Scheduled LXC update (every ${minutes} minutes)"
 | 
			
		||||
                update_lxc=true
 | 
			
		||||
                log_info "Scheduled LXC update (every $((FORCE_UPDATE_INTERVAL / 60)) minutes)"
 | 
			
		||||
            else
 | 
			
		||||
                log_info "Scheduled VM update (every ${minutes} minutes)"
 | 
			
		||||
                update_vm=true
 | 
			
		||||
                log_info "Scheduled VM update (every $((FORCE_UPDATE_INTERVAL / 60)) minutes)"
 | 
			
		||||
            fi
 | 
			
		||||
            update_all_tags "$type"
 | 
			
		||||
            eval "${last_update_var}=${current_time}"
 | 
			
		||||
        fi
 | 
			
		||||
    done
 | 
			
		||||
 | 
			
		||||
    # Final execution
 | 
			
		||||
    $update_lxc && update_all_tags "lxc"
 | 
			
		||||
    $update_vm && update_all_tags "vm"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Initialize time variables
 | 
			
		||||
@@ -872,9 +889,19 @@ main() {
 | 
			
		||||
    echo -e "${BLUE}ℹ${NC} Tag format: ${WHITE}${TAG_FORMAT:-$DEFAULT_TAG_FORMAT}${NC}"
 | 
			
		||||
    echo -e "${BLUE}ℹ${NC} Allowed CIDRs: ${WHITE}${CIDR_LIST[*]}${NC}"
 | 
			
		||||
    echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
 | 
			
		||||
    check
 | 
			
		||||
 | 
			
		||||
    if [[ "$FORCE_SINGLE_RUN" == "true" ]]; then
 | 
			
		||||
        check
 | 
			
		||||
        exit 0
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    while true; do
 | 
			
		||||
        check
 | 
			
		||||
        sleep "${LOOP_INTERVAL:-300}"
 | 
			
		||||
    done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Cache cleanup function
 | 
			
		||||
cleanup_vm_cache() {
 | 
			
		||||
    local cache_dir="/tmp"
 | 
			
		||||
@@ -997,7 +1024,7 @@ process_vms_parallel() {
 | 
			
		||||
# Parallel LXC processing function
 | 
			
		||||
process_lxc_parallel() {
 | 
			
		||||
    local lxc_list=("$@")
 | 
			
		||||
    local max_parallel=${MAX_PARALLEL_LXC_CHECKS:-7}
 | 
			
		||||
    local max_parallel=${MAX_PARALLEL_LXC_CHECKS:-2}
 | 
			
		||||
    local batch_size=${LXC_BATCH_SIZE:-20}
 | 
			
		||||
    local job_count=0
 | 
			
		||||
    local pids=()
 | 
			
		||||
@@ -1173,7 +1200,7 @@ get_lxc_ips() {
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Fallback: always do lxc-attach/pct exec with timeout if nothing found
 | 
			
		||||
    if [[ -z "$ips" ]]; then
 | 
			
		||||
    if [[ -z "$ips" && "${LXC_ALLOW_FORCED_COMMANDS:-true}" == "true" ]]; then
 | 
			
		||||
        debug_log "lxc $vmid: trying fallback lxc-attach (forced)"
 | 
			
		||||
        local attach_ip=""
 | 
			
		||||
        attach_ip=$(timeout 7s lxc-attach -n "$vmid" -- ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1)
 | 
			
		||||
@@ -1188,7 +1215,7 @@ get_lxc_ips() {
 | 
			
		||||
            method_used="lxc_attach_forced"
 | 
			
		||||
        fi
 | 
			
		||||
    fi
 | 
			
		||||
    if [[ -z "$ips" ]]; then
 | 
			
		||||
    if [[ -z "$ips" && "${LXC_ALLOW_FORCED_COMMANDS:-true}" == "true" ]]; then
 | 
			
		||||
        debug_log "lxc $vmid: trying fallback pct exec (forced)"
 | 
			
		||||
        local pct_ip=""
 | 
			
		||||
        pct_ip=$(timeout 7s pct exec "$vmid" -- ip -4 addr show 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127.0.0.1' | head -1)
 | 
			
		||||
@@ -1310,6 +1337,21 @@ msg_info "Restarting Service with optimizations"
 | 
			
		||||
systemctl restart iptag.service &>/dev/null
 | 
			
		||||
msg_ok "Service restarted with CPU optimizations"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating manual run command"
 | 
			
		||||
cat <<'EOF' >/usr/local/bin/iptag-run
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
CONFIG_FILE="/opt/iptag/iptag.conf"
 | 
			
		||||
SCRIPT_FILE="/opt/iptag/iptag"
 | 
			
		||||
if [[ ! -f "$SCRIPT_FILE" ]]; then
 | 
			
		||||
  echo "❌ Main script not found: $SCRIPT_FILE"
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
export FORCE_SINGLE_RUN=true
 | 
			
		||||
exec "$SCRIPT_FILE"
 | 
			
		||||
EOF
 | 
			
		||||
chmod +x /usr/local/bin/iptag-run
 | 
			
		||||
msg_ok "Created iptag-run executable - You can execute this manually by entering “iptag-run” in the Proxmox host, so the script is executed by hand."
 | 
			
		||||
 | 
			
		||||
SPINNER_PID=""
 | 
			
		||||
echo -e "\n${APP} installation completed successfully! ${CL}\n"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user