mirror of
				https://github.com/community-scripts/ProxmoxVE.git
				synced 2025-11-04 10:22:50 +00:00 
			
		
		
		
	Compare commits
	
		
			58 Commits
		
	
	
		
			2025-01-26
			...
			2025-01-28
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					645972077e | ||
| 
						 | 
					24dfa9590e | ||
| 
						 | 
					cecf179b34 | ||
| 
						 | 
					1f39208c1c | ||
| 
						 | 
					63061942b9 | ||
| 
						 | 
					87a987ba35 | ||
| 
						 | 
					0680fbfac7 | ||
| 
						 | 
					41a836f990 | ||
| 
						 | 
					ad14b1b1d6 | ||
| 
						 | 
					94d60a79d6 | ||
| 
						 | 
					f10e625e41 | ||
| 
						 | 
					dae705056c | ||
| 
						 | 
					b973ca9d8d | ||
| 
						 | 
					1cf8f80c71 | ||
| 
						 | 
					97002e7047 | ||
| 
						 | 
					d366d24dea | ||
| 
						 | 
					05e46a07cd | ||
| 
						 | 
					af166e3346 | ||
| 
						 | 
					8221614cab | ||
| 
						 | 
					b70cd00764 | ||
| 
						 | 
					31473b2170 | ||
| 
						 | 
					690d6d42d4 | ||
| 
						 | 
					3be6824844 | ||
| 
						 | 
					f903cfd97a | ||
| 
						 | 
					901db73d78 | ||
| 
						 | 
					67b80306a1 | ||
| 
						 | 
					7dc446c8ac | ||
| 
						 | 
					9435b9d046 | ||
| 
						 | 
					2b1b517f20 | ||
| 
						 | 
					7c297d3dac | ||
| 
						 | 
					dbb9b66355 | ||
| 
						 | 
					ff06d417b5 | ||
| 
						 | 
					84b982ffa8 | ||
| 
						 | 
					53c7ab19f8 | ||
| 
						 | 
					d13c1e5722 | ||
| 
						 | 
					be92f947cd | ||
| 
						 | 
					452012529c | ||
| 
						 | 
					661654987d | ||
| 
						 | 
					c3a21069d2 | ||
| 
						 | 
					4de8c1c358 | ||
| 
						 | 
					cd86921467 | ||
| 
						 | 
					38a540b87a | ||
| 
						 | 
					8cd3669edb | ||
| 
						 | 
					adfbff63bc | ||
| 
						 | 
					47bf8e6f86 | ||
| 
						 | 
					43f05b3aba | ||
| 
						 | 
					b17befec88 | ||
| 
						 | 
					719da560d1 | ||
| 
						 | 
					ac25b5a702 | ||
| 
						 | 
					ce1a38eb50 | ||
| 
						 | 
					030174f508 | ||
| 
						 | 
					7e1fb858d7 | ||
| 
						 | 
					5dc1a7d219 | ||
| 
						 | 
					14247ac5a9 | ||
| 
						 | 
					4911a7918a | ||
| 
						 | 
					b06ad8bde8 | ||
| 
						 | 
					8a6364902e | ||
| 
						 | 
					dfd56aebf2 | 
							
								
								
									
										7
									
								
								.github/CONTRIBUTOR_GUIDE/ct/AppName.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/CONTRIBUTOR_GUIDE/ct/AppName.md
									
									
									
									
										vendored
									
									
								
							@@ -40,8 +40,8 @@
 | 
			
		||||
- Import the build.func file.
 | 
			
		||||
- When developing your own script, change the URL to your own repository.
 | 
			
		||||
 | 
			
		||||
> [!CAUTION]
 | 
			
		||||
> Before opening a Pull Request, change the URL to point to the community-scripts repo.
 | 
			
		||||
> [!IMPORTANT] 
 | 
			
		||||
> You also need to change all apperances of this URL in `misc/build.func` and `misc/install.func`
 | 
			
		||||
 | 
			
		||||
Example for development:
 | 
			
		||||
 | 
			
		||||
@@ -55,6 +55,9 @@ Final script:
 | 
			
		||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> [!CAUTION]
 | 
			
		||||
> Before opening a Pull Request, change the URLs to point to the community-scripts repo.
 | 
			
		||||
 | 
			
		||||
### 1.3 **Metadata**
 | 
			
		||||
 | 
			
		||||
- Add clear comments for script metadata, including author, copyright, and license information.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								.github/workflows/auto-update-app-headers.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/auto-update-app-headers.yml
									
									
									
									
										vendored
									
									
								
							@@ -45,28 +45,26 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      # Step 6: Check if there are any changes
 | 
			
		||||
      - name: Check if there are any changes
 | 
			
		||||
        id: verify-diff
 | 
			
		||||
        run: |
 | 
			
		||||
          echo "Checking for changes..."
 | 
			
		||||
          git add -A  # Untracked Dateien aufnehmen
 | 
			
		||||
          git status
 | 
			
		||||
          if git diff --quiet; then
 | 
			
		||||
          if git diff --cached --quiet; then
 | 
			
		||||
            echo "No changes detected."
 | 
			
		||||
            echo "changed=false" >> $GITHUB_OUTPUT
 | 
			
		||||
            echo "changed=false" >> "$GITHUB_ENV"
 | 
			
		||||
          else
 | 
			
		||||
            echo "Changes detected:"
 | 
			
		||||
            git diff --stat
 | 
			
		||||
            echo "changed=true" >> $GITHUB_OUTPUT
 | 
			
		||||
            git diff --stat --cached
 | 
			
		||||
            echo "changed=true" >> "$GITHUB_ENV"
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
      # Step 7: Commit changes (if any) and create a PR
 | 
			
		||||
      # Step 7: Commit and create PR if changes exist
 | 
			
		||||
      - name: Commit and create PR if changes exist
 | 
			
		||||
        if: steps.verify-diff.outputs.changed == 'true'
 | 
			
		||||
        if: env.changed == 'true'
 | 
			
		||||
        run: |
 | 
			
		||||
          git add -A
 | 
			
		||||
          git commit -m "Update .app files"
 | 
			
		||||
          git checkout -b pr-update-app-files
 | 
			
		||||
          git push origin pr-update-app-files --force
 | 
			
		||||
 | 
			
		||||
          gh pr create --title "[core] update .app files" \
 | 
			
		||||
                       --body "This PR is auto-generated by a GitHub Action to update the .app files." \
 | 
			
		||||
                       --head pr-update-app-files \
 | 
			
		||||
@@ -77,6 +75,5 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      # Step 8: Output success message when no changes
 | 
			
		||||
      - name: No changes detected
 | 
			
		||||
        if: steps.verify-diff.outputs.changed == 'false'
 | 
			
		||||
        if: env.changed == 'false'
 | 
			
		||||
        run: echo "No changes to commit. Workflow completed successfully."
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -17,6 +17,54 @@ All LXC instances created using this repository come pre-installed with Midnight
 | 
			
		||||
Do not break established syntax in this file, as it is automatically updated by a Github Workflow
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 2025-01-28
 | 
			
		||||
 | 
			
		||||
### Changed
 | 
			
		||||
 | 
			
		||||
### 💥 Breaking Changes
 | 
			
		||||
 | 
			
		||||
