mirror of
				https://github.com/community-scripts/ProxmoxVE.git
				synced 2025-11-04 02:12:49 +00:00 
			
		
		
		
	Compare commits
	
		
			171 Commits
		
	
	
		
			2025-07-03
			...
			2025-07-09
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					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 | ||
| 
						 | 
					fafb7501c5 | ||
| 
						 | 
					4bac3063da | ||
| 
						 | 
					29d3015314 | ||
| 
						 | 
					4d2fcb2c66 | ||
| 
						 | 
					ca6b1a95dd | ||
| 
						 | 
					14cb9f097d | ||
| 
						 | 
					4d4726ccbe | ||
| 
						 | 
					3ce5893fe3 | ||
| 
						 | 
					993b01fa83 | ||
| 
						 | 
					5c4abb6d1d | ||
| 
						 | 
					06ec9593da | ||
| 
						 | 
					ace106051b | ||
| 
						 | 
					e2396f6667 | ||
| 
						 | 
					067b3c2f02 | ||
| 
						 | 
					73f1c261ab | ||
| 
						 | 
					2cbf0f744f | ||
| 
						 | 
					a6517f4d7e | ||
| 
						 | 
					e492a9b5d9 | ||
| 
						 | 
					5e7eb4ae3a | ||
| 
						 | 
					1a8a34b533 | ||
| 
						 | 
					c38b4c2ef3 | ||
| 
						 | 
					679699e6af | ||
| 
						 | 
					32a724ac8a | ||
| 
						 | 
					798a7b323e | ||
| 
						 | 
					f1eda9a270 | ||
| 
						 | 
					5eaee5054f | ||
| 
						 | 
					e140631760 | ||
| 
						 | 
					ae24b56c61 | ||
| 
						 | 
					cb7d58b9b0 | ||
| 
						 | 
					115b21f729 | ||
| 
						 | 
					9072459066 | ||
| 
						 | 
					c2f9737435 | ||
| 
						 | 
					e5bea1f49a | ||
| 
						 | 
					f7e9fbc473 | ||
| 
						 | 
					66a5730288 | ||
| 
						 | 
					1cefb1b842 | ||
| 
						 | 
					16ac51b551 | ||
| 
						 | 
					28ed2da95f | ||
| 
						 | 
					0c98308b60 | ||
| 
						 | 
					9128b9dd12 | ||
| 
						 | 
					301a23e5f4 | ||
| 
						 | 
					2b848ff1d8 | ||
| 
						 | 
					3d69931675 | ||
| 
						 | 
					3e504cf48f | ||
| 
						 | 
					d2cbfcd69a | ||
| 
						 | 
					ebfb6a4e34 | ||
| 
						 | 
					7403470bd7 | ||
| 
						 | 
					af9475d280 | ||
| 
						 | 
					8882a17b6f | ||
| 
						 | 
					32d6194ade | ||
| 
						 | 
					569089cb73 | ||
| 
						 | 
					f494e68016 | ||
| 
						 | 
					7561e26c0a | ||
| 
						 | 
					a95be13c95 | ||
| 
						 | 
					9ab50d4248 | ||
| 
						 | 
					f5be1d270a | ||
| 
						 | 
					524a2a422d | ||
| 
						 | 
					45fbc30cc5 | ||
| 
						 | 
					f8c1d7bde8 | ||
| 
						 | 
					9b8657fbb3 | ||
| 
						 | 
					f68f19aa3d | ||
| 
						 | 
					85758f8b91 | ||
| 
						 | 
					e981c42517 | ||
| 
						 | 
					7d6ac73153 | ||
| 
						 | 
					aad2dd6232 | ||
| 
						 | 
					cb24880115 | ||
| 
						 | 
					0e87c4fe34 | ||
| 
						 | 
					438eddbde1 | ||
| 
						 | 
					729895e2ed | 
							
								
								
									
										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") ? [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										148
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -10,12 +10,156 @@
 | 
			
		||||