- Breaking Change: Homarr v1 (Read Guide) [@MickLesk](https://github.com/MickLesk) ([#1825](https://github.com/community-scripts/ProxmoxVE/pull/1825))
 | 
			
		||||
- Update PingVin: Fix problem with update und switch to new method of getting files. [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#1819](https://github.com/community-scripts/ProxmoxVE/pull/1819))
 | 
			
		||||
 | 
			
		||||
### ✨ New Scripts
 | 
			
		||||
 | 
			
		||||
- New script: Monica LXC [@bvdberg01](https://github.com/bvdberg01) ([#1813](https://github.com/community-scripts/ProxmoxVE/pull/1813))
 | 
			
		||||
- New Script: NodeBB [@MickLesk](https://github.com/MickLesk) ([#1811](https://github.com/community-scripts/ProxmoxVE/pull/1811))
 | 
			
		||||
- New Script: Pocket ID [@Snarkenfaugister](https://github.com/Snarkenfaugister) ([#1779](https://github.com/community-scripts/ProxmoxVE/pull/1779))
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
- Update all Alpine LXC's to 3.21 (Docker, Grafana, Nextcloud, Vaultwarden, Zigbee2Mqtt, Alpine) [@MickLesk](https://github.com/MickLesk) ([#1803](https://github.com/community-scripts/ProxmoxVE/pull/1803))
 | 
			
		||||
- [Standardization] Fix Spelling for "Setup Python3" [@MickLesk](https://github.com/MickLesk) ([#1810](https://github.com/community-scripts/ProxmoxVE/pull/1810))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
- Filter out duplicate scripts in LatestScripts component and sort by creation date [@BramSuurdje](https://github.com/BramSuurdje) ([#1828](https://github.com/community-scripts/ProxmoxVE/pull/1828))
 | 
			
		||||
 | 
			
		||||
### 🧰 Maintenance
 | 
			
		||||
 | 
			
		||||
- [core]: Remove Figlet | Get Headers by Repo & Store Local [@MickLesk](https://github.com/MickLesk) ([#1802](https://github.com/community-scripts/ProxmoxVE/pull/1802))
 | 
			
		||||
- [docs] Update AppName.md: Make it clear where to change the URLs [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#1809](https://github.com/community-scripts/ProxmoxVE/pull/1809))
 | 
			
		||||
 | 
			
		||||
## 2025-01-27
 | 
			
		||||
 | 
			
		||||
### Changed
 | 
			
		||||
 | 
			
		||||
### ✨ New Scripts
 | 
			
		||||
 | 
			
		||||
- New Script: Arch Linux VM [@MickLesk](https://github.com/MickLesk) ([#1780](https://github.com/community-scripts/ProxmoxVE/pull/1780))
 | 
			
		||||
 | 
			
		||||
### 🚀 Updated Scripts
 | 
			
		||||
 | 
			
		||||
- Increase alpine-vaultwarden default var_disk size [@nayzm](https://github.com/nayzm) ([#1788](https://github.com/community-scripts/ProxmoxVE/pull/1788))
 | 
			
		||||
- Added change of the mobile GUI to disable nag request [@GarryG](https://github.com/GarryG) ([#1785](https://github.com/community-scripts/ProxmoxVE/pull/1785))
 | 
			
		||||
 | 
			
		||||
### 🌐 Website
 | 
			
		||||
 | 
			
		||||
- Update frontend alpine-vaultwarden hdd size and OS version [@nayzm](https://github.com/nayzm) ([#1789](https://github.com/community-scripts/ProxmoxVE/pull/1789))
 | 
			
		||||
- Website: Add Description for Metadata Categories [@MickLesk](https://github.com/MickLesk) ([#1783](https://github.com/community-scripts/ProxmoxVE/pull/1783))
 | 
			
		||||
- [Fix] Double "VM" on website (Arch Linux) [@lasharor](https://github.com/lasharor) ([#1782](https://github.com/community-scripts/ProxmoxVE/pull/1782))
 | 
			
		||||
 | 
			
		||||
## 2025-01-26
 | 
			
		||||
 | 
			
		||||
### Changed
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ var_cpu="1"
 | 
			
		||||
var_ram="1024"
 | 
			
		||||
var_disk="2"
 | 
			
		||||
var_os="alpine"
 | 
			
		||||
var_version="3.20"
 | 
			
		||||
var_version="3.21"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ var_cpu="1"
 | 
			
		||||
var_ram="256"
 | 
			
		||||
var_disk="1"
 | 
			
		||||
var_os="alpine"
 | 
			
		||||
var_version="3.20"
 | 
			
		||||
var_version="3.21"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ var_cpu="2"
 | 
			
		||||
var_ram="1024"
 | 
			
		||||
var_disk="2"
 | 
			
		||||
var_os="alpine"
 | 
			
		||||
var_version="3.20"
 | 
			
		||||
var_version="3.21"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,9 @@ APP="Alpine-Vaultwarden"
 | 
			
		||||
var_tags="alpine;vault"
 | 
			
		||||
var_cpu="1"
 | 
			
		||||
var_ram="256"
 | 
			
		||||
var_disk="0.3"
 | 
			
		||||
var_disk="0.5"
 | 
			
		||||
var_os="alpine"
 | 
			
		||||
var_version="3.20"
 | 
			
		||||
var_version="3.21"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ var_disk="0.3"
 | 
			
		||||
var_cpu="1"
 | 
			
		||||
var_ram="256"
 | 
			
		||||
var_os="alpine"
 | 
			
		||||
var_version="3.20"
 | 
			
		||||
var_version="3.21"
 | 
			
		||||
var_unprivileged="0"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ var_cpu="1"
 | 
			
		||||
var_ram="512"
 | 
			
		||||
var_disk="0.1"
 | 
			
		||||
var_os="alpine"
 | 
			
		||||
var_version="3.20"
 | 
			
		||||
var_version="3.21"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/monica
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/monica
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
    __  ___            _           
 | 
			
		||||
   /  |/  /___  ____  (_)________ _
 | 
			
		||||
  / /|_/ / __ \/ __ \/ / ___/ __ `/
 | 
			
		||||
 / /  / / /_/ / / / / / /__/ /_/ / 
 | 
			
		||||
/_/  /_/\____/_/ /_/_/\___/\__,_/  
 | 
			
		||||
                                   
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/nodebb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/nodebb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
    _   __          __     ____  ____ 
 | 
			
		||||
   / | / /___  ____/ /__  / __ )/ __ )
 | 
			
		||||
  /  |/ / __ \/ __  / _ \/ __  / __  |
 | 
			
		||||
 / /|  / /_/ / /_/ /  __/ /_/ / /_/ / 
 | 
			
		||||
/_/ |_/\____/\__,_/\___/_____/_____/  
 | 
			
		||||
                                      
 | 
			
		||||
							
								
								
									
										6
									
								
								ct/headers/pocketid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ct/headers/pocketid
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
    ____             __        __  ________ 
 | 
			
		||||
   / __ \____  _____/ /_____  / /_/  _/ __ \
 | 
			
		||||
  / /_/ / __ \/ ___/ //_/ _ \/ __// // / / /
 | 
			
		||||
 / ____/ /_/ / /__/ ,< /  __/ /__/ // /_/ / 
 | 
			
		||||
/_/    \____/\___/_/|_|\___/\__/___/_____/  
 | 
			
		||||
                                            
 | 
			
		||||
							
								
								
									
										41
									
								
								ct/homarr.sh
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								ct/homarr.sh
									
									
									
									
									
								
							@@ -9,7 +9,7 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/m
 | 
			
		||||
APP="Homarr"
 | 
			
		||||
var_tags="arr;dashboard"
 | 
			
		||||
var_cpu="2"
 | 
			
		||||
var_ram="2048"
 | 
			
		||||
var_ram="4096"
 | 
			
		||||
var_disk="8"
 | 
			
		||||
var_os="debian"
 | 
			
		||||
var_version="12"
 | 
			
		||||
@@ -32,46 +32,47 @@ function update_script() {
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
if [[ -f /opt/homarr/database/db.sqlite ]]; then
 | 
			
		||||
    msg_error "Old Homarr detected due to existing database file (/opt/homarr/database/db.sqlite)."
 | 
			
		||||
    msg_error "Update not supported. Refer to:"
 | 
			
		||||
    msg_error " - https://github.com/community-scripts/ProxmoxVE/discussions/1551"
 | 
			
		||||
    msg_error " - https://homarr.dev/docs/getting-started/after-the-installation/#importing-a-zip-from-version-before-100"
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
  RELEASE=$(curl -s https://api.github.com/repos/homarr-labs/homarr/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 homarr
 | 
			
		||||
    msg_ok "Services Stopped"
 | 
			
		||||
 | 
			
		||||
    msg_info "Backing up Data"
 | 
			
		||||
    msg_info "Backup Data"
 | 
			
		||||
    mkdir -p /opt/homarr-data-backup
 | 
			
		||||
    cp /opt/homarr/.env /opt/homarr-data-backup/.env
 | 
			
		||||
    cp /opt/homarr/database/db.sqlite /opt/homarr-data-backup/db.sqlite
 | 
			
		||||
    cp -r /opt/homarr/data/configs /opt/homarr-data-backup/configs
 | 
			
		||||
    msg_ok "Backed up Data"
 | 
			
		||||
    msg_ok "Backup Data"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to ${RELEASE}"
 | 
			
		||||
    wget -q "https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    wget -q "https://github.com/homarr-labs/homarr/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
    unzip -q v${RELEASE}.zip
 | 
			
		||||
    rm -rf v${RELEASE}.zip
 | 
			
		||||
    rm -rf /opt/homarr
 | 
			
		||||
    mv homarr-${RELEASE} /opt/homarr
 | 
			
		||||
    mv /opt/homarr-data-backup/.env /opt/homarr/.env
 | 
			
		||||
    cd /opt/homarr
 | 
			
		||||
    yarn install &>/dev/null
 | 
			
		||||
    yarn build &>/dev/null
 | 
			
		||||
    pnpm install &>/dev/null
 | 
			
		||||
    pnpm run db:migration:sqlite:run &>/dev/null
 | 
			
		||||
    pnpm build &>/dev/null
 | 
			
		||||
    mkdir build
 | 
			
		||||
    cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ${APP}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Restoring Data"
 | 
			
		||||
    rm -rf /opt/homarr/data/configs
 | 
			
		||||
    mv /opt/homarr-data-backup/configs /opt/homarr/data/configs
 | 
			
		||||
    mv /opt/homarr-data-backup/db.sqlite /opt/homarr/database/db.sqlite
 | 
			
		||||
    yarn db:migrate &>/dev/null
 | 
			
		||||
    rm -rf /opt/homarr-data-backup
 | 
			
		||||
    msg_ok "Restored Data"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Services"
 | 
			
		||||
    systemctl start homarr
 | 
			
		||||
    msg_ok "Started Services"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
@@ -83,4 +84,4 @@ description
 | 
			
		||||
msg_ok "Completed Successfully!\n"
 | 
			
		||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
 | 
			
		||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										81
									
								
								ct/monica.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								ct/monica.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: bvdberg01
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://www.monicahq.com/
 | 
			
		||||
 | 
			
		||||
# App Default Values
 | 
			
		||||
APP="Monica"
 | 
			
		||||
var_tags="network"
 | 
			
		||||
var_cpu="2"
 | 
			
		||||
var_ram="2048"
 | 
			
		||||
var_disk="8"
 | 
			
		||||
var_os="debian"
 | 
			
		||||
var_version="12"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
base_settings
 | 
			
		||||
 | 
			
		||||
# Core
 | 
			
		||||
variables
 | 
			
		||||
color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
  if [[ ! -d /opt/monica ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
  RELEASE=$(curl -s https://api.github.com/repos/monicahq/monica/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 Service"
 | 
			
		||||
    systemctl stop apache2
 | 
			
		||||
    msg_ok "Stopped Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt
 | 
			
		||||
    mv /opt/monica/ /opt/monica-backup
 | 
			
		||||
    wget -q "https://github.com/monicahq/monica/releases/download/v${RELEASE}/monica-v${RELEASE}.tar.bz2"
 | 
			
		||||
    tar -xjf "monica-v${RELEASE}.tar.bz2"
 | 
			
		||||
    mv "/opt/monica-v${RELEASE}" /opt/monica
 | 
			
		||||
    cd /opt/monica/
 | 
			
		||||
    cp -r /opt/monica-backup/.env /opt/monica
 | 
			
		||||
    cp -r /opt/monica-backup/storage/* /opt/monica/storage/
 | 
			
		||||
    composer install --no-interaction --no-dev &>/dev/null
 | 
			
		||||
    yarn install &>/dev/null
 | 
			
		||||
    yarn run production &>/dev/null
 | 
			
		||||
    php artisan monica:update --force &>/dev/null
 | 
			
		||||
    chown -R www-data:www-data /opt/monica
 | 
			
		||||
    chmod -R 775 /opt/monica/storage
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated $APP to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Service"
 | 
			
		||||
    systemctl start apache2
 | 
			
		||||
    msg_ok "Started Service"
 | 
			
		||||
 | 
			
		||||
    msg_info "Cleaning up"
 | 
			
		||||
    rm -r "/opt/monica-v${RELEASE}.tar.bz2"
 | 
			
		||||
    rm -r /opt/monica-backup
 | 
			
		||||
    msg_ok "Cleaned"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}"
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
build_container
 | 
			
		||||
description
 | 
			
		||||
 | 
			
		||||
msg_ok "Completed Successfully!\n"
 | 
			
		||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
 | 
			
		||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
 | 
			
		||||
							
								
								
									
										63
									
								
								ct/nodebb.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								ct/nodebb.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: MickLesk (Canbiz)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
 | 
			
		||||
# App Default Values
 | 
			
		||||
APP="NodeBB"
 | 
			
		||||
var_tags="forum"
 | 
			
		||||
var_disk="10"
 | 
			
		||||
var_cpu="4"
 | 
			
		||||
var_ram="2048"
 | 
			
		||||
var_os="ubuntu"
 | 
			
		||||
var_version="24.04"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
 | 
			
		||||
# Core
 | 
			
		||||
variables
 | 
			
		||||
color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
  header_info
 | 
			
		||||
  check_container_storage
 | 
			
		||||
  check_container_resources
 | 
			
		||||
  if [[ ! -d /opt/nodebb ]]; then
 | 
			
		||||
    msg_error "No ${APP} Installation Found!"
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  RELEASE=$(curl -s https://api.github.com/repos/NodeBB/NodeBB/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 nodebb
 | 
			
		||||
    msg_ok "Stopped ${APP}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating ${APP} to v${RELEASE}"
 | 
			
		||||
    cd /opt/nodebb
 | 
			
		||||
    ./nodebb upgrade >/dev/null 2>&1
 | 
			
		||||
    echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
    msg_ok "Updated ${APP} to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting ${APP}"
 | 
			
		||||
    systemctl start nodebb
 | 
			
		||||
    msg_ok "Started ${APP}"
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. ${APP} is already at v${RELEASE}."
 | 
			
		||||
  fi
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
build_container
 | 
			
		||||
description
 | 
			
		||||
 | 
			
		||||
msg_ok "Completed Successfully!\n"
 | 
			
		||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
 | 
			
		||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:4567${CL}"
 | 
			
		||||
@@ -32,30 +32,42 @@ function update_script() {
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
    msg_info "Stopping Pingvin Share"
 | 
			
		||||
    systemctl stop pm2-root.service
 | 
			
		||||
    msg_ok "Stopped Pingvin Share"
 | 
			
		||||
   
 | 
			
		||||
    RELEASE=$(curl -s https://api.github.com/repos/stonith404/pingvin-share/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
    if [[ ! -f /opt/$pingvin_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/pingvin_version.txt)" ]]; then
 | 
			
		||||
      
 | 
			
		||||
      msg_info "Stopping Pingvin Share"
 | 
			
		||||
      systemctl stop pm2-root.service
 | 
			
		||||
      msg_ok "Stopped Pingvin Share"
 | 
			
		||||
      
 | 
			
		||||
      msg_info "Updating Pingvin Share to v${RELEASE}"
 | 
			
		||||
      cd /opt
 | 
			
		||||
      wget -q "https://github.com/stonith404/pingvin-share/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
      unzip -q v${RELEASE}.zip
 | 
			
		||||
      mv pingvin-share-${RELEASE} /opt/pingvin-share  
 | 
			
		||||
      cd /opt/pingvin-share
 | 
			
		||||
      cd backend
 | 
			
		||||
      npm install &>/dev/null
 | 
			
		||||
      npm run build &>/dev/null
 | 
			
		||||
      cd ../frontend
 | 
			
		||||
      npm install &>/dev/null
 | 
			
		||||
      npm run build &>/dev/null
 | 
			
		||||
      echo "${RELEASE}" >"/opt/pingvin_version.txt"
 | 
			
		||||
      rm -rf /opt/v${RELEASE}.zip
 | 
			
		||||
      msg_ok "Updated Pingvin Share to v${RELEASE}"
 | 
			
		||||
 | 
			
		||||
    msg_info "Updating Pingvin Share"
 | 
			
		||||
    cd /opt/pingvin-share
 | 
			
		||||
    git fetch --tags
 | 
			
		||||
    git checkout $(git describe --tags $(git rev-list --tags --max-count=1)) &>/dev/null
 | 
			
		||||
    cd backend
 | 
			
		||||
    npm install &>/dev/null
 | 
			
		||||
    npm run build &>/dev/null
 | 
			
		||||
    cd ../frontend
 | 
			
		||||
    npm install &>/dev/null
 | 
			
		||||
    npm run build &>/dev/null
 | 
			
		||||
    msg_ok "Updated Pingvin Share"
 | 
			
		||||
      msg_info "Starting Pingvin Share"
 | 
			
		||||
      systemctl start pm2-root.service
 | 
			
		||||
      msg_ok "Started Pingvin Share"
 | 
			
		||||
 | 
			
		||||
    msg_info "Starting Pingvin Share"
 | 
			
		||||
    systemctl start pm2-root.service
 | 
			
		||||
    msg_ok "Started Pingvin Share"
 | 
			
		||||
 | 
			
		||||
    msg_ok "Updated Successfully"
 | 
			
		||||
    exit
 | 
			
		||||
      msg_ok "Updated Successfully"
 | 
			
		||||
      exit
 | 
			
		||||
  else
 | 
			
		||||
    msg_ok "No update required. Pingvin Share is already at v${RELEASE}."
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
build_container
 | 
			
		||||
description
 | 
			
		||||
@@ -63,4 +75,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}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										95
									
								
								ct/pocketid.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										95
									
								
								ct/pocketid.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Snarkenfaugister
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/stonith404/pocket-id
 | 
			
		||||
 | 
			
		||||
# App Default Values
 | 
			
		||||
APP="PocketID"
 | 
			
		||||
TAGS="identity-provider"
 | 
			
		||||
var_cpu="2"
 | 
			
		||||
var_ram="2048"
 | 
			
		||||
var_disk="4"
 | 
			
		||||
var_os="debian"
 | 
			
		||||
var_version="12"
 | 
			
		||||
var_unprivileged="1"
 | 
			
		||||
 | 
			
		||||
# App Output & Base Settings
 | 
			
		||||
header_info "$APP"
 | 
			
		||||
base_settings
 | 
			
		||||
 | 
			
		||||
# Core
 | 
			
		||||
variables
 | 
			
		||||
color
 | 
			
		||||
catch_errors
 | 
			
		||||
 | 
			
		||||
function update_script() {
 | 
			
		||||
    header_info
 | 
			
		||||
    check_container_storage
 | 
			
		||||
    check_container_resources
 | 
			
		||||
 | 
			
		||||
    if [[ ! -d /opt/pocket-id ]]; then
 | 
			
		||||
        msg_error "No ${APP} Installation Found!"
 | 
			
		||||
        exit
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    RELEASE=$(curl -fsSL https://api.github.com/repos/stonith404/pocket-id/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 "Updating $APP"
 | 
			
		||||
 | 
			
		||||
        msg_info "Stopping $APP"
 | 
			
		||||
        systemctl stop pocketid-backend.service
 | 
			
		||||
        systemctl stop pocketid-frontend.service
 | 
			
		||||
        systemctl stop caddy.service
 | 
			
		||||
        msg_ok "Stopped $APP"
 | 
			
		||||
 | 
			
		||||
        msg_info "Updating $APP to v${RELEASE}"
 | 
			
		||||
        cd /opt
 | 
			
		||||
        cp -r /opt/pocket-id/backend/data /opt/data
 | 
			
		||||
        cp /opt/pocket-id/backend/.env /opt/backend.env
 | 
			
		||||
        cp /opt/pocket-id/frontend/.env /opt/frontend.env
 | 
			
		||||
        rm -r /opt/pocket-id
 | 
			
		||||
        wget -q "https://github.com/stonith404/pocket-id/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
        unzip -q v${RELEASE}.zip
 | 
			
		||||
        mv pocket-id-${RELEASE} /opt/pocket-id
 | 
			
		||||
        mv /opt/data /opt/pocket-id/backend/data
 | 
			
		||||
        mv /opt/backend.env /opt/pocket-id/backend/.env 
 | 
			
		||||
        mv /opt/frontend.env /opt/pocket-id/frontend/.env 
 | 
			
		||||
 | 
			
		||||
        cd /opt/pocket-id/backend/cmd
 | 
			
		||||
        go build -o ../pocket-id-backend
 | 
			
		||||
        cd ../../frontend
 | 
			
		||||
        npm install
 | 
			
		||||
        npm run build
 | 
			
		||||
        msg_ok "Updated $APP to ${RELEASE}"
 | 
			
		||||
 | 
			
		||||
        msg_info "Starting $APP"
 | 
			
		||||
        systemctl start pocketid-backend.service
 | 
			
		||||
        systemctl start pocketid-frontend.service
 | 
			
		||||
        systemctl start caddy.service
 | 
			
		||||
        sleep 2
 | 
			
		||||
        msg_ok "Started $APP"
 | 
			
		||||
 | 
			
		||||
        # Cleaning up
 | 
			
		||||
        msg_info "Cleaning Up"
 | 
			
		||||
        rm -f /opt/v${RELEASE}.zip
 | 
			
		||||
        msg_ok "Cleanup Completed"
 | 
			
		||||
 | 
			
		||||
        echo "${RELEASE}" >/opt/${APP}_version.txt
 | 
			
		||||
        msg_ok "Update Successful"
 | 
			
		||||
    else
 | 
			
		||||
        msg_ok "No update required. ${APP} is already at ${RELEASE}"
 | 
			
		||||
    fi
 | 
			
		||||
    exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start
 | 
			
		||||
build_container
 | 
			
		||||
description
 | 
			
		||||
 | 
			
		||||
msg_ok "Completed Successfully!\n"
 | 
			
		||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
 | 
			
		||||
echo -e "${INFO}${YW} Configure your reverse proxy to point to:${BGN} ${IP}:80${CL}"
 | 
			
		||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
 | 
			
		||||
echo -e "${TAB}${GATEWAY}${BGN}https://{PUBLIC_URL}/login/setup${CL}"
 | 
			
		||||
@@ -4,15 +4,33 @@ import React, { useEffect, useState } from "react";
 | 
			
		||||
import { useRouter } from "next/navigation";
 | 
			
		||||
import { Card, CardContent } from "@/components/ui/card";
 | 
			
		||||
import { Button } from "@/components/ui/button";
 | 
			
		||||
import { Badge } from "@/components/ui/badge";
 | 
			
		||||
import { ChevronLeft, ChevronRight } from "lucide-react";
 | 
			
		||||
import { Category } from "@/lib/types";
 | 
			
		||||
 | 
			
		||||
const defaultLogo = "/default-logo.png"; // Fallback logo path
 | 
			
		||||
 | 
			
		||||
const MAX_DESCRIPTION_LENGTH = 100; // Set max length for description
 | 
			
		||||
const MAX_LOGOS = 5; // Max logos to display at once
 | 
			
		||||
 | 
			
		||||
const formattedBadge = (type: string) => {
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case "vm":
 | 
			
		||||
      return <Badge className="text-blue-500/75 border-blue-500/75 badge">VM</Badge>;
 | 
			
		||||
    case "ct":
 | 
			
		||||
      return (
 | 
			
		||||
        <Badge className="text-yellow-500/75 border-yellow-500/75 badge">LXC</Badge>
 | 
			
		||||
      );
 | 
			
		||||
    case "misc":
 | 
			
		||||
      return <Badge className="text-green-500/75 border-green-500/75 badge">MISC</Badge>;
 | 
			
		||||
  }
 | 
			
		||||
  return null;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const CategoryView = () => {
 | 
			
		||||
  const [categories, setCategories] = useState<Category[]>([]);
 | 
			
		||||
  const [selectedCategory, setSelectedCategory] = useState<Category | null>(null);
 | 
			
		||||
  const [selectedCategoryIndex, setSelectedCategoryIndex] = useState<number | null>(null);
 | 
			
		||||
  const [currentScripts, setCurrentScripts] = useState<any[]>([]);
 | 
			
		||||
  const [logoIndices, setLogoIndices] = useState<{ [key: string]: number }>({});
 | 
			
		||||
  const router = useRouter();
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
@@ -24,8 +42,14 @@ const CategoryView = () => {
 | 
			
		||||
          throw new Error("Failed to fetch categories");
 | 
			
		||||
        }
 | 
			
		||||
        const data = await response.json();
 | 
			
		||||
        console.log("Fetched categories:", data); // Debugging
 | 
			
		||||
        setCategories(data);
 | 
			
		||||
 | 
			
		||||
        // Initialize logo indices
 | 
			
		||||
        const initialLogoIndices: { [key: string]: number } = {};
 | 
			
		||||
        data.forEach((category: any) => {
 | 
			
		||||
          initialLogoIndices[category.name] = 0;
 | 
			
		||||
        });
 | 
			
		||||
        setLogoIndices(initialLogoIndices);
 | 
			
		||||
      } catch (error) {
 | 
			
		||||
        console.error("Error fetching categories:", error);
 | 
			
		||||
      }
 | 
			
		||||
@@ -34,91 +58,209 @@ const CategoryView = () => {
 | 
			
		||||
    fetchCategories();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  const handleCategoryClick = (category: Category) => {
 | 
			
		||||
    setSelectedCategory(category);
 | 
			
		||||
  const handleCategoryClick = (index: number) => {
 | 
			
		||||
    setSelectedCategoryIndex(index);
 | 
			
		||||
    setCurrentScripts(categories[index]?.scripts || []); // Update scripts for the selected category
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleBackClick = () => {
 | 
			
		||||
    setSelectedCategory(null);
 | 
			
		||||
    setSelectedCategoryIndex(null);
 | 
			
		||||
    setCurrentScripts([]); // Clear scripts when going back
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleScriptClick = (scriptSlug: string) => {
 | 
			
		||||
    router.push(`/scripts?id=${scriptSlug}`);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const navigateCategory = (direction: "prev" | "next") => {
 | 
			
		||||
    if (selectedCategoryIndex !== null) {
 | 
			
		||||
      const newIndex =
 | 
			
		||||
        direction === "prev"
 | 
			
		||||
          ? (selectedCategoryIndex - 1 + categories.length) % categories.length
 | 
			
		||||
          : (selectedCategoryIndex + 1) % categories.length;
 | 
			
		||||
      setSelectedCategoryIndex(newIndex);
 | 
			
		||||
      setCurrentScripts(categories[newIndex]?.scripts || []); // Update scripts for the new category
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const switchLogos = (categoryName: string, direction: "prev" | "next") => {
 | 
			
		||||
    setLogoIndices((prev) => {
 | 
			
		||||
      const currentIndex = prev[categoryName] || 0;
 | 
			
		||||
      const category = categories.find((cat) => cat.name === categoryName);
 | 
			
		||||
      if (!category || !category.scripts) return prev;
 | 
			
		||||
 | 
			
		||||
      const totalLogos = category.scripts.length;
 | 
			
		||||
      const newIndex =
 | 
			
		||||
        direction === "prev"
 | 
			
		||||
          ? (currentIndex - MAX_LOGOS + totalLogos) % totalLogos
 | 
			
		||||
          : (currentIndex + MAX_LOGOS) % totalLogos;
 | 
			
		||||
 | 
			
		||||
      return { ...prev, [categoryName]: newIndex };
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const truncateDescription = (text: string) => {
 | 
			
		||||
    return text.length > MAX_DESCRIPTION_LENGTH
 | 
			
		||||
      ? `${text.slice(0, MAX_DESCRIPTION_LENGTH)}...`
 | 
			
		||||
      : text;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const renderResources = (script: any) => {
 | 
			
		||||
    const cpu = script.install_methods[0]?.resources.cpu;
 | 
			
		||||
    const ram = script.install_methods[0]?.resources.ram;
 | 
			
		||||
    const hdd = script.install_methods[0]?.resources.hdd;
 | 
			
		||||
 | 
			
		||||
    const resourceParts = [];
 | 
			
		||||
    if (cpu) resourceParts.push(<span key="cpu"><b>CPU:</b> {cpu}vCPU</span>);
 | 
			
		||||
    if (ram) resourceParts.push(<span key="ram"><b>RAM:</b> {ram}MB</span>);
 | 
			
		||||
    if (hdd) resourceParts.push(<span key="hdd"><b>HDD:</b> {hdd}GB</span>);
 | 
			
		||||
 | 
			
		||||
    return resourceParts.length > 0 ? (
 | 
			
		||||
      <div className="text-sm text-gray-400">
 | 
			
		||||
        {resourceParts.map((part, index) => (
 | 
			
		||||
          <React.Fragment key={index}>
 | 
			
		||||
            {part}
 | 
			
		||||
            {index < resourceParts.length - 1 && " | "}
 | 
			
		||||
          </React.Fragment>
 | 
			
		||||
        ))}
 | 
			
		||||
      </div>
 | 
			
		||||
    ) : null;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="p-4 mt-20">
 | 
			
		||||
    <div className="p-6 mt-20">
 | 
			
		||||
      {categories.length === 0 && (
 | 
			
		||||
        <p className="text-center text-gray-500">No categories available. Please check the API endpoint.</p>
 | 
			
		||||
      )}
 | 
			
		||||
      {selectedCategory ? (
 | 
			
		||||
      {selectedCategoryIndex !== null ? (
 | 
			
		||||
        <div>
 | 
			
		||||
          <Button variant="default" onClick={handleBackClick} className="mb-4">
 | 
			
		||||
            Back to Categories
 | 
			
		||||
          </Button>
 | 
			
		||||
          <h2 className="text-xl font-semibold mb-4">{selectedCategory.name}</h2>
 | 
			
		||||
          <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
 | 
			
		||||
            {selectedCategory.scripts
 | 
			
		||||
          {/* Header with Navigation */}
 | 
			
		||||
          <div className="flex items-center justify-between mb-6">
 | 
			
		||||
            <Button
 | 
			
		||||
              variant="ghost"
 | 
			
		||||
              onClick={() => navigateCategory("prev")}
 | 
			
		||||
              className="p-2 transition-transform duration-300 hover:scale-105"
 | 
			
		||||
            >
 | 
			
		||||
              <ChevronLeft className="h-6 w-6" />
 | 
			
		||||
            </Button>
 | 
			
		||||
            <h2 className="text-3xl font-semibold transition-opacity duration-300 hover:opacity-90">
 | 
			
		||||
              {categories[selectedCategoryIndex].name}
 | 
			
		||||
            </h2>
 | 
			
		||||
            <Button
 | 
			
		||||
              variant="ghost"
 | 
			
		||||
              onClick={() => navigateCategory("next")}
 | 
			
		||||
              className="p-2 transition-transform duration-300 hover:scale-105"
 | 
			
		||||
            >
 | 
			
		||||
              <ChevronRight className="h-6 w-6" />
 | 
			
		||||
            </Button>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          {/* Scripts Grid */}
 | 
			
		||||
          <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
 | 
			
		||||
            {currentScripts
 | 
			
		||||
              .sort((a, b) => a.name.localeCompare(b.name))
 | 
			
		||||
              .map((script) => (
 | 
			
		||||
                <Card key={script.name} className="p-4 cursor-pointer" onClick={() => handleScriptClick(script.slug)}>
 | 
			
		||||
                <Card
 | 
			
		||||
                  key={script.name}
 | 
			
		||||
                  className="p-4 cursor-pointer hover:shadow-md transition-shadow duration-300"
 | 
			
		||||
                  onClick={() => handleScriptClick(script.slug)}
 | 
			
		||||
                >
 | 
			
		||||
                  <CardContent className="flex flex-col gap-4">
 | 
			
		||||
                    <div className="flex items-center gap-4">
 | 
			
		||||
                      <img
 | 
			
		||||
                        src={script.logo || defaultLogo}
 | 
			
		||||
                        alt={script.name}
 | 
			
		||||
                        className="h-12 w-12 object-contain"
 | 
			
		||||
                      />
 | 
			
		||||
                      <div>
 | 
			
		||||
                        <h3 className="text-lg font-bold">{script.name}</h3>
 | 
			
		||||
                        <p className="text-sm text-gray-500"><b>Created at:</b> {script.date_created || "No date available"}</p>
 | 
			
		||||
                        <p className="text-sm text-gray-700">
 | 
			
		||||
                          {truncateDescription(script.description || "No description available.")}
 | 
			
		||||
                        </p>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div className="text-sm text-gray-600">
 | 
			
		||||
                      <b>CPU:</b> {script.install_methods[0]?.resources.cpu || "N/A"}vCPU | <b>RAM:</b> {script.install_methods[0]?.resources.ram || "N/A"}MB | <b>HDD:</b> {script.install_methods[0]?.resources.hdd || "N/A"}GB
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <h3 className="text-lg font-bold script-text text-center hover:text-blue-600 transition-colors duration-300">
 | 
			
		||||
                      {script.name}
 | 
			
		||||
                    </h3>
 | 
			
		||||
                    <img
 | 
			
		||||
                      src={script.logo || defaultLogo}
 | 
			
		||||
                      alt={script.name || "Script logo"}
 | 
			
		||||
                      className="h-12 w-12 object-contain mx-auto"
 | 
			
		||||
                    />
 | 
			
		||||
                    <p className="text-sm text-gray-500 text-center">
 | 
			
		||||
                      <b>Created at:</b> {script.date_created || "No date available"}
 | 
			
		||||
                    </p>
 | 
			
		||||
                    <p
 | 
			
		||||
                      className="text-sm text-gray-700 hover:text-gray-900 text-center transition-colors duration-300"
 | 
			
		||||
                      title={script.description || "No description available."}
 | 
			
		||||
                    >
 | 
			
		||||
                      {truncateDescription(script.description || "No description available.")}
 | 
			
		||||
                    </p>
 | 
			
		||||
                    {renderResources(script)}
 | 
			
		||||
                  </CardContent>
 | 
			
		||||
                </Card>
 | 
			
		||||
              ))}
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          {/* Back to Categories Button */}
 | 
			
		||||
          <div className="mt-8 text-center">
 | 
			
		||||
            <Button
 | 
			
		||||
              variant="default"
 | 
			
		||||
              onClick={handleBackClick}
 | 
			
		||||
              className="px-6 py-2 text-white bg-blue-600 hover:bg-blue-700 rounded-lg shadow-md transition-transform duration-300 hover:scale-105"
 | 
			
		||||
            >
 | 
			
		||||
              Back to Categories
 | 
			
		||||
            </Button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      ) : (
 | 
			
		||||
        <div>
 | 
			
		||||
          <div className="flex justify-between items-center mb-6">
 | 
			
		||||
            <h1 className="text-2xl font-bold">Categories</h1>
 | 
			
		||||
          {/* Categories Grid */}
 | 
			
		||||
          <div className="flex justify-between items-center mb-8">
 | 
			
		||||
            <h1 className="text-3xl font-semibold mb-4">Categories</h1>
 | 
			
		||||
            <p className="text-sm text-gray-500">
 | 
			
		||||
              {categories.reduce((acc, cat) => acc + (cat.scripts?.length || 0), 0)} Total scripts
 | 
			
		||||
              {categories.reduce((total, category) => total + (category.scripts?.length || 0), 0)} Total scripts
 | 
			
		||||
            </p>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
 | 
			
		||||
            {categories.map((category) => (
 | 
			
		||||
          <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8">
 | 
			
		||||
            {categories.map((category, index) => (
 | 
			
		||||
              <Card
 | 
			
		||||
                key={category.name}
 | 
			
		||||
                onClick={() => handleCategoryClick(category)}
 | 
			
		||||
                className="cursor-pointer hover:shadow-lg flex flex-col items-center justify-center"
 | 
			
		||||
                onClick={() => handleCategoryClick(index)}
 | 
			
		||||
                className="cursor-pointer hover:shadow-lg flex flex-col items-center justify-center py-6 transition-shadow duration-300"
 | 
			
		||||
              >
 | 
			
		||||
                <CardContent className="flex flex-col items-center">
 | 
			
		||||
                  <div className="flex flex-wrap justify-center gap-1 mb-2">
 | 
			
		||||
                    {category.scripts && category.scripts.slice(0, 4).map((script, index) => (
 | 
			
		||||
                      <img
 | 
			
		||||
                        key={index}
 | 
			
		||||
                        src={script.logo || defaultLogo}
 | 
			
		||||
                        alt={script.name || "Script logo"}
 | 
			
		||||
                        className="h-6 w-6 object-contain"
 | 
			
		||||
                      />
 | 
			
		||||
                    ))}
 | 
			
		||||
                  <h3 className="text-xl font-bold mb-4 category-title transition-colors duration-300 hover:text-blue-600">
 | 
			
		||||
                    {category.name}
 | 
			
		||||
                  </h3>
 | 
			
		||||
                  <div className="flex justify-center items-center gap-2 mb-4">
 | 
			
		||||
                    <Button
 | 
			
		||||
                      variant="ghost"
 | 
			
		||||
                      onClick={(e) => {
 | 
			
		||||
                        e.stopPropagation();
 | 
			
		||||
                        switchLogos(category.name, "prev");
 | 
			
		||||
                      }}
 | 
			
		||||
                      className="p-1 transition-transform duration-300 hover:scale-110"
 | 
			
		||||
                    >
 | 
			
		||||
                      <ChevronLeft className="h-4 w-4" />
 | 
			
		||||
                    </Button>
 | 
			
		||||
                    {category.scripts &&
 | 
			
		||||
                      category.scripts
 | 
			
		||||
                        .slice(logoIndices[category.name] || 0, (logoIndices[category.name] || 0) + MAX_LOGOS)
 | 
			
		||||
                        .map((script, i) => (
 | 
			
		||||
                          <div key={i} className="flex flex-col items-center">
 | 
			
		||||
                            <img
 | 
			
		||||
                              src={script.logo || defaultLogo}
 | 
			
		||||
                              alt={script.name || "Script logo"}
 | 
			
		||||
                              title={script.name}
 | 
			
		||||
                              className="h-8 w-8 object-contain cursor-pointer"
 | 
			
		||||
                              onClick={(e) => {
 | 
			
		||||
                                e.stopPropagation();
 | 
			
		||||
                                handleScriptClick(script.slug);
 | 
			
		||||
                              }}
 | 
			
		||||
                            />
 | 
			
		||||
                            {formattedBadge(script.type)}
 | 
			
		||||
                          </div>
 | 
			
		||||
                        ))}
 | 
			
		||||
                    <Button
 | 
			
		||||
                      variant="ghost"
 | 
			
		||||
                      onClick={(e) => {
 | 
			
		||||
                        e.stopPropagation();
 | 
			
		||||
                        switchLogos(category.name, "next");
 | 
			
		||||
                      }}
 | 
			
		||||
                      className="p-1 transition-transform duration-300 hover:scale-110"
 | 
			
		||||
                    >
 | 
			
		||||
                      <ChevronRight className="h-4 w-4" />
 | 
			
		||||
                    </Button>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <h3 className="text-lg font-bold mb-1">{category.name}</h3>
 | 
			
		||||
                  <p className="text-sm text-gray-500 text-center">
 | 
			
		||||
                  <p className="text-sm text-gray-400 text-center">
 | 
			
		||||
                    {(category as any).description || "No description available."}
 | 
			
		||||
                  </p>
 | 
			
		||||
                </CardContent>
 | 
			
		||||
@@ -131,4 +273,4 @@ const CategoryView = () => {
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default CategoryView;
 | 
			
		||||
export default CategoryView;
 | 
			
		||||
 
 | 
			
		||||
@@ -35,8 +35,18 @@ export function LatestScripts({ items }: { items: Category[] }) {
 | 
			
		||||
 | 
			
		||||
  const latestScripts = useMemo(() => {
 | 
			
		||||
    if (!items) return [];
 | 
			
		||||
    
 | 
			
		||||
    const scripts = items.flatMap((category) => category.scripts || []);
 | 
			
		||||
    return scripts.sort(
 | 
			
		||||
 | 
			
		||||
    // Filter out duplicates by slug
 | 
			
		||||
    const uniqueScriptsMap = new Map<string, Script>();
 | 
			
		||||
    scripts.forEach((script) => {
 | 
			
		||||
      if (!uniqueScriptsMap.has(script.slug)) {
 | 
			
		||||
        uniqueScriptsMap.set(script.slug, script);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return Array.from(uniqueScriptsMap.values()).sort(
 | 
			
		||||
      (a, b) =>
 | 
			
		||||
        new Date(b.date_created).getTime() - new Date(a.date_created).getTime(),
 | 
			
		||||
    );
 | 
			
		||||
@@ -49,7 +59,7 @@ export function LatestScripts({ items }: { items: Category[] }) {
 | 
			
		||||
  const goToPreviousPage = () => {
 | 
			
		||||
    setPage((prevPage) => prevPage - 1);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  const startIndex = (page - 1) * ITEMS_PER_PAGE;
 | 
			
		||||
  const endIndex = page * ITEMS_PER_PAGE;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,13 +19,13 @@ $STD apt-get install -y sudo
 | 
			
		||||
$STD apt-get install -y mc
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Bazarr"
 | 
			
		||||
mkdir -p /var/lib/bazarr/
 | 
			
		||||
 
 | 
			
		||||
@@ -47,13 +47,13 @@ $STD apt-get install -y \
 | 
			
		||||
  gnupg
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Node.js Repository"
 | 
			
		||||
mkdir -p /etc/apt/keyrings
 | 
			
		||||
 
 | 
			
		||||
@@ -20,13 +20,13 @@ $STD apt-get install -y mc
 | 
			
		||||
$STD apt-get install -y python3-libtorrent
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Deluge"
 | 
			
		||||
$STD pip install deluge[all]
 | 
			
		||||
 
 | 
			
		||||
@@ -20,14 +20,14 @@ $STD apt-get install -y mc
 | 
			
		||||
$STD apt-get install -y git
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip \
 | 
			
		||||
  python3-venv
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing ESPHome"
 | 
			
		||||
mkdir /root/config
 | 
			
		||||
 
 | 
			
		||||
@@ -18,10 +18,10 @@ msg_info "Installing Dependencies (Patience)"
 | 
			
		||||
$STD apt-get install -y {curl,sudo,mc,git,gpg,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb2,libtbb-dev,libdc1394-22-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Python3 Dependencies"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils,python3-pip}
 | 
			
		||||
$STD pip install --upgrade pip
 | 
			
		||||
msg_ok "Installed Python3 Dependencies"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Node.js"
 | 
			
		||||
mkdir -p /etc/apt/keyrings
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 tteck
 | 
			
		||||
# Author: tteck (tteckster)
 | 
			
		||||
# Co-Author: MickLesk (Canbiz)
 | 
			
		||||
# License: MIT
 | 
			
		||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: MickLesk (Canbiz)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/ajnart/homarr
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
 | 
			
		||||
@@ -20,6 +18,7 @@ $STD apt-get install -y \
 | 
			
		||||
  sudo \
 | 
			
		||||
  mc \
 | 
			
		||||
  curl \
 | 
			
		||||
  redis-server \
 | 
			
		||||
  ca-certificates \
 | 
			
		||||
  gnupg \
 | 
			
		||||
  make \
 | 
			
		||||
@@ -30,32 +29,40 @@ msg_ok "Installed Dependencies"
 | 
			
		||||
msg_info "Setting up Node.js Repository"
 | 
			
		||||
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_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list
 | 
			
		||||
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
 | 
			
		||||
msg_ok "Set up Node.js Repository"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Node.js/Yarn"
 | 
			
		||||
msg_info "Installing Node.js/pnpm"
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y nodejs
 | 
			
		||||
$STD npm install -g yarn
 | 
			
		||||
msg_ok "Installed Node.js/Yarn"
 | 
			
		||||
$STD npm install -g pnpm@latest
 | 
			
		||||
msg_ok "Installed Node.js/pnpm"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Homarr (Patience)"
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
wget -q "https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
cd /opt
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/homarr-labs/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
wget -q "https://github.com/homarr-labs/homarr/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
unzip -q v${RELEASE}.zip
 | 
			
		||||
rm -rf v${RELEASE}.zip
 | 
			
		||||
mv homarr-${RELEASE} /opt/homarr
 | 
			
		||||
mkdir -p /opt/homarr_db
 | 
			
		||||
touch /opt/homarr_db/db.sqlite
 | 
			
		||||
AUTH_SECRET="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
 | 
			
		||||
SECRET_ENCRYPTION_KEY="$(openssl rand -hex 32)"
 | 
			
		||||
 | 
			
		||||
cat <<EOF >/opt/homarr/.env
 | 
			
		||||
DATABASE_URL="file:./database/db.sqlite"
 | 
			
		||||
NEXTAUTH_URL="http://localhost:3000"
 | 
			
		||||
NEXTAUTH_SECRET="$(openssl rand -base64 32)"
 | 
			
		||||
NEXT_PUBLIC_DISABLE_ANALYTICS="true"
 | 
			
		||||
DEFAULT_COLOR_SCHEME="dark"
 | 
			
		||||
AUTH_SECRET='${AUTH_SECRET}'
 | 
			
		||||
DB_DRIVER='better-sqlite3'
 | 
			
		||||
SECRET_ENCRYPTION_KEY='${SECRET_ENCRYPTION_KEY}'
 | 
			
		||||
DB_URL='/opt/homarr_db/db.sqlite'
 | 
			
		||||
TURBO_TELEMETRY_DISABLED=1
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
cd /opt/homarr
 | 
			
		||||
$STD yarn install
 | 
			
		||||
$STD yarn build
 | 
			
		||||
$STD yarn db:migrate
 | 
			
		||||
$STD pnpm install
 | 
			
		||||
$STD pnpm run db:migration:sqlite:run
 | 
			
		||||
$STD pnpm build
 | 
			
		||||
mkdir build
 | 
			
		||||
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed Homarr"
 | 
			
		||||
 | 
			
		||||
@@ -69,18 +76,19 @@ After=network.target
 | 
			
		||||
Type=exec
 | 
			
		||||
WorkingDirectory=/opt/homarr
 | 
			
		||||
EnvironmentFile=-/opt/homarr/.env
 | 
			
		||||
ExecStart=/usr/bin/yarn start
 | 
			
		||||
ExecStart=/usr/bin/pnpm start
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
systemctl enable -q --now homarr.service
 | 
			
		||||
systemctl enable -q --now homarr
 | 
			
		||||
msg_ok "Created Service"
 | 
			
		||||
 | 
			
		||||
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"
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ $STD apt-get install -y \
 | 
			
		||||
  pkg-config
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Setup Python3/pip"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
$STD apt-get remove --purge -y python3.12 python3.12-dev python3.12-venv
 | 
			
		||||
 
 | 
			
		||||
@@ -19,14 +19,14 @@ $STD apt-get install -y sudo
 | 
			
		||||
$STD apt-get install -y mc
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip \
 | 
			
		||||
  python3-venv
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing runlike"
 | 
			
		||||
$STD pip install runlike
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										104
									
								
								install/monica-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								install/monica-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: bvdberg01
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
verb_ip6
 | 
			
		||||
catch_errors
 | 
			
		||||
setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  curl \
 | 
			
		||||
  sudo \
 | 
			
		||||
  mc \
 | 
			
		||||
  gnupg2\
 | 
			
		||||
  mariadb-server \
 | 
			
		||||
  apache2 \
 | 
			
		||||
  libapache2-mod-php \
 | 
			
		||||
  php-{bcmath,curl,dom,gd,gmp,iconv,intl,json,mbstring,mysqli,opcache,pdo-mysql,redis,tokenizer,xml,zip} \
 | 
			
		||||
  composer
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up MariaDB"
 | 
			
		||||
DB_NAME=monica
 | 
			
		||||
DB_USER=monica
 | 
			
		||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
 | 
			
		||||
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
 | 
			
		||||
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');"
 | 
			
		||||
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
 | 
			
		||||
{
 | 
			
		||||
    echo "monica-Credentials"
 | 
			
		||||
    echo "monica Database User: $DB_USER"
 | 
			
		||||
    echo "monica Database Password: $DB_PASS"
 | 
			
		||||
    echo "monica Database Name: $DB_NAME"
 | 
			
		||||
} >> ~/monica.creds
 | 
			
		||||
msg_ok "Set up MariaDB"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Node.js/Yarn"
 | 
			
		||||
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_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y nodejs
 | 
			
		||||
$STD npm install -g npm@latest
 | 
			
		||||
$STD npm install -g yarn
 | 
			
		||||
msg_ok "Installed Node.js/Yarn"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing monica"
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/monicahq/monica/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
cd /opt
 | 
			
		||||
wget -q "https://github.com/monicahq/monica/releases/download/v${RELEASE}/monica-v${RELEASE}.tar.bz2"
 | 
			
		||||
tar -xjf "monica-v${RELEASE}.tar.bz2"
 | 
			
		||||
mv "/opt/monica-v${RELEASE}" /opt/monica
 | 
			
		||||
cd /opt/monica
 | 
			
		||||
cp /opt/monica/.env.example /opt/monica/.env
 | 
			
		||||
HASH_SALT=$(openssl rand -base64 32)
 | 
			
		||||
sed -i -e "s|^DB_USERNAME=.*|DB_USERNAME=${DB_USER}|" \
 | 
			
		||||
       -e "s|^DB_PASSWORD=.*|DB_PASSWORD=${DB_PASS}|" \
 | 
			
		||||
       -e "s|^HASH_SALT=.*|HASH_SALT=${HASH_SALT}|" \
 | 
			
		||||
       /opt/monica/.env
 | 
			
		||||
$STD composer install --no-dev -o --no-interaction
 | 
			
		||||
$STD yarn install
 | 
			
		||||
$STD yarn run production
 | 
			
		||||
$STD php artisan key:generate
 | 
			
		||||
$STD php artisan setup:production --email=admin@helper-scripts.com --password=helper-scripts.com --force
 | 
			
		||||
chown -R www-data:www-data /opt/monica
 | 
			
		||||
chmod -R 775 /opt/monica/storage
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Installed monica"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/apache2/sites-available/monica.conf
 | 
			
		||||
<VirtualHost *:80>
 | 
			
		||||
    ServerName monica
 | 
			
		||||
    DocumentRoot /opt/monica/public
 | 
			
		||||
    <Directory /opt/monica/public>
 | 
			
		||||
        Options Indexes FollowSymLinks
 | 
			
		||||
        AllowOverride All
 | 
			
		||||
        Require all granted
 | 
			
		||||
    </Directory>
 | 
			
		||||
 | 
			
		||||
    ErrorLog /var/log/apache2/monica_error.log
 | 
			
		||||
    CustomLog /var/log/apache2/monica_access.log combined
 | 
			
		||||
</VirtualHost>
 | 
			
		||||
EOF
 | 
			
		||||
$STD a2ensite monica
 | 
			
		||||
$STD a2enmod rewrite
 | 
			
		||||
$STD a2dissite 000-default.conf
 | 
			
		||||
$STD systemctl reload apache2
 | 
			
		||||
msg_ok "Created Service"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -rf "/opt/monica-v${RELEASE}.tar.bz2"
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
@@ -21,13 +21,13 @@ $STD apt-get install -y git
 | 
			
		||||
$STD apt-get install -y cifs-utils
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Motion"
 | 
			
		||||
$STD apt-get install -y motion
 | 
			
		||||
 
 | 
			
		||||
@@ -26,11 +26,11 @@ $STD apt-get install -y unrar
 | 
			
		||||
rm /etc/apt/sources.list.d/non-free.list
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
$STD pip install -U --no-cache-dir pip
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing ${APPLICATION}"
 | 
			
		||||
mkdir -p /opt/mylar3
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										164
									
								
								install/nodebb-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								install/nodebb-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2024 tteck
 | 
			
		||||
# Author: MickLesk (Canbiz)
 | 
			
		||||
# License: MIT | https://github.com/tteck/Proxmox/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/NodeBB/NodeBB
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
verb_ip6
 | 
			
		||||
catch_errors
 | 
			
		||||
setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies (Patience)"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  build-essential \
 | 
			
		||||
  curl \
 | 
			
		||||
  sudo \
 | 
			
		||||
  make \
 | 
			
		||||
  redis-server \
 | 
			
		||||
  expect \
 | 
			
		||||
  gnupg \
 | 
			
		||||
  ca-certificates \
 | 
			
		||||
  mc
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Node.js & MongoDB Repository"
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | gpg --dearmor -o /etc/apt/keyrings/mongodb-server-8.0.gpg
 | 
			
		||||
echo "deb [arch=amd64,arm64 signed-by=/etc/apt/keyrings/mongodb-server-8.0.gpg] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" > /etc/apt/sources.list.d/mongodb-org-8.0.list
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
msg_ok "Set up Repositories"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Node.js"
 | 
			
		||||
$STD apt-get install -y nodejs
 | 
			
		||||
msg_ok "Installed Node.js"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing MongoDB"
 | 
			
		||||
$STD apt-get install -y mongodb-org
 | 
			
		||||
systemctl enable -q --now mongod
 | 
			
		||||
sleep 10 # MongoDB needs some secounds to start, if not sleep it collide with following mongosh
 | 
			
		||||
msg_ok "Installed MongoDB"   
 | 
			
		||||
 | 
			
		||||
msg_info "Configure MongoDB"
 | 
			
		||||
MONGO_ADMIN_USER="admin"
 | 
			
		||||
MONGO_ADMIN_PWD="$(openssl rand -base64 18 | cut -c1-13)"
 | 
			
		||||
NODEBB_USER="nodebb"
 | 
			
		||||
NODEBB_PWD="$(openssl rand -base64 18 | cut -c1-13)"
 | 
			
		||||
MONGO_CONNECTION_STRING="mongodb://${NODEBB_USER}:${NODEBB_PWD}@localhost:27017/nodebb"
 | 
			
		||||
NODEBB_SECRET=$(uuidgen)
 | 
			
		||||
{
 | 
			
		||||
    echo "NodeBB-Credentials"
 | 
			
		||||
    echo "Mongo Database User: $MONGO_ADMIN_USER"
 | 
			
		||||
    echo "Mongo Database Password: $MONGO_ADMIN_PWD"
 | 
			
		||||
    echo "NodeBB User: $NODEBB_USER"
 | 
			
		||||
	echo "NodeBB Password: $NODEBB_PWD"
 | 
			
		||||
	echo "NodeBB Secret: $NODEBB_SECRET"
 | 
			
		||||
} >> ~/nodebb.creds
 | 
			
		||||
 | 
			
		||||
$STD mongosh <<EOF
 | 
			
		||||
use admin
 | 
			
		||||
db.createUser({
 | 
			
		||||
  user: "$MONGO_ADMIN_USER",
 | 
			
		||||
  pwd: "$MONGO_ADMIN_PWD",
 | 
			
		||||
  roles: [{ role: "root", db: "admin" }]
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
use nodebb
 | 
			
		||||
db.createUser({
 | 
			
		||||
  user: "$NODEBB_USER",
 | 
			
		||||
  pwd: "$NODEBB_PWD",
 | 
			
		||||
  roles: [
 | 
			
		||||
    { role: "readWrite", db: "nodebb" },
 | 
			
		||||
    { role: "clusterMonitor", db: "admin" }
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
quit()
 | 
			
		||||
EOF
 | 
			
		||||
sed -i 's/bindIp: 127.0.0.1/bindIp: 0.0.0.0/' /etc/mongod.conf
 | 
			
		||||
sed -i '/security:/d' /etc/mongod.conf
 | 
			
		||||
bash -c 'echo -e "\nsecurity:\n  authorization: enabled" >> /etc/mongod.conf'
 | 
			
		||||
systemctl restart mongod
 | 
			
		||||
msg_ok "MongoDB successfully configurated" 
 | 
			
		||||
 | 
			
		||||
msg_info "Install NodeBB" 
 | 
			
		||||
cd /opt
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/NodeBB/NodeBB/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
wget -q "https://github.com/NodeBB/NodeBB/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
unzip -q v${RELEASE}.zip
 | 
			
		||||
mv NodeBB-${RELEASE} /opt/nodebb
 | 
			
		||||
cd /opt/nodebb
 | 
			
		||||
touch pidfile
 | 
			
		||||
expect <<EOF > /dev/null 2>&1
 | 
			
		||||
log_file /dev/null
 | 
			
		||||
set timeout -1
 | 
			
		||||
 | 
			
		||||
spawn ./nodebb setup
 | 
			
		||||
expect "URL used to access this NodeBB" {
 | 
			
		||||
    send "http://localhost:4567\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Please enter a NodeBB secret" {
 | 
			
		||||
    send "$NODEBB_SECRET\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Would you like to submit anonymous plugin usage to nbbpm? (yes)" {
 | 
			
		||||
    send "no\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Which database to use (mongo)" {
 | 
			
		||||
    send "mongo\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Format: mongodb://*" {
 | 
			
		||||
    send "$MONGO_CONNECTION_STRING\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Administrator username" {
 | 
			
		||||
    send "helper-scripts\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Administrator email address" {
 | 
			
		||||
    send "helper-scripts@local.com\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Password" {
 | 
			
		||||
    send "helper-scripts\r"
 | 
			
		||||
}
 | 
			
		||||
expect "Confirm Password" {
 | 
			
		||||
    send "helper-scripts\r"
 | 
			
		||||
}
 | 
			
		||||
expect eof
 | 
			
		||||
EOF
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
msg_ok "Installed NodeBB"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Services"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/nodebb.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=NodeBB
 | 
			
		||||
Documentation=https://docs.nodebb.org
 | 
			
		||||
After=system.slice multi-user.target mongod.service
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=forking
 | 
			
		||||
User=root
 | 
			
		||||
 | 
			
		||||
WorkingDirectory=/opt/nodebb
 | 
			
		||||
PIDFile=/opt/nodebb/pidfile
 | 
			
		||||
ExecStart=/usr/bin/node /opt/nodebb/loader.js
 | 
			
		||||
Restart=always
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
systemctl enable -q --now nodebb
 | 
			
		||||
msg_ok "Created Service"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -R /opt/v${RELEASE}.zip
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
@@ -22,7 +22,7 @@ $STD apt-get install -y libyaml-dev
 | 
			
		||||
$STD apt-get install -y build-essential
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
@@ -31,7 +31,7 @@ $STD apt-get install -y \
 | 
			
		||||
 | 
			
		||||
$STD apt-get install -y python3-setuptools
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating user octoprint"
 | 
			
		||||
useradd -m -s /bin/bash -p $(openssl passwd -1 octoprint) octoprint
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 tteck
 | 
			
		||||
# Author: tteck (tteckster)
 | 
			
		||||
# Co-Author: michelroegl-brunner
 | 
			
		||||
# License: MIT
 | 
			
		||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
 | 
			
		||||
@@ -14,11 +15,12 @@ network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y curl
 | 
			
		||||
$STD apt-get install -y sudo
 | 
			
		||||
$STD apt-get install -y mc
 | 
			
		||||
$STD apt-get install -y git
 | 
			
		||||
$STD apt-get install -y gnupg
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  curl \
 | 
			
		||||
  sudo \
 | 
			
		||||
  mc \
 | 
			
		||||
  git \
 | 
			
		||||
  gnupg
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Node.js Repository"
 | 
			
		||||
@@ -34,11 +36,14 @@ $STD npm install pm2 -g
 | 
			
		||||
msg_ok "Installed Node.js"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Pingvin Share (Patience)"
 | 
			
		||||
git clone -q https://github.com/stonith404/pingvin-share /opt/pingvin-share
 | 
			
		||||
cd /opt/pingvin-share
 | 
			
		||||
$STD git fetch --tags
 | 
			
		||||
$STD git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
 | 
			
		||||
cd backend
 | 
			
		||||
cd /opt
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/stonith404/pingvin-share/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
 | 
			
		||||
wget -q "https://github.com/stonith404/pingvin-share/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
unzip -q v${RELEASE}.zip
 | 
			
		||||
echo "${RELEASE}" >"/opt/pingvin_version.txt"
 | 
			
		||||
mv pingvin-share-${RELEASE} /opt/pingvin-share
 | 
			
		||||
cd /opt/pingvin-share/backend
 | 
			
		||||
$STD npm install
 | 
			
		||||
$STD npm run build
 | 
			
		||||
$STD pm2 start --name="pingvin-share-backend" npm -- run prod
 | 
			
		||||
@@ -57,6 +62,7 @@ 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"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										130
									
								
								install/pocketid-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								install/pocketid-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: Snarkenfaugister
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
# Source: https://github.com/stonith404/pocket-id
 | 
			
		||||
 | 
			
		||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
 | 
			
		||||
color
 | 
			
		||||
verb_ip6
 | 
			
		||||
catch_errors
 | 
			
		||||
setting_up_container
 | 
			
		||||
network_check
 | 
			
		||||
update_os
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Dependencies"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  curl \
 | 
			
		||||
  sudo \
 | 
			
		||||
  mc \
 | 
			
		||||
  gpg \
 | 
			
		||||
  caddy \
 | 
			
		||||
  gcc
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Node.js Repository"
 | 
			
		||||
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
 | 
			
		||||
msg_ok "Set up Node.js Repository"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Node.js"
 | 
			
		||||
$STD apt-get update
 | 
			
		||||
$STD apt-get install -y nodejs
 | 
			
		||||
msg_ok "Installed Node.js"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Golang"
 | 
			
		||||
cd /tmp
 | 
			
		||||
set +o pipefail
 | 
			
		||||
GO_RELEASE=$(curl -s https://go.dev/dl/ | grep -o -m 1 "go.*\linux-amd64.tar.gz")
 | 
			
		||||
wget -q https://golang.org/dl/${GO_RELEASE}
 | 
			
		||||
tar -xzf ${GO_RELEASE} -C /usr/local
 | 
			
		||||
ln -s /usr/local/go/bin/go /usr/bin/go
 | 
			
		||||
set -o pipefail
 | 
			
		||||
msg_ok "Installed Golang"
 | 
			
		||||
 | 
			
		||||
read -r -p "What public URL do you want to use (e.g. pocketid.mydomain.com)? " public_url
 | 
			
		||||
msg_info "Setup Pocket ID"
 | 
			
		||||
cd /opt
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/stonith404/pocket-id/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
 | 
			
		||||
wget -q "https://github.com/stonith404/pocket-id/archive/refs/tags/v${RELEASE}.zip"
 | 
			
		||||
unzip -q v${RELEASE}.zip
 | 
			
		||||
mv pocket-id-${RELEASE}/ /opt/pocket-id
 | 
			
		||||
 | 
			
		||||
cd /opt/pocket-id/backend
 | 
			
		||||
cp .env.example .env
 | 
			
		||||
sed -i "s/PUBLIC_APP_URL=http:\/\/localhost/PUBLIC_APP_URL=https:\/\/${public_url}/" .env
 | 
			
		||||
cd cmd
 | 
			
		||||
CGO_ENABLED=1 
 | 
			
		||||
GOOS=linux
 | 
			
		||||
$STD go build -o ../pocket-id-backend
 | 
			
		||||
 | 
			
		||||
cd ../../frontend
 | 
			
		||||
cp .env.example .env
 | 
			
		||||
sed -i "s/PUBLIC_APP_URL=http:\/\/localhost/PUBLIC_APP_URL=https:\/\/${public_url}/" .env
 | 
			
		||||
$STD npm install
 | 
			
		||||
$STD npm run build
 | 
			
		||||
 | 
			
		||||
cd ..
 | 
			
		||||
cp reverse-proxy/Caddyfile /etc/caddy/Caddyfile
 | 
			
		||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
 | 
			
		||||
msg_ok "Setup Pocket ID"
 | 
			
		||||
 | 
			
		||||
msg_info "Creating Service"
 | 
			
		||||
cat <<EOF >/etc/systemd/system/pocketid-backend.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Pocket ID Backend
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
User=root
 | 
			
		||||
Group=root
 | 
			
		||||
WorkingDirectory=/opt/pocket-id/backend
 | 
			
		||||
EnvironmentFile=/opt/pocket-id/backend/.env
 | 
			
		||||
ExecStart=/opt/pocket-id/backend/pocket-id-backend
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=10
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
cat <<EOF >/etc/systemd/system/pocketid-frontend.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Pocket ID Frontend
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
User=root
 | 
			
		||||
Group=root
 | 
			
		||||
WorkingDirectory=/opt/pocket-id/frontend
 | 
			
		||||
EnvironmentFile=/opt/pocket-id/frontend/.env
 | 
			
		||||
ExecStart=/usr/bin/node build/index.js
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=10
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
EOF
 | 
			
		||||
msg_ok "Created Service"
 | 
			
		||||
 | 
			
		||||
msg_info "Starting Services"
 | 
			
		||||
systemctl enable -q --now pocketid-backend
 | 
			
		||||
systemctl enable -q --now pocketid-frontend
 | 
			
		||||
systemctl restart caddy
 | 
			
		||||
msg_ok "Started Services"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
 | 
			
		||||
msg_info "Cleaning up"
 | 
			
		||||
rm -f /opt/v${RELEASE}.zip
 | 
			
		||||
$STD apt-get -y autoremove
 | 
			
		||||
$STD apt-get -y autoclean
 | 
			
		||||
msg_ok "Cleaned"
 | 
			
		||||
 | 
			
		||||
motd_ssh
 | 
			
		||||
customize
 | 
			
		||||
@@ -27,13 +27,13 @@ $STD apt-get install -y unrar
 | 
			
		||||
rm /etc/apt/sources.list.d/non-free.list
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip
 | 
			
		||||
$STD apt-get install -y python3-setuptools
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing SABnzbd"
 | 
			
		||||
RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
 | 
			
		||||
 
 | 
			
		||||
@@ -32,14 +32,14 @@ $STD apt-get install -y --no-install-recommends \
 | 
			
		||||
  mc
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-setuptools \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Setting up Node.js Repository"
 | 
			
		||||
mkdir -p /etc/apt/keyrings
 | 
			
		||||
 
 | 
			
		||||
@@ -21,13 +21,13 @@ $STD apt-get install -y git
 | 
			
		||||
$STD apt-get install -y pip
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Tautulli"
 | 
			
		||||
cd /opt
 | 
			
		||||
 
 | 
			
		||||
@@ -19,13 +19,13 @@ $STD apt-get install -y sudo
 | 
			
		||||
$STD apt-get install -y mc
 | 
			
		||||
msg_ok "Installed Dependencies"
 | 
			
		||||
 | 
			
		||||
msg_info "Updating Python3"
 | 
			
		||||
msg_info "Setup Python3"
 | 
			
		||||
$STD apt-get install -y \
 | 
			
		||||
  python3 \
 | 
			
		||||
  python3-dev \
 | 
			
		||||
  python3-pip
 | 
			
		||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
 | 
			
		||||
msg_ok "Updated Python3"
 | 
			
		||||
msg_ok "Setup Python3"
 | 
			
		||||
 | 
			
		||||
msg_info "Installing Whoogle"
 | 
			
		||||
$STD pip install brotli
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
                "ram": 512,
 | 
			
		||||
                "hdd": 0.1,
 | 
			
		||||
                "os": "alpine",
 | 
			
		||||
                "version": "3.19"
 | 
			
		||||
                "version": "3.21"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								json/archlinux-vm.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								json/archlinux-vm.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Arch Linux",
 | 
			
		||||
  "slug": "archlinux-vm",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    2
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-01-27",
 | 
			
		||||
  "type": "vm",
 | 
			
		||||
  "updateable": false,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": null,
 | 
			
		||||
  "documentation": null,
 | 
			
		||||
  "website": null,
 | 
			
		||||
  "logo": "https://raw.githubusercontent.com/ArchLinuxStudio/ArchLinuxTutorial/refs/heads/master/docs/arch_seo.png",
 | 
			
		||||
  "description": "Arch Linux is a highly customizable, independent Linux distribution that gives users complete control over their system. Known for its rolling release model, Arch Linux is always up-to-date with the latest software. It's favored by experienced users who appreciate its minimalist approach, demanding a hands-on installation and configuration process. This level of control and flexibility makes it a popular choice for those who want to tailor their Linux system to their exact needs.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "vm/archlinux-vm.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 1,
 | 
			
		||||
        "ram": 1024,
 | 
			
		||||
        "hdd": 4,
 | 
			
		||||
        "os": null,
 | 
			
		||||
        "version": null
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "doesnt work with lvm and lvmthin disks!",
 | 
			
		||||
      "type": "warning"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
                "ram": 1024,
 | 
			
		||||
                "hdd": 2,
 | 
			
		||||
                "os": "alpine",
 | 
			
		||||
                "version": "3.19"
 | 
			
		||||
                "version": "3.21"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
                "ram": 256,
 | 
			
		||||
                "hdd": 1,
 | 
			
		||||
                "os": "alpine",
 | 
			
		||||
                "version": "3.19"
 | 
			
		||||
                "version": "3.21"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    "categories": [
 | 
			
		||||
        10
 | 
			
		||||
    ],
 | 
			
		||||
    "date_created": "2024-05-02",
 | 
			
		||||
    "date_created": "2025-01-28",
 | 
			
		||||
    "type": "ct",
 | 
			
		||||
    "updateable": true,
 | 
			
		||||
    "privileged": false,
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
            "script": "ct/homarr.sh",
 | 
			
		||||
            "resources": {
 | 
			
		||||
                "cpu": 2,
 | 
			
		||||
                "ram": 2048,
 | 
			
		||||
                "ram": 4096,
 | 
			
		||||
                "hdd": 8,
 | 
			
		||||
                "os": "debian",
 | 
			
		||||
                "version": "12"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,30 @@
 | 
			
		||||
{
 | 
			
		||||
	"categories": [
 | 
			
		||||
		{ "name": "Proxmox & Virtualization", "id": 1, "sort_order": 1.0 },
 | 
			
		||||
		{ "name": "Operating Systems", "id": 2, "sort_order": 2.0 },
 | 
			
		||||
		{ "name": "Containers & Docker", "id": 3, "sort_order": 3.0 },
 | 
			
		||||
		{ "name": "Network & Firewall", "id": 4, "sort_order": 4.0 },
 | 
			
		||||
		{ "name": "Adblock & DNS", "id": 5, "sort_order": 5.0 },
 | 
			
		||||
		{ "name": "Authentication & Security", "id": 6, "sort_order": 6.0 },
 | 
			
		||||
		{ "name": "Backup & Recovery", "id": 7, "sort_order": 7.0 },
 | 
			
		||||
		{ "name": "Databases", "id": 8, "sort_order": 8.0 },
 | 
			
		||||
		{ "name": "Monitoring & Analytics", "id": 9, "sort_order": 9.0 },
 | 
			
		||||
		{ "name": "Dashboards & Frontends", "id": 10, "sort_order": 10.0 },
 | 
			
		||||
		{ "name": "Files & Downloads", "id": 11, "sort_order": 11.0 },
 | 
			
		||||
		{ "name": "Documents & Notes", "id": 12, "sort_order": 12.0 },
 | 
			
		||||
		{ "name": "Media & Streaming", "id": 13, "sort_order": 13.0 },
 | 
			
		||||
		{ "name": "*Arr Suite", "id": 14, "sort_order": 14.0 },
 | 
			
		||||
		{ "name": "NVR & Cameras", "id": 15, "sort_order": 15.0 },
 | 
			
		||||
		{ "name": "IoT & Smart Home", "id": 16, "sort_order": 16.0 },
 | 
			
		||||
		{ "name": "ZigBee, Z-Wave & Matter", "id": 17, "sort_order": 17.0 },
 | 
			
		||||
		{ "name": "MQTT & Messaging", "id": 18, "sort_order": 18.0 },
 | 
			
		||||
		{ "name": "Automation & Scheduling", "id": 19, "sort_order": 19.0 },
 | 
			
		||||
		{ "name": "AI / Coding & Dev-Tools", "id": 20, "sort_order": 20.0 },
 | 
			
		||||
		{ "name": "Webservers & Proxies", "id": 21, "sort_order": 21.0 },
 | 
			
		||||
		{ "name": "Bots & ChatOps", "id": 22, "sort_order": 22.0 },
 | 
			
		||||
		{ "name": "Finance & Budgeting", "id": 23, "sort_order": 23.0 },
 | 
			
		||||
		{ "name": "Gaming & Leisure", "id": 24, "sort_order": 24.0 },
 | 
			
		||||
		{ "name": "Business & ERP", "id": 25, "sort_order": 25.0 },
 | 
			
		||||
		{ "name": "Miscellaneous", "id": 0, "sort_order": 99.0 }
 | 
			
		||||
		{ "name": "Proxmox & Virtualization", "id": 1, "sort_order": 1.0, "description": "Tools and scripts to manage Proxmox VE and virtualization platforms effectively." },
 | 
			
		||||
		{ "name": "Operating Systems", "id": 2, "sort_order": 2.0, "description": "Scripts for deploying and managing various operating systems." },
 | 
			
		||||
		{ "name": "Containers & Docker", "id": 3, "sort_order": 3.0, "description": "Solutions for containerization using Docker and related technologies." },
 | 
			
		||||
		{ "name": "Network & Firewall", "id": 4, "sort_order": 4.0, "description": "Enhance network security and configure firewalls with ease." },
 | 
			
		||||
		{ "name": "Adblock & DNS", "id": 5, "sort_order": 5.0, "description": "Optimize your network with DNS and ad-blocking solutions." },
 | 
			
		||||
		{ "name": "Authentication & Security", "id": 6, "sort_order": 6.0, "description": "Secure your infrastructure with authentication and security tools." },
 | 
			
		||||
		{ "name": "Backup & Recovery", "id": 7, "sort_order": 7.0, "description": "Reliable backup and recovery scripts to protect your data." },
 | 
			
		||||
		{ "name": "Databases", "id": 8, "sort_order": 8.0, "description": "Deploy and manage robust database systems with ease." },
 | 
			
		||||
		{ "name": "Monitoring & Analytics", "id": 9, "sort_order": 9.0, "description": "Monitor system performance and analyze data seamlessly." },
 | 
			
		||||
		{ "name": "Dashboards & Frontends", "id": 10, "sort_order": 10.0, "description": "Create interactive dashboards and user-friendly frontends." },
 | 
			
		||||
		{ "name": "Files & Downloads", "id": 11, "sort_order": 11.0, "description": "Manage file sharing and downloading solutions efficiently." },
 | 
			
		||||
		{ "name": "Documents & Notes", "id": 12, "sort_order": 12.0, "description": "Organize and manage documents and note-taking tools." },
 | 
			
		||||
		{ "name": "Media & Streaming", "id": 13, "sort_order": 13.0, "description": "Stream and manage media effortlessly across devices." },
 | 
			
		||||
		{ "name": "*Arr Suite", "id": 14, "sort_order": 14.0, "description": "Automated media management with the popular *Arr suite tools." },
 | 
			
		||||
		{ "name": "NVR & Cameras", "id": 15, "sort_order": 15.0, "description": "Manage network video recorders and camera setups." },
 | 
			
		||||
		{ "name": "IoT & Smart Home", "id": 16, "sort_order": 16.0, "description": "Control and automate IoT devices and smart home systems." },
 | 
			
		||||
		{ "name": "ZigBee, Z-Wave & Matter", "id": 17, "sort_order": 17.0, "description": "Solutions for ZigBee, Z-Wave, and Matter-based device management." },
 | 
			
		||||
		{ "name": "MQTT & Messaging", "id": 18, "sort_order": 18.0, "description": "Set up reliable messaging and MQTT-based communication systems." },
 | 
			
		||||
		{ "name": "Automation & Scheduling", "id": 19, "sort_order": 19.0, "description": "Automate tasks and manage scheduling with powerful tools." },
 | 
			
		||||
		{ "name": "AI / Coding & Dev-Tools", "id": 20, "sort_order": 20.0, "description": "Leverage AI and developer tools for smarter coding workflows." },
 | 
			
		||||
		{ "name": "Webservers & Proxies", "id": 21, "sort_order": 21.0, "description": "Deploy and configure web servers and proxy solutions." },
 | 
			
		||||
		{ "name": "Bots & ChatOps", "id": 22, "sort_order": 22.0, "description": "Enhance collaboration with bots and ChatOps integrations." },
 | 
			
		||||
		{ "name": "Finance & Budgeting", "id": 23, "sort_order": 23.0, "description": "Track expenses and manage budgets efficiently." },
 | 
			
		||||
		{ "name": "Gaming & Leisure", "id": 24, "sort_order": 24.0, "description": "Scripts for gaming servers and leisure-related tools." },
 | 
			
		||||
		{ "name": "Business & ERP", "id": 25, "sort_order": 25.0, "description": "Streamline business operations with ERP and management tools." },
 | 
			
		||||
		{ "name": "Miscellaneous", "id": 0, "sort_order": 99.0, "description": "General scripts and tools that don't fit into other categories." }
 | 
			
		||||
	]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								json/monica.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								json/monica.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "Monica",
 | 
			
		||||
    "slug": "monica",
 | 
			
		||||
    "categories": [
 | 
			
		||||
        24
 | 
			
		||||
    ],
 | 
			
		||||
    "date_created": "2025-01-28",
 | 
			
		||||
    "type": "ct",
 | 
			
		||||
    "updateable": true,
 | 
			
		||||
    "privileged": false,
 | 
			
		||||
    "interface_port": 80,
 | 
			
		||||
    "documentation": "https://github.com/monicahq/monica/tree/4.x/docs",
 | 
			
		||||
    "website": "https://www.monicahq.com/",
 | 
			
		||||
    "logo": "https://raw.githubusercontent.com/monicahq/monica/0400350b4f9bf02300b030b9924b66ef2960b188/public/img/favicon.svg",
 | 
			
		||||
    "description": "Monica is an open-source personal CRM designed to help you manage and strengthen your relationships. It allows you to store important details about your contacts, track interactions, set reminders for special dates, and log activities—all in one secure, private place. Perfect for busy individuals, Monica helps you stay organized, remember meaningful moments, and nurture your connections without ads or data mining. Install it on your own server for full control!",
 | 
			
		||||
    "install_methods": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "default",
 | 
			
		||||
            "script": "ct/monica.sh",
 | 
			
		||||
            "resources": {
 | 
			
		||||
                "cpu": 2,
 | 
			
		||||
                "ram": 2048,
 | 
			
		||||
                "hdd": 8,
 | 
			
		||||
                "os": "debian",
 | 
			
		||||
                "version": "12"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "default_credentials": {
 | 
			
		||||
        "username": "admin@helper-scripts.com",
 | 
			
		||||
        "password": "helper-scripts.com"
 | 
			
		||||
    },
 | 
			
		||||
    "notes": []
 | 
			
		||||
}
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
                "ram": 1024,
 | 
			
		||||
                "hdd": 2,
 | 
			
		||||
                "os": "alpine",
 | 
			
		||||
                "version": "3.19"
 | 
			
		||||
                "version": "3.21"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								json/nodebb.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								json/nodebb.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "NodeBB",
 | 
			
		||||
  "slug": "nodebb",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    10,
 | 
			
		||||
    25
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-01-28",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 4567,
 | 
			
		||||
  "documentation": "https://docs.nodebb.org/",
 | 
			
		||||
  "website": "https://nodebb.org/",
 | 
			
		||||
  "logo": "https://raw.githubusercontent.com/NodeBB/NodeBB/refs/heads/master/public/logo.png",
 | 
			
		||||
  "description": "NodeBB Forum Software is powered by Node.js and supports either Redis, MongoDB, or a PostgreSQL database. It utilizes web sockets for instant interactions and real-time notifications. NodeBB takes the best of the modern web: real-time streaming discussions, mobile responsiveness, and rich RESTful read/write APIs, while staying true to the original bulletin board/forum format → categorical hierarchies, local user accounts, and asynchronous messaging.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/nodebb.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 4,
 | 
			
		||||
        "ram": 2048,
 | 
			
		||||
        "hdd": 10,
 | 
			
		||||
        "os": "Ubuntu",
 | 
			
		||||
        "version": "24.04"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": "helper-scripts",
 | 
			
		||||
    "password": "helper-scripts"
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Only use Ubuntu 24.04!",
 | 
			
		||||
      "type": "warning"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								json/pocketid.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								json/pocketid.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Pocket ID",
 | 
			
		||||
  "slug": "pocketid",
 | 
			
		||||
  "categories": [
 | 
			
		||||
    6
 | 
			
		||||
  ],
 | 
			
		||||
  "date_created": "2025-01-28",
 | 
			
		||||
  "type": "ct",
 | 
			
		||||
  "updateable": true,
 | 
			
		||||
  "privileged": false,
 | 
			
		||||
  "interface_port": 80,
 | 
			
		||||
  "documentation": "https://stonith404.github.io/pocket-id/introduction",
 | 
			
		||||
  "website": "https://github.com/stonith404/pocket-id",
 | 
			
		||||
  "logo": "https://raw.githubusercontent.com/stonith404/pocket-id/refs/heads/main/docs/static/img/pocket-id.png",
 | 
			
		||||
  "description": "Pocket ID is a simple OIDC provider that allows users to authenticate with their passkeys to your services.",
 | 
			
		||||
  "install_methods": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "default",
 | 
			
		||||
      "script": "ct/pocketid.sh",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "cpu": 2,
 | 
			
		||||
        "ram": 2048,
 | 
			
		||||
        "hdd": 4,
 | 
			
		||||
        "os": "Debian",
 | 
			
		||||
        "version": "12"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "default_credentials": {
 | 
			
		||||
    "username": null,
 | 
			
		||||
    "password": null
 | 
			
		||||
  },
 | 
			
		||||
  "notes": [
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Pocket ID requires https to work.",
 | 
			
		||||
      "type": "warning"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "text": "Configuration Path: `/opt/pocket-id/backend/.env`, `/opt/pocket-id/frontend/.env`.",
 | 
			
		||||
      "type": "info"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -31,9 +31,9 @@
 | 
			
		||||
            "resources": {
 | 
			
		||||
                "cpu": 1,
 | 
			
		||||
                "ram": 256,
 | 
			
		||||
                "hdd": 0.3,
 | 
			
		||||
                "hdd": 0.5,
 | 
			
		||||
                "os": "alpine",
 | 
			
		||||
                "version": "3.19"
 | 
			
		||||
                "version": "3.21"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
                "ram": 256,
 | 
			
		||||
                "hdd": 0.3,
 | 
			
		||||
                "os": "alpine",
 | 
			
		||||
                "version": "3.19"
 | 
			
		||||
                "version": "3.21"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -233,65 +233,41 @@ update_motd_ip() {
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# This function sets the APP-Name into an ASCII Header in Slant, figlet needed on proxmox main node.
 | 
			
		||||
header_info() {
 | 
			
		||||
  # Helper function: Install FIGlet and download fonts
 | 
			
		||||
  install_figlet() {
 | 
			
		||||
    echo -e "${INFO}${BOLD}${DGN}Installing FIGlet...${CL}"
 | 
			
		||||
# Function to download & save header files
 | 
			
		||||
get_header() {
 | 
			
		||||
  local app_name=$(echo ${APP,,} | tr -d ' ') 
 | 
			
		||||
  local header_url="https://github.com/community-scripts/ProxmoxVE/raw/main/ct/headers/${app_name}"
 | 
			
		||||
  local local_header_path="/usr/local/community-scripts/headers/${app_name}"
 | 
			
		||||
 | 
			
		||||
    temp_dir=$(mktemp -d)
 | 
			
		||||
    curl -sL https://github.com/community-scripts/ProxmoxVE/raw/refs/heads/main/misc/figlet.tar.xz -o "$temp_dir/figlet.tar.xz"
 | 
			
		||||
    mkdir -p /tmp/figlet
 | 
			
		||||
    tar -xf "$temp_dir/figlet.tar.xz" -C /tmp/figlet --strip-components=1
 | 
			
		||||
    cd /tmp/figlet
 | 
			
		||||
    make >/dev/null
 | 
			
		||||
  mkdir -p "/usr/local/community-scripts/headers"
 | 
			
		||||
 | 
			
		||||
    if [ -f "figlet" ]; then
 | 
			
		||||
      chmod +x figlet
 | 
			
		||||
      mv figlet /usr/local/bin/
 | 
			
		||||
      mkdir -p /usr/local/share/figlet
 | 
			
		||||
      cp -r /tmp/figlet/fonts/*.flf /usr/local/share/figlet/
 | 
			
		||||
      echo -e "${CM}${BOLD}${DGN}FIGlet successfully installed.${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${ERR}${BOLD}${RED}Failed to install FIGlet.${CL}"
 | 
			
		||||
  # Check if local file already present
 | 
			
		||||
  if [ ! -f "$local_header_path" ]; then
 | 
			
		||||
    wget -qO "$local_header_path" "$header_url"
 | 
			
		||||
    if [ $? -ne 0 ]; then
 | 
			
		||||
      echo -e "${WARN}${BOLD}${YLW}Failed to download header for ${app_name}. No header will be displayed.${CL}"
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
    rm -rf "$temp_dir"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  # Check if figlet and the slant font are available
 | 
			
		||||
  if ! figlet -f slant "Test" &>/dev/null; then
 | 
			
		||||
    echo -e "${INFO}${BOLD}${DGN}FIGlet or the slant font is missing. Installing...${CL}"
 | 
			
		||||
 | 
			
		||||
    if [ -f /etc/debian_version ] || [ -f /etc/lsb-release ]; then
 | 
			
		||||
      # Debian/Ubuntu-based systems
 | 
			
		||||
      apt-get update -y &>/dev/null
 | 
			
		||||
      apt-get install -y wget build-essential &>/dev/null
 | 
			
		||||
      install_figlet
 | 
			
		||||
 | 
			
		||||
    elif [ -f /etc/alpine-release ]; then
 | 
			
		||||
      # Alpine-based systems
 | 
			
		||||
      apk add --no-cache tar xz build-base wget &>/dev/null
 | 
			
		||||
      export TERM=xterm
 | 
			
		||||
      install_figlet
 | 
			
		||||
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${ERR}${BOLD}${RED}Unsupported operating system.${CL}"
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    # Ensure the slant font is available
 | 
			
		||||
    if [ ! -f "/usr/share/figlet/slant.flf" ]; then
 | 
			
		||||
      echo -e "${INFO}${BOLD}${DGN}Downloading slant font...${CL}"
 | 
			
		||||
      wget -qO /usr/share/figlet/slant.flf "http://www.figlet.org/fonts/slant.flf"
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
  cat "$local_header_path"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  # Display ASCII header
 | 
			
		||||
# This function sets the APP-Name into an ASCII Header in Slant, figlet needed on proxmox main node.
 | 
			
		||||
header_info() {
 | 
			
		||||
  local app_name=$(echo ${APP,,} | tr -d ' ') 
 | 
			
		||||
  local header_content
 | 
			
		||||
 | 
			
		||||
  # Download & save Header-File locally
 | 
			
		||||
  header_content=$(get_header "$app_name")
 | 
			
		||||
  if [ $? -ne 0 ]; then
 | 
			
		||||
    # Fallback: Doesn't show Header
 | 
			
		||||
    return 0
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Show ASCII-Header
 | 
			
		||||
  term_width=$(tput cols 2>/dev/null || echo 120)
 | 
			
		||||
  ascii_art=$(figlet -f slant -w "$term_width" "$APP")
 | 
			
		||||
  clear
 | 
			
		||||
  echo "$ascii_art"
 | 
			
		||||
  echo "$header_content"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit.
 | 
			
		||||
 
 | 
			
		||||
@@ -120,8 +120,11 @@ EOF
 | 
			
		||||
    yes)
 | 
			
		||||
      whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58
 | 
			
		||||
      msg_info "Disabling subscription nag"
 | 
			
		||||
      # Normal GUI:
 | 
			
		||||
      echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script
 | 
			
		||||
      apt --reinstall install proxmox-widget-toolkit &>/dev/null
 | 
			
		||||
      # JS-Library used when accessing via mobile device browser
 | 
			
		||||
      echo "DPkg::Post-Invoke { \"dpkg -V pmg-gui | grep -q '/pmgmanagerlib-mobile\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from Mobile UI...'; sed -i '/data\.status.*{/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js; }; fi\"; };" >/etc/apt/apt.conf.d/no-nag-script
 | 
			
		||||
      apt --reinstall install proxmox-widget-toolkit pmg-gui &>/dev/null
 | 
			
		||||
      msg_ok "Disabled subscription nag (Delete browser cache)"
 | 
			
		||||
      ;;
 | 
			
		||||
    no)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										497
									
								
								vm/archlinux-vm.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										497
									
								
								vm/archlinux-vm.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,497 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Copyright (c) 2021-2025 community-scripts ORG
 | 
			
		||||
# Author: MickLesk (CanbiZ)
 | 
			
		||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
 | 
			
		||||
 | 
			
		||||
function header_info {
 | 
			
		||||
  clear
 | 
			
		||||
  cat <<"EOF"
 | 
			
		||||
    ___              __       __    _                     _    ____  ___
 | 
			
		||||
   /   |  __________/ /_     / /   (_)___  __  ___  __   | |  / /  |/  /
 | 
			
		||||
  / /| | / ___/ ___/ __ \   / /   / / __ \/ / / / |/_/   | | / / /|_/ / 
 | 
			
		||||
 / ___ |/ /  / /__/ / / /  / /___/ / / / / /_/ />  <     | |/ / /  / /  
 | 
			
		||||
/_/  |_/_/   \___/_/ /_/  /_____/_/_/ /_/\__,_/_/|_|     |___/_/  /_/   
 | 
			
		||||
                                                                        
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
header_info
 | 
			
		||||
echo -e "\n Loading..."
 | 
			
		||||
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
 | 
			
		||||
NEXTID=$(pvesh get /cluster/nextid)
 | 
			
		||||
 | 
			
		||||
YW=$(echo "\033[33m")
 | 
			
		||||
BL=$(echo "\033[36m")
 | 
			
		||||
RD=$(echo "\033[01;31m")
 | 
			
		||||
BGN=$(echo "\033[4;92m")
 | 
			
		||||
GN=$(echo "\033[1;92m")
 | 
			
		||||
DGN=$(echo "\033[32m")
 | 
			
		||||
CL=$(echo "\033[m")
 | 
			
		||||
 | 
			
		||||
CL=$(echo "\033[m")
 | 
			
		||||
BOLD=$(echo "\033[1m")
 | 
			
		||||
BFR="\\r\\033[K"
 | 
			
		||||
HOLD=" "
 | 
			
		||||
TAB="  "
 | 
			
		||||
 | 
			
		||||
CM="${TAB}✔️${TAB}${CL}"
 | 
			
		||||
CROSS="${TAB}✖️${TAB}${CL}"
 | 
			
		||||
INFO="${TAB}💡${TAB}${CL}"
 | 
			
		||||
OS="${TAB}🖥️${TAB}${CL}"
 | 
			
		||||
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
 | 
			
		||||
DISKSIZE="${TAB}💾${TAB}${CL}"
 | 
			
		||||
CPUCORE="${TAB}🧠${TAB}${CL}"
 | 
			
		||||
RAMSIZE="${TAB}🛠️${TAB}${CL}"
 | 
			
		||||
CONTAINERID="${TAB}🆔${TAB}${CL}"
 | 
			
		||||
HOSTNAME="${TAB}🏠${TAB}${CL}"
 | 
			
		||||
BRIDGE="${TAB}🌉${TAB}${CL}"
 | 
			
		||||
GATEWAY="${TAB}🌐${TAB}${CL}"
 | 
			
		||||
DEFAULT="${TAB}⚙️${TAB}${CL}"
 | 
			
		||||
MACADDRESS="${TAB}🔗${TAB}${CL}"
 | 
			
		||||
VLANTAG="${TAB}🏷️${TAB}${CL}"
 | 
			
		||||
CREATING="${TAB}🚀${TAB}${CL}"
 | 
			
		||||
ADVANCED="${TAB}🧩${TAB}${CL}"
 | 
			
		||||
 | 
			
		||||
THIN="discard=on,ssd=1,"
 | 
			
		||||
set -e
 | 
			
		||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
 | 
			
		||||
trap cleanup EXIT
 | 
			
		||||
function error_handler() {
 | 
			
		||||
  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"
 | 
			
		||||
  cleanup_vmid
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function cleanup_vmid() {
 | 
			
		||||
  if qm status $VMID &>/dev/null; then
 | 
			
		||||
    qm stop $VMID &>/dev/null
 | 
			
		||||
    qm destroy $VMID &>/dev/null
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function cleanup() {
 | 
			
		||||
  popd >/dev/null
 | 
			
		||||
  rm -rf $TEMP_DIR
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEMP_DIR=$(mktemp -d)
 | 
			
		||||
pushd $TEMP_DIR >/dev/null
 | 
			
		||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Arch Linux VM" --yesno "This will create a New Arch Linux VM. Proceed?" 10 58; then
 | 
			
		||||
  :
 | 
			
		||||
else
 | 
			
		||||
  header_info &&   echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
function msg_info() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function msg_ok() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  echo -e "${BFR}${CM}${GN}${msg}${CL}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function msg_error() {
 | 
			
		||||
  local msg="$1"
 | 
			
		||||
  echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function check_root() {
 | 
			
		||||
  if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
 | 
			
		||||
    clear
 | 
			
		||||
    msg_error "Please run this script as root."
 | 
			
		||||
    echo -e "\nExiting..."
 | 
			
		||||
    sleep 2
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function pve_check() {
 | 
			
		||||
  if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
 | 
			
		||||
    msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
 | 
			
		||||
    echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
 | 
			
		||||
    echo -e "Exiting..."
 | 
			
		||||
    sleep 2
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function arch_check() {
 | 
			
		||||
  if [ "$(dpkg --print-architecture)" != "amd64" ]; then
 | 
			
		||||
    echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
 | 
			
		||||
    echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
 | 
			
		||||
    echo -e "Exiting..."
 | 
			
		||||
    sleep 2
 | 
			
		||||
    exit
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ssh_check() {
 | 
			
		||||
  if command -v pveversion >/dev/null 2>&1; then
 | 
			
		||||
    if [ -n "${SSH_CLIENT:+x}" ]; then
 | 
			
		||||
      if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
 | 
			
		||||
        echo "you've been warned"
 | 
			
		||||
      else
 | 
			
		||||
        clear
 | 
			
		||||
        exit
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function exit-script() {
 | 
			
		||||
  clear
 | 
			
		||||
  echo -e "\n${CROSS}${RD}User exited script${CL}\n"
 | 
			
		||||
  exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function default_settings() {
 | 
			
		||||
  VMID="$NEXTID"
 | 
			
		||||
  FORMAT=",efitype=4m"
 | 
			
		||||
  MACHINE=""
 | 
			
		||||
  DISK_SIZE="4G"
 | 
			
		||||
  DISK_CACHE=""
 | 
			
		||||
  HN="arch-linux"
 | 
			
		||||
  CPU_TYPE=""
 | 
			
		||||
  CORE_COUNT="1"
 | 
			
		||||
  RAM_SIZE="1024"
 | 
			
		||||
  BRG="vmbr0"
 | 
			
		||||
  MAC="$GEN_MAC"
 | 
			
		||||
  VLAN=""
 | 
			
		||||
  MTU=""
 | 
			
		||||
  START_VM="yes"
 | 
			
		||||
  echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
 | 
			
		||||
  echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
 | 
			
		||||
  echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
 | 
			
		||||
  echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
 | 
			
		||||
  echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
 | 
			
		||||
  echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
 | 
			
		||||
  echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
 | 
			
		||||
  echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
 | 
			
		||||
  echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
 | 
			
		||||
  echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}"
 | 
			
		||||
  echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
 | 
			
		||||
  echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
 | 
			
		||||
  echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
 | 
			
		||||
  echo -e "${CREATING}${BOLD}${DGN}Creating a Arch Linux VM using the above default settings${CL}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function advanced_settings() {
 | 
			
		||||
  while true; do
 | 
			
		||||
    if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
      if [ -z "$VMID" ]; then
 | 
			
		||||
        VMID="$NEXTID"
 | 
			
		||||
      fi
 | 
			
		||||
      if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then
 | 
			
		||||
        echo -e "${CROSS}${RD} ID $VMID is already in use${CL}"
 | 
			
		||||
        sleep 2
 | 
			
		||||
        continue
 | 
			
		||||
      fi
 | 
			
		||||
      echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
 | 
			
		||||
      break
 | 
			
		||||
    else
 | 
			
		||||
      exit-script
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
 | 
			
		||||
    "i440fx" "Machine i440fx" ON \
 | 
			
		||||
    "q35" "Machine q35" OFF \
 | 
			
		||||
    3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ $MACH = q35 ]; then
 | 
			
		||||
      echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
 | 
			
		||||
      FORMAT=""
 | 
			
		||||
      MACHINE=" -machine q35"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
 | 
			
		||||
      FORMAT=",efitype=4m"
 | 
			
		||||
      MACHINE=""
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
  
 | 
			
		||||
  if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
 | 
			
		||||
    if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
 | 
			
		||||
      DISK_SIZE="${DISK_SIZE}G"
 | 
			
		||||
      echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
 | 
			
		||||
    elif [[ "$DISK_SIZE" =~ ^[0-9]+G$ ]]; then
 | 
			
		||||
      echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
 | 
			
		||||
      exit-script
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
  
 | 
			
		||||
  if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
 | 
			
		||||
    "0" "None (Default)" ON \
 | 
			
		||||
    "1" "Write Through" OFF \
 | 
			
		||||
    3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ $DISK_CACHE = "1" ]; then
 | 
			
		||||
      echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
 | 
			
		||||
      DISK_CACHE="cache=writethrough,"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
 | 
			
		||||
      DISK_CACHE=""
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 arch-linux --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ -z $VM_NAME ]; then
 | 
			
		||||
      HN="arch-linux"
 | 
			
		||||
      echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      HN=$(echo ${VM_NAME,,} | tr -d ' ')
 | 
			
		||||
      echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
 | 
			
		||||
    "0" "KVM64 (Default)" ON \
 | 
			
		||||
    "1" "Host" OFF \
 | 
			
		||||
    3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ $CPU_TYPE1 = "1" ]; then
 | 
			
		||||
      echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
 | 
			
		||||
      CPU_TYPE=" -cpu host"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
 | 
			
		||||
      CPU_TYPE=""
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ -z $CORE_COUNT ]; then
 | 
			
		||||
      CORE_COUNT="2"
 | 
			
		||||
      echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ -z $RAM_SIZE ]; then
 | 
			
		||||
      RAM_SIZE="2048"
 | 
			
		||||
      echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ -z $BRG ]; then
 | 
			
		||||
      BRG="vmbr0"
 | 
			
		||||
      echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ -z $MAC1 ]; then
 | 
			
		||||
      MAC="$GEN_MAC"
 | 
			
		||||
      echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      MAC="$MAC1"
 | 
			
		||||
      echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ -z $VLAN1 ]; then
 | 
			
		||||
      VLAN1="Default"
 | 
			
		||||
      VLAN=""
 | 
			
		||||
      echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      VLAN=",tag=$VLAN1"
 | 
			
		||||
      echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
 | 
			
		||||
    if [ -z $MTU1 ]; then
 | 
			
		||||
      MTU1="Default"
 | 
			
		||||
      MTU=""
 | 
			
		||||
      echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
 | 
			
		||||
    else
 | 
			
		||||
      MTU=",mtu=$MTU1"
 | 
			
		||||
      echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    exit-script
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
 | 
			
		||||
    echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
 | 
			
		||||
    START_VM="yes"
 | 
			
		||||
  else
 | 
			
		||||
    echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}no${CL}"
 | 
			
		||||
    START_VM="no"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Arch Linux VM?" --no-button Do-Over 10 58); then
 | 
			
		||||
    echo -e "${CREATING}${BOLD}${DGN}Creating a Arch Linux VM using the above advanced settings${CL}"
 | 
			
		||||
  else
 | 
			
		||||
    header_info
 | 
			
		||||
    echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
 | 
			
		||||
    advanced_settings
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function start_script() {
 | 
			
		||||
  if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then
 | 
			
		||||
    header_info
 | 
			
		||||
    echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings${CL}"
 | 
			
		||||
    default_settings
 | 
			
		||||
  else
 | 
			
		||||
    header_info
 | 
			
		||||
    echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
 | 
			
		||||
    advanced_settings
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
check_root
 | 
			
		||||
arch_check
 | 
			
		||||
pve_check
 | 
			
		||||
ssh_check
 | 
			
		||||
start_script
 | 
			
		||||
 | 
			
		||||
msg_info "Validating Storage"
 | 
			
		||||
while read -r line; do
 | 
			
		||||
  TAG=$(echo $line | awk '{print $1}')
 | 
			
		||||
  TYPE=$(echo $line | awk '{printf "%-10s", $2}')
 | 
			
		||||
  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
 | 
			
		||||
  ITEM="  Type: $TYPE Free: $FREE "
 | 
			
		||||
  OFFSET=2
 | 
			
		||||
  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
 | 
			
		||||
    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
 | 
			
		||||
  fi
 | 
			
		||||
  STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
 | 
			
		||||
done < <(pvesm status -content images | awk 'NR>1')
 | 
			
		||||
VALID=$(pvesm status -content images | awk 'NR>1')
 | 
			
		||||
if [ -z "$VALID" ]; then
 | 
			
		||||
  msg_error "Unable to detect a valid storage location."
 | 
			
		||||
  exit
 | 
			
		||||
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
 | 
			
		||||
  STORAGE=${STORAGE_MENU[0]}
 | 
			
		||||
else
 | 
			
		||||
  while [ -z "${STORAGE:+x}" ]; do
 | 
			
		||||
    STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
 | 
			
		||||
      "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
 | 
			
		||||
      16 $(($MSG_MAX_LENGTH + 23)) 6 \
 | 
			
		||||
      "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit
 | 
			
		||||
  done
 | 
			
		||||
fi
 | 
			
		||||
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
 | 
			
		||||
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
 | 
			
		||||
msg_info "Retrieving the URL for the Arch Linux .iso File"
 | 
			
		||||
URL=https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso
 | 
			
		||||
sleep 2
 | 
			
		||||
msg_ok "${CL}${BL}${URL}${CL}"
 | 
			
		||||
wget -q --show-progress $URL
 | 
			
		||||
echo -en "\e[1A\e[0K"
 | 
			
		||||
FILE=$(basename $URL)
 | 
			
		||||
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
 | 
			
		||||
 | 
			
		||||
STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')
 | 
			
		||||
case $STORAGE_TYPE in
 | 
			
		||||
nfs | dir | cifs)
 | 
			
		||||
  DISK_EXT=".qcow2"
 | 
			
		||||
  DISK_REF="$VMID/"
 | 
			
		||||
  DISK_IMPORT="-format qcow2"
 | 
			
		||||
  THIN=""
 | 
			
		||||
  ;;
 | 
			
		||||
btrfs)
 | 
			
		||||
  DISK_EXT=".raw"
 | 
			
		||||
  DISK_REF="$VMID/"
 | 
			
		||||
  DISK_IMPORT="-format raw"
 | 
			
		||||
  FORMAT=",efitype=4m"
 | 
			
		||||
  THIN=""
 | 
			
		||||
  ;;
 | 
			
		||||
esac
 | 
			
		||||
for i in {0,1}; do
 | 
			
		||||
  disk="DISK$i"
 | 
			
		||||
  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}
 | 
			
		||||
  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
msg_info "Creating a Arch Linux VM"
 | 
			
		||||
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
 | 
			
		||||
  -name $HN -tags community-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
 | 
			
		||||
pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null
 | 
			
		||||
qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
 | 
			
		||||
qm set $VMID \
 | 
			
		||||
  -efidisk0 ${DISK0_REF}${FORMAT} \
 | 
			
		||||
  -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \
 | 
			
		||||
  -ide2 ${STORAGE}:cloudinit \
 | 
			
		||||
  -boot order=scsi0 \
 | 
			
		||||
  -serial0 socket >/dev/null
 | 
			
		||||
DESCRIPTION=$(
 | 
			
		||||
  cat <<EOF
 | 
			
		||||
<div align='center'>
 | 
			
		||||
  <a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
 | 
			
		||||
    <img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
 | 
			
		||||
  </a>
 | 
			
		||||
 | 
			
		||||
  <h2 style='font-size: 24px; margin: 20px 0;'>Arch Linux VM</h2>
 | 
			
		||||
 | 
			
		||||
  <p style='margin: 16px 0;'>
 | 
			
		||||
    <a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
 | 
			
		||||
      <img src='https://img.shields.io/badge/☕-Buy us a coffee-blue' alt='spend Coffee' />
 | 
			
		||||
    </a>
 | 
			
		||||
  </p>
 | 
			
		||||
  
 | 
			
		||||
  <span style='margin: 0 10px;'>
 | 
			
		||||
    <i class="fa fa-github fa-fw" style="color: #f5f5f5;"></i>
 | 
			
		||||
    <a href='https://github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>GitHub</a>
 | 
			
		||||
  </span>
 | 
			
		||||
  <span style='margin: 0 10px;'>
 | 
			
		||||
    <i class="fa fa-comments fa-fw" style="color: #f5f5f5;"></i>
 | 
			
		||||
    <a href='https://github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Discussions</a>
 | 
			
		||||
  </span>
 | 
			
		||||
  <span style='margin: 0 10px;'>
 | 
			
		||||
    <i class="fa fa-exclamation-circle fa-fw" style="color: #f5f5f5;"></i>
 | 
			
		||||
    <a href='https://github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Issues</a>
 | 
			
		||||
  </span>
 | 
			
		||||
</div>
 | 
			
		||||
EOF
 | 
			
		||||
)
 | 
			
		||||
qm set "$VMID" -description "$DESCRIPTION" >/dev/null
 | 
			
		||||
if [ -n "$DISK_SIZE" ]; then
 | 
			
		||||
    msg_info "Resizing disk to $DISK_SIZE GB"
 | 
			
		||||
    qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null
 | 
			
		||||
else
 | 
			
		||||
    msg_info "Using default disk size of $DEFAULT_DISK_SIZE GB"
 | 
			
		||||
    qm resize $VMID scsi0 ${DEFAULT_DISK_SIZE} >/dev/null
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
msg_ok "Created a Arch Linux VM ${CL}${BL}(${HN})"
 | 
			
		||||
if [ "$START_VM" == "yes" ]; then
 | 
			
		||||
  msg_info "Starting Arch Linux VM"
 | 
			
		||||
  qm start $VMID
 | 
			
		||||
  msg_ok "Started Arch Linux VM"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
msg_ok "Completed Successfully!\n"
 | 
			
		||||
		Reference in New Issue
	
	Block a user