> [!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-10
 | 
			
		||||
 | 
			
		||||
## 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
 | 
			
		||||
 | 
			
		||||
  - Refactor: Barcodebuddy [@tremor021](https://github.com/tremor021) ([#5735](https://github.com/community-scripts/ProxmoxVE/pull/5735))
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Fix update script for Mafl: ensure directory is removed recursively [@jonalbr](https://github.com/jonalbr) ([#5759](https://github.com/community-scripts/ProxmoxVE/pull/5759))
 | 
			
		||||
    - BookStack: Typo fix [@tremor021](https://github.com/tremor021) ([#5746](https://github.com/community-scripts/ProxmoxVE/pull/5746))
 | 
			
		||||
    - Resolves incorrect URL at end of Pocket ID script [@johnsturgeon](https://github.com/johnsturgeon) ([#5743](https://github.com/community-scripts/ProxmoxVE/pull/5743))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - [Feature] Add option to expose Docker via TCP port (alpine docker) [@oformaniuk](https://github.com/oformaniuk) ([#5716](https://github.com/community-scripts/ProxmoxVE/pull/5716))
 | 
			
		||||
 | 
			
		||||
  - #### 🔧 Refactor
 | 
			
		||||
 | 
			
		||||
    - Refactor: Bitmagnet [@tremor021](https://github.com/tremor021) ([#5733](https://github.com/community-scripts/ProxmoxVE/pull/5733))
 | 
			
		||||
    - Refactor: Baikal [@tremor021](https://github.com/tremor021) ([#5736](https://github.com/community-scripts/ProxmoxVE/pull/5736))
 | 
			
		||||
 | 
			
		||||
## 2025-07-05
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🔧 Refactor
 | 
			
		||||
 | 
			
		||||
    - Refactor: BookStack [@tremor021](https://github.com/tremor021) ([#5732](https://github.com/community-scripts/ProxmoxVE/pull/5732))
 | 
			
		||||
    - Refactor: Authelia [@tremor021](https://github.com/tremor021) ([#5722](https://github.com/community-scripts/ProxmoxVE/pull/5722))
 | 
			
		||||
    - Refactor: Dashy [@tremor021](https://github.com/tremor021) ([#5723](https://github.com/community-scripts/ProxmoxVE/pull/5723))
 | 
			
		||||
    - Refactor: CryptPad [@tremor021](https://github.com/tremor021) ([#5724](https://github.com/community-scripts/ProxmoxVE/pull/5724))
 | 
			
		||||
    - Refactor: ByteStash [@tremor021](https://github.com/tremor021) ([#5725](https://github.com/community-scripts/ProxmoxVE/pull/5725))
 | 
			
		||||
    - Refactor: AgentDVR [@tremor021](https://github.com/tremor021) ([#5726](https://github.com/community-scripts/ProxmoxVE/pull/5726))
 | 
			
		||||
 | 
			
		||||
## 2025-07-04
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
  - #### 🐞 Bug Fixes
 | 
			
		||||
 | 
			
		||||
    - Refactor: Mafl [@tremor021](https://github.com/tremor021) ([#5702](https://github.com/community-scripts/ProxmoxVE/pull/5702))
 | 
			
		||||
    - Outline: Fix sed command for v0.85.0 [@tremor021](https://github.com/tremor021) ([#5688](https://github.com/community-scripts/ProxmoxVE/pull/5688))
 | 
			
		||||
    - Komodo: Update Script to use FerretDB / remove psql & sqlite options [@MickLesk](https://github.com/MickLesk) ([#5690](https://github.com/community-scripts/ProxmoxVE/pull/5690))
 | 
			
		||||
    - ESPHome: Fix Linking issue to prevent version mismatch [@MickLesk](https://github.com/MickLesk) ([#5685](https://github.com/community-scripts/ProxmoxVE/pull/5685))
 | 
			
		||||
    - Cloudflare-DDNS: fix unvisible read command at install [@MickLesk](https://github.com/MickLesk) ([#5682](https://github.com/community-scripts/ProxmoxVE/pull/5682))
 | 
			
		||||
 | 
			
		||||
  - #### ✨ New Features
 | 
			
		||||
 | 
			
		||||
    - Core layer refactor: centralized error traps and msg_* consistency [@MickLesk](https://github.com/MickLesk) ([#5705](https://github.com/community-scripts/ProxmoxVE/pull/5705))
 | 
			
		||||
 | 
			
		||||
  - #### 💥 Breaking Changes
 | 
			
		||||
 | 
			
		||||
    - Update Iptag [@DesertGamer](https://github.com/DesertGamer) ([#5677](https://github.com/community-scripts/ProxmoxVE/pull/5677))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
  - #### 📝 Script Information
 | 
			
		||||
 | 
			
		||||
    - MySQL phpMyAdmin Access Information [@austinpilz](https://github.com/austinpilz) ([#5679](https://github.com/community-scripts/ProxmoxVE/pull/5679))
 | 
			
		||||
 | 
			
		||||
## 2025-07-03
 | 
			
		||||
 | 
			
		||||
### 🚀 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>
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,15 @@ function update_script() {
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  COMPOSE_BASENAME=$(basename "$COMPOSE_FILE")
 | 
			
		||||
 | 
			
		||||
  if [[ "$COMPOSE_BASENAME" == "sqlite.compose.yaml" || "$COMPOSE_BASENAME" == "postgres.compose.yaml" ]]; then
 | 
			
		||||
    msg_error "❌ Detected outdated Komodo setup using SQLite or PostgreSQL (FerretDB v1)."
 | 
			
		||||
    echo -e "${YW}This configuration is no longer supported since Komodo v1.18.0.${CL}"
 | 
			
		||||
    echo -e "${YW}Please follow the migration guide:${CL}"
 | 
			
		||||
    echo -e "${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/5689${CL}\n"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  BACKUP_FILE="/opt/komodo/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)"
 | 
			
		||||
  cp "$COMPOSE_FILE" "$BACKUP_FILE" || {
 | 
			
		||||
    msg_error "Failed to create backup of ${COMPOSE_BASENAME}!"
 | 
			
		||||
 
 | 
			
		||||
@@ -22,30 +22,30 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
    if [[ ! -d "/etc/authelia/" ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    RELEASE=$(curl -fsSL https://api.github.com/repos/authelia/authelia/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
    if [[ "${RELEASE}" != "$(/usr/bin/authelia -v | awk '{print substr($3, 2, length($2)) }')" ]]; then
 | 
			
		||||
        msg_info "Updating $APP to ${RELEASE}"
 | 
			
		||||
        $STD apt-get update
 | 
			
		||||
        $STD apt-get -y upgrade
 | 
			
		||||
        curl -fsSL "https://github.com/authelia/authelia/releases/download/${RELEASE}/authelia_${RELEASE}_amd64.deb" -o $(basename "https://github.com/authelia/authelia/releases/download/${RELEASE}/authelia_${RELEASE}_amd64.deb")
 | 
			
		||||
        $STD dpkg -i "authelia_${RELEASE}_amd64.deb"
 | 
			
		||||
        msg_info "Cleaning Up"
 | 
			
		||||
        rm -f "authelia_${RELEASE}_amd64.deb"
 | 
			
		||||
        $STD apt-get -y autoremove
 | 
			
		||||
        $STD apt-get -y autoclean
 | 
			
		||||
        msg_ok "Cleanup Completed"
 | 
			
		||||
        msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
    else
 | 
			
		||||
        msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
    fi
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
  if [[ ! -d "/etc/authelia/" ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/authelia/authelia/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(/usr/bin/authelia -v | awk '{print substr($3, 2, length($2)) }')" ]]; then
 | 
			
		||||
    $STD apt-get update
 | 
			
		||||
    $STD apt-get -y upgrade
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "authelia" "authelia/authelia" "binary"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    $STD apt-get -y autoremove
 | 
			
		||||
    $STD apt-get -y autoclean
 | 
			
		||||
    msg_ok "Cleanup Completed"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
@@ -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}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								ct/baikal.sh
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								ct/baikal.sh
									
									
									
									
									
								
							@@ -23,34 +23,35 @@ function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -d /opt/baikal ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/sabre-io/Baikal/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
  if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.baikal 2>/dev/null)" ]] || [[ ! -f ~/.baikal ]]; then
 | 
			
		||||
    msg_info "Stopping Service"
 | 
			
		||||
    systemctl stop apache2
 | 
			
		||||
    msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt
 | 
			
		||||
    curl -fsSL "https://github.com/sabre-io/baikal/releases/download/${RELEASE}/baikal-${RELEASE}.zip" -o $(basename "https://github.com/sabre-io/baikal/releases/download/${RELEASE}/baikal-${RELEASE}.zip")
 | 
			
		||||
    msg_info "Backing up data"
 | 
			
		||||
    mv /opt/baikal /opt/baikal-backup
 | 
			
		||||
    $STD unzip -o "baikal-${RELEASE}.zip"
 | 
			
		||||
    msg_ok "Backed up data"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "baikal" "sabre-io/Baikal"
 | 
			
		||||
 | 
			
		||||
    msg_info "Configuring Baikal"
 | 
			
		||||
    cp -r /opt/baikal-backup/config/baikal.yaml /opt/baikal/config/
 | 
			
		||||
    cp -r /opt/baikal-backup/Specific/ /opt/baikal/
 | 
			
		||||
    chown -R www-data:www-data /opt/baikal/
 | 
			
		||||
    chmod -R 755 /opt/baikal/
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
    msg_ok "Configured Baikal"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Service"
 | 
			
		||||
    systemctl start apache2
 | 
			
		||||
    msg_ok "Started Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning up"
 | 
			
		||||
    rm -rf "/opt/baikal-${RELEASE}.zip"
 | 
			
		||||
    rm -rf /opt/baikal-backup
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
 
 | 
			
		||||
@@ -23,27 +23,28 @@ function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -d /opt/barcodebuddy ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/Forceu/barcodebuddy/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 ~/.barcodebuddy 2>/dev/null)" ]] || [[ ! -f ~/.barcodebuddy ]]; then
 | 
			
		||||
    msg_info "Stopping Service"
 | 
			
		||||
    systemctl stop apache2
 | 
			
		||||
    systemctl stop barcodebuddy
 | 
			
		||||
    msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt
 | 
			
		||||
    msg_info "Backing up data"
 | 
			
		||||
    mv /opt/barcodebuddy/ /opt/barcodebuddy-backup
 | 
			
		||||
    curl -fsSL "https://github.com/Forceu/barcodebuddy/archive/refs/tags/v${RELEASE}.zip" -o $(basename "https://github.com/Forceu/barcodebuddy/archive/refs/tags/v${RELEASE}.zip")
 | 
			
		||||
    $STD unzip "v${RELEASE}.zip"
 | 
			
		||||
    mv "/opt/barcodebuddy-${RELEASE}" /opt/barcodebuddy
 | 
			
		||||
    msg_ok "Backed up data"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "barcodebuddy" "Forceu/barcodebuddy"
 | 
			
		||||
 | 
			
		||||
    msg_info "Configuring ${APP}"
 | 
			
		||||
    cp -r /opt/barcodebuddy-backup/data/. /opt/barcodebuddy/data
 | 
			
		||||
    chown -R www-data:www-data /opt/barcodebuddy/data
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
    msg_ok "Configured ${APP}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Service"
 | 
			
		||||
    systemctl start apache2
 | 
			
		||||
@@ -51,7 +52,6 @@ function update_script() {
 | 
			
		||||
    msg_ok "Started Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning up"
 | 
			
		||||
    rm -r "/opt/v${RELEASE}.zip"
 | 
			
		||||
    rm -r /opt/barcodebuddy-backup
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
 
 | 
			
		||||
@@ -28,12 +28,12 @@ function update_script() {
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/bitmagnet-io/bitmagnet/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 ~/.bitmagnet 2>/dev/null)" ]] || [[ ! -f ~/.bitmagnet ]]; then
 | 
			
		||||
    msg_info "Stopping Service"
 | 
			
		||||
    systemctl stop bitmagnet-web
 | 
			
		||||
    msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Backing up database"
 | 
			
		||||
    msg_info "Backing up data"
 | 
			
		||||
    rm -f /tmp/backup.sql
 | 
			
		||||
    $STD sudo -u postgres pg_dump \
 | 
			
		||||
      --column-inserts \
 | 
			
		||||
@@ -56,31 +56,26 @@ function update_script() {
 | 
			
		||||
      bitmagnet \
 | 
			
		||||
      >/tmp/backup.sql
 | 
			
		||||
    mv /tmp/backup.sql /opt/
 | 
			
		||||
    msg_ok "Database backed up"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    [ -f /opt/bitmagnet/.env ] && cp /opt/bitmagnet/.env /opt/
 | 
			
		||||
    [ -f /opt/bitmagnet/config.yml ] && cp /opt/bitmagnet/config.yml /opt/
 | 
			
		||||
    rm -rf /opt/bitmagnet/*
 | 
			
		||||
    temp_file=$(mktemp)
 | 
			
		||||
    curl -fsSL "https://github.com/bitmagnet-io/bitmagnet/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
    tar zxf "$temp_file" --strip-components=1 -C /opt/bitmagnet
 | 
			
		||||
    msg_ok "Data backed up"
 | 
			
		||||
 | 
			
		||||
    rm -rf /opt/bitmagnet
 | 
			
		||||
    fetch_and_deploy_gh_release "bitmagnet" "bitmagnet-io/bitmagnet"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt/bitmagnet
 | 
			
		||||
    VREL=v$RELEASE
 | 
			
		||||
    $STD go build -ldflags "-s -w -X github.com/bitmagnet-io/bitmagnet/internal/version.GitTag=$VREL"
 | 
			
		||||
    chmod +x bitmagnet
 | 
			
		||||
    [ -f "/opt/.env" ] && cp "/opt/.env" /opt/bitmagnet/
 | 
			
		||||
    [ -f "/opt/config.yml" ] && cp "/opt/config.yml" /opt/bitmagnet/
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Service"
 | 
			
		||||
    systemctl start bitmagnet-web
 | 
			
		||||
    msg_ok "Started Service"
 | 
			
		||||
 | 
			
		||||
    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}"
 | 
			
		||||
 
 | 
			
		||||
@@ -23,25 +23,32 @@ function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
  if [[ ! -d /opt/bookstack ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/BookStackApp/BookStack/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 ~/.bookstack 2>/dev/null)" ]] || [[ ! -f ~/.bookstack ]]; then
 | 
			
		||||
    msg_info "Stopping Apache2"
 | 
			
		||||
    systemctl stop apache2
 | 
			
		||||
    msg_ok "Services Stopped"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    msg_info "Backing up data"
 | 
			
		||||
    mv /opt/bookstack /opt/bookstack-backup
 | 
			
		||||
    curl -fsSL "https://github.com/BookStackApp/BookStack/archive/refs/tags/v${RELEASE}.zip" -o "/opt/BookStack-${RELEASE}.zip"
 | 
			
		||||
    $STD unzip "/opt/BookStack-${RELEASE}.zip" -d /opt
 | 
			
		||||
    mv "/opt/BookStack-${RELEASE}" /opt/bookstack
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring backup"
 | 
			
		||||
    cp /opt/bookstack-backup/.env /opt/bookstack/.env
 | 
			
		||||
    [[ -d /opt/bookstack-backup/public/uploads ]] && cp -a /opt/bookstack-backup/public/uploads/. /opt/bookstack/public/uploads/
 | 
			
		||||
    [[ -d /opt/bookstack-backup/storage/uploads ]] && cp -a /opt/bookstack-backup/storage/uploads/. /opt/bookstack/storage/uploads/
 | 
			
		||||
    [[ -d /opt/bookstack-backup/themes ]] && cp -a /opt/bookstack-backup/themes/. /opt/bookstack/themes/
 | 
			
		||||
    msg_ok "Backup restored"
 | 
			
		||||
 | 
			
		||||
    msg_info "Configuring BookStack"
 | 
			
		||||
    cd /opt/bookstack
 | 
			
		||||
    export COMPOSER_ALLOW_SUPERUSER=1
 | 
			
		||||
    $STD composer install --no-dev
 | 
			
		||||
@@ -51,7 +58,7 @@ function update_script() {
 | 
			
		||||
    chmod -R 775 /opt/bookstack/storage /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads
 | 
			
		||||
    chmod -R 640 /opt/bookstack/.env
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ${APP} to v${RELEASE}"
 | 
			
		||||
    msg_ok "Configured BookStack"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Apache2"
 | 
			
		||||
    systemctl start apache2
 | 
			
		||||
@@ -59,7 +66,6 @@ function update_script() {
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning Up"
 | 
			
		||||
    rm -rf /opt/bookstack-backup
 | 
			
		||||
    rm -rf "/opt/BookStack-${RELEASE}.zip"
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
 
 | 
			
		||||
@@ -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}"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,47 +20,47 @@ color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
    if [[ ! -d /opt/bytestash ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    RELEASE=$(curl -fsSL https://api.github.com/repos/jordan-dalby/ByteStash/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
    if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
 | 
			
		||||
        msg_info "Stopping Services"
 | 
			
		||||
        systemctl stop bytestash-backend
 | 
			
		||||
        systemctl stop bytestash-frontend
 | 
			
		||||
        msg_ok "Services Stopped"
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
 | 
			
		||||
        msg_info "Updating ${APP} to ${RELEASE}"
 | 
			
		||||
        temp_file=$(mktemp)
 | 
			
		||||
curl -fsSL "https://github.com/jordan-dalby/ByteStash/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
        tar zxf $temp_file
 | 
			
		||||
        rm -rf /opt/bytestash/server/node_modules
 | 
			
		||||
        rm -rf /opt/bytestash/client/node_modules
 | 
			
		||||
        cp -rf ByteStash-${RELEASE}/* /opt/bytestash
 | 
			
		||||
        cd /opt/bytestash/server
 | 
			
		||||
        $STD npm install
 | 
			
		||||
        cd /opt/bytestash/client
 | 
			
		||||
        $STD npm install
 | 
			
		||||
        echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
        msg_ok "Updated ${APP}"
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting Services"
 | 
			
		||||
        systemctl start bytestash-backend
 | 
			
		||||
        systemctl start bytestash-frontend
 | 
			
		||||
        msg_ok "Started Services"
 | 
			
		||||
 | 
			
		||||
        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}"
 | 
			
		||||
    fi
 | 
			
		||||
  if [[ ! -d /opt/bytestash ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/jordan-dalby/ByteStash/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.bytestash 2>/dev/null)" ]] || [[ ! -f ~/.bytestash ]]; then
 | 
			
		||||
 | 
			
		||||
    read -rp "${TAB3}Did you make a backup via application WebUI? (y/n): " backuped
 | 
			
		||||
    if [[ "$backuped" =~ ^[Yy]$ ]]; then
 | 
			
		||||
      msg_info "Stopping Services"
 | 
			
		||||
      systemctl stop bytestash-backend
 | 
			
		||||
      systemctl stop bytestash-frontend
 | 
			
		||||
      msg_ok "Services Stopped"
 | 
			
		||||
 | 
			
		||||
      rm -rf /opt/bytestash
 | 
			
		||||
      fetch_and_deploy_gh_release "bytestash" "jordan-dalby/ByteStash"
 | 
			
		||||
 | 
			
		||||
      msg_info "Configuring ByteStash"
 | 
			
		||||
      cd /opt/bytestash/server
 | 
			
		||||
      $STD npm install
 | 
			
		||||
      cd /opt/bytestash/client
 | 
			
		||||
      $STD npm install
 | 
			
		||||
      msg_ok "Updated ${APP}"
 | 
			
		||||
 | 
			
		||||
      msg_info "Starting Services"
 | 
			
		||||
      systemctl start bytestash-backend
 | 
			
		||||
      systemctl start bytestash-frontend
 | 
			
		||||
      msg_ok "Started Services"
 | 
			
		||||
    else
 | 
			
		||||
      msg_error "PLEASE MAKE A BACKUP FIRST!"
 | 
			
		||||
      exit
 | 
			
		||||
    fi
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
@@ -70,4 +70,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}:3000${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -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}"
 | 
			
		||||
 
 | 
			
		||||
@@ -20,48 +20,46 @@ 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/cryptpad" ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    RELEASE=$(curl -fsSL https://api.github.com/repos/cryptpad/cryptpad/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
    if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
 | 
			
		||||
        msg_info "Stopping $APP"
 | 
			
		||||
        systemctl stop cryptpad
 | 
			
		||||
        msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
        msg_info "Updating $APP to ${RELEASE}"
 | 
			
		||||
        temp_dir=$(mktemp -d)
 | 
			
		||||
        cp -f /opt/cryptpad/config/config.js /opt/config.js
 | 
			
		||||
        curl -fsSL "https://github.com/cryptpad/cryptpad/archive/refs/tags/${RELEASE}.tar.gz" -o "$temp_dir/cryptpad-${RELEASE}.tar.gz"
 | 
			
		||||
        cd "$temp_dir"
 | 
			
		||||
        tar zxf "cryptpad-${RELEASE}.tar.gz"
 | 
			
		||||
        cp -rf "cryptpad-${RELEASE}"/* /opt/cryptpad
 | 
			
		||||
        cd /opt/cryptpad
 | 
			
		||||
        $STD npm ci
 | 
			
		||||
        $STD npm run install:components
 | 
			
		||||
        $STD npm run build
 | 
			
		||||
        cp -f /opt/config.js /opt/cryptpad/config/config.js
 | 
			
		||||
        echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
        msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
        msg_info "Cleaning Up"
 | 
			
		||||
        rm -rf $temp_dir
 | 
			
		||||
        msg_ok "Cleanup Completed"
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting $APP"
 | 
			
		||||
        systemctl start cryptpad
 | 
			
		||||
        msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
        msg_ok "Update Successful"
 | 
			
		||||
    else
 | 
			
		||||
        msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
    fi
 | 
			
		||||
  if [[ ! -d "/opt/cryptpad" ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/cryptpad/cryptpad/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.cryptpad 2>/dev/null)" ]] || [[ ! -f ~/.cryptpad ]]; then
 | 
			
		||||
    msg_info "Stopping $APP"
 | 
			
		||||
    systemctl stop cryptpad
 | 
			
		||||
    msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
    msg_info "Backing up configuration"
 | 
			
		||||
    [ -f /opt/cryptpad/config/config.js ] && mv /opt/cryptpad/config/config.js /opt/
 | 
			
		||||
    msg_ok "Backed up configuration"
 | 
			
		||||
 | 
			
		||||
    fetch_and_deploy_gh_release "cryptpad" "cryptpad/cryptpad"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating $APP to ${RELEASE}"
 | 
			
		||||
    cd /opt/cryptpad
 | 
			
		||||
    $STD npm ci
 | 
			
		||||
    $STD npm run install:components
 | 
			
		||||
    $STD npm run build
 | 
			
		||||
    msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring configuration"
 | 
			
		||||
    mv /opt/config.js /opt/cryptpad/config/
 | 
			
		||||
    msg_ok "Configuration restored"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting $APP"
 | 
			
		||||
    systemctl start cryptpad
 | 
			
		||||
    msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Update Successful"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								ct/dashy.sh
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ct/dashy.sh
									
									
									
									
									
								
							@@ -29,7 +29,7 @@ function update_script() {
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/Lissy93/dashy/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.dashy 2>/dev/null)" ]] || [[ ! -f ~/.dashy ]]; then
 | 
			
		||||
    msg_info "Stopping ${APP}"
 | 
			
		||||
    systemctl stop dashy
 | 
			
		||||
    msg_ok "Stopped ${APP}"
 | 
			
		||||
@@ -43,14 +43,13 @@ function update_script() {
 | 
			
		||||
    fi
 | 
			
		||||
    msg_ok "Backed up conf.yml"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to ${RELEASE}"
 | 
			
		||||
    rm -rf /opt/dashy
 | 
			
		||||
    mkdir -p /opt/dashy
 | 
			
		||||
    curl -fsSL "https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz" | tar -xz -C /opt/dashy --strip-components=1
 | 
			
		||||
    fetch_and_deploy_gh_release "dashy" "Lissy93/dashy"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to ${RELEASE}"
 | 
			
		||||
    cd /opt/dashy
 | 
			
		||||
    npm install
 | 
			
		||||
    npm run build
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ${APP} to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring conf.yml"
 | 
			
		||||
@@ -65,6 +64,7 @@ function update_script() {
 | 
			
		||||
    msg_info "Starting Dashy"
 | 
			
		||||
    systemctl start dashy
 | 
			
		||||
    msg_ok "Started Dashy"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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}"
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,11 @@ EOF
 | 
			
		||||
    msg_ok "Updated systemd service"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Linking esphome to /usr/local/bin"
 | 
			
		||||
  rm -f /usr/local/bin/esphome
 | 
			
		||||
  ln -s /opt/esphome/.venv/bin/esphome /usr/local/bin/esphome
 | 
			
		||||
  msg_ok "Linked esphome binary"
 | 
			
		||||
 | 
			
		||||
  msg_info "Starting ${APP}"
 | 
			
		||||
  systemctl start esphomeDashboard
 | 
			
		||||
  msg_ok "Started ${APP}"
 | 
			
		||||
 
 | 
			
		||||
@@ -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}."
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
  ______     _ ___                    _   __      __           
 | 
			
		||||
 /_  __/____(_) (_)_  ______ ___     / | / /___  / /____  _____
 | 
			
		||||
  / / / ___/ / / / / / / __ `__ \   /  |/ / __ \/ __/ _ \/ ___/
 | 
			
		||||
 / / / /  / / / / /_/ / / / / / /  / /|  / /_/ / /_/  __(__  ) 
 | 
			
		||||
/_/ /_/  /_/_/_/\__,_/_/ /_/ /_/  /_/ |_/\____/\__/\___/____/  
 | 
			
		||||
                                                               
 | 
			
		||||
  ______     _ ___               
 | 
			
		||||
 /_  __/____(_) (_)_  ______ ___ 
 | 
			
		||||
  / / / ___/ / / / / / / __ `__ \
 | 
			
		||||
 / / / /  / / / / /_/ / / / / / /
 | 
			
		||||
/_/ /_/  /_/_/_/\__,_/_/ /_/ /_/ 
 | 
			
		||||
                                 
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,15 @@ function update_script() {
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  COMPOSE_BASENAME=$(basename "$COMPOSE_FILE")
 | 
			
		||||
 | 
			
		||||
  if [[ "$COMPOSE_BASENAME" == "sqlite.compose.yaml" || "$COMPOSE_BASENAME" == "postgres.compose.yaml" ]]; then
 | 
			
		||||
    msg_error "❌ Detected outdated Komodo setup using SQLite or PostgreSQL (FerretDB v1)."
 | 
			
		||||
    echo -e "${YW}This configuration is no longer supported since Komodo v1.18.0.${CL}"
 | 
			
		||||
    echo -e "${YW}Please follow the migration guide:${CL}"
 | 
			
		||||
    echo -e "${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/5689${CL}\n"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  BACKUP_FILE="/opt/komodo/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)"
 | 
			
		||||
  cp "$COMPOSE_FILE" "$BACKUP_FILE" || {
 | 
			
		||||
    msg_error "Failed to create backup of ${COMPOSE_BASENAME}!"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								ct/mafl.sh
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								ct/mafl.sh
									
									
									
									
									
								
							@@ -27,18 +27,31 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -fsSL https://api.github.com/repos/hywax/mafl/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
  msg_info "Updating Mafl to v${RELEASE} (Patience)"
 | 
			
		||||
  systemctl stop mafl
 | 
			
		||||
  curl -fsSL "https://github.com/hywax/mafl/archive/refs/tags/v${RELEASE}.tar.gz" -o $(basename "https://github.com/hywax/mafl/archive/refs/tags/v${RELEASE}.tar.gz")
 | 
			
		||||
  tar -xzf v${RELEASE}.tar.gz
 | 
			
		||||
  cp -r mafl-${RELEASE}/* /opt/mafl/
 | 
			
		||||
  rm -rf mafl-${RELEASE}
 | 
			
		||||
  cd /opt/mafl
 | 
			
		||||
  yarn install
 | 
			
		||||
  yarn build
 | 
			
		||||
  systemctl start mafl
 | 
			
		||||
  msg_ok "Updated Mafl to v${RELEASE}"
 | 
			
		||||
  if [[ "${RELEASE}" != "$(cat ~/.mafl 2>/dev/null)" ]] || [[ ! -f ~/.mafl ]]; then
 | 
			
		||||
    msg_info "Stopping Mafl service"
 | 
			
		||||
    systemctl stop mafl
 | 
			
		||||
    msg_ok "Service stopped"
 | 
			
		||||
 | 
			
		||||
    msg_info "Performing backup"
 | 
			
		||||
    mkdir -p /opt/mafl-backup/data
 | 
			
		||||
    mv /opt/mafl/data /opt/mafl-backup/data
 | 
			
		||||
    rm -rf /opt/mafl
 | 
			
		||||
    msg_ok "Backup complete"
 | 
			
		||||
    
 | 
			
		||||
    fetch_and_deploy_gh_release "mafl" "hywax/mafl"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating Mafl to v${RELEASE}"
 | 
			
		||||
    cd /opt/mafl
 | 
			
		||||
    yarn install
 | 
			
		||||
    yarn build
 | 
			
		||||
    mv /opt/mafl-backup/data /opt/mafl/data
 | 
			
		||||
    systemctl start mafl
 | 
			
		||||
    msg_ok "Updated Mafl to v${RELEASE}"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -86,4 +86,4 @@ msg_ok "Completed Successfully!\n"
 | 
			
		||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
 | 
			
		||||
echo -e "${INFO}${YW} Configure your reverse proxy to point to:${BGN} ${IP}:1411${CL}"
 | 
			
		||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}https://{PUBLIC_URL}/login/setup${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}https://{PUBLIC_URL}/setup${CL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/TriliumNext/Trilium
 | 
			
		||||
 | 
			
		||||
APP="Trilium Notes"
 | 
			
		||||
APP="Trilium"
 | 
			
		||||
var_tags="${var_tags:-notes}"
 | 
			
		||||
var_cpu="${var_cpu:-1}"
 | 
			
		||||
var_ram="${var_ram:-512}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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/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": [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								frontend/public/json/mysql.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								frontend/public/json/mysql.json
									
									
									
										generated
									
									
									
								
							@@ -39,6 +39,10 @@
 | 
			
		||||
        {
 | 
			
		||||
            "text": "With an option to install the MySQL 8.4 LTS release instead of MySQL 8.0",
 | 
			
		||||
            "type": "info"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "text": "If installed, access phpMyAdmin at `http://<LXC_IP>/phpMyAdmin`, case sensitive.",
 | 
			
		||||
            "type": "info"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										700
									
								
								frontend/public/json/versions.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										700
									
								
								frontend/public/json/versions.json
									
									
									
										generated
									
									
									
								
							@@ -1,13 +1,358 @@
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "name": "outline/outline",
 | 
			
		||||
    "version": "v0.85.0",
 | 
			
		||||
    "date": "2025-07-03T23:31:00Z"
 | 
			
		||||
    "name": "steveiliop56/tinyauth",
 | 
			
		||||
    "version": "v3.6.0",
 | 
			
		||||
    "date": "2025-07-09T23:15:25Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "msgbyte/tianji",
 | 
			
		||||
    "version": "v1.23.3",
 | 
			
		||||
    "date": "2025-07-09T16:39:30Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "hargata/lubelog",
 | 
			
		||||
    "version": "v1.4.9",
 | 
			
		||||
    "date": "2025-07-09T16:27:46Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "duplicati/duplicati",
 | 
			
		||||
    "version": "v2.1.0.123-2.1.0.123_canary_2025-07-09",
 | 
			
		||||
    "date": "2025-07-09T16:08:36Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "keycloak/keycloak",
 | 
			
		||||
    "version": "26.3.1",
 | 
			
		||||
    "date": "2025-07-09T15:41:43Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "15.2",
 | 
			
		||||
    "date": "2025-04-14T15:37:12Z"
 | 
			
		||||
    "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": "crowdsecurity/crowdsec",
 | 
			
		||||
    "version": "v1.6.9",
 | 
			
		||||
    "date": "2025-06-17T11:54:50Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "n8n-io/n8n",
 | 
			
		||||
    "version": "n8n@1.102.0",
 | 
			
		||||
    "date": "2025-07-07T15:32:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "Jackett/Jackett",
 | 
			
		||||
    "version": "v0.22.2135",
 | 
			
		||||
    "date": "2025-07-09T05:58:50Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "MediaBrowser/Emby.Releases",
 | 
			
		||||
    "version": "4.9.1.2",
 | 
			
		||||
    "date": "2025-06-26T22:08:00Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "rcourtman/Pulse",
 | 
			
		||||
    "version": "v3.40.1",
 | 
			
		||||
    "date": "2025-07-08T21:06:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "jenkinsci/jenkins",
 | 
			
		||||
    "version": "jenkins-2.518",
 | 
			
		||||
    "date": "2025-07-08T13:52:55Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "mattermost/mattermost",
 | 
			
		||||
    "version": "preview-v0.1",
 | 
			
		||||
    "date": "2025-06-27T14:35:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "ollama/ollama",
 | 
			
		||||
    "version": "v0.9.6",
 | 
			
		||||
    "date": "2025-07-08T01:26:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "mongodb/mongo",
 | 
			
		||||
    "version": "r8.0.12-rc0",
 | 
			
		||||
    "date": "2025-07-07T23:35:35Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "TandoorRecipes/recipes",
 | 
			
		||||
    "version": "1.5.35",
 | 
			
		||||
    "date": "2025-06-22T08:30:10Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "meilisearch/meilisearch",
 | 
			
		||||
    "version": "prototype-incremental-vector-store-3",
 | 
			
		||||
    "date": "2025-07-07T10:27:19Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Paymenter/Paymenter",
 | 
			
		||||
    "version": "v1.2.1",
 | 
			
		||||
    "date": "2025-07-07T10:11:26Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nzbgetcom/nzbget",
 | 
			
		||||
    "version": "v25.2",
 | 
			
		||||
    "date": "2025-07-04T08:21:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zwave-js/zwave-js-ui",
 | 
			
		||||
    "version": "v10.8.0",
 | 
			
		||||
    "date": "2025-07-07T08:37:45Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "morpheus65535/bazarr",
 | 
			
		||||
    "version": "v1.5.2",
 | 
			
		||||
    "date": "2025-05-11T16:40:55Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "firefly-iii/firefly-iii",
 | 
			
		||||
    "version": "v6.2.20",
 | 
			
		||||
    "date": "2025-07-02T04:03:37Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "slskd/slskd",
 | 
			
		||||
    "version": "0.23.1",
 | 
			
		||||
    "date": "2025-07-06T23:57:52Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pelican-dev/panel",
 | 
			
		||||
    "version": "v1.0.0-beta22",
 | 
			
		||||
    "date": "2025-07-06T21:16:00Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pelican-dev/wings",
 | 
			
		||||
    "version": "v1.0.0-beta14",
 | 
			
		||||
    "date": "2025-07-06T21:07:07Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Luligu/matterbridge",
 | 
			
		||||
    "version": "3.1.2",
 | 
			
		||||
    "date": "2025-07-06T20:55:23Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "bluenviron/mediamtx",
 | 
			
		||||
    "version": "v1.13.0",
 | 
			
		||||
    "date": "2025-07-06T19:23:55Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "syncthing/syncthing",
 | 
			
		||||
    "version": "v1.30.0",
 | 
			
		||||
    "date": "2025-07-01T11:29:11Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Part-DB/Part-DB-server",
 | 
			
		||||
    "version": "v1.17.2",
 | 
			
		||||
    "date": "2025-07-06T12:21:52Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "redis/redis",
 | 
			
		||||
    "version": "8.0.3",
 | 
			
		||||
    "date": "2025-07-06T12:19:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "fallenbagel/jellyseerr",
 | 
			
		||||
    "version": "preview-OIDC",
 | 
			
		||||
    "date": "2025-07-06T00:51:06Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "hyperion-project/hyperion.ng",
 | 
			
		||||
    "version": "2.1.1",
 | 
			
		||||
    "date": "2025-06-14T17:45:06Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Kareadita/Kavita",
 | 
			
		||||
    "version": "v0.8.7",
 | 
			
		||||
    "date": "2025-07-05T20:08:58Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "cross-seed/cross-seed",
 | 
			
		||||
    "version": "v6.12.7",
 | 
			
		||||
    "date": "2025-06-18T03:44:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "runtipi/runtipi",
 | 
			
		||||
    "version": "v4.3.0",
 | 
			
		||||
    "date": "2025-07-05T12:14:52Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "theonedev/onedev",
 | 
			
		||||
    "version": "v11.11.4",
 | 
			
		||||
    "date": "2025-07-05T09:23:25Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "linkwarden/linkwarden",
 | 
			
		||||
    "version": "v2.11.3",
 | 
			
		||||
    "date": "2025-07-05T04:34:46Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "home-assistant/core",
 | 
			
		||||
    "version": "2025.7.1",
 | 
			
		||||
    "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": "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": "Graylog2/graylog2-server",
 | 
			
		||||
    "version": "6.3.1",
 | 
			
		||||
    "date": "2025-07-04T11:20:48Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "outline/outline",
 | 
			
		||||
    "version": "v0.85.0",
 | 
			
		||||
    "date": "2025-07-04T00:06:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "cloudflare/cloudflared",
 | 
			
		||||
@@ -19,131 +364,31 @@
 | 
			
		||||
    "version": "v4.1.2",
 | 
			
		||||
    "date": "2025-07-03T16:59:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "bunkerity/bunkerweb",
 | 
			
		||||
    "version": "v1.6.1",
 | 
			
		||||
    "date": "2025-03-15T17:29:17Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Checkmk/checkmk",
 | 
			
		||||
    "version": "v2.4.0p6",
 | 
			
		||||
    "date": "2025-07-03T16:40:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "influxdata/influxdb",
 | 
			
		||||
    "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": "fuma-nama/fumadocs",
 | 
			
		||||
    "version": "fumadocs-openapi@9.0.17",
 | 
			
		||||
    "date": "2025-07-03T06:57:48Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "mattermost/mattermost",
 | 
			
		||||
    "version": "preview-v0.1",
 | 
			
		||||
    "date": "2025-06-27T14:35:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Jackett/Jackett",
 | 
			
		||||
    "version": "v0.22.2111",
 | 
			
		||||
    "date": "2025-07-03T05:50:31Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "cross-seed/cross-seed",
 | 
			
		||||
    "version": "v6.12.7",
 | 
			
		||||
    "date": "2025-06-18T03:44:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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": "redis/redis",
 | 
			
		||||
    "version": "8.2-rc1-int",
 | 
			
		||||
    "date": "2025-07-02T19:27:08Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "keycloak/keycloak",
 | 
			
		||||
    "version": "26.3.0",
 | 
			
		||||
    "date": "2025-07-02T12:26:44Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "ollama/ollama",
 | 
			
		||||
    "version": "v0.9.5",
 | 
			
		||||
    "date": "2025-07-02T18:39:28Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "firefly-iii/firefly-iii",
 | 
			
		||||
    "version": "v6.2.20",
 | 
			
		||||
    "date": "2025-07-02T04:03:37Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "home-assistant/core",
 | 
			
		||||
    "version": "2025.7.0",
 | 
			
		||||
    "date": "2025-07-02T16:23:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nzbgetcom/nzbget",
 | 
			
		||||
    "version": "v25.1",
 | 
			
		||||
    "date": "2025-06-27T09:14:14Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Graylog2/graylog2-server",
 | 
			
		||||
    "version": "6.2.5",
 | 
			
		||||
    "date": "2025-07-02T13:06:30Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "wazuh/wazuh",
 | 
			
		||||
    "version": "coverity-w27-4.13.0",
 | 
			
		||||
    "date": "2025-07-01T03:17:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "glpi-project/glpi",
 | 
			
		||||
    "version": "10.0.18",
 | 
			
		||||
@@ -169,21 +414,11 @@
 | 
			
		||||
    "version": "v0.20.2",
 | 
			
		||||
    "date": "2025-07-02T00:37:07Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "hyperion-project/hyperion.ng",
 | 
			
		||||
    "version": "2.1.1",
 | 
			
		||||
    "date": "2025-06-14T17:45:06Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Threadfin/Threadfin",
 | 
			
		||||
    "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",
 | 
			
		||||
@@ -199,26 +434,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": "syncthing/syncthing",
 | 
			
		||||
    "version": "v1.30.0",
 | 
			
		||||
    "date": "2025-07-01T11:29:11Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "rcourtman/Pulse",
 | 
			
		||||
    "version": "v99.99.99",
 | 
			
		||||
    "date": "2025-07-01T08:26:41Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zabbix/zabbix",
 | 
			
		||||
    "version": "7.4.0",
 | 
			
		||||
@@ -229,21 +444,11 @@
 | 
			
		||||
    "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",
 | 
			
		||||
@@ -259,11 +464,6 @@
 | 
			
		||||
    "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",
 | 
			
		||||
@@ -279,26 +479,6 @@
 | 
			
		||||
    "version": "0.50.5",
 | 
			
		||||
    "date": "2025-06-29T08:54:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "theonedev/onedev",
 | 
			
		||||
    "version": "v11.11.2",
 | 
			
		||||
    "date": "2025-06-29T01:40:39Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "linkwarden/linkwarden",
 | 
			
		||||
    "version": "v2.11.2",
 | 
			
		||||
    "date": "2025-06-28T17:33:38Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "msgbyte/tianji",
 | 
			
		||||
    "version": "v1.22.5",
 | 
			
		||||
    "date": "2025-06-28T16:06:19Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Luligu/matterbridge",
 | 
			
		||||
    "version": "3.1.0",
 | 
			
		||||
    "date": "2025-06-28T09:02:38Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "plexguide/Huntarr.io",
 | 
			
		||||
    "version": "8.1.11",
 | 
			
		||||
@@ -309,56 +489,21 @@
 | 
			
		||||
    "version": "v3.2.4",
 | 
			
		||||
    "date": "2025-06-28T02:47:31Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pocket-id/pocket-id",
 | 
			
		||||
    "version": "v1.5.0",
 | 
			
		||||
    "date": "2025-06-27T22:04:32Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "homarr-labs/homarr",
 | 
			
		||||
    "version": "v1.26.0",
 | 
			
		||||
    "date": "2025-06-27T19:15:24Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "goauthentik/authentik",
 | 
			
		||||
    "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": "fallenbagel/jellyseerr",
 | 
			
		||||
    "version": "preview-seerr",
 | 
			
		||||
    "date": "2025-06-27T06:10:03Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "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",
 | 
			
		||||
@@ -369,16 +514,6 @@
 | 
			
		||||
    "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",
 | 
			
		||||
@@ -404,11 +539,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",
 | 
			
		||||
@@ -429,16 +559,6 @@
 | 
			
		||||
    "version": "RELEASE.2025-06-13T11-33-47Z",
 | 
			
		||||
    "date": "2025-06-23T20:58:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "runtipi/runtipi",
 | 
			
		||||
    "version": "v4.2.1",
 | 
			
		||||
    "date": "2025-06-03T20:04:28Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "VictoriaMetrics/VictoriaMetrics",
 | 
			
		||||
    "version": "pmm-6401-v1.120.0",
 | 
			
		||||
    "date": "2025-06-23T15:12:12Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "gotson/komga",
 | 
			
		||||
    "version": "1.22.0",
 | 
			
		||||
@@ -454,11 +574,6 @@
 | 
			
		||||
    "version": "v3.0.7",
 | 
			
		||||
    "date": "2025-06-22T17:49:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "TandoorRecipes/recipes",
 | 
			
		||||
    "version": "1.5.35",
 | 
			
		||||
    "date": "2025-06-22T08:30:10Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "inventree/InvenTree",
 | 
			
		||||
    "version": "0.17.14",
 | 
			
		||||
@@ -519,11 +634,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",
 | 
			
		||||
@@ -544,11 +654,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",
 | 
			
		||||
@@ -569,21 +674,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",
 | 
			
		||||
@@ -594,11 +684,6 @@
 | 
			
		||||
    "version": "2.402",
 | 
			
		||||
    "date": "2025-06-17T05:20:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "kimai/kimai",
 | 
			
		||||
    "version": "2.36.1",
 | 
			
		||||
    "date": "2025-06-16T19:20:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "open-webui/open-webui",
 | 
			
		||||
    "version": "v0.6.15",
 | 
			
		||||
@@ -624,11 +709,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",
 | 
			
		||||
@@ -639,16 +719,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": "traccar/traccar",
 | 
			
		||||
    "version": "v6.7.3",
 | 
			
		||||
    "date": "2025-06-15T05:46:17Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "advplyr/audiobookshelf",
 | 
			
		||||
    "version": "v2.25.1",
 | 
			
		||||
@@ -669,21 +739,11 @@
 | 
			
		||||
    "version": "v2025-06-12",
 | 
			
		||||
    "date": "2025-06-12T20:59:47Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "zitadel/zitadel",
 | 
			
		||||
    "version": "v3.3.0",
 | 
			
		||||
    "date": "2025-06-12T06:54:48Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "autobrr/autobrr",
 | 
			
		||||
    "version": "v1.63.1",
 | 
			
		||||
    "date": "2025-06-11T11:05:42Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "steveiliop56/tinyauth",
 | 
			
		||||
    "version": "v3.4.1",
 | 
			
		||||
    "date": "2025-06-11T07:53:44Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "OctoPrint/OctoPrint",
 | 
			
		||||
    "version": "1.11.2",
 | 
			
		||||
@@ -814,11 +874,6 @@
 | 
			
		||||
    "version": "5.10.0",
 | 
			
		||||
    "date": "2025-05-28T05:48:20Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "bluenviron/mediamtx",
 | 
			
		||||
    "version": "v1.12.3",
 | 
			
		||||
    "date": "2025-05-27T20:43:10Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "dani-garcia/vaultwarden",
 | 
			
		||||
    "version": "1.34.1",
 | 
			
		||||
@@ -849,16 +904,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": "Part-DB/Part-DB-server",
 | 
			
		||||
    "version": "v1.17.1",
 | 
			
		||||
    "date": "2025-05-18T21:06:41Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "sbondCo/Watcharr",
 | 
			
		||||
    "version": "v2.1.0",
 | 
			
		||||
@@ -879,11 +924,6 @@
 | 
			
		||||
    "version": "v25.05.2",
 | 
			
		||||
    "date": "2025-05-17T12:53:29Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Paymenter/Paymenter",
 | 
			
		||||
    "version": "v1.1.1",
 | 
			
		||||
    "date": "2025-05-17T10:10:36Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Ombi-app/Ombi",
 | 
			
		||||
    "version": "v4.47.1",
 | 
			
		||||
@@ -909,16 +949,6 @@
 | 
			
		||||
    "version": "v0.2.3",
 | 
			
		||||
    "date": "2025-05-10T21:14:45Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pelican-dev/wings",
 | 
			
		||||
    "version": "v1.0.0-beta13",
 | 
			
		||||
    "date": "2025-05-09T23:14:41Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "pelican-dev/panel",
 | 
			
		||||
    "version": "v1.0.0-beta21",
 | 
			
		||||
    "date": "2025-05-09T23:14:23Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "getumbrel/umbrel",
 | 
			
		||||
    "version": "1.4.2",
 | 
			
		||||
@@ -944,21 +974,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",
 | 
			
		||||
@@ -974,11 +994,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",
 | 
			
		||||
@@ -1009,11 +1024,6 @@
 | 
			
		||||
    "version": "v4.3.0",
 | 
			
		||||
    "date": "2025-04-21T17:44:40Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Kareadita/Kavita",
 | 
			
		||||
    "version": "v0.8.6.2",
 | 
			
		||||
    "date": "2025-04-20T16:55:38Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "caddyserver/caddy",
 | 
			
		||||
    "version": "v2.10.0",
 | 
			
		||||
@@ -1024,11 +1034,6 @@
 | 
			
		||||
    "version": "v0.4.15",
 | 
			
		||||
    "date": "2024-12-19T03:19:49Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "slskd/slskd",
 | 
			
		||||
    "version": "0.22.5",
 | 
			
		||||
    "date": "2025-04-15T02:52:26Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Tautulli/Tautulli",
 | 
			
		||||
    "version": "v2.15.2",
 | 
			
		||||
@@ -1109,11 +1114,6 @@
 | 
			
		||||
    "version": "v2.5.307",
 | 
			
		||||
    "date": "2025-03-24T01:33:31Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "nicolargo/glances",
 | 
			
		||||
    "version": "v4.3.1",
 | 
			
		||||
    "date": "2025-03-23T09:02:54Z"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "Donkie/Spoolman",
 | 
			
		||||
    "version": "v0.22.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -14,11 +14,12 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y apt-transport-https
 | 
			
		||||
$STD apt-get install -y alsa-utils
 | 
			
		||||
$STD apt-get install -y libxext-dev
 | 
			
		||||
$STD apt-get install -y fontconfig
 | 
			
		||||
$STD apt-get install -y libva-drm2
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apt-transport-https \
 | 
			
		||||
  alsa-utils \
 | 
			
		||||
  libxext-dev \
 | 
			
		||||
  fontconfig \
 | 
			
		||||
  libva-drm2
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing AgentDVR"
 | 
			
		||||
@@ -27,7 +28,6 @@ RELEASE=$(curl -fsSL "https://www.ispyconnect.com/api/Agent/DownloadLocation4?pl
 | 
			
		||||
cd /opt/agentdvr/agent
 | 
			
		||||
curl -fsSL "$RELEASE" -o $(basename "$RELEASE")
 | 
			
		||||
$STD unzip Agent_Linux64*.zip
 | 
			
		||||
rm -rf Agent_Linux64*.zip
 | 
			
		||||
chmod +x ./Agent
 | 
			
		||||
msg_ok "Installed AgentDVR"
 | 
			
		||||
 | 
			
		||||
@@ -54,6 +54,7 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf Agent_Linux64*.zip
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -67,5 +67,14 @@ if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
 | 
			
		||||
  msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
 | 
			
		||||
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"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 
 | 
			
		||||
@@ -28,8 +28,7 @@ msg_ok "Enabled Docker Service"
 | 
			
		||||
 | 
			
		||||
echo "${TAB3}Choose the database for Komodo installation:"
 | 
			
		||||
echo "${TAB3}1) MongoDB (recommended)"
 | 
			
		||||
echo "${TAB3}2) SQLite"
 | 
			
		||||
echo "${TAB3}3) PostgreSQL"
 | 
			
		||||
echo "${TAB3}2) FerretDB"
 | 
			
		||||
read -rp "${TAB3}Enter your choice (default: 1): " DB_CHOICE
 | 
			
		||||
DB_CHOICE=${DB_CHOICE:-1}
 | 
			
		||||
 | 
			
		||||
@@ -38,10 +37,7 @@ case $DB_CHOICE in
 | 
			
		||||
  DB_COMPOSE_FILE="mongo.compose.yaml"
 | 
			
		||||
  ;;
 | 
			
		||||
2)
 | 
			
		||||
  DB_COMPOSE_FILE="sqlite.compose.yaml"
 | 
			
		||||
  ;;
 | 
			
		||||
3)
 | 
			
		||||
  DB_COMPOSE_FILE="postgres.compose.yaml"
 | 
			
		||||
  DB_COMPOSE_FILE="ferretdb.compose.yaml"
 | 
			
		||||
  ;;
 | 
			
		||||
*)
 | 
			
		||||
  echo "Invalid choice. Defaulting to MongoDB."
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -13,13 +13,9 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Authelia"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/authelia/authelia/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
curl -fsSL "https://github.com/authelia/authelia/releases/download/${RELEASE}/authelia_${RELEASE}_amd64.deb" -o "authelia_${RELEASE}_amd64.deb"
 | 
			
		||||
$STD dpkg -i "authelia_${RELEASE}_amd64.deb"
 | 
			
		||||
msg_ok "Install Authelia completed"
 | 
			
		||||
fetch_and_deploy_gh_release "authelia" "authelia/authelia" "binary"
 | 
			
		||||
 | 
			
		||||
read -p "${TAB3}Enter your domain (ex. example.com): " DOMAIN
 | 
			
		||||
read -rp "${TAB3}Enter your domain (ex. example.com): " DOMAIN
 | 
			
		||||
 | 
			
		||||
msg_info "Setting Authelia up"
 | 
			
		||||
touch /etc/authelia/emails.txt
 | 
			
		||||
@@ -72,7 +68,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f "authelia_${RELEASE}_amd64.deb"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -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,14 +13,9 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apache2 \
 | 
			
		||||
  libapache2-mod-php \
 | 
			
		||||
  php-{pgsql,dom}
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PG_VERSION="16" setup_postgresql
 | 
			
		||||
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"
 | 
			
		||||
DB_NAME=baikal
 | 
			
		||||
@@ -36,11 +31,7 @@ $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMP
 | 
			
		||||
} >>~/baikal.creds
 | 
			
		||||
msg_ok "Set up PostgreSQL Database"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Baikal"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/sabre-io/Baikal/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
cd /opt
 | 
			
		||||
curl -fsSL "https://github.com/sabre-io/baikal/releases/download/${RELEASE}/baikal-${RELEASE}.zip" -o "baikal-${RELEASE}.zip"
 | 
			
		||||
$STD unzip "baikal-${RELEASE}.zip"
 | 
			
		||||
msg_info "Configuring Baikal"
 | 
			
		||||
cat <<EOF >/opt/baikal/config/baikal.yaml
 | 
			
		||||
database:
 | 
			
		||||
    backend: pgsql
 | 
			
		||||
@@ -51,7 +42,6 @@ database:
 | 
			
		||||
EOF
 | 
			
		||||
chown -R www-data:www-data /opt/baikal/
 | 
			
		||||
chmod -R 755 /opt/baikal/
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Installed Baikal"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
@@ -90,7 +80,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf "/opt/baikal-${RELEASE}.zip"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -16,20 +16,15 @@ update_os
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apache2 \
 | 
			
		||||
  redis \
 | 
			
		||||
  php-{curl,date,json,mbstring,redis,sqlite3,sockets} \
 | 
			
		||||
  libapache2-mod-php
 | 
			
		||||
  redis
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing barcodebuddy"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/Forceu/barcodebuddy/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
cd /opt
 | 
			
		||||
curl -fsSL "https://github.com/Forceu/barcodebuddy/archive/refs/tags/v${RELEASE}.zip" -o "v${RELEASE}.zip"
 | 
			
		||||
$STD unzip "v${RELEASE}.zip"
 | 
			
		||||
mv "/opt/barcodebuddy-${RELEASE}" /opt/barcodebuddy
 | 
			
		||||
PHP_VERSION="8.2" PHP_APACHE="YES" PHP_MODULE="date, json, redis, sqlite3, sockets" setup_php
 | 
			
		||||
fetch_and_deploy_gh_release "barcodebuddy" "Forceu/barcodebuddy"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring barcodebuddy"
 | 
			
		||||
chown -R www-data:www-data /opt/barcodebuddy/data
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Installed barcodebuddy"
 | 
			
		||||
msg_ok "Configured barcodebuddy"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Services"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/barcodebuddy.service
 | 
			
		||||
@@ -73,7 +68,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf "/opt/v${RELEASE}.zip"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -22,17 +22,10 @@ msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PG_VERSION="16" setup_postgresql
 | 
			
		||||
setup_go
 | 
			
		||||
fetch_and_deploy_gh_release "bitmagnet" "bitmagnet-io/bitmagnet"
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/bitmagnet-io/bitmagnet/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
 | 
			
		||||
msg_info "Installing bitmagnet v${RELEASE}"
 | 
			
		||||
mkdir -p /opt/bitmagnet
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
curl -fsSL "https://github.com/bitmagnet-io/bitmagnet/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
tar zxf "$temp_file" --strip-components=1 -C /opt/bitmagnet
 | 
			
		||||
cd /opt/bitmagnet
 | 
			
		||||
VREL=v$RELEASE
 | 
			
		||||
$STD go build -ldflags "-s -w -X github.com/bitmagnet-io/bitmagnet/internal/version.GitTag=$VREL"
 | 
			
		||||
chmod +x bitmagnet
 | 
			
		||||
msg_info "Setting up database"
 | 
			
		||||
POSTGRES_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
 | 
			
		||||
$STD sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$POSTGRES_PASSWORD';"
 | 
			
		||||
$STD sudo -u postgres psql -c "CREATE DATABASE bitmagnet;"
 | 
			
		||||
@@ -41,8 +34,14 @@ $STD sudo -u postgres psql -c "CREATE DATABASE bitmagnet;"
 | 
			
		||||
  echo ""
 | 
			
		||||
  echo "postgres user password: $POSTGRES_PASSWORD"
 | 
			
		||||
} >>~/postgres.creds
 | 
			
		||||
echo "${RELEASE}" >/opt/bitmagnet_version.txt
 | 
			
		||||
msg_ok "Installed bitmagnet v${RELEASE}"
 | 
			
		||||
msg_ok "Database set up"
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring bitmagnet v${RELEASE}"
 | 
			
		||||
cd /opt/bitmagnet
 | 
			
		||||
VREL=v$RELEASE
 | 
			
		||||
$STD go build -ldflags "-s -w -X github.com/bitmagnet-io/bitmagnet/internal/version.GitTag=$VREL"
 | 
			
		||||
chmod +x bitmagnet
 | 
			
		||||
msg_ok "Configured bitmagnet v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
read -r -p "${TAB3}Enter your TMDB API key if you have one: " tmdbapikey
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +71,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"
 | 
			
		||||
 
 | 
			
		||||
@@ -16,12 +16,12 @@ update_os
 | 
			
		||||
msg_info "Installing Dependencies (Patience)"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apache2 \
 | 
			
		||||
  php8.2-{mbstring,gd,fpm,curl,intl,ldap,tidy,bz2,mysql,zip,xml} \
 | 
			
		||||
  composer \
 | 
			
		||||
  libapache2-mod-php \
 | 
			
		||||
  make
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
PHP_MODULE="ldap,tidy,bz2,mysqli" PHP_FPM="YES" PHP_APACHE="YES" PHP_VERSION="8.3" setup_php
 | 
			
		||||
 | 
			
		||||
setup_composer
 | 
			
		||||
setup_mariadb
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Database"
 | 
			
		||||
@@ -39,13 +39,10 @@ $STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUS
 | 
			
		||||
} >>~/bookstack.creds
 | 
			
		||||
msg_ok "Set up database"
 | 
			
		||||
 | 
			
		||||
msg_info "Setup Bookstack (Patience)"
 | 
			
		||||
fetch_and_deploy_gh_release "bookstack" "BookStackApp/BookStack"
 | 
			
		||||
LOCAL_IP="$(hostname -I | awk '{print $1}')"
 | 
			
		||||
cd /opt
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/BookStackApp/BookStack/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
curl -fsSL "https://github.com/BookStackApp/BookStack/archive/refs/tags/v${RELEASE}.zip" -o "v${RELEASE}.zip"
 | 
			
		||||
$STD unzip v${RELEASE}.zip
 | 
			
		||||
mv BookStack-${RELEASE} /opt/bookstack
 | 
			
		||||
 | 
			
		||||
msg_info "Configuring Bookstack (Patience)"
 | 
			
		||||
cd /opt/bookstack
 | 
			
		||||
cp .env.example .env
 | 
			
		||||
sudo sed -i "s|APP_URL=.*|APP_URL=http://$LOCAL_IP|g" /opt/bookstack/.env
 | 
			
		||||
@@ -60,9 +57,8 @@ 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
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed Bookstack"
 | 
			
		||||
$STD a2enmod php8.3
 | 
			
		||||
msg_ok "Configured Bookstack"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/apache2/sites-available/bookstack.conf
 | 
			
		||||
@@ -111,7 +107,6 @@ motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf /opt/v${RELEASE}.zip
 | 
			
		||||
$STD apt-get autoremove
 | 
			
		||||
$STD apt-get autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 
 | 
			
		||||
@@ -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}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,22 +14,17 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
fetch_and_deploy_gh_release "bytestash" "jordan-dalby/ByteStash"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing ByteStash"
 | 
			
		||||
JWT_SECRET=$(openssl rand -base64 32 | tr -d '/+=')
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/jordan-dalby/ByteStash/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
curl -fsSL "https://github.com/jordan-dalby/ByteStash/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
tar zxf $temp_file
 | 
			
		||||
mv ByteStash-${RELEASE} /opt/bytestash
 | 
			
		||||
cd /opt/bytestash/server
 | 
			
		||||
$STD npm install
 | 
			
		||||
cd /opt/bytestash/client
 | 
			
		||||
$STD npm install
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed ByteStash"
 | 
			
		||||
 | 
			
		||||
read -p "${TAB3}Do you want to allow registration of multiple accounts? [y/n]: " allowreg
 | 
			
		||||
read -rp "${TAB3}Do you want to allow registration of multiple accounts? [y/n]: " allowreg
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/bytestash-backend.service
 | 
			
		||||
@@ -73,7 +68,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"
 | 
			
		||||
 
 | 
			
		||||
@@ -15,16 +15,15 @@ update_os
 | 
			
		||||
 | 
			
		||||
setup_go
 | 
			
		||||
 | 
			
		||||
msg_info "Configure Application"
 | 
			
		||||
var_cf_api_token="default"
 | 
			
		||||
read -rp "Enter the Cloudflare API token: " var_cf_api_token
 | 
			
		||||
read -rp "${TAB3}Enter the Cloudflare API token: " var_cf_api_token
 | 
			
		||||
 | 
			
		||||
var_cf_domains="default"
 | 
			
		||||
read -rp "Enter the domains separated with a comma (*.example.org,www.example.org) " var_cf_domains
 | 
			
		||||
read -rp "${TAB3}Enter the domains separated with a comma (*.example.org,www.example.org) " var_cf_domains
 | 
			
		||||
 | 
			
		||||
var_cf_proxied="false"
 | 
			
		||||
while true; do
 | 
			
		||||
  read -rp "Proxied? (y/n): " answer
 | 
			
		||||
  read -rp "${TAB3}Proxied? (y/n): " answer
 | 
			
		||||
  case "$answer" in
 | 
			
		||||
  [Yy]*)
 | 
			
		||||
    var_cf_proxied="true"
 | 
			
		||||
@@ -39,7 +38,7 @@ while true; do
 | 
			
		||||
done
 | 
			
		||||
var_cf_ip6_provider="none"
 | 
			
		||||
while true; do
 | 
			
		||||
  read -rp "Enable IPv6 support? (y/n): " answer
 | 
			
		||||
  read -rp "${TAB3}Enable IPv6 support? (y/n): " answer
 | 
			
		||||
  case "$answer" in
 | 
			
		||||
  [Yy]*)
 | 
			
		||||
    var_cf_ip6_provider="auto"
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,20 +14,15 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  git
 | 
			
		||||
$STD apt-get install -y git
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
 | 
			
		||||
read -p "${TAB3}Install OnlyOffice components instead of CKEditor? (Y/N): " onlyoffice
 | 
			
		||||
read -rp "${TAB3}Install OnlyOffice components instead of CKEditor? (Y/N): " onlyoffice
 | 
			
		||||
fetch_and_deploy_gh_release "cryptpad" "cryptpad/cryptpad"
 | 
			
		||||
 | 
			
		||||
msg_info "Setup ${APPLICATION}"
 | 
			
		||||
temp_file=$(mktemp)
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/cryptpad/cryptpad/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
curl -fsSL "https://github.com/cryptpad/cryptpad/archive/refs/tags/${RELEASE}.tar.gz" -o "$temp_file"
 | 
			
		||||
tar zxf $temp_file
 | 
			
		||||
mv cryptpad-$RELEASE /opt/cryptpad
 | 
			
		||||
cd /opt/cryptpad
 | 
			
		||||
$STD npm ci
 | 
			
		||||
$STD npm run install:components
 | 
			
		||||
@@ -39,7 +34,6 @@ sed -i "80s#//httpAddress: 'localhost'#httpAddress: '0.0.0.0'#g" /opt/cryptpad/c
 | 
			
		||||
if [[ "$onlyoffice" =~ ^[Yy]$ ]]; then
 | 
			
		||||
  $STD bash -c "./install-onlyoffice.sh --accept-license"
 | 
			
		||||
fi
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Setup ${APPLICATION}"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
@@ -69,7 +63,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,15 +14,12 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" setup_nodejs
 | 
			
		||||
fetch_and_deploy_gh_release "dashy" "Lissy93/dashy"
 | 
			
		||||
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/Lissy93/dashy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
msg_info "Installing Dashy ${RELEASE} (Patience)"
 | 
			
		||||
mkdir -p /opt/dashy
 | 
			
		||||
curl -fsSL "https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz" | tar -xz -C /opt/dashy --strip-components=1
 | 
			
		||||
cd /opt/dashy
 | 
			
		||||
$STD npm install
 | 
			
		||||
$STD npm run build
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Installed Dashy ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,32 @@ else
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
read -r -p "${TAB3}Expose Docker TCP socket (⚠️ insecure)? <y/N> " prompt
 | 
			
		||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
 | 
			
		||||
  msg_info "Enabling Docker TCP socket on port 2375 (insecure)"
 | 
			
		||||
  
 | 
			
		||||
  mkdir -p /etc/docker
 | 
			
		||||
  echo '{ "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"] }' > /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 now available on tcp://0.0.0.0:2375"
 | 
			
		||||
  else
 | 
			
		||||
    msg_error "Docker failed to restart. Check journalctl -xeu docker.service"
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,23 @@ setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  apt-transport-https \
 | 
			
		||||
  ca-certificates \
 | 
			
		||||
  lsb-release
 | 
			
		||||
msg_ok "Installed dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing EMQX"
 | 
			
		||||
$STD bash <(curl -fsSL https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh)
 | 
			
		||||
curl -fsSL https://packagecloud.io/emqx/emqx/gpgkey | gpg --dearmor -o /usr/share/keyrings/emqx-archive-keyring.gpg
 | 
			
		||||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/emqx-archive-keyring.gpg] https://packagecloud.io/emqx/emqx/debian/ bookworm main" >/etc/apt/sources.list.d/emqx.list
 | 
			
		||||
$STD apt-get install -y emqx
 | 
			
		||||
$STD systemctl enable --now emqx
 | 
			
		||||
msg_ok "Installed EMQX"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
apt-get autoremove >/dev/null
 | 
			
		||||
apt-get autoclean >/dev/null
 | 
			
		||||
$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"
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,11 @@ $STD /opt/esphome/.venv/bin/python -m pip install --upgrade pip
 | 
			
		||||
$STD /opt/esphome/.venv/bin/python -m pip install esphome tornado esptool
 | 
			
		||||
msg_ok "Setup and Installed ESPHome"
 | 
			
		||||
 | 
			
		||||
msg_info "Linking esphome to /usr/local/bin"
 | 
			
		||||
rm -f /usr/local/bin/esphome
 | 
			
		||||
ln -s /opt/esphome/.venv/bin/esphome /usr/local/bin/esphome
 | 
			
		||||
msg_ok "Linked esphome binary"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
mkdir -p /root/config
 | 
			
		||||
cat <<EOF >/etc/systemd/system/esphomeDashboard.service
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -93,7 +93,7 @@ if [[ "$CTTYPE" == "0" ]]; then
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Dependencies Installed"
 | 
			
		||||
 | 
			
		||||
read -r -p "Install OpenVINO dependencies for Intel HW-accelerated machine-learning? y/N " prompt
 | 
			
		||||
read -r -p "${TAB3}Install OpenVINO dependencies for Intel HW-accelerated machine-learning? y/N " prompt
 | 
			
		||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
 | 
			
		||||
  msg_info "Installing OpenVINO dependencies"
 | 
			
		||||
  touch ~/.openvino
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,7 @@ msg_ok "Installed Docker"
 | 
			
		||||
 | 
			
		||||
echo "${TAB3}Choose the database for Komodo installation:"
 | 
			
		||||
echo "${TAB3}1) MongoDB (recommended)"
 | 
			
		||||
echo "${TAB3}2) SQLite"
 | 
			
		||||
echo "${TAB3}3) PostgreSQL"
 | 
			
		||||
echo "${TAB3}2) FerretDB"
 | 
			
		||||
read -rp "${TAB3}Enter your choice (default: 1): " DB_CHOICE
 | 
			
		||||
DB_CHOICE=${DB_CHOICE:-1}
 | 
			
		||||
 | 
			
		||||
@@ -49,10 +48,7 @@ case $DB_CHOICE in
 | 
			
		||||
  DB_COMPOSE_FILE="mongo.compose.yaml"
 | 
			
		||||
  ;;
 | 
			
		||||
2)
 | 
			
		||||
  DB_COMPOSE_FILE="sqlite.compose.yaml"
 | 
			
		||||
  ;;
 | 
			
		||||
3)
 | 
			
		||||
  DB_COMPOSE_FILE="postgres.compose.yaml"
 | 
			
		||||
  DB_COMPOSE_FILE="ferretdb.compose.yaml"
 | 
			
		||||
  ;;
 | 
			
		||||
*)
 | 
			
		||||
  echo "Invalid choice. Defaulting to MongoDB."
 | 
			
		||||
 
 | 
			
		||||
@@ -14,22 +14,17 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y make
 | 
			
		||||
$STD apt-get install -y g++
 | 
			
		||||
$STD apt-get install -y gcc
 | 
			
		||||
$STD apt-get install -y ca-certificates
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  ca-certificates \
 | 
			
		||||
  build-essential
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
 | 
			
		||||
fetch_and_deploy_gh_release "mafl" "hywax/mafl"
 | 
			
		||||
 | 
			
		||||
RELEASE=$(curl -fsSL https://api.github.com/repos/hywax/mafl/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
msg_info "Installing Mafl v${RELEASE}"
 | 
			
		||||
curl -fsSL "https://github.com/hywax/mafl/archive/refs/tags/v${RELEASE}.tar.gz" -o "v${RELEASE}.tar.gz"
 | 
			
		||||
tar -xzf v${RELEASE}.tar.gz
 | 
			
		||||
mkdir -p /opt/mafl/data
 | 
			
		||||
curl -fsSL "https://raw.githubusercontent.com/hywax/mafl/main/.example/config.yml" -o "/opt/mafl/data/config.yml"
 | 
			
		||||
mv mafl-${RELEASE}/* /opt/mafl
 | 
			
		||||
rm -rf mafl-${RELEASE}
 | 
			
		||||
cd /opt/mafl
 | 
			
		||||
export NUXT_TELEMETRY_DISABLED=true
 | 
			
		||||
$STD yarn install
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@ sed -i 's/NODE_ENV=production/NODE_ENV=development/g' /opt/outline/.env
 | 
			
		||||
sed -i "s/generate_a_new_key/${SECRET_KEY}/g" /opt/outline/.env
 | 
			
		||||
sed -i "s/user:pass@postgres/${DB_USER}:${DB_PASS}@localhost/g" /opt/outline/.env
 | 
			
		||||
sed -i 's/redis:6379/localhost:6379/g' /opt/outline/.env
 | 
			
		||||
sed -i "32s#URL=#URL=http://${LOCAL_IP}#g" /opt/outline/.env
 | 
			
		||||
sed -i "5s#URL=#URL=http://${LOCAL_IP}#g" /opt/outline/.env
 | 
			
		||||
sed -i 's/FORCE_HTTPS=true/FORCE_HTTPS=false/g' /opt/outline/.env
 | 
			
		||||
$STD yarn install --frozen-lockfile
 | 
			
		||||
export NODE_OPTIONS="--max-old-space-size=3584"
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -83,11 +83,6 @@ update_os() {
 | 
			
		||||
  msg_info "Updating Container OS"
 | 
			
		||||
  $STD apk -U upgrade
 | 
			
		||||
  msg_ok "Updated Container OS"
 | 
			
		||||
 | 
			
		||||
  msg_info "Installing core dependencies"
 | 
			
		||||
  $STD apk update
 | 
			
		||||
  $STD apk add newt curl openssh nano mc ncurses gpg
 | 
			
		||||
  msg_ok "Core dependencies installed"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# This function modifies the message of the day (motd) and SSH settings
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										118
									
								
								misc/build.func
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								misc/build.func
									
									
									
									
									
								
							@@ -304,13 +304,12 @@ echo_default() {
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Output the selected values with icons
 | 
			
		||||
  echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}"
 | 
			
		||||
  echo -e "${OSVERSION}${BOLD}${DGN}Version: ${BGN}$var_version${CL}"
 | 
			
		||||
  echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}"
 | 
			
		||||
  echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os ($var_version)${CL}"
 | 
			
		||||
  echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}"
 | 
			
		||||
  echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}"
 | 
			
		||||
  echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
 | 
			
		||||
  echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}"
 | 
			
		||||
  echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}"
 | 
			
		||||
  if [ "$VERB" == "yes" ]; then
 | 
			
		||||
    echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}"
 | 
			
		||||
  fi
 | 
			
		||||
@@ -1095,7 +1094,9 @@ build_container() {
 | 
			
		||||
  # This executes create_lxc.sh and creates the container and .conf file
 | 
			
		||||
  bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/create_lxc.sh)" $?
 | 
			
		||||
 | 
			
		||||
  LXC_CONFIG=/etc/pve/lxc/${CTID}.conf
 | 
			
		||||
  LXC_CONFIG="/etc/pve/lxc/${CTID}.conf"
 | 
			
		||||
 | 
			
		||||
  # USB passthrough for privileged LXC (CT_TYPE=0)
 | 
			
		||||
  if [ "$CT_TYPE" == "0" ]; then
 | 
			
		||||
    cat <<EOF >>"$LXC_CONFIG"
 | 
			
		||||
# USB passthrough
 | 
			
		||||
@@ -1111,38 +1112,82 @@ lxc.mount.entry: /dev/ttyACM1       dev/ttyACM1       none bind,optional,create=
 | 
			
		||||
EOF
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ "$CT_TYPE" == "0" ]; then
 | 
			
		||||
    if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "immich" || "$APP" == "Tdarr" || "$APP" == "Open WebUI" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then
 | 
			
		||||
      cat <<EOF >>"$LXC_CONFIG"
 | 
			
		||||
# VAAPI hardware transcoding
 | 
			
		||||
lxc.cgroup2.devices.allow: c 226:0 rwm
 | 
			
		||||
lxc.cgroup2.devices.allow: c 226:128 rwm
 | 
			
		||||
lxc.cgroup2.devices.allow: c 29:0 rwm
 | 
			
		||||
lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
 | 
			
		||||
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
 | 
			
		||||
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
 | 
			
		||||
EOF
 | 
			
		||||
  # VAAPI passthrough for privileged containers or known apps
 | 
			
		||||
  VAAPI_APPS=(
 | 
			
		||||
    "immich"
 | 
			
		||||
    "Channels"
 | 
			
		||||
    "Emby"
 | 
			
		||||
    "ErsatzTV"
 | 
			
		||||
    "Frigate"
 | 
			
		||||
    "Jellyfin"
 | 
			
		||||
    "Plex"
 | 
			
		||||
    "Scrypted"
 | 
			
		||||
    "Tdarr"
 | 
			
		||||
    "Unmanic"
 | 
			
		||||
    "Ollama"
 | 
			
		||||
    "FileFlows"
 | 
			
		||||
    "Open WebUI"
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  is_vaapi_app=false
 | 
			
		||||
  for vaapi_app in "${VAAPI_APPS[@]}"; do
 | 
			
		||||
    if [[ "$APP" == "$vaapi_app" ]]; then
 | 
			
		||||
      is_vaapi_app=true
 | 
			
		||||
      break
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "immich" || "$APP" == "Tdarr" || "$APP" == "Open WebUI" || "$APP" == "Unmanic" || "$APP" == "Ollama" || "$APP" == "FileFlows" ]]; then
 | 
			
		||||
      if [[ -e "/dev/dri/renderD128" ]]; then
 | 
			
		||||
        if [[ -e "/dev/dri/card0" ]]; then
 | 
			
		||||
          cat <<EOF >>"$LXC_CONFIG"
 | 
			
		||||
# VAAPI hardware transcoding
 | 
			
		||||
dev0: /dev/dri/card0,gid=44
 | 
			
		||||
dev1: /dev/dri/renderD128,gid=104
 | 
			
		||||
EOF
 | 
			
		||||
        else
 | 
			
		||||
          cat <<EOF >>"$LXC_CONFIG"
 | 
			
		||||
# VAAPI hardware transcoding
 | 
			
		||||
dev0: /dev/dri/card1,gid=44
 | 
			
		||||
dev1: /dev/dri/renderD128,gid=104
 | 
			
		||||
EOF
 | 
			
		||||
        fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  if ([ "$CT_TYPE" == "0" ] || [ "$is_vaapi_app" == "true" ]) &&
 | 
			
		||||
    ([[ -e /dev/dri/renderD128 ]] || [[ -e /dev/dri/card0 ]] || [[ -e /dev/fb0 ]]); then
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
      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"
 | 
			
		||||
        }
 | 
			
		||||
        [[ -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"
 | 
			
		||||
        }
 | 
			
		||||
        [[ -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"
 | 
			
		||||
        }
 | 
			
		||||
        [[ -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
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
  # TUN device passthrough
 | 
			
		||||
  if [ "$ENABLE_TUN" == "yes" ]; then
 | 
			
		||||
    cat <<EOF >>"$LXC_CONFIG"
 | 
			
		||||
lxc.cgroup2.devices.allow: c 10:200 rwm
 | 
			
		||||
@@ -1172,10 +1217,13 @@ EOF'
 | 
			
		||||
    locale-gen >/dev/null && \
 | 
			
		||||
    export LANG=\$locale_line"
 | 
			
		||||
 | 
			
		||||
    if [[ -z "${tz:-}" ]]; then
 | 
			
		||||
      tz=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Etc/UTC")
 | 
			
		||||
    fi
 | 
			
		||||
    if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then
 | 
			
		||||
      pct exec "$CTID" -- bash -c "echo $tz >/etc/timezone && ln -sf /usr/share/zoneinfo/$tz /etc/localtime"
 | 
			
		||||
      pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime"
 | 
			
		||||
    else
 | 
			
		||||
      msg_info "Skipping timezone setup – zone '$tz' not found in container"
 | 
			
		||||
      msg_warn "Skipping timezone setup – zone '$tz' not found in container"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 >/dev/null"
 | 
			
		||||
@@ -1255,7 +1303,9 @@ api_exit_script() {
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trap 'api_exit_script' EXIT
 | 
			
		||||
if command -v pveversion >/dev/null 2>&1; then
 | 
			
		||||
  trap 'api_exit_script' EXIT
 | 
			
		||||
fi
 | 
			
		||||
trap 'post_update_to_api "failed" "$BASH_COMMAND"' ERR
 | 
			
		||||
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
 | 
			
		||||
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										399
									
								
								misc/core.func
									
									
									
									
									
								
							
							
						
						
									
										399
									
								
								misc/core.func
									
									
									
									
									
								
							@@ -1,30 +1,6 @@
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/LICENSE
 | 
			
		||||
 | 
			
		||||
# if ! declare -f wait_for >/dev/null; then
 | 
			
		||||
#   echo "[DEBUG] Undefined function 'wait_for' used from: ${BASH_SOURCE[*]}" >&2
 | 
			
		||||
#   wait_for() {
 | 
			
		||||
#     echo "[DEBUG] Fallback: wait_for called with: $*" >&2
 | 
			
		||||
#     true
 | 
			
		||||
#   }
 | 
			
		||||
# fi
 | 
			
		||||
 | 
			
		||||
trap 'on_error $? $LINENO' ERR
 | 
			
		||||
trap 'on_exit' EXIT
 | 
			
		||||
trap 'on_interrupt' INT
 | 
			
		||||
trap 'on_terminate' TERM
 | 
			
		||||
 | 
			
		||||
if ! declare -f wait_for >/dev/null; then
 | 
			
		||||
  wait_for() {
 | 
			
		||||
    true
 | 
			
		||||
  }
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
declare -A MSG_INFO_SHOWN=()
 | 
			
		||||
SPINNER_PID=""
 | 
			
		||||
SPINNER_ACTIVE=0
 | 
			
		||||
SPINNER_MSG=""
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
# Loads core utility groups once (colors, formatting, icons, defaults).
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
@@ -43,100 +19,51 @@ load_functions() {
 | 
			
		||||
  # add more
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
on_error() {
 | 
			
		||||
  local exit_code="$1"
 | 
			
		||||
  local lineno="$2"
 | 
			
		||||
# ============================================================================
 | 
			
		||||
# Error & Signal Handling – robust, universal, subshell-safe
 | 
			
		||||
# ============================================================================
 | 
			
		||||
 | 
			
		||||
  stop_spinner
 | 
			
		||||
 | 
			
		||||
  case "$exit_code" in
 | 
			
		||||
  1) msg_error "Generic error occurred (line $lineno)" ;;
 | 
			
		||||
  2) msg_error "Shell misuse (line $lineno)" ;;
 | 
			
		||||
  126) msg_error "Command cannot execute (line $lineno)" ;;
 | 
			
		||||
  127) msg_error "Command not found (line $lineno)" ;;
 | 
			
		||||
  128) msg_error "Invalid exit argument (line $lineno)" ;;
 | 
			
		||||
  130) msg_error "Script aborted by user (CTRL+C)" ;;
 | 
			
		||||
  143) msg_error "Script terminated by SIGTERM" ;;
 | 
			
		||||
  *) msg_error "Script failed at line $lineno with exit code $exit_code" ;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  exit "$exit_code"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
on_exit() {
 | 
			
		||||
  cleanup_spinner || true
 | 
			
		||||
  [[ "${VERBOSE:-no}" == "yes" ]] && msg_info "Script exited"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
on_interrupt() {
 | 
			
		||||
  msg_error "Interrupted by user (CTRL+C)"
 | 
			
		||||
  exit 130
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
on_terminate() {
 | 
			
		||||
  msg_error "Terminated by signal (TERM)"
 | 
			
		||||
  exit 143
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
setup_trap_abort_handling() {
 | 
			
		||||
  trap '__handle_signal_abort SIGINT' SIGINT
 | 
			
		||||
  trap '__handle_signal_abort SIGTERM' SIGTERM
 | 
			
		||||
  trap '__handle_unexpected_error $?' ERR
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__handle_signal_abort() {
 | 
			
		||||
  local signal="$1"
 | 
			
		||||
  echo
 | 
			
		||||
  [ -n "${SPINNER_PID:-}" ] && kill "$SPINNER_PID" 2>/dev/null && wait "$SPINNER_PID" 2>/dev/null
 | 
			
		||||
 | 
			
		||||
  case "$signal" in
 | 
			
		||||
  SIGINT)
 | 
			
		||||
    msg_error "Script aborted by user (CTRL+C)"
 | 
			
		||||
    exit 130
 | 
			
		||||
_tool_error_hint() {
 | 
			
		||||
  local cmd="$1"
 | 
			
		||||
  local code="$2"
 | 
			
		||||
  case "$cmd" in
 | 
			
		||||
  curl)
 | 
			
		||||
    case "$code" in
 | 
			
		||||
    6) echo "Curl: Could not resolve host (DNS problem)" ;;
 | 
			
		||||
    7) echo "Curl: Failed to connect to host (connection refused)" ;;
 | 
			
		||||
    22) echo "Curl: HTTP error (404/403 etc)" ;;
 | 
			
		||||
    28) echo "Curl: Operation timeout" ;;
 | 
			
		||||
    *) echo "Curl: Unknown error ($code)" ;;
 | 
			
		||||
    esac
 | 
			
		||||
    ;;
 | 
			
		||||
  SIGTERM)
 | 
			
		||||
    msg_error "Script terminated (SIGTERM)"
 | 
			
		||||
    exit 143
 | 
			
		||||
  wget)
 | 
			
		||||
    echo "Wget failed – URL unreachable or permission denied"
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    msg_error "Script interrupted (unknown signal: $signal)"
 | 
			
		||||
    exit 1
 | 
			
		||||
  systemctl)
 | 
			
		||||
    echo "Systemd unit failure – check service name and permissions"
 | 
			
		||||
    ;;
 | 
			
		||||
  jq)
 | 
			
		||||
    echo "jq parse error – malformed JSON or missing key"
 | 
			
		||||
    ;;
 | 
			
		||||
  mariadb | mysql)
 | 
			
		||||
    echo "MySQL/MariaDB command failed – check credentials or DB"
 | 
			
		||||
    ;;
 | 
			
		||||
  unzip)
 | 
			
		||||
    echo "unzip failed – corrupt file or missing permission"
 | 
			
		||||
    ;;
 | 
			
		||||
  tar)
 | 
			
		||||
    echo "tar failed – invalid format or missing binary"
 | 
			
		||||
    ;;
 | 
			
		||||
  node | npm | pnpm | yarn)
 | 
			
		||||
    echo "Node tool failed – check version compatibility or package.json"
 | 
			
		||||
    ;;
 | 
			
		||||
  *) echo "" ;;
 | 
			
		||||
  esac
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__handle_unexpected_error() {
 | 
			
		||||
  local exit_code="$1"
 | 
			
		||||
  echo
 | 
			
		||||
  [ -n "${SPINNER_PID:-}" ] && kill "$SPINNER_PID" 2>/dev/null && wait "$SPINNER_PID" 2>/dev/null
 | 
			
		||||
 | 
			
		||||
  case "$exit_code" in
 | 
			
		||||
  1)
 | 
			
		||||
    msg_error "Generic error occurred (exit code 1)"
 | 
			
		||||
    ;;
 | 
			
		||||
  2)
 | 
			
		||||
    msg_error "Misuse of shell builtins (exit code 2)"
 | 
			
		||||
    ;;
 | 
			
		||||
  126)
 | 
			
		||||
    msg_error "Command invoked cannot execute (exit code 126)"
 | 
			
		||||
    ;;
 | 
			
		||||
  127)
 | 
			
		||||
    msg_error "Command not found (exit code 127)"
 | 
			
		||||
    ;;
 | 
			
		||||
  128)
 | 
			
		||||
    msg_error "Invalid exit argument (exit code 128)"
 | 
			
		||||
    ;;
 | 
			
		||||
  130)
 | 
			
		||||
    msg_error "Script aborted by user (CTRL+C)"
 | 
			
		||||
    ;;
 | 
			
		||||
  143)
 | 
			
		||||
    msg_error "Script terminated by SIGTERM"
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    msg_error "Unexpected error occurred (exit code $exit_code)"
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
  exit "$exit_code"
 | 
			
		||||
catch_errors() {
 | 
			
		||||
  set -Eeuo pipefail
 | 
			
		||||
  trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
@@ -153,6 +80,13 @@ color() {
 | 
			
		||||
  CL=$(echo "\033[m")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Special for spinner and colorized output via printf
 | 
			
		||||
color_spinner() {
 | 
			
		||||
  CS_YW=$'\033[33m'
 | 
			
		||||
  CS_YWB=$'\033[93m'
 | 
			
		||||
  CS_CL=$'\033[m'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
# Defines formatting helpers like tab, bold, and line reset sequences.
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
@@ -196,6 +130,7 @@ icons() {
 | 
			
		||||
  ADVANCED="${TAB}🧩${TAB}${CL}"
 | 
			
		||||
  FUSE="${TAB}🗂️${TAB}${CL}"
 | 
			
		||||
  HOURGLASS="${TAB}⏳${TAB}"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
@@ -227,7 +162,7 @@ silent() {
 | 
			
		||||
# Function to download & save header files
 | 
			
		||||
get_header() {
 | 
			
		||||
  local app_name=$(echo "${APP,,}" | tr -d ' ')
 | 
			
		||||
  local app_type=${APP_TYPE:-ct} # Default 'ct'
 | 
			
		||||
  local app_type=${APP_TYPE:-ct}
 | 
			
		||||
  local header_url="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/${app_type}/headers/${app_name}"
 | 
			
		||||
  local local_header_path="/usr/local/community-scripts/headers/${app_type}/${app_name}"
 | 
			
		||||
 | 
			
		||||
@@ -257,77 +192,39 @@ header_info() {
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
# Performs a curl request with retry logic and inline feedback.
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
run_curl() {
 | 
			
		||||
  if [ "$VERBOSE" = "no" ]; then
 | 
			
		||||
    $STD curl "$@"
 | 
			
		||||
  else
 | 
			
		||||
    curl "$@"
 | 
			
		||||
ensure_tput() {
 | 
			
		||||
  if ! command -v tput >/dev/null 2>&1; then
 | 
			
		||||
    if grep -qi 'alpine' /etc/os-release; then
 | 
			
		||||
      apk add --no-cache ncurses >/dev/null 2>&1
 | 
			
		||||
    elif command -v apt-get >/dev/null 2>&1; then
 | 
			
		||||
      apt-get update -qq >/dev/null
 | 
			
		||||
      apt-get install -y -qq ncurses-bin >/dev/null 2>&1
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
curl_handler() {
 | 
			
		||||
  set +e
 | 
			
		||||
  trap 'set -e' RETURN
 | 
			
		||||
  local args=()
 | 
			
		||||
  local url=""
 | 
			
		||||
  local max_retries=3
 | 
			
		||||
  local delay=2
 | 
			
		||||
  local attempt=1
 | 
			
		||||
  local exit_code
 | 
			
		||||
  local has_output_file=false
 | 
			
		||||
  local result=""
 | 
			
		||||
is_alpine() {
 | 
			
		||||
  local os_id="${var_os:-${PCT_OSTYPE:-}}"
 | 
			
		||||
 | 
			
		||||
  # Parse arguments
 | 
			
		||||
  for arg in "$@"; do
 | 
			
		||||
    if [[ "$arg" != -* && -z "$url" ]]; then
 | 
			
		||||
      url="$arg"
 | 
			
		||||
    fi
 | 
			
		||||
    [[ "$arg" == "-o" || "$arg" == --output ]] && has_output_file=true
 | 
			
		||||
    args+=("$arg")
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  if [[ -z "$url" ]]; then
 | 
			
		||||
    msg_error "No valid URL or option entered for curl_handler"
 | 
			
		||||
    return 1
 | 
			
		||||
  if [[ -z "$os_id" && -f /etc/os-release ]]; then
 | 
			
		||||
    os_id="$(
 | 
			
		||||
      . /etc/os-release 2>/dev/null
 | 
			
		||||
      echo "${ID:-}"
 | 
			
		||||
    )"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  $STD msg_info "Fetching: $url"
 | 
			
		||||
  [[ "$os_id" == "alpine" ]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  while [[ $attempt -le $max_retries ]]; do
 | 
			
		||||
    if $has_output_file; then
 | 
			
		||||
      $STD run_curl "${args[@]}"
 | 
			
		||||
      exit_code=$?
 | 
			
		||||
    else
 | 
			
		||||
      result=$(run_curl "${args[@]}")
 | 
			
		||||
      exit_code=$?
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if [[ $exit_code -eq 0 ]]; then
 | 
			
		||||
      $STD msg_ok "Fetched: $url"
 | 
			
		||||
      $has_output_file || printf '%s' "$result"
 | 
			
		||||
      return 0
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ((attempt >= max_retries)); then
 | 
			
		||||
      # Read error log if it exists
 | 
			
		||||
      if [ -s /tmp/curl_error.log ]; then
 | 
			
		||||
        local curl_stderr
 | 
			
		||||
        curl_stderr=$(</tmp/curl_error.log)
 | 
			
		||||
        rm -f /tmp/curl_error.log
 | 
			
		||||
      fi
 | 
			
		||||
      __curl_err_handler "$exit_code" "$url" "${curl_stderr:-}"
 | 
			
		||||
      exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    $STD printf "\r\033[K${INFO}${YW}Retry $attempt/$max_retries in ${delay}s...${CL}" >&2
 | 
			
		||||
    sleep "$delay"
 | 
			
		||||
    ((attempt++))
 | 
			
		||||
  done
 | 
			
		||||
  set -e
 | 
			
		||||
is_verbose_mode() {
 | 
			
		||||
  local verbose="${VERBOSE:-${var_verbose:-no}}"
 | 
			
		||||
  local tty_status
 | 
			
		||||
  if [[ -t 2 ]]; then
 | 
			
		||||
    tty_status="interactive"
 | 
			
		||||
  else
 | 
			
		||||
    tty_status="not-a-tty"
 | 
			
		||||
  fi
 | 
			
		||||
  [[ "$verbose" != "no" || ! -t 2 ]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# ------------------------------------------------------------------------------
 | 
			
		||||
@@ -372,144 +269,92 @@ fatal() {
 | 
			
		||||
  kill -INT $$
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Ensure POSIX compatibility across Alpine and Debian/Ubuntu
 | 
			
		||||
# === Spinner Start ===
 | 
			
		||||
# Trap cleanup on various signals
 | 
			
		||||
trap 'cleanup_spinner' EXIT INT TERM HUP
 | 
			
		||||
 | 
			
		||||
spinner_frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
 | 
			
		||||
 | 
			
		||||
# === Spinner Start ===
 | 
			
		||||
start_spinner() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  local spin_i=0
 | 
			
		||||
  local interval=0.1
 | 
			
		||||
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  SPINNER_MSG="$msg"
 | 
			
		||||
  SPINNER_ACTIVE=1
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    while [[ "$SPINNER_ACTIVE" -eq 1 ]]; do
 | 
			
		||||
      if [[ -t 2 ]]; then
 | 
			
		||||
        printf "\r\e[2K%s %b" "${TAB}${spinner_frames[spin_i]}${TAB}" "${YW}${SPINNER_MSG}${CL}" >&2
 | 
			
		||||
      else
 | 
			
		||||
        printf "%s...\n" "$SPINNER_MSG" >&2
 | 
			
		||||
        break
 | 
			
		||||
      fi
 | 
			
		||||
      spin_i=$(((spin_i + 1) % ${#spinner_frames[@]}))
 | 
			
		||||
      sleep "$interval"
 | 
			
		||||
    done
 | 
			
		||||
  } &
 | 
			
		||||
 | 
			
		||||
  local pid=$!
 | 
			
		||||
  if ps -p "$pid" >/dev/null 2>&1; then
 | 
			
		||||
    SPINNER_PID="$pid"
 | 
			
		||||
  else
 | 
			
		||||
    SPINNER_ACTIVE=0
 | 
			
		||||
    SPINNER_PID=""
 | 
			
		||||
  fi
 | 
			
		||||
spinner() {
 | 
			
		||||
  local chars=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏)
 | 
			
		||||
  local i=0
 | 
			
		||||
  while true; do
 | 
			
		||||
    local index=$((i++ % ${#chars[@]}))
 | 
			
		||||
    printf "\r\033[2K%s %b" "${CS_YWB}${chars[$index]}${CS_CL}" "${CS_YWB}${SPINNER_MSG:-}${CS_CL}"
 | 
			
		||||
    sleep 0.1
 | 
			
		||||
  done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
clear_line() {
 | 
			
		||||
  tput cr 2>/dev/null || echo -en "\r"
 | 
			
		||||
  tput el 2>/dev/null || echo -en "\033[K"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# === Spinner Stop ===
 | 
			
		||||
stop_spinner() {
 | 
			
		||||
  if [[ "$SPINNER_ACTIVE" -eq 1 && -n "$SPINNER_PID" ]]; then
 | 
			
		||||
    SPINNER_ACTIVE=0
 | 
			
		||||
  local pid="${SPINNER_PID:-}"
 | 
			
		||||
  [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(</tmp/.spinner.pid)
 | 
			
		||||
 | 
			
		||||
    if kill -0 "$SPINNER_PID" 2>/dev/null; then
 | 
			
		||||
      kill "$SPINNER_PID" 2>/dev/null || true
 | 
			
		||||
      for _ in $(seq 1 10); do
 | 
			
		||||
        sleep 0.05
 | 
			
		||||
        kill -0 "$SPINNER_PID" 2>/dev/null || break
 | 
			
		||||
      done
 | 
			
		||||
  if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]]; then
 | 
			
		||||
    if kill "$pid" 2>/dev/null; then
 | 
			
		||||
      sleep 0.05
 | 
			
		||||
      kill -9 "$pid" 2>/dev/null || true
 | 
			
		||||
      wait "$pid" 2>/dev/null || true
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if [[ "$SPINNER_PID" =~ ^[0-9]+$ ]]; then
 | 
			
		||||
      ps -p "$SPINNER_PID" -o pid= >/dev/null 2>&1 && wait "$SPINNER_PID" 2>/dev/null || true
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    printf "\r\e[2K" >&2
 | 
			
		||||
    SPINNER_PID=""
 | 
			
		||||
    rm -f /tmp/.spinner.pid
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cleanup_spinner() {
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  unset SPINNER_PID SPINNER_MSG
 | 
			
		||||
  stty sane 2>/dev/null || true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
msg_info() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  [[ -z "$msg" || -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return
 | 
			
		||||
  [[ -z "$msg" ]] && return
 | 
			
		||||
 | 
			
		||||
  if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then
 | 
			
		||||
    declare -gA MSG_INFO_SHOWN=()
 | 
			
		||||
  fi
 | 
			
		||||
  [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return
 | 
			
		||||
  MSG_INFO_SHOWN["$msg"]=1
 | 
			
		||||
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  SPINNER_MSG="$msg"
 | 
			
		||||
 | 
			
		||||
  if [[ "${VERBOSE:-no}" == "no" && -t 2 ]]; then
 | 
			
		||||
    start_spinner "$msg"
 | 
			
		||||
  else
 | 
			
		||||
  if is_verbose_mode || is_alpine; then
 | 
			
		||||
    local HOURGLASS="${TAB}⏳${TAB}"
 | 
			
		||||
    printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2
 | 
			
		||||
    return
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  color_spinner
 | 
			
		||||
  spinner &
 | 
			
		||||
  SPINNER_PID=$!
 | 
			
		||||
  echo "$SPINNER_PID" >/tmp/.spinner.pid
 | 
			
		||||
  disown "$SPINNER_PID" 2>/dev/null || true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
msg_ok() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  [[ -z "$msg" ]] && return
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  printf "\r\e[2K%s %b\n" "$CM" "${GN}${msg}${CL}" >&2
 | 
			
		||||
  clear_line
 | 
			
		||||
  printf "%s %b\n" "$CM" "${GN}${msg}${CL}" >&2
 | 
			
		||||
  unset MSG_INFO_SHOWN["$msg"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
msg_error() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  [[ -z "$msg" ]] && return
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  printf "\r\e[2K%s %b\n" "$CROSS" "${RD}${msg}${CL}" >&2
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  echo -e "${BFR:-} ${CROSS:-✖️} ${RD}${msg}${CL}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
msg_warn() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  [[ -z "$msg" ]] && return
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  printf "\r\e[2K%s %b\n" "$INFO" "${YWB}${msg}${CL}" >&2
 | 
			
		||||
  unset MSG_INFO_SHOWN["$msg"]
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  echo -e "${BFR:-} ${INFO:-ℹ️} ${YWB}${msg}${CL}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
msg_custom() {
 | 
			
		||||
  local symbol="${1:-"[*]"}"
 | 
			
		||||
  local color="${2:-"\e[36m"}" # Default: Cyan
 | 
			
		||||
  local color="${2:-"\e[36m"}"
 | 
			
		||||
  local msg="${3:-}"
 | 
			
		||||
 | 
			
		||||
  [[ -z "$msg" ]] && return
 | 
			
		||||
  stop_spinner 2>/dev/null || true
 | 
			
		||||
  printf "\r\e[2K%s %b\n" "$symbol" "${color}${msg}${CL:-\e[0m}" >&2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
msg_progress() {
 | 
			
		||||
  local current="$1"
 | 
			
		||||
  local total="$2"
 | 
			
		||||
  local label="$3"
 | 
			
		||||
  local width=40
 | 
			
		||||
  local filled percent bar empty
 | 
			
		||||
  local fill_char="#"
 | 
			
		||||
  local empty_char="-"
 | 
			
		||||
 | 
			
		||||
  if ! [[ "$current" =~ ^[0-9]+$ ]] || ! [[ "$total" =~ ^[0-9]+$ ]] || [[ "$total" -eq 0 ]]; then
 | 
			
		||||
    printf "\r\e[2K%s %b\n" "$CROSS" "${RD}Invalid progress input${CL}" >&2
 | 
			
		||||
    return
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  percent=$(((current * 100) / total))
 | 
			
		||||
  filled=$(((current * width) / total))
 | 
			
		||||
  empty=$((width - filled))
 | 
			
		||||
 | 
			
		||||
  bar=$(printf "%${filled}s" | tr ' ' "$fill_char")
 | 
			
		||||
  bar+=$(printf "%${empty}s" | tr ' ' "$empty_char")
 | 
			
		||||
 | 
			
		||||
  printf "\r\e[2K%s [%s] %3d%% %s" "${TAB}" "$bar" "$percent" "$label" >&2
 | 
			
		||||
 | 
			
		||||
  if [[ "$current" -eq "$total" ]]; then
 | 
			
		||||
    printf "\n" >&2
 | 
			
		||||
  fi
 | 
			
		||||
  stop_spinner
 | 
			
		||||
  echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
run_container_safe() {
 | 
			
		||||
@@ -560,3 +405,5 @@ check_or_create_swap() {
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trap 'stop_spinner' EXIT INT TERM
 | 
			
		||||
 
 | 
			
		||||
@@ -21,36 +21,67 @@ fi
 | 
			
		||||
# This sets error handling options and defines the error_handler function to handle errors
 | 
			
		||||
set -Eeuo pipefail
 | 
			
		||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
 | 
			
		||||
trap on_exit EXIT
 | 
			
		||||
trap on_interrupt INT
 | 
			
		||||
trap on_terminate TERM
 | 
			
		||||
 | 
			
		||||
function on_exit() {
 | 
			
		||||
  local exit_code="$?"
 | 
			
		||||
  [[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
 | 
			
		||||
  exit "$exit_code"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# This function handles errors
 | 
			
		||||
function error_handler() {
 | 
			
		||||
  printf "\e[?25h"
 | 
			
		||||
 | 
			
		||||
  local exit_code="$?"
 | 
			
		||||
  local line_number="$1"
 | 
			
		||||
  local command="$2"
 | 
			
		||||
  local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
 | 
			
		||||
  echo -e "\n$error_message\n"
 | 
			
		||||
  exit 200
 | 
			
		||||
  printf "\e[?25h"
 | 
			
		||||
  echo -e "\n${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\n"
 | 
			
		||||
  exit "$exit_code"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function on_interrupt() {
 | 
			
		||||
  echo -e "\n${RD}Interrupted by user (SIGINT)${CL}"
 | 
			
		||||
  exit 130
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function on_terminate() {
 | 
			
		||||
  echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}"
 | 
			
		||||
  exit 143
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function check_storage_support() {
 | 
			
		||||
  local CONTENT="$1"
 | 
			
		||||
  local -a VALID_STORAGES=()
 | 
			
		||||
 | 
			
		||||
  while IFS= read -r line; do
 | 
			
		||||
    local STORAGE=$(awk '{print $1}' <<<"$line")
 | 
			
		||||
    [[ "$STORAGE" == "storage" || -z "$STORAGE" ]] && continue
 | 
			
		||||
    VALID_STORAGES+=("$STORAGE")
 | 
			
		||||
  done < <(pvesm status -content "$CONTENT" 2>/dev/null | awk 'NR>1')
 | 
			
		||||
 | 
			
		||||
  [[ ${#VALID_STORAGES[@]} -gt 0 ]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# This checks for the presence of valid Container Storage and Template Storage locations
 | 
			
		||||
msg_info "Validating Storage"
 | 
			
		||||
VALIDCT=$(pvesm status -content rootdir | awk 'NR>1')
 | 
			
		||||
if [ -z "$VALIDCT" ]; then
 | 
			
		||||
  msg_error "Unable to detect a valid Container Storage location."
 | 
			
		||||
if ! check_storage_support "rootdir"; then
 | 
			
		||||
 | 
			
		||||
  msg_error "No valid storage found for 'rootdir' (Container)."
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
VALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1')
 | 
			
		||||
if [ -z "$VALIDTMP" ]; then
 | 
			
		||||
  msg_error "Unable to detect a valid Template Storage location."
 | 
			
		||||
if ! check_storage_support "vztmpl"; then
 | 
			
		||||
 | 
			
		||||
  msg_error "No valid storage found for 'vztmpl' (Template)."
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Validated Storage (rootdir / vztmpl)."
 | 
			
		||||
 | 
			
		||||
# This function is used to select the storage class and determine the corresponding storage content type and label.
 | 
			
		||||
function select_storage() {
 | 
			
		||||
  local CLASS=$1
 | 
			
		||||
  local CONTENT
 | 
			
		||||
  local CONTENT_LABEL
 | 
			
		||||
  local CLASS=$1 CONTENT CONTENT_LABEL
 | 
			
		||||
 | 
			
		||||
  case $CLASS in
 | 
			
		||||
  container)
 | 
			
		||||
    CONTENT='rootdir'
 | 
			
		||||
@@ -60,51 +91,72 @@ function select_storage() {
 | 
			
		||||
    CONTENT='vztmpl'
 | 
			
		||||
    CONTENT_LABEL='Container template'
 | 
			
		||||
    ;;
 | 
			
		||||
  *) false || {
 | 
			
		||||
    msg_error "Invalid storage class."
 | 
			
		||||
    exit 201
 | 
			
		||||
  } ;;
 | 
			
		||||
  iso)
 | 
			
		||||
    CONTENT='iso'
 | 
			
		||||
    CONTENT_LABEL='ISO image'
 | 
			
		||||
    ;;
 | 
			
		||||
  images)
 | 
			
		||||
    CONTENT='images'
 | 
			
		||||
    CONTENT_LABEL='VM Disk image'
 | 
			
		||||
    ;;
 | 
			
		||||
  backup)
 | 
			
		||||
    CONTENT='backup'
 | 
			
		||||
    CONTENT_LABEL='Backup'
 | 
			
		||||
    ;;
 | 
			
		||||
  snippets)
 | 
			
		||||
    CONTENT='snippets'
 | 
			
		||||
    CONTENT_LABEL='Snippets'
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    msg_error "Invalid storage class '$CLASS'"
 | 
			
		||||
    return 1
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  # Collect storage options
 | 
			
		||||
  local -a MENU
 | 
			
		||||
  local MSG_MAX_LENGTH=0
 | 
			
		||||
local -a MENU
 | 
			
		||||
  local -A STORAGE_MAP
 | 
			
		||||
  local COL_WIDTH=0
 | 
			
		||||
 | 
			
		||||
  while read -r TAG TYPE _ _ _ FREE _; do
 | 
			
		||||
    local TYPE_PADDED
 | 
			
		||||
    local FREE_FMT
 | 
			
		||||
 | 
			
		||||
    TYPE_PADDED=$(printf "%-10s" "$TYPE")
 | 
			
		||||
    FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.2f <<<"$FREE")B
 | 
			
		||||
    local ITEM="Type: $TYPE_PADDED Free: $FREE_FMT"
 | 
			
		||||
 | 
			
		||||
    ((${#ITEM} + 2 > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=$((${#ITEM} + 2))
 | 
			
		||||
 | 
			
		||||
    MENU+=("$TAG" "$ITEM" "OFF")
 | 
			
		||||
  while read -r TAG TYPE _ TOTAL USED FREE _; do
 | 
			
		||||
    [[ -n "$TAG" && -n "$TYPE" ]] || continue
 | 
			
		||||
    local DISPLAY="${TAG} (${TYPE})"
 | 
			
		||||
    local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED")
 | 
			
		||||
    local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE")
 | 
			
		||||
    local INFO="Free: ${FREE_FMT}B  Used: ${USED_FMT}B"
 | 
			
		||||
    STORAGE_MAP["$DISPLAY"]="$TAG"
 | 
			
		||||
    MENU+=("$DISPLAY" "$INFO" "OFF")
 | 
			
		||||
    ((${#DISPLAY} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY}
 | 
			
		||||
  done < <(pvesm status -content "$CONTENT" | awk 'NR>1')
 | 
			
		||||
 | 
			
		||||
  local OPTION_COUNT=$((${#MENU[@]} / 3))
 | 
			
		||||
  if [ ${#MENU[@]} -eq 0 ]; then
 | 
			
		||||
    msg_error "No storage found for content type '$CONTENT'."
 | 
			
		||||
    return 2
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Auto-select if only one option available
 | 
			
		||||
  if [[ "$OPTION_COUNT" -eq 1 ]]; then
 | 
			
		||||
    echo "${MENU[0]}"
 | 
			
		||||
  if [ $((${#MENU[@]} / 3)) -eq 1 ]; then
 | 
			
		||||
    STORAGE_RESULT="${STORAGE_MAP[${MENU[0]}]}"
 | 
			
		||||
    return 0
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Display selection menu
 | 
			
		||||
  local STORAGE
 | 
			
		||||
  while [[ -z "${STORAGE:+x}" ]]; do
 | 
			
		||||
    STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
 | 
			
		||||
      "Select the storage pool to use for the ${CONTENT_LABEL,,}.\nUse the spacebar to make a selection.\n" \
 | 
			
		||||
      16 $((MSG_MAX_LENGTH + 23)) 6 \
 | 
			
		||||
      "${MENU[@]}" 3>&1 1>&2 2>&3) || {
 | 
			
		||||
      msg_error "Storage selection cancelled."
 | 
			
		||||
      exit 202
 | 
			
		||||
    }
 | 
			
		||||
  done
 | 
			
		||||
  local WIDTH=$((COL_WIDTH + 42))
 | 
			
		||||
  while true; do
 | 
			
		||||
    local DISPLAY_SELECTED=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
 | 
			
		||||
      --title "Storage Pools" \
 | 
			
		||||
      --radiolist "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \
 | 
			
		||||
      16 "$WIDTH" 6 "${MENU[@]}" 3>&1 1>&2 2>&3)
 | 
			
		||||
 | 
			
		||||
  echo "$STORAGE"
 | 
			
		||||
    [[ $? -ne 0 ]] && return 3
 | 
			
		||||
 | 
			
		||||
    if [[ -z "$DISPLAY_SELECTED" || -z "${STORAGE_MAP[$DISPLAY_SELECTED]+_}" ]]; then
 | 
			
		||||
      whiptail --msgbox "No valid storage selected. Please try again." 8 58
 | 
			
		||||
      continue
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    STORAGE_RESULT="${STORAGE_MAP[$DISPLAY_SELECTED]}"
 | 
			
		||||
    return 0
 | 
			
		||||
  done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Test if required variables are set
 | 
			
		||||
[[ "${CTID:-}" ]] || {
 | 
			
		||||
  msg_error "You need to set 'CTID' variable."
 | 
			
		||||
@@ -129,13 +181,55 @@ if qm status "$CTID" &>/dev/null || pct status "$CTID" &>/dev/null; then
 | 
			
		||||
  exit 206
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Get template storage
 | 
			
		||||
TEMPLATE_STORAGE=$(select_storage template)
 | 
			
		||||
msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage."
 | 
			
		||||
# DEFAULT_FILE="/usr/local/community-scripts/default_storage"
 | 
			
		||||
# if [[ -f "$DEFAULT_FILE" ]]; then
 | 
			
		||||
#   source "$DEFAULT_FILE"
 | 
			
		||||
#   if [[ -n "$TEMPLATE_STORAGE" && -n "$CONTAINER_STORAGE" ]]; then
 | 
			
		||||
#     msg_info "Using default storage configuration from: $DEFAULT_FILE"
 | 
			
		||||
#     msg_ok "Template Storage: ${BL}$TEMPLATE_STORAGE${CL} ${GN}|${CL} Container Storage: ${BL}$CONTAINER_STORAGE${CL}"
 | 
			
		||||
#   else
 | 
			
		||||
#     msg_warn "Default storage file exists but is incomplete – falling back to manual selection"
 | 
			
		||||
#     TEMPLATE_STORAGE=$(select_storage template)
 | 
			
		||||
#     msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage."
 | 
			
		||||
#     CONTAINER_STORAGE=$(select_storage container)
 | 
			
		||||
#     msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage."
 | 
			
		||||
#   fi
 | 
			
		||||
# else
 | 
			
		||||
#   # TEMPLATE STORAGE SELECTION
 | 
			
		||||
#   # Template Storage
 | 
			
		||||
#   while true; do
 | 
			
		||||
#     TEMPLATE_STORAGE=$(select_storage template)
 | 
			
		||||
#     if [[ -n "$TEMPLATE_STORAGE" ]]; then
 | 
			
		||||
#       msg_ok "Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage."
 | 
			
		||||
#       break
 | 
			
		||||
#     fi
 | 
			
		||||
#     msg_warn "No valid template storage selected. Please try again."
 | 
			
		||||
#   done
 | 
			
		||||
 | 
			
		||||
# Get container storage
 | 
			
		||||
CONTAINER_STORAGE=$(select_storage container)
 | 
			
		||||
msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage."
 | 
			
		||||
#   while true; do
 | 
			
		||||
#     CONTAINER_STORAGE=$(select_storage container)
 | 
			
		||||
#     if [[ -n "$CONTAINER_STORAGE" ]]; then
 | 
			
		||||
#       msg_ok "Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage."
 | 
			
		||||
#       break
 | 
			
		||||
#     fi
 | 
			
		||||
#     msg_warn "No valid container storage selected. Please try again."
 | 
			
		||||
#   done
 | 
			
		||||
 | 
			
		||||
# fi
 | 
			
		||||
 | 
			
		||||
while true; do
 | 
			
		||||
  if select_storage template; then
 | 
			
		||||
    TEMPLATE_STORAGE="$STORAGE_RESULT"
 | 
			
		||||
    break
 | 
			
		||||
  fi
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
while true; do
 | 
			
		||||
  if select_storage container; then
 | 
			
		||||
    CONTAINER_STORAGE="$STORAGE_RESULT"
 | 
			
		||||
    break
 | 
			
		||||
  fi
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Check free space on selected container storage
 | 
			
		||||
STORAGE_FREE=$(pvesm status | awk -v s="$CONTAINER_STORAGE" '$1 == s { print $6 }')
 | 
			
		||||
@@ -204,7 +298,7 @@ if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE" || ! zstdcat "$TEMPLAT
 | 
			
		||||
  done
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
msg_ok "LXC Template '$TEMPLATE' is ready to use."
 | 
			
		||||
msg_info "Creating LXC Container"
 | 
			
		||||
# Check and fix subuid/subgid
 | 
			
		||||
grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
 | 
			
		||||
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
 | 
			
		||||
@@ -215,12 +309,15 @@ PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
 | 
			
		||||
 | 
			
		||||
# Secure creation of the LXC container with lock and template check
 | 
			
		||||
lockfile="/tmp/template.${TEMPLATE}.lock"
 | 
			
		||||
exec 9>"$lockfile"
 | 
			
		||||
exec 9>"$lockfile" >/dev/null 2>&1 || {
 | 
			
		||||
  msg_error "Failed to create lock file '$lockfile'."
 | 
			
		||||
  exit 200
 | 
			
		||||
}
 | 
			
		||||
flock -w 60 9 || {
 | 
			
		||||
  msg_error "Timeout while waiting for template lock"
 | 
			
		||||
  exit 211
 | 
			
		||||
}
 | 
			
		||||
msg_info "Creating LXC Container"
 | 
			
		||||
 | 
			
		||||
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
 | 
			
		||||
  msg_error "Container creation failed. Checking if template is corrupted or incomplete."
 | 
			
		||||
 | 
			
		||||
@@ -252,16 +349,23 @@ if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[
 | 
			
		||||
  sleep 1 # I/O-Sync-Delay
 | 
			
		||||
 | 
			
		||||
  msg_ok "Re-downloaded LXC Template"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
  if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
 | 
			
		||||
    msg_error "Container creation failed after re-downloading template."
 | 
			
		||||
    exit 200
 | 
			
		||||
if ! pct list | awk '{print $1}' | grep -qx "$CTID"; then
 | 
			
		||||
  msg_error "Container ID $CTID not listed in 'pct list' – unexpected failure."
 | 
			
		||||
  exit 215
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if ! grep -q '^rootfs:' "/etc/pve/lxc/$CTID.conf"; then
 | 
			
		||||
  msg_error "RootFS entry missing in container config – storage not correctly assigned."
 | 
			
		||||
  exit 216
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if grep -q '^hostname:' "/etc/pve/lxc/$CTID.conf"; then
 | 
			
		||||
  CT_HOSTNAME=$(grep '^hostname:' "/etc/pve/lxc/$CTID.conf" | awk '{print $2}')
 | 
			
		||||
  if [[ ! "$CT_HOSTNAME" =~ ^[a-z0-9-]+$ ]]; then
 | 
			
		||||
    msg_warn "Hostname '$CT_HOSTNAME' contains invalid characters – may cause issues with networking or DNS."
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if ! pct status "$CTID" &>/dev/null; then
 | 
			
		||||
  msg_error "Container not found after pct create – assuming failure."
 | 
			
		||||
  exit 210
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
 | 
			
		||||
 
 | 
			
		||||
@@ -62,9 +62,11 @@ setting_up_container() {
 | 
			
		||||
  rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
  systemctl disable -q --now systemd-networkd-wait-online.service
 | 
			
		||||
  msg_ok "Set up Container OS"
 | 
			
		||||
  msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)"
 | 
			
		||||
  #msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)"
 | 
			
		||||
  msg_ok "Network Connected: ${BL}$(hostname -I)"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
 | 
			
		||||
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
 | 
			
		||||
network_check() {
 | 
			
		||||
  set +e
 | 
			
		||||
@@ -72,6 +74,7 @@ network_check() {
 | 
			
		||||
  ipv4_connected=false
 | 
			
		||||
  ipv6_connected=false
 | 
			
		||||
  sleep 1
 | 
			
		||||
 | 
			
		||||
  # Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers.
 | 
			
		||||
  if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
 | 
			
		||||
    msg_ok "IPv4 Internet Connected"
 | 
			
		||||
@@ -100,25 +103,26 @@ network_check() {
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # DNS resolution checks for GitHub-related domains (IPv4 and/or IPv6)
 | 
			
		||||
  GITHUB_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com")
 | 
			
		||||
  GITHUB_STATUS="GitHub DNS:"
 | 
			
		||||
  GIT_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org")
 | 
			
		||||
  GIT_STATUS="Git DNS:"
 | 
			
		||||
  DNS_FAILED=false
 | 
			
		||||
 | 
			
		||||
  for HOST in "${GITHUB_HOSTS[@]}"; do
 | 
			
		||||
  for HOST in "${GIT_HOSTS[@]}"; do
 | 
			
		||||
    RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1)
 | 
			
		||||
    if [[ -z "$RESOLVEDIP" ]]; then
 | 
			
		||||
      GITHUB_STATUS+="$HOST:($DNSFAIL)"
 | 
			
		||||
      GIT_STATUS+="$HOST:($DNSFAIL)"
 | 
			
		||||
      DNS_FAILED=true
 | 
			
		||||
    else
 | 
			
		||||
      GITHUB_STATUS+=" $HOST:($DNSOK)"
 | 
			
		||||
      GIT_STATUS+=" $HOST:($DNSOK)"
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  if [[ "$DNS_FAILED" == true ]]; then
 | 
			
		||||
    fatal "$GITHUB_STATUS"
 | 
			
		||||
    fatal "$GIT_STATUS"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "$GITHUB_STATUS"
 | 
			
		||||
    msg_ok "$GIT_STATUS"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  set -e
 | 
			
		||||
  trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										251
									
								
								misc/tools.func
									
									
									
									
									
								
							
							
						
						
									
										251
									
								
								misc/tools.func
									
									
									
									
									
								
							@@ -239,10 +239,14 @@ setup_mariadb() {
 | 
			
		||||
  DISTRO_CODENAME="$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)"
 | 
			
		||||
  CURRENT_OS="$(awk -F= '/^ID=/{print $2}' /etc/os-release)"
 | 
			
		||||
 | 
			
		||||
  if ! curl -fsI http://mirror.mariadb.org/repo/ >/dev/null; then
 | 
			
		||||
    msg_error "MariaDB mirror not reachable"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  msg_info "Setting up MariaDB $MARIADB_VERSION"
 | 
			
		||||
  # grab dynamic latest LTS version
 | 
			
		||||
  if [[ "$MARIADB_VERSION" == "latest" ]]; then
 | 
			
		||||
    $STD msg_info "Resolving latest GA MariaDB version"
 | 
			
		||||
    MARIADB_VERSION=$(curl -fsSL http://mirror.mariadb.org/repo/ |
 | 
			
		||||
      grep -Eo '[0-9]+\.[0-9]+\.[0-9]+/' |
 | 
			
		||||
      grep -vE 'rc/|rolling/' |
 | 
			
		||||
@@ -253,7 +257,6 @@ setup_mariadb() {
 | 
			
		||||
      msg_error "Could not determine latest GA MariaDB version"
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    $STD msg_ok "Latest GA MariaDB version is $MARIADB_VERSION"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  local CURRENT_VERSION=""
 | 
			
		||||
@@ -278,7 +281,6 @@ setup_mariadb() {
 | 
			
		||||
    $STD msg_info "Setup MariaDB $MARIADB_VERSION"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  $STD msg_info "Setting up MariaDB Repository"
 | 
			
		||||
  curl -fsSL "https://mariadb.org/mariadb_release_signing_key.asc" |
 | 
			
		||||
    gpg --dearmor -o /etc/apt/trusted.gpg.d/mariadb.gpg
 | 
			
		||||
 | 
			
		||||
@@ -366,25 +368,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:-}"
 | 
			
		||||
@@ -433,6 +416,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}"
 | 
			
		||||
@@ -441,11 +431,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
 | 
			
		||||
@@ -456,10 +452,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
 | 
			
		||||
@@ -649,6 +641,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"
 | 
			
		||||
@@ -757,6 +758,7 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
  local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile
 | 
			
		||||
  local version="${4:-latest}"
 | 
			
		||||
  local target="${5:-/opt/$app}"
 | 
			
		||||
  local asset_pattern="${6:-}"
 | 
			
		||||
 | 
			
		||||
  local app_lc=$(echo "${app,,}" | tr -d ' ')
 | 
			
		||||
  local version_file="$HOME/.${app_lc}"
 | 
			
		||||
@@ -851,9 +853,9 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
    assets=$(echo "$json" | jq -r '.assets[].browser_download_url')
 | 
			
		||||
 | 
			
		||||
    # If explicit filename pattern is provided (param $6), match that first
 | 
			
		||||
    if [[ -n "$6" ]]; then
 | 
			
		||||
    if [[ -n "$asset_pattern" ]]; then
 | 
			
		||||
      for u in $assets; do
 | 
			
		||||
        [[ "$u" =~ $6 || "$u" == *"$6" ]] && url_match="$u" && break
 | 
			
		||||
        [[ "$u" =~ $asset_pattern || "$u" == *"$asset_pattern" ]] && url_match="$u" && break
 | 
			
		||||
      done
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
@@ -896,7 +898,7 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ### Prebuild Mode ###
 | 
			
		||||
  ### Prebuild Mode ###
 | 
			
		||||
  elif [[ "$mode" == "prebuild" ]]; then
 | 
			
		||||
    local pattern="${6%\"}"
 | 
			
		||||
    pattern="${pattern#\"}"
 | 
			
		||||
@@ -915,7 +917,6 @@ function fetch_and_deploy_gh_release() {
 | 
			
		||||
        break
 | 
			
		||||
        ;;
 | 
			
		||||
      esac
 | 
			
		||||
 | 
			
		||||
    done
 | 
			
		||||
 | 
			
		||||
    [[ -z "$asset_url" ]] && {
 | 
			
		||||
@@ -931,20 +932,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%\"}"
 | 
			
		||||
@@ -974,13 +997,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"
 | 
			
		||||
@@ -1659,3 +1689,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"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user