diff --git a/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md b/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md
index 89421da2d..be6c6f848 100644
--- a/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md
+++ b/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md
@@ -95,7 +95,7 @@ Example:
>| Variable | Description | Notes |
>|----------|-------------|-------|
>| `APP` | Application name | Must match ct\AppName.sh |
->| `TAGS` | Proxmox display tags without Spaces, only ; | Limit the number |
+>| `var_tags` | Proxmox display tags without Spaces, only ; | Limit the number |
>| `var_cpu` | CPU cores | Number of cores |
>| `var_ram` | RAM | In MB |
>| `var_disk` | Disk capacity | In GB |
@@ -193,13 +193,13 @@ wget -q
unzip -q
```
-- If a command does not come with this functionality use `&>/dev/null` to suppress it's output.
+- If a command does not come with this functionality use `$STD` to suppress it's output.
Example:
```bash
-php artisan migrate --force &>/dev/null
-php artisan config:clear &>/dev/null
+$STD php artisan migrate --force
+$STD php artisan config:clear
```
### 3.5 **Backups**
@@ -247,7 +247,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no automatic update function for ${APP}."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
```
diff --git a/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh b/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh
index ff8d03c27..b61262bb1 100644
--- a/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh
+++ b/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh
@@ -8,7 +8,7 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/m
# App Default Values
APP="[APP_NAME]"
# Name of the app (e.g. Google, Adventurelog, Apache-Guacamole"
-TAGS="[TAGS]"
+var_tags="[TAGS]"
# Tags for Proxmox VE, maximum 2 pcs., no spaces allowed, separated by a semicolon ; (e.g. database | adblock;dhcp)
var_cpu="[CPU]"
# Number of cores (1-X) (e.g. 4) - default are 2
diff --git a/.github/autolabeler-config.json b/.github/autolabeler-config.json
index 399004ee1..5406bdaa4 100644
--- a/.github/autolabeler-config.json
+++ b/.github/autolabeler-config.json
@@ -1,17 +1,5 @@
{
- "breaking change": [
- {
- "fileStatus": "renamed",
- "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"],
- "excludeGlobs": []
- },
- {
- "fileStatus": "removed",
- "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"],
- "excludeGlobs": []
- }
- ],
"new script": [
{
"fileStatus": "added",
@@ -33,10 +21,17 @@
"excludeGlobs": []
}
],
- "rename script": [
+ "maintenance": [
{
- "fileStatus": "renamed",
- "includeGlobs": ["ct/**", "install/**", "misc/**", "turnkey/**", "vm/**"],
+ "fileStatus": null,
+ "includeGlobs": ["*.md", ".github/**", "misc/*.func", "ct/create_lxc.sh", "api/**"],
+ "excludeGlobs": []
+ }
+ ],
+ "core": [
+ {
+ "fileStatus": null,
+ "includeGlobs": ["misc/*.func", "ct/create_lxc.sh"],
"excludeGlobs": []
}
],
@@ -47,20 +42,28 @@
"excludeGlobs": []
}
],
- "maintenance": [
- {
- "fileStatus": null,
- "includeGlobs": ["*.md", ".github/**", "misc/*.func", "ct/create_lxc.sh"],
- "excludeGlobs": ["misc/api.func"]
- }
- ],
- "api": [
+ "api": [
{
"fileStatus": null,
"includeGlobs": ["api/**", "misc/api.func"],
"excludeGlobs": []
}
],
+ "github": [
+ {
+ "fileStatus": null,
+ "includeGlobs": [".github/**"],
+ "excludeGlobs": []
+ }
+ ],
+ "json": [
+ {
+ "fileStatus": "modified",
+ "includeGlobs": ["json/**"],
+ "excludeGlobs": []
+ }
+ ],
+
"high risk": [
{
"fileStatus": null,
@@ -68,4 +71,6 @@
"excludeGlobs": []
}
]
-}
+
+
+}
\ No newline at end of file
diff --git a/.github/changelog-pr-config.json b/.github/changelog-pr-config.json
index 8168251b6..2c62aa3f0 100644
--- a/.github/changelog-pr-config.json
+++ b/.github/changelog-pr-config.json
@@ -1,42 +1,97 @@
[
- {
- "title": "π₯ Breaking Changes",
- "labels": ["breaking change"]
- },
{
"title": "π New Scripts",
"labels": ["new script"]
},
{
"title": "π Updated Scripts",
- "labels": ["update script"]
- },
- {
- "title": "π Bug Fixes (Updated Scripts)",
- "labels": ["update script", "bugfix"]
- },
- {
- "title": "β¨ Feature Updates (Updated Scripts)",
- "labels": ["update script", "feature"]
- },
- {
- "title": "β¨ New Features",
- "labels": ["feature"]
- },
- {
- "title": "π Website",
- "labels": ["website"]
- },
- {
- "title": "π‘ API",
- "labels": ["api"]
+ "labels": ["update script"],
+ "subCategories": [
+ {
+ "title": "π Bug Fixes",
+ "labels": ["bugfix"],
+ "notes" : []
+ },
+ {
+ "title": "β¨ New Features",
+ "labels": ["feature"],
+ "notes" : []
+ },
+ {
+ "title": "π₯ Breaking Changes",
+ "labels": ["breaking change"],
+ "notes" : []
+ }
+ ]
},
{
"title": "π§° Maintenance",
- "labels": ["maintenance"]
+ "labels": ["maintenance"],
+ "subCategories": [
+ {
+ "title": "π Bug Fixes",
+ "labels": ["bugfix"],
+ "notes" : []
+ },
+ {
+ "title": "β¨ New Features",
+ "labels": ["feature"],
+ "notes" : []
+ },
+ {
+ "title": "π₯ Breaking Changes",
+ "labels": ["breaking change"],
+ "notes" : []
+ },
+ {
+ "title": "π‘ API",
+ "labels": ["api"],
+ "notes" : []
+ },
+ {
+ "title": "πΎ Core",
+ "labels": ["core"],
+ "notes" : []
+ },
+ {
+ "title": "π Github",
+ "labels": ["github"],
+ "notes" : []
+ }
+ ]
+ },
+ {
+ "title": "π Website",
+ "labels": ["website"],
+ "subCategories": [
+ {
+ "title": "π Bug Fixes",
+ "labels": ["bugfix"],
+ "notes" : []
+ },
+ {
+ "title": "β¨ New Features",
+ "labels": ["feature"],
+ "notes" : []
+ },
+ {
+ "title": "π₯ Breaking Changes",
+ "labels": ["breaking change"],
+ "notes" : []
+ },
+ {
+ "title": "π Script Information",
+ "labels": ["json"],
+ "notes" : []
+ }
+ ]
},
{
"title": "β Unlabelled",
"labels": []
+ },
+ {
+ "title": "π₯ Breaking Changes",
+ "labels": ["breaking change"]
}
]
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 11a90a774..d669ec78a 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,25 +1,25 @@
## βοΈ Description
-
## π Related PR / Discussion / Issue
+
Link: #
-
-
## β
Prerequisites
+
Before this PR can be reviewed, the following must be completed:
+
- [] **Self-review performed** β Code follows established patterns and conventions.
- [] **Testing performed** β Changes have been thoroughly tested and verified.
-
## π οΈ Type of Change
-Select all that apply:
-- [] π **Bug fix** β Resolves an issue without breaking functionality.
-- [] β¨ **New feature** β Adds new, non-breaking functionality.
-- [] π₯ **Breaking change** β Alters existing functionality in a way that may require updates.
-- [] π **New script** β A fully functional and tested script or script set.
+Select all that apply:
+
+- [] π **New script** β A fully functional and tested script or script set.
+- [] π **Bug fix** β Resolves an issue without breaking functionality.
+- [] β¨ **New feature** β Adds new, non-breaking functionality.
+- [] π₯ **Breaking change** β Alters existing functionality in a way that may require updates.
## π Additional Information (optional)
diff --git a/.github/runner/docker/gh-runner-self.dockerfile b/.github/runner/docker/gh-runner-self.dockerfile
new file mode 100644
index 000000000..e5ae072ab
--- /dev/null
+++ b/.github/runner/docker/gh-runner-self.dockerfile
@@ -0,0 +1,68 @@
+FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy as build
+
+ARG TARGETOS
+ARG TARGETARCH
+ARG DOCKER_VERSION=27.5.1
+ARG BUILDX_VERSION=0.20.1
+ARG RUNNER_ARCH="x64"
+
+RUN apt update -y && apt install sudo curl unzip -y
+
+WORKDIR /actions-runner
+
+RUN RUNNER_VERSION=$(curl -s https://api.github.com/repos/actions/runner/releases/latest | grep "tag_name" | head -n 1 | awk '{print substr($2, 3, length($2)-4)}') \
+ && curl -f -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${RUNNER_ARCH}-${RUNNER_VERSION}.tar.gz \
+ && tar xzf ./runner.tar.gz \
+ && rm runner.tar.gz
+
+RUN RUNNER_CONTAINER_HOOKS_VERSION=$(curl -s https://api.github.com/repos/actions/runner-container-hooks/releases/latest | grep "tag_name" | head -n 1 | awk '{print substr($2, 3, length($2)-4)}') \
+ && curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \
+ && unzip ./runner-container-hooks.zip -d ./k8s \
+ && rm runner-container-hooks.zip
+
+RUN export RUNNER_ARCH=${TARGETARCH} \
+ && if [ "$RUNNER_ARCH" = "amd64" ]; then export DOCKER_ARCH=x86_64 ; fi \
+ && if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \
+ && curl -fLo docker.tgz https://download.docker.com/${TARGETOS}/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz \
+ && tar zxvf docker.tgz \
+ && rm -rf docker.tgz \
+ && mkdir -p /usr/local/lib/docker/cli-plugins \
+ && curl -fLo /usr/local/lib/docker/cli-plugins/docker-buildx \
+ "https://github.com/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-${TARGETARCH}" \
+ && chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx
+
+FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy
+
+ENV DEBIAN_FRONTEND=noninteractive
+ENV RUNNER_MANUALLY_TRAP_SIG=1
+ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
+ENV ImageOS=ubuntu22
+
+RUN apt update -y \
+ && apt install -y --no-install-recommends sudo lsb-release gpg-agent software-properties-common curl jq unzip \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN add-apt-repository ppa:git-core/ppa \
+ && apt update -y \
+ && apt install -y git \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN adduser --disabled-password --gecos "" --uid 1001 runner \
+ && groupadd docker --gid 123 \
+ && usermod -aG sudo runner \
+ && usermod -aG docker runner \
+ && echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers \
+ && echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >> /etc/sudoers
+
+# Install own dependencies in final image
+RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
+ && apt-get install -y nodejs \
+ && apt-get install -y gh jq git
+
+WORKDIR /home/runner
+
+COPY --chown=runner:docker --from=build /actions-runner .
+COPY --from=build /usr/local/lib/docker/cli-plugins/docker-buildx /usr/local/lib/docker/cli-plugins/docker-buildx
+RUN install -o root -g root -m 755 docker/* /usr/bin/ && rm -rf docker
+
+USER runner
diff --git a/.github/workflows/auto-update-app-headers.yml b/.github/workflows/auto-update-app-headers.yml
index 5e447ea54..b6c4f2b77 100644
--- a/.github/workflows/auto-update-app-headers.yml
+++ b/.github/workflows/auto-update-app-headers.yml
@@ -10,7 +10,7 @@ on:
jobs:
update-app-files:
- runs-on: ubuntu-latest
+ runs-on: runner-cluster-htl-set
permissions:
contents: write
diff --git a/.github/workflows/close-discussion.yml b/.github/workflows/close-discussion.yml
new file mode 100644
index 000000000..dd9a80b33
--- /dev/null
+++ b/.github/workflows/close-discussion.yml
@@ -0,0 +1,122 @@
+name: Close Discussion on PR Merge
+
+on:
+ pull_request:
+ types: [closed]
+
+jobs:
+ close-discussion:
+ runs-on: runner-cluster-htl-set
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Set Up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "20"
+ - name: Install Dependencies
+ run: npm install zx @octokit/graphql
+
+ - name: Close Discussion
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PR_BODY: ${{ github.event.pull_request.body }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ REPO_OWNER: ${{ github.repository_owner }}
+ REPO_NAME: ${{ github.event.repository.name }}
+ run: |
+ npx zx << 'EOF'
+ import { graphql } from "@octokit/graphql";
+ (async function() {
+ try {
+ const token = process.env.GITHUB_TOKEN;
+ const prBody = process.env.PR_BODY;
+ const prNumber = process.env.PR_NUMBER;
+ const owner = process.env.REPO_OWNER;
+ const repo = process.env.REPO_NAME;
+
+ if (!token || !prBody || !prNumber || !owner || !repo) {
+ console.log("Missing required environment variables.");
+ process.exit(1);
+ }
+
+ const match = prBody.match(/#(\d+)/);
+ if (!match) {
+ console.log("No discussion ID found in PR body.");
+ return;
+ }
+ const discussionNumber = match[1];
+
+ console.log(`Extracted Discussion Number: ${discussionNumber}`);
+ console.log(`PR Number: ${prNumber}`);
+ console.log(`Repository: ${owner}/${repo}`);
+
+ const graphqlWithAuth = graphql.defaults({
+ headers: { authorization: `Bearer ${token}` },
+ });
+
+ const discussionQuery = `
+ query($owner: String!, $repo: String!, $number: Int!) {
+ repository(owner: $owner, name: $repo) {
+ discussion(number: $number) {
+ id
+ }
+ }
+ }
+ `;
+
+ const discussionResponse = await graphqlWithAuth(discussionQuery, {
+ owner,
+ repo,
+ number: parseInt(discussionNumber, 10),
+ });
+
+ const discussionQLId = discussionResponse.repository.discussion.id;
+ if (!discussionQLId) {
+ console.log("Failed to fetch discussion GraphQL ID.");
+ return;
+ }
+
+ console.log(`GraphQL Discussion ID: ${discussionQLId}`);
+
+ const commentMutation = `
+ mutation($discussionId: ID!, $body: String!) {
+ addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
+ comment { id body }
+ }
+ }
+ `;
+
+ const commentResponse = await graphqlWithAuth(commentMutation, {
+ discussionId: discussionQLId,
+ body: `Merged with PR #${prNumber}`,
+ });
+
+ const commentId = commentResponse.addDiscussionComment.comment.id;
+ if (!commentId) {
+ console.log("Failed to post the comment.");
+ return;
+ }
+
+ console.log(`Comment Posted Successfully! Comment ID: ${commentId}`);
+
+ const markAnswerMutation = `
+ mutation($id: ID!) {
+ markDiscussionCommentAsAnswer(input: { id: $id }) {
+ discussion { id title }
+ }
+ }
+ `;
+
+ await graphqlWithAuth(markAnswerMutation, { id: commentId });
+
+ console.log("Comment marked as answer successfully!");
+
+ } catch (error) {
+ console.error("Error:", error);
+ return;
+ }
+ })();
+ EOF
\ No newline at end of file
diff --git a/.github/workflows/create-docker-for-runner.yml b/.github/workflows/create-docker-for-runner.yml
new file mode 100644
index 000000000..c9fef0a5c
--- /dev/null
+++ b/.github/workflows/create-docker-for-runner.yml
@@ -0,0 +1,37 @@
+name: Build and Publish Docker Image
+
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - '.github/runner/docker/**'
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ build:
+ runs-on: ubuntu-latest #To ensure it always builds we use the github runner with all the right tooling
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Log in to GHCR
+ uses: docker/login-action@v2
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build Docker image
+ run: |
+ repo_name=${{ github.repository }} # Get repository name
+ repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
+ docker build -t ghcr.io/$repo_name_lower/gh-runner-self:latest -f .github/runner/docker/gh-runner-self.dockerfile .
+
+ - name: Push Docker image to GHCR
+ run: |
+ repo_name=${{ github.repository }} # Get repository name
+ repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
+ docker push ghcr.io/$repo_name_lower/gh-runner-self:latest
diff --git a/.github/workflows/delete-json-branch.yml b/.github/workflows/delete-json-branch.yml
index e4cdcf24f..b72868402 100644
--- a/.github/workflows/delete-json-branch.yml
+++ b/.github/workflows/delete-json-branch.yml
@@ -9,7 +9,7 @@ on:
jobs:
delete_branch:
- runs-on: ubuntu-latest
+ runs-on: runner-cluster-htl-set
steps:
- name: Checkout the code
uses: actions/checkout@v3
diff --git a/.github/workflows/frontend-cicd.yml b/.github/workflows/frontend-cicd.yml
index dd242f6ef..c4f1a6418 100644
--- a/.github/workflows/frontend-cicd.yml
+++ b/.github/workflows/frontend-cicd.yml
@@ -27,7 +27,7 @@ concurrency:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: runner-cluster-htl-set
defaults:
run:
working-directory: frontend # Set default working directory for all run steps
diff --git a/.github/workflows/script-test.yml b/.github/workflows/script-test.yml
index 6b9e100eb..5c8803907 100644
--- a/.github/workflows/script-test.yml
+++ b/.github/workflows/script-test.yml
@@ -13,7 +13,7 @@ jobs:
run-install-script:
runs-on: pvenode
steps:
- - name: Checkout PR branch (supports forks)
+ - name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
@@ -37,7 +37,8 @@ jobs:
echo "Changed files: $CHANGED_FILES"
echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
- name: Get scripts
id: check-install-script
@@ -61,59 +62,71 @@ jobs:
id: run-install
continue-on-error: true
run: |
- set +e
- #run for each files in /ct
- for FILE in ${{ env.ALL_FILES }}; do
- STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
- echo "Running Test for: $STRIPPED_NAME"
- if [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
- CT_SCRIPT="ct/$STRIPPED_NAME.sh"
- if [[ ! -f $CT_SCRIPT ]]; then
- echo "No CT script found for $STRIPPED_NAME"
- ERROR_MSG="No CT script found for $FILE"
- echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
+ set +e
+ #run for each files in /ct
+ for FILE in ${{ env.ALL_FILES }}; do
+ STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
+ echo "Running Test for: $STRIPPED_NAME"
+ if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "$FILE"; then
+ echo "The script contains an interactive prompt. Skipping execution."
continue
fi
- echo "Found CT script for $STRIPPED_NAME"
- chmod +x "$CT_SCRIPT"
- RUNNING_FILE=$CT_SCRIPT
- elif [[ $FILE =~ ^ct/.*\.sh$ ]]; then
- INSTALL_SCRIPT="install/$STRIPPED_NAME-install.sh"
- if [[ ! -f $INSTALL_SCRIPT ]]; then
- echo "No install script found for $STRIPPED_NAME"
- ERROR_MSG="No install script found for $FILE"
+ if [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
+ CT_SCRIPT="ct/$STRIPPED_NAME.sh"
+ if [[ ! -f $CT_SCRIPT ]]; then
+ echo "No CT script found for $STRIPPED_NAME"
+ ERROR_MSG="No CT script found for $FILE"
+ echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
+ continue
+ fi
+ if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "install/$STRIPPED_NAME-install.sh"; then
+ echo "The script contains an interactive prompt. Skipping execution."
+ continue
+ fi
+ echo "Found CT script for $STRIPPED_NAME"
+ chmod +x "$CT_SCRIPT"
+ RUNNING_FILE=$CT_SCRIPT
+ elif [[ $FILE =~ ^ct/.*\.sh$ ]]; then
+ INSTALL_SCRIPT="install/$STRIPPED_NAME-install.sh"
+ if [[ ! -f $INSTALL_SCRIPT ]]; then
+ echo "No install script found for $STRIPPED_NAME"
+ ERROR_MSG="No install script found for $FILE"
+ echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
+ continue
+ fi
+ echo "Found install script for $STRIPPED_NAME"
+ chmod +x "$INSTALL_SCRIPT"
+ RUNNING_FILE=$FILE
+ if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "ct/$STRIPPED_NAME.sh"; then
+ echo "The script contains an interactive prompt. Skipping execution."
+ continue
+ fi
+ fi
+ git remote add community-scripts https://github.com/community-scripts/ProxmoxVE.git
+ git fetch community-scripts
+ rm -f .github/workflows/scripts/app-test/pr-build.func || true
+ rm -f .github/workflows/scripts/app-test/pr-install.func || true
+ rm -f .github/workflows/scripts/app-test/pr-alpine-install.func || true
+ rm -f .github/workflows/scripts/app-test/pr-create-lxc.sh || true
+ git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-build.func
+ git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-install.func
+ git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-alpine-install.func
+ git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-create-lxc.sh
+ chmod +x $RUNNING_FILE
+ chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
+ chmod +x .github/workflows/scripts/app-test/pr-install.func
+ chmod +x .github/workflows/scripts/app-test/pr-alpine-install.func
+ chmod +x .github/workflows/scripts/app-test/pr-build.func
+ sed -i 's|source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)|source .github/workflows/scripts/app-test/pr-build.func|g' "$RUNNING_FILE"
+ echo "Executing $RUNNING_FILE"
+ ERROR_MSG=$(./$RUNNING_FILE 2>&1 > /dev/null)
+ echo "Finished running $FILE"
+ if [ -n "$ERROR_MSG" ]; then
+ echo "ERROR in $STRIPPED_NAME: $ERROR_MSG"
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
- continue
- fi
- echo "Found install script for $STRIPPED_NAME"
- chmod +x "$INSTALL_SCRIPT"
- RUNNING_FILE=$FILE
- fi
- git remote add community-scripts https://github.com/community-scripts/ProxmoxVE.git
- git fetch community-scripts
- rm -f .github/workflows/scripts/app-test/pr-build.func || true
- rm -f .github/workflows/scripts/app-test/pr-install.func || true
- rm -f .github/workflows/scripts/app-test/pr-alpine-install.func || true
- rm -f .github/workflows/scripts/app-test/pr-create-lxc.sh || true
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-build.func
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-install.func
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-alpine-install.func
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-create-lxc.sh
- chmod +x $RUNNING_FILE
- chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
- chmod +x .github/workflows/scripts/app-test/pr-install.func
- chmod +x .github/workflows/scripts/app-test/pr-alpine-install.func
- chmod +x .github/workflows/scripts/app-test/pr-build.func
- sed -i 's|source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)|source .github/workflows/scripts/app-test/pr-build.func|g' "$RUNNING_FILE"
- echo "Executing $RUNNING_FILE"
- ERROR_MSG=$(./$RUNNING_FILE 2>&1 > /dev/null)
- echo "Finished running $FILE"
- if [ -n "$ERROR_MSG" ]; then
- echo "ERROR in $STRIPPED_NAME: $ERROR_MSG"
- echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
- fi
- done
- set -e # Restore exit-on-error
+ fi
+ done
+ set -e # Restore exit-on-error
- name: Cleanup PVE Node
run: |
@@ -125,35 +138,40 @@ jobs:
pct stop $container_id
pct destroy $container_id
fi
- done
-
+ done
+
- name: Post error comments
run: |
ERROR="false"
- SEARCH_LINE=".github/workflows/scripts/app-test/pr-build.func: line 253:"
+ SEARCH_LINE=".github/workflows/scripts/app-test/pr-build.func: line 255:"
+
+ # Get all existing comments on the PR
+ EXISTING_COMMENTS=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments --jq '.comments[].body')
+
for FILE in ${{ env.ALL_FILES }}; do
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
if [[ ! -f result_$STRIPPED_NAME.log ]]; then
continue
fi
ERROR_MSG=$(cat result_$STRIPPED_NAME.log)
-
+
if [ -n "$ERROR_MSG" ]; then
CLEANED_ERROR_MSG=$(echo "$ERROR_MSG" | sed "s|$SEARCH_LINE.*||")
- echo "Posting error message for $FILE"
- echo ${CLEANED_ERROR_MSG}
- gh pr comment ${{ github.event.pull_request.number }} \
- --repo ${{ github.repository }} \
- --body ":warning: The script _**$FILE**_ failed with the following message:
${CLEANED_ERROR_MSG}
"
-
-
- ERROR="true"
+ COMMENT_BODY=":warning: The script _**$FILE**_ failed with the following message:
${CLEANED_ERROR_MSG}
"
+
+ # Check if the comment already exists
+ if echo "$EXISTING_COMMENTS" | grep -qF "$COMMENT_BODY"; then
+ echo "Skipping duplicate comment for $FILE"
+ else
+ echo "Posting error message for $FILE"
+ gh pr comment ${{ github.event.pull_request.number }} \
+ --repo ${{ github.repository }} \
+ --body "$COMMENT_BODY"
+ ERROR="true"
+ fi
fi
done
+
echo "ERROR=$ERROR" >> $GITHUB_ENV
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Fail if error
- if: ${{ env.ERROR == 'true' }}
- run: exit 1
+
+
diff --git a/.github/workflows/script_format.yml b/.github/workflows/script_format.yml
new file mode 100644
index 000000000..a86a512b4
--- /dev/null
+++ b/.github/workflows/script_format.yml
@@ -0,0 +1,243 @@
+name: Script Format Check
+permissions:
+ pull-requests: write
+on:
+ pull_request_target:
+ branches:
+ - main
+ paths:
+ - 'install/*.sh'
+ - 'ct/*.sh'
+
+jobs:
+ run-install-script:
+ runs-on: pvenode
+ steps:
+ - name: Checkout PR branch (supports forks)
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.ref }}
+ repository: ${{ github.event.pull_request.head.repo.full_name }}
+ fetch-depth: 0
+
+ - name: Add Git safe directory
+ run: |
+ git config --global --add safe.directory /__w/ProxmoxVE/ProxmoxVE
+
+ - name: Set up GH_TOKEN
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
+
+ - name: Get Changed Files
+ run: |
+ CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
+ CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
+ echo "Changed files: $CHANGED_FILES"
+ echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Check scripts
+ id: run-install
+ continue-on-error: true
+ run: |
+ for FILE in ${{ env.SCRIPT }}; do
+ STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
+ echo "Running Test for: $STRIPPED_NAME"
+ FILE_STRIPPED="${FILE##*/}"
+ LOG_FILE="result_$FILE_STRIPPED.log"
+
+ if [[ $FILE =~ ^ct/.*\.sh$ ]]; then
+
+ FIRST_LINE=$(sed -n '1p' "$FILE")
+ [[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
+ SECOND_LINE=$(sed -n '2p' "$FILE")
+ [[ "$SECOND_LINE" != "source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" ]] &&
+ echo "Line 2 was $SECOND_LINE | Should be: source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" >> "$LOG_FILE"
+ THIRD_LINE=$(sed -n '3p' "$FILE")
+ if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
+ echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
+ fi
+
+ EXPECTED_AUTHOR="# Author:"
+ EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
+ EXPECTED_SOURCE="# Source:"
+ EXPECTED_EMPTY=""
+
+ for i in {4..7}; do
+ LINE=$(sed -n "${i}p" "$FILE")
+
+ case $i in
+ 4)
+ [[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
+ ;;
+ 5)
+ [[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
+ ;;
+ 6)
+ [[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
+ ;;
+ 7)
+ [[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
+ ;;
+ esac
+ done
+
+
+ EXPECTED_PREFIXES=(
+ "APP="
+ "var_tags="
+ "var_cpu=" # Must be a number
+ "var_ram=" # Must be a number
+ "var_disk=" # Must be a number
+ "var_os=" # Must be debian, alpine, or ubuntu
+ "var_version="
+ "var_unprivileged=" # Must be 0 or 1
+ )
+
+
+ for i in {8..15}; do
+ LINE=$(sed -n "${i}p" "$FILE")
+ INDEX=$((i - 8))
+
+ case $INDEX in
+ 2|3|4) # var_cpu, var_ram, var_disk (must be numbers)
+ if [[ "$LINE" =~ ^${EXPECTED_PREFIXES[$INDEX]}([0-9]+)$ ]]; then
+ continue # Valid
+ else
+ echo "Line $i was '$LINE' | Should be: '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE"
+ fi
+ ;;
+ 5) # var_os (must be debian, alpine, or ubuntu)
+ if [[ "$LINE" =~ ^var_os=(debian|alpine|ubuntu)$ ]]; then
+ continue # Valid
+ else
+ echo "Line $i was '$LINE' | Should be: 'var_os=[debian|alpine|ubuntu]'" >> "$LOG_FILE"
+ fi
+ ;;
+ 7) # var_unprivileged (must be 0 or 1)
+ if [[ "$LINE" =~ ^var_unprivileged=[01]$ ]]; then
+ continue # Valid
+ else
+ echo "Line $i was '$LINE' | Should be: 'var_unprivileged=[0|1]'" >> "$LOG_FILE"
+ fi
+ ;;
+ *) # Other lines (must start with expected prefix)
+ if [[ "$LINE" == ${EXPECTED_PREFIXES[$INDEX]}* ]]; then
+ continue # Valid
+ else
+ echo "Line $i was '$LINE' | Should start with '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE"
+ fi
+ ;;
+ esac
+ done
+
+ for i in {16..20}; do
+ LINE=$(sed -n "${i}p" "$FILE")
+ EXPECTED=(
+ "header_info \"$APP\""
+ "variables"
+ "color"
+ "catch_errors"
+ "function update_script() {"
+ )
+ [[ "$LINE" != "${EXPECTED[$((i-16))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-16))]}" >> "$LOG_FILE"
+ done
+ cat "$LOG_FILE"
+ elif [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
+
+ FIRST_LINE=$(sed -n '1p' "$FILE")
+ [[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
+
+ SECOND_LINE=$(sed -n '2p' "$FILE")
+ [[ -n "$SECOND_LINE" ]] && echo "Line 2 should be empty" >> "$LOG_FILE"
+
+ THIRD_LINE=$(sed -n '3p' "$FILE")
+ if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
+ echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
+ fi
+
+ EXPECTED_AUTHOR="# Author:"
+ EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
+ EXPECTED_SOURCE="# Source:"
+ EXPECTED_EMPTY=""
+
+ for i in {4..7}; do
+ LINE=$(sed -n "${i}p" "$FILE")
+
+ case $i in
+ 4)
+ [[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
+ ;;
+ 5)
+ [[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
+ ;;
+ 6)
+ [[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
+ ;;
+ 7)
+ [[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
+ ;;
+ esac
+ done
+
+ [[ "$(sed -n '8p' "$FILE")" != 'source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' ]] && echo 'Line 8 should be: source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' >> "$LOG_FILE"
+
+ for i in {9..14}; do
+ LINE=$(sed -n "${i}p" "$FILE")
+ EXPECTED=(
+ "color"
+ "verb_ip6"
+ "catch_errors"
+ "setting_up_container"
+ "network_check"
+ "update_os"
+ )
+ [[ "$LINE" != "${EXPECTED[$((i-9))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-9))]}" >> "$LOG_FILE"
+ done
+
+ [[ -n "$(sed -n '15p' "$FILE")" ]] && echo "Line 15 should be empty" >> "$LOG_FILE"
+ [[ "$(sed -n '16p' "$FILE")" != 'msg_info "Installing Dependencies"' ]] && echo 'Line 16 should be: msg_info "Installing Dependencies"' >> "$LOG_FILE"
+
+ LAST_3_LINES=$(tail -n 3 "$FILE")
+ [[ "$LAST_3_LINES" != *"$STD apt-get -y autoremove"* ]] && echo 'Third to last line should be: $STD apt-get -y autoremove' >> "$LOG_FILE"
+ [[ "$LAST_3_LINES" != *"$STD apt-get -y autoclean"* ]] && echo 'Second to last line should be: $STD apt-get -y clean' >> "$LOG_FILE"
+ [[ "$LAST_3_LINES" != *'msg_ok "Cleaned"'* ]] && echo 'Last line should be: msg_ok "Cleaned"' >> "$LOG_FILE"
+ cat "$LOG_FILE"
+ fi
+
+ done
+
+
+ - name: Post error comments
+ run: |
+ ERROR="false"
+ for FILE in ${{ env.SCRIPT }}; do
+ FILE_STRIPPED="${FILE##*/}"
+ LOG_FILE="result_$FILE_STRIPPED.log"
+ echo $LOG_FILE
+ if [[ ! -f $LOG_FILE ]]; then
+ continue
+ fi
+ ERROR_MSG=$(cat $LOG_FILE)
+
+ if [ -n "$ERROR_MSG" ]; then
+ echo "Posting error message for $FILE"
+ echo ${ERROR_MSG}
+ gh pr comment ${{ github.event.pull_request.number }} \
+ --repo ${{ github.repository }} \
+ --body ":warning: The script _**$FILE**_ has the following formatting errors:
${ERROR_MSG}
"
+
+
+ ERROR="true"
+ fi
+ done
+ echo "ERROR=$ERROR" >> $GITHUB_ENV
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Fail if error
+ if: ${{ env.ERROR == 'true' }}
+ run: exit 1
diff --git a/.github/workflows/scripts/app-test/pr-alpine-install.func b/.github/workflows/scripts/app-test/pr-alpine-install.func
index 39a6a82fb..ae3bc174d 100644
--- a/.github/workflows/scripts/app-test/pr-alpine-install.func
+++ b/.github/workflows/scripts/app-test/pr-alpine-install.func
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
-# Author: michelroegl-brunner
+# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
@@ -11,7 +11,7 @@ catch_errors() {
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
-
+# This function handles errors
error_handler() {
local line_number="$1"
local command="$2"
@@ -21,8 +21,8 @@ error_handler() {
exit 0
}
verb_ip6() {
- STD=""
- return
+ STD=""
+ return
}
msg_info() {
@@ -30,13 +30,13 @@ msg_info() {
echo -ne "${msg}\n"
}
-msg_ok() {
+msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
-
+
local msg="$1"
echo -e "${msg}\n"
}
@@ -71,7 +71,7 @@ network_check() {
}
update_os() {
- msg_info "Updating Container OS"
+ msg_info "Updating Container OS"
apk update
apk upgrade
msg_ok "Updated Container OS"
@@ -82,7 +82,5 @@ motd_ssh() {
}
customize() {
- return
-}
-
-
+ return
+}
\ No newline at end of file
diff --git a/.github/workflows/scripts/app-test/pr-build.func b/.github/workflows/scripts/app-test/pr-build.func
index 360c15ede..4ca15d099 100644
--- a/.github/workflows/scripts/app-test/pr-build.func
+++ b/.github/workflows/scripts/app-test/pr-build.func
@@ -6,12 +6,13 @@
variables() {
NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
+
}
NEXTID=$(pvesh get /cluster/nextid)
timezone=$(cat /etc/timezone)
-header_info(){
- return
+header_info() {
+ return
}
base_settings() {
@@ -20,10 +21,10 @@ base_settings() {
DISK_SIZE="4"
CORE_COUNT="1"
RAM_SIZE="1024"
- VERBOSE="${1:-no}"
+ VERBOSE="no"
PW=""
CT_ID=$NEXTID
- HN="Testing"
+ HN=$NSAPP
BRG="vmbr0"
NET="dhcp"
GATE=""
@@ -106,7 +107,7 @@ catch_errors() {
}
# This function handles errors
-error_handler() {
+error_handler() {
local line_number="$1"
local command="$2"
SCRIPT_NAME=$(basename "$0")
@@ -120,17 +121,17 @@ msg_info() {
echo -ne "${msg}\n"
}
-msg_ok() {
+msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
-
+
local msg="$1"
echo -e "${msg}\n"
}
-start(){
+start() {
base_settings
return
}
@@ -146,9 +147,9 @@ build_container() {
TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null
if [ "$var_os" == "alpine" ]; then
- export FUNCTIONS_FILE_PATH="$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/.github/workflows/scripts/app-test/pr-alpine-install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-alpine-install.func)"
else
- export FUNCTIONS_FILE_PATH="$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/.github/workflows/scripts/app-test/pr-install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-install.func)"
fi
export CACHER="$APT_CACHER"
@@ -182,9 +183,8 @@ build_container() {
"
echo "Container ID: $CTID"
-
# This executes create_lxc.sh and creates the container and .conf file
- bash /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/.github/workflows/scripts/app-test/pr-create-lxc.sh
+ bash -c "$(wget -qLO - https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-create-lxc.sh)"
LXC_CONFIG=/etc/pve/lxc/${CTID}.conf
if [ "$CT_TYPE" == "0" ]; then
@@ -233,6 +233,7 @@ EOF
fi
fi
fi
+
# This starts the container and executes -install.sh
msg_info "Starting LXC Container"
pct start "$CTID"
@@ -242,7 +243,7 @@ EOF
msg_error "No install script found for $APP"
exit 1
fi
- if [ "$var_os" == "alpine" ]; then
+ if [ "$var_os" == "alpine" ]; then
sleep 3
pct exec "$CTID" -- /bin/sh -c 'cat </etc/apk/repositories
http://dl-cdn.alpinelinux.org/alpine/latest-stable/main
@@ -250,11 +251,10 @@ http://dl-cdn.alpinelinux.org/alpine/latest-stable/community
EOF'
pct exec "$CTID" -- ash -c "apk add bash >/dev/null"
fi
- lxc-attach -n "$CTID" -- bash -c "$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh)" $var_install.sh
+ lxc-attach -n "$CTID" -- bash -c "$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh)"
}
-description(){
- IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
- return
-}
+description() {
+ IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
+}
\ No newline at end of file
diff --git a/.github/workflows/scripts/app-test/pr-create-lxc.sh b/.github/workflows/scripts/app-test/pr-create-lxc.sh
index 6ca899cf4..0bb2a9d2f 100644
--- a/.github/workflows/scripts/app-test/pr-create-lxc.sh
+++ b/.github/workflows/scripts/app-test/pr-create-lxc.sh
@@ -11,8 +11,9 @@ catch_errors() {
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
+# This function handles errors
error_handler() {
- local exit_code="$?"
+ local exit_code="$?"
local line_number="$1"
local command="$2"
local error_message="Failure in line $line_number: exit code $exit_code: while executing command $command"
@@ -20,7 +21,7 @@ error_handler() {
exit 100
}
verb_ip6() {
- return
+ return
}
msg_info() {
@@ -28,18 +29,17 @@ msg_info() {
echo -ne "${msg}\n"
}
-msg_ok() {
+msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
-
+
local msg="$1"
echo -e "${msg}\n"
}
-
VALIDCT=$(pvesm status -content rootdir | awk 'NR>1')
if [ -z "$VALIDCT" ]; then
msg_error "Unable to detect a valid Container Storage location."
@@ -64,9 +64,12 @@ function select_storage() {
CONTENT='vztmpl'
CONTENT_LABEL='Container template'
;;
- *) false || { msg_error "Invalid storage class."; exit 201; };;
+ *) false || {
+ msg_error "Invalid storage class."
+ exit 201
+ } ;;
esac
-
+
# This Queries all storage locations
local -a MENU
while read -r line; do
@@ -80,23 +83,32 @@ function select_storage() {
fi
MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content $CONTENT | awk 'NR>1')
-
+
# Select storage location
- if [ $((${#MENU[@]}/3)) -eq 1 ]; then
+ if [ $((${#MENU[@]} / 3)) -eq 1 ]; then
printf ${MENU[0]}
else
- msg_error "STORAGE ISSUES!"
- exit 202
+ msg_error "STORAGE ISSUES!"
+ exit 202
fi
}
+[[ "${CTID:-}" ]] || {
+ msg_error "You need to set 'CTID' variable."
+ exit 203
+}
+[[ "${PCT_OSTYPE:-}" ]] || {
+ msg_error "You need to set 'PCT_OSTYPE' variable."
+ exit 204
+}
+# Test if ID is valid
+[ "$CTID" -ge "100" ] || {
+ msg_error "ID cannot be less than 100."
+ exit 205
+}
-[[ "${CTID:-}" ]] || { msg_error "You need to set 'CTID' variable."; exit 203; }
-[[ "${PCT_OSTYPE:-}" ]] || { msg_error "You need to set 'PCT_OSTYPE' variable."; exit 204; }
-
-[ "$CTID" -ge "100" ] || { msg_error "ID cannot be less than 100."; exit 205; }
-
+# Test if ID is in use
if pct status $CTID &>/dev/null; then
echo -e "ID '$CTID' is already in use."
unset CTID
@@ -110,10 +122,12 @@ CONTAINER_STORAGE=$(select_storage container) || exit
pveam update >/dev/null
-
TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-}
mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V)
-[ ${#TEMPLATES[@]} -gt 0 ] || { msg_error "Unable to find a template when searching for '$TEMPLATE_SEARCH'."; exit 207; }
+[ ${#TEMPLATES[@]} -gt 0 ] || {
+ msg_error "Unable to find a template when searching for '$TEMPLATE_SEARCH'."
+ exit 207
+}
TEMPLATE="${TEMPLATES[-1]}"
TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
@@ -121,28 +135,29 @@ TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
- { msg_error "A problem occurred while downloading the LXC template."; exit 208; }
+ {
+ msg_error "A problem occurred while downloading the LXC template."
+ exit 208
+ }
fi
-
-grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >> /etc/subuid
-grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >> /etc/subgid
+grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
+grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
+if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
+ [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
+
+ pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
+ {
+ msg_error "A problem occurred while re-downloading the LXC template."
+ exit 208
+ }
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
- [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
-
-
- pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
- { msg_error "A problem occurred while re-downloading the LXC template."; exit 208; }
-
-
- if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
- msg_error "A problem occurred while trying to create container after re-downloading template."
- exit 200
- fi
+ msg_error "A problem occurred while trying to create container after re-downloading template."
+ exit 200
fi
-
+fi
diff --git a/.github/workflows/scripts/app-test/pr-install.func b/.github/workflows/scripts/app-test/pr-install.func
index 49195f365..1719a1a9e 100644
--- a/.github/workflows/scripts/app-test/pr-install.func
+++ b/.github/workflows/scripts/app-test/pr-install.func
@@ -1,31 +1,31 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
-# Author: michelroegl-brunner
+# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
return
}
-SCRIPT_NAME="${BASH_SOURCE[0]:-unknown_script}"
catch_errors() {
- set -Euoe pipefail
+ set -Euo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
error_handler() {
local line_number="$1"
local command="$2"
- local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command '$command'"
- echo -e "\n$error_message"
- exit 300
+ local error_message="Failure in line $line_number while executing command '$command'"
+ echo -e "\n$error_message\n" >&2
+ exit 1
}
verb_ip6() {
- STD="silent"
- silent() {
- "$@" >/dev/null 2>&1 || error_handler "${BASH_LINENO[0]}" "$*"
- }
+ STD="silent"
+ silent() {
+ "$@" >/dev/null 2>&1 || error_handler "${BASH_LINENO[0]}" "$*"
+ }
+ return
}
msg_info() {
@@ -33,19 +33,21 @@ msg_info() {
echo -ne "${msg}\n"
}
-msg_ok() {
+msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
-
+
local msg="$1"
echo -e "${msg}\n"
}
- RETRY_NUM=10
- RETRY_EVERY=3
+
+RETRY_NUM=10
+RETRY_EVERY=3
setting_up_container() {
+
sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen
locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1)
echo "LANG=${locale_line}" >/etc/default/locale
@@ -53,12 +55,11 @@ setting_up_container() {
export LANG=${locale_line}
echo $tz >/etc/timezone
ln -sf /usr/share/zoneinfo/$tz /etc/localtime
-
+
for ((i = RETRY_NUM; i > 0; i--)); do
if [ "$(hostname -I)" != "" ]; then
break
fi
- echo 1>&2 -en "No Network! "
sleep $RETRY_EVERY
done
if [ "$(hostname -I)" = "" ]; then
@@ -68,8 +69,6 @@ setting_up_container() {
fi
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
systemctl disable -q --now systemd-networkd-wait-online.service
- msg_ok "Set up Container OS"
- msg_ok "Network Connected: $(hostname -I)"
}
network_check() {
@@ -79,11 +78,10 @@ network_check() {
}
update_os() {
- msg_info "Updating Container OS"
- apt-get update
- apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
+ export DEBIAN_FRONTEND=noninteractive
+ apt-get update >/dev/null 2>&1
+ apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade >/dev/null
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
- msg_ok "Updated Container OS"
}
motd_ssh() {
@@ -91,5 +89,5 @@ motd_ssh() {
}
customize() {
- return
+ return
}
\ No newline at end of file
diff --git a/.github/workflows/update-json-date.yml b/.github/workflows/update-json-date.yml
index 7e9c24973..26957e50c 100644
--- a/.github/workflows/update-json-date.yml
+++ b/.github/workflows/update-json-date.yml
@@ -10,7 +10,7 @@ on:
jobs:
update-app-files:
- runs-on: ubuntu-latest
+ runs-on: runner-cluster-htl-set
permissions:
contents: write
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c8de4823..0a1ba15ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,9 +13,217 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
> [!NOTE]
All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment.
-> [!IMPORTANT]
-Do not break established syntax in this file, as it is automatically updated by a Github Workflow
+## 2025-03-03
+
+### π New Scripts
+
+ - Habitica [@tremor021](https://github.com/tremor021) ([#2779](https://github.com/community-scripts/ProxmoxVE/pull/2779))
+
+### π Updated Scripts
+
+ - #### π Bug Fixes
+
+ - Zigbee2Mqtt Use fixed pnpm Version 10.4.1 [@MickLesk](https://github.com/MickLesk) ([#2805](https://github.com/community-scripts/ProxmoxVE/pull/2805))
+ - Linkwarden: Fix & Update Monolith-Installation [@MickLesk](https://github.com/MickLesk) ([#2787](https://github.com/community-scripts/ProxmoxVE/pull/2787))
+
+ - #### β¨ New Features
+
+ - Feature: MinIO use now static port 9001 [@MickLesk](https://github.com/MickLesk) ([#2786](https://github.com/community-scripts/ProxmoxVE/pull/2786))
+ - Feature Template Path for Mountings [@MickLesk](https://github.com/MickLesk) ([#2785](https://github.com/community-scripts/ProxmoxVE/pull/2785))
+
+### π Website
+
+ - #### β¨ New Features
+
+ - Feature: Website - show default OS [@MickLesk](https://github.com/MickLesk) ([#2790](https://github.com/community-scripts/ProxmoxVE/pull/2790))
+
+ - #### π Script Information
+
+ - Update zigbee2mqtt.json - make sure link is clickable [@gurtjun](https://github.com/gurtjun) ([#2802](https://github.com/community-scripts/ProxmoxVE/pull/2802))
+
+## 2025-03-02
+
+### π Updated Scripts
+
+ - #### π Bug Fixes
+
+ - Fix gpg Repo for nzbget [@flatlinebb](https://github.com/flatlinebb) ([#2774](https://github.com/community-scripts/ProxmoxVE/pull/2774))
+
+## 2025-03-01
+
+### π Updated Scripts
+
+ - #### π Bug Fixes
+
+ - Firefly III: FIx Ownership for OAuth Key [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2759](https://github.com/community-scripts/ProxmoxVE/pull/2759))
+ - homarr: double restart to fix homarr migration [@CrazyWolf13](https://github.com/CrazyWolf13) ([#2757](https://github.com/community-scripts/ProxmoxVE/pull/2757))
+
+ - #### β¨ New Features
+
+ - ActualBudget: New Installation Script with new Repo [@MickLesk](https://github.com/MickLesk) ([#2770](https://github.com/community-scripts/ProxmoxVE/pull/2770))
+
+ - #### π₯ Breaking Changes
+
+ - Breaking: Remove Update Function for Actual Budget until it fixed [@MickLesk](https://github.com/MickLesk) ([#2768](https://github.com/community-scripts/ProxmoxVE/pull/2768))
+
+### π§° Maintenance
+
+ - #### π Bug Fixes
+
+ - Remove Note on Changelog [@MickLesk](https://github.com/MickLesk) ([#2758](https://github.com/community-scripts/ProxmoxVE/pull/2758))
+ - Fix Release Creation if Changelog.md to long [@MickLesk](https://github.com/MickLesk) ([#2752](https://github.com/community-scripts/ProxmoxVE/pull/2752))
+
+## 2025-02-28
+
+### π§° Maintenance
+
+ - #### β¨ New Features
+
+ - Shell Format Workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2400](https://github.com/community-scripts/ProxmoxVE/pull/2400))
+
+ - #### π Github
+
+ - Update all Action to new selfhosted Runner Cluster [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2739](https://github.com/community-scripts/ProxmoxVE/pull/2739))
+ - Update Script Test Workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2741](https://github.com/community-scripts/ProxmoxVE/pull/2741))
+
+## 2025-02-27
+
+### π New Scripts
+
+ - web-check [@CrazyWolf13](https://github.com/CrazyWolf13) ([#2662](https://github.com/community-scripts/ProxmoxVE/pull/2662))
+- Pelican Panel [@bvdberg01](https://github.com/bvdberg01) ([#2678](https://github.com/community-scripts/ProxmoxVE/pull/2678))
+- Pelican Wings [@bvdberg01](https://github.com/bvdberg01) ([#2677](https://github.com/community-scripts/ProxmoxVE/pull/2677))
+- ByteStash [@tremor021](https://github.com/tremor021) ([#2680](https://github.com/community-scripts/ProxmoxVE/pull/2680))
+
+### π Updated Scripts
+
+ - ByteStash: Removed sed, app supports Node v22 now [@tremor021](https://github.com/tremor021) ([#2728](https://github.com/community-scripts/ProxmoxVE/pull/2728))
+- Keycloak: Update installation script [@tremor021](https://github.com/tremor021) ([#2714](https://github.com/community-scripts/ProxmoxVE/pull/2714))
+- ByteStash: Fix Node 22 compatibility (thanks t2lc) [@tremor021](https://github.com/tremor021) ([#2705](https://github.com/community-scripts/ProxmoxVE/pull/2705))
+
+ - #### π Bug Fixes
+
+ - EOF not detected [@CrazyWolf13](https://github.com/CrazyWolf13) ([#2726](https://github.com/community-scripts/ProxmoxVE/pull/2726))
+ - Zitadel-install.sh: Remove one version file and update to our standard [@bvdberg01](https://github.com/bvdberg01) ([#2710](https://github.com/community-scripts/ProxmoxVE/pull/2710))
+ - Outline: Change key to hex32 [@tremor021](https://github.com/tremor021) ([#2709](https://github.com/community-scripts/ProxmoxVE/pull/2709))
+ - Typo in update scripts [@bvdberg01](https://github.com/bvdberg01) ([#2707](https://github.com/community-scripts/ProxmoxVE/pull/2707))
+ - SFTPGo Remove unneeded RELEASE variable [@MickLesk](https://github.com/MickLesk) ([#2683](https://github.com/community-scripts/ProxmoxVE/pull/2683))
+
+### π§° Maintenance
+
+ - #### π Bug Fixes
+
+ - Update install.func: Change Line Number for Error message. [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2690](https://github.com/community-scripts/ProxmoxVE/pull/2690))
+
+ - #### π Github
+
+ - New Workflow to close Script Request Discussions on PR merge [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2688](https://github.com/community-scripts/ProxmoxVE/pull/2688))
+ - Improve Script-Test Workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2712](https://github.com/community-scripts/ProxmoxVE/pull/2712))
+ - Switch all actions to self-hosted Runners [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2711](https://github.com/community-scripts/ProxmoxVE/pull/2711))
+
+### π Website
+
+ - #### β¨ New Features
+
+ - Use HTML button element for copying to clipboard [@scallaway](https://github.com/scallaway) ([#2720](https://github.com/community-scripts/ProxmoxVE/pull/2720))
+ - Add basic pagination to Data Viewer [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2715](https://github.com/community-scripts/ProxmoxVE/pull/2715))
+
+ - #### π Script Information
+
+ - wger - Add HTTPS instructions to the website [@tremor021](https://github.com/tremor021) ([#2695](https://github.com/community-scripts/ProxmoxVE/pull/2695))
+
+## 2025-02-26
+
+### π New Scripts
+
+ - New Script: Outline [@tremor021](https://github.com/tremor021) ([#2653](https://github.com/community-scripts/ProxmoxVE/pull/2653))
+
+### π Updated Scripts
+
+ - Fix: SABnzbd - Removed few artefacts in the code preventing the update [@tremor021](https://github.com/tremor021) ([#2670](https://github.com/community-scripts/ProxmoxVE/pull/2670))
+
+ - #### π Bug Fixes
+
+ - Fix: Homarr - Manually correct db-migration wrong-folder [@CrazyWolf13](https://github.com/CrazyWolf13) ([#2676](https://github.com/community-scripts/ProxmoxVE/pull/2676))
+ - Kimai: add local.yaml & fix path permissions [@MickLesk](https://github.com/MickLesk) ([#2646](https://github.com/community-scripts/ProxmoxVE/pull/2646))
+ - PiHole: Fix Unbound sed for DNS [@MickLesk](https://github.com/MickLesk) ([#2647](https://github.com/community-scripts/ProxmoxVE/pull/2647))
+ - Alpine IT-Tools fix typo "unexpected EOF while looking for matching `"' [@MickLesk](https://github.com/MickLesk) ([#2644](https://github.com/community-scripts/ProxmoxVE/pull/2644))
+
+### π§° Maintenance
+
+ - #### π Github
+
+ - [gh] Furhter Impove Changelog Workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2655](https://github.com/community-scripts/ProxmoxVE/pull/2655))
+
+### π Website
+
+ - #### π Bug Fixes
+
+ - Website: PocketID Change of website and documentation links [@schneider-de-com](https://github.com/schneider-de-com) ([#2643](https://github.com/community-scripts/ProxmoxVE/pull/2643))
+
+ - #### π Script Information
+
+ - Fix: Graylog - Improve application description for website [@tremor021](https://github.com/tremor021) ([#2658](https://github.com/community-scripts/ProxmoxVE/pull/2658))
+
+## 2025-02-25
+
+### Changes
+
+### β¨ New Features
+
+- Update Tailscale: Add Tag when installation is finished [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2633](https://github.com/community-scripts/ProxmoxVE/pull/2633))
+
+### π Updated Scripts
+
+ #### π Bug Fixes
+
+ - Fix Omada installer [@JcMinarro](https://github.com/JcMinarro) ([#2625](https://github.com/community-scripts/ProxmoxVE/pull/2625))
+
+### π Website
+
+- Update Tailscale-lxc Json: Add message for Supported OS [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2629](https://github.com/community-scripts/ProxmoxVE/pull/2629))
+
+### π§° Maintenance
+
+- [gh] Updated Changelog Workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2632](https://github.com/community-scripts/ProxmoxVE/pull/2632))
+
+## 2025-02-24
+
+### Changes
+
+### π New Scripts
+
+- New Script: wger [@tremor021](https://github.com/tremor021) ([#2574](https://github.com/community-scripts/ProxmoxVE/pull/2574))
+- New Script: VictoriaMetrics [@tremor021](https://github.com/tremor021) ([#2565](https://github.com/community-scripts/ProxmoxVE/pull/2565))
+- New Script: Authelia [@thost96](https://github.com/thost96) ([#2060](https://github.com/community-scripts/ProxmoxVE/pull/2060))
+- New Script: Jupyter Notebook [@Dave-code-creater](https://github.com/Dave-code-creater) ([#2561](https://github.com/community-scripts/ProxmoxVE/pull/2561))
+
+### π Bug Fixes
+
+- Fix Docmost: default upload size and saving data when updating [@bvdberg01](https://github.com/bvdberg01) ([#2598](https://github.com/community-scripts/ProxmoxVE/pull/2598))
+- Fix: homarr db migration [@CrazyWolf13](https://github.com/CrazyWolf13) ([#2575](https://github.com/community-scripts/ProxmoxVE/pull/2575))
+- Fix: Wireguard - Restart wgdashboard automatically after update [@LostALice](https://github.com/LostALice) ([#2587](https://github.com/community-scripts/ProxmoxVE/pull/2587))
+- Fix: Authelia Unbound Variable Argon2id [@MickLesk](https://github.com/MickLesk) ([#2604](https://github.com/community-scripts/ProxmoxVE/pull/2604))
+- Fix: Omada check for AVX Support and use the correct MongoDB Version [@MickLesk](https://github.com/MickLesk) ([#2600](https://github.com/community-scripts/ProxmoxVE/pull/2600))
+- Fix: Update-Script Firefly III based on their docs [@MickLesk](https://github.com/MickLesk) ([#2534](https://github.com/community-scripts/ProxmoxVE/pull/2534))
+
+### β¨ New Features
+
+- Feature: Template-Check, Better Handling of Downloads, Better Network⦠[@MickLesk](https://github.com/MickLesk) ([#2592](https://github.com/community-scripts/ProxmoxVE/pull/2592))
+- Feature: Possibility to perform updates in silent / verbose (+ logging) [@MickLesk](https://github.com/MickLesk) ([#2583](https://github.com/community-scripts/ProxmoxVE/pull/2583))
+- Feature: Use Verbose Mode for all Scripts (removed &>/dev/null) [@MickLesk](https://github.com/MickLesk) ([#2596](https://github.com/community-scripts/ProxmoxVE/pull/2596))
+
+### π Website
+
+- Fix: Authelia - Make user enter their domain manually [@tremor021](https://github.com/tremor021) ([#2618](https://github.com/community-scripts/ProxmoxVE/pull/2618))
+- Website: Change Info for PiHole Password [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2602](https://github.com/community-scripts/ProxmoxVE/pull/2602))
+- Fix: Jupyter Json (missing logo & improve name on website) [@MickLesk](https://github.com/MickLesk) ([#2584](https://github.com/community-scripts/ProxmoxVE/pull/2584))
+
+### π§° Maintenance
+
+- [gh] Update Script Test Workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2599](https://github.com/community-scripts/ProxmoxVE/pull/2599))
+- [gh] Contributor-Guide: Update AppName.md & AppName.sh [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2603](https://github.com/community-scripts/ProxmoxVE/pull/2603))
## 2025-02-23
diff --git a/ct/2fauth.sh b/ct/2fauth.sh
index 503f2f917..6a88d6a9e 100644
--- a/ct/2fauth.sh
+++ b/ct/2fauth.sh
@@ -35,8 +35,8 @@ function update_script() {
if [[ "${RELEASE}" != "$(cat /opt/2fauth_version.txt)" ]] || [[ ! -f /opt/2fauth_version.txt ]]; then
msg_info "Updating $APP to ${RELEASE}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
# Creating Backup
msg_info "Creating Backup"
@@ -55,7 +55,7 @@ function update_script() {
chmod -R 755 "/opt/2fauth"
export COMPOSER_ALLOW_SUPERUSER=1
- composer install --no-dev --prefer-source &>/dev/null
+ $STD composer install --no-dev --prefer-source
php artisan 2fauth:install
diff --git a/ct/actualbudget.sh b/ct/actualbudget.sh
index e3675fe13..8512b1712 100644
--- a/ct/actualbudget.sh
+++ b/ct/actualbudget.sh
@@ -28,89 +28,8 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit 1
fi
-
- RELEASE=$(curl -s https://api.github.com/repos/actualbudget/actual/releases/latest | \
- grep "tag_name" | awk -F '"' '{print substr($4, 2)}')
-
- if [[ ! -f /opt/actualbudget_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/actualbudget_version.txt)" ]]; then
- msg_info "Stopping ${APP}"
- systemctl stop actualbudget
- msg_ok "${APP} Stopped"
-
- msg_info "Updating ${APP} to ${RELEASE}"
- cd /tmp
- wget -q "https://github.com/actualbudget/actual-server/archive/refs/tags/v${RELEASE}.tar.gz"
-
- mv /opt/actualbudget /opt/actualbudget_bak
- tar -xzf "v${RELEASE}.tar.gz" &>/dev/null
- mv *ctual-server-* /opt/actualbudget
-
- mkdir -p /opt/actualbudget-data/{server-files,upload,migrate,user-files,migrations,config}
- for dir in server-files .migrate user-files migrations; do
- if [[ -d /opt/actualbudget_bak/$dir ]]; then
- mv /opt/actualbudget_bak/$dir/* /opt/actualbudget-data/$dir/ 2>/dev/null || true
- fi
- done
- if [[ -f /opt/actualbudget-data/migrate/.migrations ]]; then
- sed -i 's/null/1732656575219/g' /opt/actualbudget-data/migrate/.migrations
- sed -i 's/null/1732656575220/g' /opt/actualbudget-data/migrate/.migrations
- fi
- if [[ -f /opt/actualbudget/server-files/account.sqlite ]] && [[ ! -f /opt/actualbudget-data/server-files/account.sqlite ]]; then
- mv /opt/actualbudget/server-files/account.sqlite /opt/actualbudget-data/server-files/account.sqlite
- fi
-
- if [[ -f /opt/actualbudget_bak/.env ]]; then
- mv /opt/actualbudget_bak/.env /opt/actualbudget-data/.env
- else
- cat < /opt/actualbudget-data/.env
-ACTUAL_UPLOAD_DIR=/opt/actualbudget-data/upload
-ACTUAL_DATA_DIR=/opt/actualbudget-data
-ACTUAL_SERVER_FILES_DIR=/opt/actualbudget-data/server-files
-ACTUAL_USER_FILES=/opt/actualbudget-data/user-files
-PORT=5006
-ACTUAL_TRUSTED_PROXIES="10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32,::1/128,fc00::/7"
-ACTUAL_HTTPS_KEY=/opt/actualbudget/selfhost.key
-ACTUAL_HTTPS_CERT=/opt/actualbudget/selfhost.crt
-EOF
- fi
- cd /opt/actualbudget
- yarn install &>/dev/null
- echo "${RELEASE}" > /opt/actualbudget_version.txt
- msg_ok "Updated ${APP}"
-
- msg_info "Starting ${APP}"
- cat < /etc/systemd/system/actualbudget.service
-[Unit]
-Description=Actual Budget Service
-After=network.target
-
-[Service]
-Type=simple
-User=root
-Group=root
-WorkingDirectory=/opt/actualbudget
-EnvironmentFile=/opt/actualbudget-data/.env
-ExecStart=/usr/bin/yarn start
-Restart=always
-RestartSec=10
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
- systemctl daemon-reload
- systemctl start actualbudget
- msg_ok "Started ${APP}"
-
- msg_info "Cleaning Up"
- rm -rf /opt/actualbudget_bak
- rm -rf "/tmp/v${RELEASE}.tar.gz"
- msg_ok "Cleaned"
- msg_ok "Updated Successfully"
- else
- msg_ok "No update required. ${APP} is already at ${RELEASE}"
- fi
- exit 0
+ msg_error "Due to major changes in the Actual Budget repository, we are currently unable to provide updates. Please check back later."
+ exit
}
start
diff --git a/ct/adventurelog.sh b/ct/adventurelog.sh
index 0b05d6055..8136ee204 100644
--- a/ct/adventurelog.sh
+++ b/ct/adventurelog.sh
@@ -43,15 +43,15 @@ function update_script() {
mv /opt/adventurelog-backup/backend/server/.env /opt/adventurelog/backend/server/.env
mv /opt/adventurelog-backup/backend/server/media /opt/adventurelog/backend/server/media
cd /opt/adventurelog/backend/server
- pip install --upgrade pip &>/dev/null
- pip install -r requirements.txt &>/dev/null
- python3 manage.py collectstatic --noinput &>/dev/null
- python3 manage.py migrate &>/dev/null
+ $STD pip install --upgrade pip
+ $STD pip install -r requirements.txt
+ $STD python3 manage.py collectstatic --noinput
+ $STD python3 manage.py migrate
mv /opt/adventurelog-backup/frontend/.env /opt/adventurelog/frontend/.env
cd /opt/adventurelog/frontend
- pnpm install &>/dev/null
- pnpm run build &>/dev/null
+ $STD pnpm install
+ $STD pnpm run build
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP}"
diff --git a/ct/agentdvr.sh b/ct/agentdvr.sh
index 23f5a7695..2c6766c1a 100644
--- a/ct/agentdvr.sh
+++ b/ct/agentdvr.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/alpine-it-tools.sh b/ct/alpine-it-tools.sh
index d24f267f6..40d9d087c 100644
--- a/ct/alpine-it-tools.sh
+++ b/ct/alpine-it-tools.sh
@@ -30,7 +30,7 @@ if [ ! -d /usr/share/nginx/html ]; then
fi
RELEASE=$(curl -s https://api.github.com/repos/CorentinTh/it-tools/releases/latest | grep '"tag_name":' | cut -d '"' -f4)
-if [ "${RELEASE}" != "$(cat /opt/${APP}_version.txt 2>/dev/null)" ] || [ ! -f /opt/${APP}_version.txt ]; then
+if [ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ] || [ ! -f /opt/${APP}_version.txt ]; then
DOWNLOAD_URL="https://github.com/CorentinTh/it-tools/releases/download/${RELEASE}/it-tools-${RELEASE#v}.zip"
msg_info "Updating ${APP} LXC"
curl -fsSL -o it-tools.zip "$DOWNLOAD_URL"
diff --git a/ct/apache-cassandra.sh b/ct/apache-cassandra.sh
index 0a11f2201..d2134f929 100644
--- a/ct/apache-cassandra.sh
+++ b/ct/apache-cassandra.sh
@@ -28,7 +28,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/apache-couchdb.sh b/ct/apache-couchdb.sh
index e6e6e168e..169cf01ee 100644
--- a/ct/apache-couchdb.sh
+++ b/ct/apache-couchdb.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/apache-guacamole.sh b/ct/apache-guacamole.sh
index 9379aa876..9fa7a7161 100644
--- a/ct/apache-guacamole.sh
+++ b/ct/apache-guacamole.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "Ther is currently no automatic update function for ${APP}."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/apt-cacher-ng.sh b/ct/apt-cacher-ng.sh
index eb91296cc..66244598b 100644
--- a/ct/apt-cacher-ng.sh
+++ b/ct/apt-cacher-ng.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/aria2.sh b/ct/aria2.sh
index 1b9029769..08b25d3c8 100644
--- a/ct/aria2.sh
+++ b/ct/aria2.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/authelia.sh b/ct/authelia.sh
new file mode 100644
index 000000000..de6eb07ca
--- /dev/null
+++ b/ct/authelia.sh
@@ -0,0 +1,55 @@
+#!/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: thost96 (thost96)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://www.authelia.com/
+
+APP="Authelia"
+TAGS=""
+var_cpu="1"
+var_ram="512"
+var_disk="2"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+base_settings
+
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d "/etc/authelia/" ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
+ RELEASE=$(curl -s https://api.github.com/repos/authelia/authelia/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
+ if [[ "${RELEASE}" != "$(/usr/bin/authelia -v | awk '{print substr($3, 2, length($2)) }' )" ]]; then
+ msg_info "Updating $APP to ${RELEASE}"
+ $STD apt-get update
+ $STD apt-get -y upgrade
+ wget -q "https://github.com/authelia/authelia/releases/download/${RELEASE}/authelia_${RELEASE}_amd64.deb"
+ $STD dpkg -i "authelia_${RELEASE}_amd64.deb"
+ msg_info "Cleaning Up"
+ rm -f "authelia_${RELEASE}_amd64.deb"
+ $STD apt-get -y autoremove
+ $STD apt-get -y autoclean
+ msg_ok "Cleanup Completed"
+ msg_ok "Updated $APP to ${RELEASE}"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ fi
+ 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}:9091${CL}"
diff --git a/ct/authentik.sh b/ct/authentik.sh
index 77f0ddb8d..18e7cc365 100644
--- a/ct/authentik.sh
+++ b/ct/authentik.sh
@@ -40,11 +40,11 @@ function update_script() {
tar -xzf authentik.tar.gz -C /opt/authentik --strip-components 1 --overwrite
rm -rf authentik.tar.gz
cd /opt/authentik/website
- npm install &>/dev/null
- npm run build-bundled &>/dev/null
+ $STD npm install
+ $STD npm run build-bundled
cd /opt/authentik/web
- npm install &>/dev/null
- npm run build &>/dev/null
+ $STD npm install
+ $STD npm run build
msg_ok "Built ${APP} website"
msg_info "Building ${APP} server"
@@ -56,15 +56,15 @@ function update_script() {
msg_info "Installing Python Dependencies"
cd /opt/authentik
- poetry install --only=main --no-ansi --no-interaction --no-root &>/dev/null
- poetry export --without-hashes --without-urls -f requirements.txt --output requirements.txt &>/dev/null
- pip install --no-cache-dir -r requirements.txt &>/dev/null
- pip install . &>/dev/null
+ $STD poetry install --only=main --no-ansi --no-interaction --no-root
+ $STD poetry export --without-hashes --without-urls -f requirements.txt --output requirements.txt
+ $STD pip install --no-cache-dir -r requirements.txt
+ $STD pip install .
msg_ok "Installed Python Dependencies"
msg_info "Updating ${APP} to v${RELEASE} (Patience)"
cp -r /opt/authentik/authentik/blueprints /opt/authentik/blueprints
- bash /opt/authentik/lifecycle/ak migrate &>/dev/null
+ $STD bash /opt/authentik/lifecycle/ak migrate
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to v${RELEASE}"
diff --git a/ct/bazarr.sh b/ct/bazarr.sh
index 1802d72a2..b329fadcd 100755
--- a/ct/bazarr.sh
+++ b/ct/bazarr.sh
@@ -25,8 +25,8 @@ function update_script() {
check_container_resources
if [[ ! -d /var/lib/bazarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/beszel.sh b/ct/beszel.sh
index c159800be..1ed2b1560 100644
--- a/ct/beszel.sh
+++ b/ct/beszel.sh
@@ -28,7 +28,7 @@ function update_script() {
exit
fi
/opt/beszel/beszel update
- msg_error "Ther is currently no automatic update function for ${APP}."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/blocky.sh b/ct/blocky.sh
index 667e52433..84e480779 100644
--- a/ct/blocky.sh
+++ b/ct/blocky.sh
@@ -25,8 +25,8 @@ function update_script() {
check_container_resources
if [[ ! -d /var ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/bookstack.sh b/ct/bookstack.sh
index dbd21336b..65631d7bf 100644
--- a/ct/bookstack.sh
+++ b/ct/bookstack.sh
@@ -39,12 +39,13 @@ function update_script() {
unzip -q /opt/v${RELEASE}.zip -d /opt
mv /opt/BookStack-${RELEASE} /opt/bookstack
cp /opt/bookstack-backup/.env /opt/bookstack/.env
- cp -r /opt/bookstack-backup/public/uploads/* /opt/bookstack/public/uploads/ 2>/dev/null || true
- cp -r /opt/bookstack-backup/storage/uploads/* /opt/bookstack/storage/uploads/ 2>/dev/null || true
- cp -r /opt/bookstack-backup/themes/* /opt/bookstack/themes/ 2>/dev/null || true
+ cp -r /opt/bookstack-backup/public/uploads/* /opt/bookstack/public/uploads/ || true
+ cp -r /opt/bookstack-backup/storage/uploads/* /opt/bookstack/storage/uploads/ || true
+ cp -r /opt/bookstack-backup/themes/* /opt/bookstack/themes/ || true
cd /opt/bookstack
- COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev &>/dev/null
- php artisan migrate --force &>/dev/null
+ export COMPOSER_ALLOW_SUPERUSER=1
+ $STD composer install --no-dev
+ $STD php artisan migrate --force
chown www-data:www-data -R /opt/bookstack /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads /opt/bookstack/storage
chmod -R 755 /opt/bookstack /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads /opt/bookstack/storage
chmod -R 775 /opt/bookstack/storage /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads
diff --git a/ct/bytestash.sh b/ct/bytestash.sh
new file mode 100644
index 000000000..52384e2c4
--- /dev/null
+++ b/ct/bytestash.sh
@@ -0,0 +1,73 @@
+#!/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: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/jordan-dalby/ByteStash
+
+APP="ByteStash"
+var_tags="code"
+var_disk="4"
+var_cpu="1"
+var_ram="1024"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /opt/bytestash ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/jordan-dalby/ByteStash/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+ if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
+ msg_info "Stopping Services"
+ systemctl stop bytestash-backend
+ systemctl stop bytestash-frontend
+ msg_ok "Services Stopped"
+
+ msg_info "Updating ${APP} to ${RELEASE}"
+ temp_file=$(mktemp)
+ wget -q "https://github.com/jordan-dalby/ByteStash/archive/refs/tags/v${RELEASE}.tar.gz" -O $temp_file
+ tar zxf $temp_file
+ rm -rf /opt/bytestash/server/node_modules
+ rm -rf /opt/bytestash/client/node_modules
+ cp -rf ByteStash-${RELEASE}/* /opt/bytestash
+ cd /opt/bytestash/server
+ $STD npm install
+ cd /opt/bytestash/client
+ $STD npm install
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated ${APP}"
+
+ msg_info "Starting Services"
+ systemctl start bytestash-backend
+ systemctl start bytestash-frontend
+ msg_ok "Started Services"
+
+ msg_info "Cleaning Up"
+ rm -f $temp_file
+ msg_ok "Cleaned"
+ msg_ok "Updated Successfully"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ fi
+ 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}:3000${CL}"
diff --git a/ct/caddy.sh b/ct/caddy.sh
index d7993fa94..781b9b896 100644
--- a/ct/caddy.sh
+++ b/ct/caddy.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/calibre-web.sh b/ct/calibre-web.sh
index 91c61d1d5..535711da6 100644
--- a/ct/calibre-web.sh
+++ b/ct/calibre-web.sh
@@ -115,10 +115,10 @@ function update_script() {
echo "${options[*]}"
)
echo $cps_options >/opt/calibre-web/options.txt
- pip install --upgrade calibreweb[$cps_options] &>/dev/null
+ $STD pip install --upgrade calibreweb[$cps_options]
else
rm -rf /opt/calibre-web/options.txt
- pip install --upgrade calibreweb &>/dev/null
+ $STD pip install --upgrade calibreweb
fi
msg_info "Starting ${APP}"
diff --git a/ct/casaos.sh b/ct/casaos.sh
index 3da5f3147..d6b3f96a1 100644
--- a/ct/casaos.sh
+++ b/ct/casaos.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/changedetection.sh b/ct/changedetection.sh
index f4714018d..17b8877b4 100644
--- a/ct/changedetection.sh
+++ b/ct/changedetection.sh
@@ -31,31 +31,31 @@ function update_script() {
if ! dpkg -s libjpeg-dev >/dev/null 2>&1; then
msg_info "Installing Dependencies"
- apt-get update
- apt-get install -y libjpeg-dev
+ $STD apt-get update
+ $STD apt-get install -y libjpeg-dev
msg_ok "Updated Dependencies"
fi
msg_info "Updating ${APP}"
- pip3 install changedetection.io --upgrade &>/dev/null
+ $STD pip3 install changedetection.io --upgrade
msg_ok "Updated ${APP}"
msg_info "Updating Playwright"
- pip3 install playwright --upgrade &>/dev/null
+ $STD pip3 install playwright --upgrade
msg_ok "Updated Playwright"
if [[ -f /etc/systemd/system/browserless.service ]]; then
msg_info "Updating Browserless (Patience)"
- git -C /opt/browserless/ fetch --all &>/dev/null
- git -C /opt/browserless/ reset --hard origin/main &>/dev/null
- npm update --prefix /opt/browserless &>/dev/null
- /opt/browserless/node_modules/playwright-core/cli.js install --with-deps &>/dev/null
+ $STD git -C /opt/browserless/ fetch --all
+ $STD git -C /opt/browserless/ reset --hard origin/main
+ $STD npm update --prefix /opt/browserless
+ $STD /opt/browserless/node_modules/playwright-core/cli.js install --with-deps
# Update Chrome separately, as it has to be done with the force option. Otherwise the installation of other browsers will not be done if Chrome is already installed.
- /opt/browserless/node_modules/playwright-core/cli.js install --force chrome &>/dev/null
- /opt/browserless/node_modules/playwright-core/cli.js install chromium firefox webkit &>/dev/null
- npm run build --prefix /opt/browserless &>/dev/null
- npm run build:function --prefix /opt/browserless &>/dev/null
- npm prune production --prefix /opt/browserless &>/dev/null
+ $STD /opt/browserless/node_modules/playwright-core/cli.js install --force chrome
+ $STD /opt/browserless/node_modules/playwright-core/cli.js install chromium firefox webkit
+ $STD npm run build --prefix /opt/browserless
+ $STD npm run build:function --prefix /opt/browserless
+ $STD npm prune production --prefix /opt/browserless
systemctl restart browserless
msg_ok "Updated Browserless"
else
diff --git a/ct/channels.sh b/ct/channels.sh
index 01f315d43..218122708 100644
--- a/ct/channels.sh
+++ b/ct/channels.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/checkmk.sh b/ct/checkmk.sh
index af006c041..d7daba209 100644
--- a/ct/checkmk.sh
+++ b/ct/checkmk.sh
@@ -30,14 +30,14 @@ function update_script() {
RELEASE=$(curl -fsSL https://api.github.com/repos/checkmk/checkmk/tags | grep "name" | awk '{print substr($2, 3, length($2)-4) }' | tr ' ' '\n' | grep -v '\-rc' | sort -V | tail -n 1)
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating ${APP} to v${RELEASE}"
- omd stop monitoring &>/dev/null
- omd cp monitoring monitoringbackup &>/dev/null
+ $STD omd stop monitoring
+ $STD omd cp monitoring monitoringbackup
wget -q https://download.checkmk.com/checkmk/${RELEASE}/check-mk-raw-${RELEASE}_0.bookworm_amd64.deb -O /opt/checkmk.deb
- apt-get install -y /opt/checkmk.deb &>/dev/null
- omd --force -V ${RELEASE}.cre update --conflict=install monitoring &>/dev/null
- omd start monitoring &>/dev/null
- omd -f rm monitoringbackup &>/dev/null
- omd cleanup &>/dev/null
+ $STD apt-get install -y /opt/checkmk.deb
+ $STD omd --force -V ${RELEASE}.cre update --conflict=install monitoring
+ $STD omd start monitoring
+ $STD omd -f rm monitoringbackup
+ $STD omd cleanup
rm -rf /opt/checkmk.deb
msg_ok "Updated ${APP} to v${RELEASE}"
else
diff --git a/ct/cloudflared.sh b/ct/cloudflared.sh
index 2b499f10b..1a3665009 100644
--- a/ct/cloudflared.sh
+++ b/ct/cloudflared.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/cockpit.sh b/ct/cockpit.sh
index ee0e03cb8..e3e61a7b1 100644
--- a/ct/cockpit.sh
+++ b/ct/cockpit.sh
@@ -36,48 +36,48 @@ function update_script() {
if [ "$UPD" == "1" ]; then
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
fi
if [ "$UPD" == "2" ]; then
msg_info "Installing dependencies (patience)"
- apt-get install -y attr &>/dev/null
- apt-get install -y nfs-kernel-server &>/dev/null
- apt-get install -y samba &>/dev/null
- apt-get install -y samba-common-bin &>/dev/null
- apt-get install -y winbind &>/dev/null
- apt-get install -y gawk &>/dev/null
+ $STD apt-get install -y attr
+ $STD apt-get install -y nfs-kernel-server
+ $STD apt-get install -y samba
+ $STD apt-get install -y samba-common-bin
+ $STD apt-get install -y winbind
+ $STD apt-get install -y gawk
msg_ok "Installed dependencies"
msg_info "Installing Cockpit file sharing"
wget -q $(curl -s https://api.github.com/repos/45Drives/cockpit-file-sharing/releases/latest | grep download | grep focal_all.deb | cut -d\" -f4)
- dpkg -i cockpit-file-sharing_*focal_all.deb &>/dev/null
+ $STD dpkg -i cockpit-file-sharing_*focal_all.deb
rm cockpit-file-sharing_*focal_all.deb
msg_ok "Installed Cockpit file sharing"
exit
fi
if [ "$UPD" == "3" ]; then
msg_info "Installing dependencies (patience)"
- apt-get install -y psmisc &>/dev/null
- apt-get install -y samba &>/dev/null
- apt-get install -y samba-common-bin &>/dev/null
+ $STD apt-get install -y psmisc
+ $STD apt-get install -y samba
+ $STD apt-get install -y samba-common-bin
msg_ok "Installed dependencies"
msg_info "Installing Cockpit identities"
wget -q $(curl -s https://api.github.com/repos/45Drives/cockpit-identities/releases/latest | grep download | grep focal_all.deb | cut -d\" -f4)
- dpkg -i cockpit-identities_*focal_all.deb &>/dev/null
+ $STD dpkg -i cockpit-identities_*focal_all.deb
rm cockpit-identities_*focal_all.deb
msg_ok "Installed Cockpit identities"
exit
fi
if [ "$UPD" == "4" ]; then
msg_info "Installing dependencies"
- apt-get install -y rsync &>/dev/null
- apt-get install -y zip &>/dev/null
+ $STD apt-get install -y rsync
+ $STD apt-get install -y zip
msg_ok "Installed dependencies"
msg_info "Installing Cockpit navigator"
wget -q $(curl -s https://api.github.com/repos/45Drives/cockpit-navigator/releases/latest | grep download | grep focal_all.deb | cut -d\" -f4)
- dpkg -i cockpit-navigator_*focal_all.deb &>/dev/null
+ $STD dpkg -i cockpit-navigator_*focal_all.deb
rm cockpit-navigator_*focal_all.deb
msg_ok "Installed Cockpit navigator"
exit
diff --git a/ct/create_lxc.sh b/ct/create_lxc.sh
index 8f5722bf2..df493ed10 100644
--- a/ct/create_lxc.sh
+++ b/ct/create_lxc.sh
@@ -35,7 +35,7 @@ trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
# This function handles errors
function error_handler() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
local exit_code="$?"
local line_number="$1"
@@ -50,13 +50,13 @@ function spinner() {
local frames=('β ' 'β ' 'β Ή' 'β Έ' 'β Ό' 'β ΄' 'β ¦' 'β §' 'β ' 'β ')
local spin_i=0
local interval=0.1
- printf "\e[?25l"
+ printf "\e[?25l"
local color="${YWB}"
while true; do
printf "\r ${color}%s${CL}" "${frames[spin_i]}"
- spin_i=$(( (spin_i + 1) % ${#frames[@]} ))
+ spin_i=$(((spin_i + 1) % ${#frames[@]}))
sleep "$interval"
done
}
@@ -69,9 +69,16 @@ function msg_info() {
SPINNER_PID=$!
}
+function msg_warn() {
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
+ printf "\e[?25h"
+ local msg="$1"
+ echo -e "${BFR}${INFO}${YWB}${msg}${CL}"
+}
+
# This function displays a success message with a green color.
function msg_ok() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
local msg="$1"
echo -e "${BFR}${CM}${GN}${msg}${CL}"
@@ -79,7 +86,7 @@ function msg_ok() {
# This function displays a error message with a red color.
function msg_error() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
local msg="$1"
echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
@@ -112,9 +119,12 @@ function select_storage() {
CONTENT='vztmpl'
CONTENT_LABEL='Container template'
;;
- *) false || { msg_error "Invalid storage class."; exit 201; };
+ *) false || {
+ msg_error "Invalid storage class."
+ exit 201
+ } ;;
esac
-
+
# This Queries all storage locations
local -a MENU
while read -r line; do
@@ -128,34 +138,60 @@ function select_storage() {
fi
MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content $CONTENT | awk 'NR>1')
-
+
# Select storage location
- if [ $((${#MENU[@]}/3)) -eq 1 ]; then
+ if [ $((${#MENU[@]} / 3)) -eq 1 ]; then
printf ${MENU[0]}
else
local STORAGE
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 the ${CONTENT_LABEL,,}?\nTo make a selection, use the Spacebar.\n" \
- 16 $(($MSG_MAX_LENGTH + 23)) 6 \
- "${MENU[@]}" 3>&1 1>&2 2>&3) || { msg_error "Menu aborted."; exit 202; }
+ "Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\nTo make a selection, use the Spacebar.\n" \
+ 16 $(($MSG_MAX_LENGTH + 23)) 6 \
+ "${MENU[@]}" 3>&1 1>&2 2>&3) || {
+ msg_error "Menu aborted."
+ exit 202
+ }
if [ $? -ne 0 ]; then
echo -e "${CROSS}${RD} Menu aborted by user.${CL}"
- exit 0
+ exit 0
fi
done
printf "%s" "$STORAGE"
fi
}
# Test if required variables are set
-[[ "${CTID:-}" ]] || { msg_error "You need to set 'CTID' variable."; exit 203; }
-[[ "${PCT_OSTYPE:-}" ]] || { msg_error "You need to set 'PCT_OSTYPE' variable."; exit 204; }
+[[ "${CTID:-}" ]] || {
+ msg_error "You need to set 'CTID' variable."
+ exit 203
+}
+[[ "${PCT_OSTYPE:-}" ]] || {
+ msg_error "You need to set 'PCT_OSTYPE' variable."
+ exit 204
+}
# Test if ID is valid
-[ "$CTID" -ge "100" ] || { msg_error "ID cannot be less than 100."; exit 205; }
+[ "$CTID" -ge "100" ] || {
+ msg_error "ID cannot be less than 100."
+ exit 205
+}
+
+# Check for network connectivity (IPv4 & IPv6)
+#function check_network() {
+# local CHECK_URLS=("8.8.8.8" "1.1.1.1" "9.9.9.9" "2606:4700:4700::1111" "2001:4860:4860::8888" "2620:fe::fe")
+#
+# for url in "${CHECK_URLS[@]}"; do
+# if ping -c 1 -W 2 "$url" &>/dev/null; then
+# return 0 # Success: At least one connection works
+# fi
+# done
+#
+# msg_error "No network connection detected. Check your internet connection."
+# exit 101
+#}
# Test if ID is in use
-if pct status $CTID &>/dev/null; then
+if qm status "$CTID" &>/dev/null || pct status "$CTID" &>/dev/null; then
echo -e "ID '$CTID' is already in use."
unset CTID
msg_error "Cannot use ID that is already in use."
@@ -227,28 +263,38 @@ else
msg_ok "Downloaded LXC Template"
fi
fi
+msg_ok "LXC Template is ready to use."
# Check and fix subuid/subgid
-grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >> /etc/subuid
-grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >> /etc/subgid
+grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
+grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
# Combine all options
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
-# Create container with template integrity check
msg_info "Creating LXC Container"
- if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
- [[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
-
- msg_ok "Template integrity check completed"
- pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
- { msg_error "A problem occurred while re-downloading the LXC template."; exit 208; }
-
+if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
+ msg_error "Container creation failed. Checking if template is corrupted."
+
+ if ! zstdcat "$TEMPLATE_PATH" | tar -tf - >/dev/null 2>&1; then
+ msg_error "Template appears to be corrupted. Removing and re-downloading."
+ rm -f "$TEMPLATE_PATH"
+
+ if ! timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null; then
+ msg_error "Failed to re-download template."
+ exit 208
+ fi
+
msg_ok "Re-downloaded LXC Template"
+
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
- msg_error "A problem occurred while trying to create container after re-downloading template."
+ msg_error "Container creation failed after re-downloading template."
exit 200
fi
+ else
+ msg_error "Container creation failed, but template is not corrupted."
+ exit 209
fi
+fi
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
diff --git a/ct/cronicle.sh b/ct/cronicle.sh
index 54663ae9e..43584a199 100644
--- a/ct/cronicle.sh
+++ b/ct/cronicle.sh
@@ -36,12 +36,12 @@ function update_script() {
if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then
if ! command -v npm >/dev/null 2>&1; then
echo "Installing NPM..."
- apt-get install -y npm >/dev/null 2>&1
+ $STD apt-get install -y npm
echo "Installed NPM..."
fi
fi
msg_info "Updating ${APP}"
- /opt/cronicle/bin/control.sh upgrade &>/dev/null
+ $STD /opt/cronicle/bin/control.sh upgrade
msg_ok "Updated ${APP}"
exit
fi
@@ -49,7 +49,7 @@ function update_script() {
if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then
if ! command -v npm >/dev/null 2>&1; then
echo "Installing NPM..."
- apt-get install -y npm >/dev/null 2>&1
+ $STD apt-get install -y npm
echo "Installed NPM..."
fi
fi
@@ -57,12 +57,12 @@ function update_script() {
IP=$(hostname -I | awk '{print $1}')
msg_info "Installing Dependencies"
- apt-get install -y git &>/dev/null
- apt-get install -y make &>/dev/null
- apt-get install -y g++ &>/dev/null
- apt-get install -y gcc &>/dev/null
- apt-get install -y ca-certificates &>/dev/null
- apt-get install -y gnupg &>/dev/null
+ $STD apt-get install -y git
+ $STD apt-get install -y make
+ $STD apt-get install -y g++
+ $STD apt-get install -y gcc
+ $STD apt-get install -y ca-certificates
+ $STD apt-get install -y gnupg
msg_ok "Installed Dependencies"
msg_info "Setting up Node.js Repository"
@@ -72,21 +72,21 @@ function update_script() {
msg_ok "Set up Node.js Repository"
msg_info "Installing Node.js"
- apt-get update &>/dev/null
- apt-get install -y nodejs &>/dev/null
+ $STD apt-get update
+ $STD apt-get install -y nodejs
msg_ok "Installed Node.js"
msg_info "Installing Cronicle Worker"
mkdir -p /opt/cronicle
cd /opt/cronicle
- tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 &>/dev/null
- npm install &>/dev/null
- node bin/build.js dist &>/dev/null
+ $STD tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1
+ $STD npm install
+ $STD node bin/build.js dist
sed -i "s/localhost:3012/${IP}:3012/g" /opt/cronicle/conf/config.json
- /opt/cronicle/bin/control.sh start &>/dev/null
- cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled &>/dev/null
+ $STD /opt/cronicle/bin/control.sh start
+ $STD cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled
chmod 775 /etc/init.d/cronicled
- update-rc.d cronicled defaults &>/dev/null
+ $STD update-rc.d cronicled defaults
msg_ok "Installed Cronicle Worker"
echo -e "\n Add Masters secret key to /opt/cronicle/conf/config.json \n"
exit
diff --git a/ct/cross-seed.sh b/ct/cross-seed.sh
index 1cb34a39a..0a2337acf 100644
--- a/ct/cross-seed.sh
+++ b/ct/cross-seed.sh
@@ -29,7 +29,7 @@ function update_script() {
latest_version=$(npm show cross-seed version)
if [ "$current_version" != "$latest_version" ]; then
msg_info "Updating ${APP} from version v${current_version} to v${latest_version}"
- npm install -g cross-seed@latest &> /dev/null
+ $STD npm install -g cross-seed@latest
systemctl restart cross-seed
msg_ok "Updated Successfully"
else
diff --git a/ct/daemonsync.sh b/ct/daemonsync.sh
index ae2fb6a2e..c65d08cdd 100644
--- a/ct/daemonsync.sh
+++ b/ct/daemonsync.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/debian.sh b/ct/debian.sh
index f4c3d6bff..0c12a60bc 100644
--- a/ct/debian.sh
+++ b/ct/debian.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/deconz.sh b/ct/deconz.sh
index 3d1d0dbec..57023b6a2 100644
--- a/ct/deconz.sh
+++ b/ct/deconz.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/deluge.sh b/ct/deluge.sh
index 038ed996d..effa41a91 100644
--- a/ct/deluge.sh
+++ b/ct/deluge.sh
@@ -28,7 +28,7 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
+ $STD apt-get update
pip3 install deluge[all] --upgrade
msg_ok "Updated $APP LXC"
exit
diff --git a/ct/docker.sh b/ct/docker.sh
index e21e9e0ff..8a49cadfe 100644
--- a/ct/docker.sh
+++ b/ct/docker.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/docmost.sh b/ct/docmost.sh
index 75e1f9363..443e7007e 100644
--- a/ct/docmost.sh
+++ b/ct/docmost.sh
@@ -34,6 +34,7 @@ function update_script() {
msg_info "Updating ${APP} to v${RELEASE}"
cp /opt/docmost/.env /opt/
+ cp -r /opt/docmost/data /opt/
rm -rf /opt/docmost
temp_file=$(mktemp)
wget -q "https://github.com/docmost/docmost/archive/refs/tags/v${RELEASE}.tar.gz" -O "$temp_file"
@@ -41,8 +42,9 @@ function update_script() {
mv docmost-${RELEASE} /opt/docmost
cd /opt/docmost
mv /opt/.env /opt/docmost/.env
- pnpm install --force &>/dev/null
- pnpm build &>/dev/null
+ mv /opt/data /opt/docmost/data
+ $STD pnpm install --force
+ $STD pnpm build
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP}"
diff --git a/ct/dotnetaspwebapi.sh b/ct/dotnetaspwebapi.sh
index 667cb5b18..6345e87d5 100644
--- a/ct/dotnetaspwebapi.sh
+++ b/ct/dotnetaspwebapi.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/elementsynapse.sh b/ct/elementsynapse.sh
index d1b482be5..64057fa4d 100644
--- a/ct/elementsynapse.sh
+++ b/ct/elementsynapse.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/emby.sh b/ct/emby.sh
index eaa02bde7..0a9e9f575 100644
--- a/ct/emby.sh
+++ b/ct/emby.sh
@@ -33,8 +33,8 @@ function update_script() {
msg_ok "Stopped ${APP}"
msg_info "Updating ${APP}"
- wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null
- dpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null
+ $STD wget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb
+ $STD dpkg -i emby-server-deb_${LATEST}_amd64.deb
rm emby-server-deb_${LATEST}_amd64.deb
msg_ok "Updated ${APP}"
diff --git a/ct/emqx.sh b/ct/emqx.sh
index 08026b790..5f44b8325 100644
--- a/ct/emqx.sh
+++ b/ct/emqx.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/esphome.sh b/ct/esphome.sh
index 5c451f662..aaeca7e2b 100644
--- a/ct/esphome.sh
+++ b/ct/esphome.sh
@@ -33,9 +33,9 @@ function update_script() {
msg_info "Updating ESPHome"
if [[ -d /srv/esphome ]]; then
- source /srv/esphome/bin/activate &>/dev/null
+ $STD source /srv/esphome/bin/activate
fi
- pip3 install -U esphome &>/dev/null
+ $STD pip3 install -U esphome
msg_ok "Updated ESPHome"
msg_info "Starting ESPHome"
diff --git a/ct/evcc.sh b/ct/evcc.sh
index df9ff5797..154555fd3 100644
--- a/ct/evcc.sh
+++ b/ct/evcc.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating evcc LXC"
- apt update &>/dev/null
- apt --only-upgrade install -y evcc &>/dev/null
+ $STD apt update
+ $STD apt --only-upgrade install -y evcc
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/excalidraw.sh b/ct/excalidraw.sh
index d0ff3a27a..c1347b41c 100644
--- a/ct/excalidraw.sh
+++ b/ct/excalidraw.sh
@@ -43,7 +43,7 @@ function update_script() {
rm -rf /opt/excalidraw
mv excalidraw-${RELEASE} /opt/excalidraw
cd /opt/excalidraw
- yarn &> /dev/null
+ $STD yarn
msg_ok "Updated $APP to v${RELEASE}"
msg_info "Starting $APP"
diff --git a/ct/fenrus.sh b/ct/fenrus.sh
index a22e164ea..d9d4eec7b 100644
--- a/ct/fenrus.sh
+++ b/ct/fenrus.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
msg_info "Updating ${APP}"
systemctl stop ${APP}
diff --git a/ct/fhem.sh b/ct/fhem.sh
index aa87bb3dc..b3dd23968 100644
--- a/ct/fhem.sh
+++ b/ct/fhem.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/firefly.sh b/ct/firefly.sh
index efb5f8109..2f86e668c 100644
--- a/ct/firefly.sh
+++ b/ct/firefly.sh
@@ -37,21 +37,19 @@ check_container_resources
msg_info "Updating ${APP} to v${RELEASE}"
cp /opt/firefly/.env /opt/.env
cp -r /opt/firefly/storage /opt/storage
- rm -rf /opt/firefly/*
cd /opt
wget -q "https://github.com/firefly-iii/firefly-iii/releases/download/v${RELEASE}/FireflyIII-v${RELEASE}.tar.gz"
tar -xzf FireflyIII-v${RELEASE}.tar.gz -C /opt/firefly --exclude='storage'
+ cp /opt/.env /opt/firefly/.env
+ cp -r /opt/storage /opt/firefly/storage
cd /opt/firefly
- composer install --no-dev --no-interaction &>/dev/null
- php artisan migrate --seed --force &>/dev/null
- php artisan firefly:decrypt-all &>/dev/null
- php artisan cache:clear &>/dev/null
- php artisan view:clear &>/dev/null
- php artisan firefly:upgrade-database &>/dev/null
- php artisan firefly:laravel-passport-keys &>/dev/null
chown -R www-data:www-data /opt/firefly
chmod -R 775 /opt/firefly/storage
-
+ $STD php artisan migrate --seed --force
+ $STD php artisan cache:clear
+ $STD php artisan view:clear
+ $STD php artisan firefly-iii:upgrade-database
+ $STD php artisan firefly-iii:laravel-passport-keys
echo "${RELEASE}" >"/opt/${APP}_version.txt"
msg_ok "Updated ${APP} to v${RELEASE}"
@@ -76,4 +74,4 @@ description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
-echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
\ No newline at end of file
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/ct/ghost.sh b/ct/ghost.sh
index 7a496b85f..8003ba206 100644
--- a/ct/ghost.sh
+++ b/ct/ghost.sh
@@ -30,7 +30,7 @@ function update_script() {
latest_version=$(npm show ghost-cli version)
if [ "$current_version" != "$latest_version" ]; then
msg_info "Updating ${APP} from version v${current_version} to v${latest_version}"
- npm install -g ghost-cli@latest &> /dev/null
+ $STD npm install -g ghost-cli@latest
msg_ok "Updated Successfully"
else
msg_ok "${APP} is already at v${current_version}"
diff --git a/ct/glpi.sh b/ct/glpi.sh
index a25dba350..de03f7dd9 100644
--- a/ct/glpi.sh
+++ b/ct/glpi.sh
@@ -30,7 +30,7 @@ function update_script() {
fi
RELEASE=$(curl -s https://api.github.com/repos/glpi-project/glpi/releases/latest | grep '"tag_name"' | sed -E 's/.*"tag_name": "([^"]+)".*/\1/')
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
- msg_error "Ther is currently no automatic update function for ${APP}."
+ msg_error "Currently we don't provide an update function for this ${APP}."
else
msg_ok "No update required. ${APP} is already at v${RELEASE}."
fi
diff --git a/ct/gokapi.sh b/ct/gokapi.sh
index 868e9a36a..d3cab30f0 100644
--- a/ct/gokapi.sh
+++ b/ct/gokapi.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/grafana.sh b/ct/grafana.sh
index 0cdd0712a..37afd4496 100644
--- a/ct/grafana.sh
+++ b/ct/grafana.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/graylog.sh b/ct/graylog.sh
index ffed4bf22..5beed3753 100644
--- a/ct/graylog.sh
+++ b/ct/graylog.sh
@@ -34,8 +34,8 @@ function update_script() {
msg_ok "Stopped $APP"
msg_info "Updating $APP"
- apt-get update &> /dev/null
- apt-get upgrade -y &> /dev/null
+ $STD apt-get update
+ $STD apt-get upgrade -y
msg_ok "Updated $APP"
msg_info "Starting $APP"
diff --git a/ct/grist.sh b/ct/grist.sh
index f361552e4..217bcba78 100644
--- a/ct/grist.sh
+++ b/ct/grist.sh
@@ -53,15 +53,15 @@ function update_script() {
cd grist
msg_info "Installing Dependencies"
- yarn install >/dev/null 2>&1
+ $STD yarn install
msg_ok "Installed Dependencies"
msg_info "Building"
- yarn run build:prod >/dev/null 2>&1
+ $STD yarn run build:prod
msg_ok "Done building"
msg_info "Installing Python"
- yarn run install:python >/dev/null 2>&1
+ $STD yarn run install:python
msg_ok "Installed Python"
echo "${RELEASE}" >/opt/${APP}_version.txt
diff --git a/ct/habitica.sh b/ct/habitica.sh
new file mode 100644
index 000000000..a85a973ef
--- /dev/null
+++ b/ct/habitica.sh
@@ -0,0 +1,74 @@
+#!/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: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/HabitRPG/habitica
+
+APP="Habitica"
+var_tags="gaming"
+var_cpu="2"
+var_ram="4096"
+var_disk="8"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+
+ if [[ ! -d "/opt/habitica" ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/HabitRPG/habitica/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
+ msg_info "Stopping $APP"
+ systemctl stop habitica-mongodb
+ systemctl stop habitica
+ systemctl stop habitica-client
+ msg_ok "Stopped $APP"
+
+ msg_info "Updating $APP to ${RELEASE}"
+ temp_file=$(mktemp)
+ wget -q "https://github.com/HabitRPG/habitica/archive/refs/tags/v${RELEASE}.tar.gz" -O $temp_file
+ tar zxf $temp_file
+ cp -rf habitica-${RELEASE}/* /opt/habitica
+ cd /opt/habitica
+ $STD npm i
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated $APP to ${RELEASE}"
+
+ msg_info "Starting $APP"
+ systemctl start habitica-mongodb
+ systemctl start habitica
+ systemctl start habitica-client
+ msg_ok "Started $APP"
+
+ msg_info "Cleaning Up"
+ rm -f $temp_file
+ rm -rf ~/habitica-${RELEASE}
+ msg_ok "Cleanup Completed"
+
+ msg_ok "Update Successful"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ fi
+ exit
+}
+
+start
+build_container
+description
+
+msg_ok "Completed Successfully!\n"
+echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/ct/headers/authelia b/ct/headers/authelia
new file mode 100644
index 000000000..ed9aa67a7
--- /dev/null
+++ b/ct/headers/authelia
@@ -0,0 +1,6 @@
+ ___ __ __ ___
+ / | __ __/ /_/ /_ ___ / (_)___ _
+ / /| |/ / / / __/ __ \/ _ \/ / / __ `/
+ / ___ / /_/ / /_/ / / / __/ / / /_/ /
+/_/ |_\__,_/\__/_/ /_/\___/_/_/\__,_/
+
diff --git a/ct/headers/bytestash b/ct/headers/bytestash
new file mode 100644
index 000000000..73089fe1c
--- /dev/null
+++ b/ct/headers/bytestash
@@ -0,0 +1,6 @@
+ ____ __ _____ __ __
+ / __ )__ __/ /____ / ___// /_____ ______/ /_
+ / __ / / / / __/ _ \\__ \/ __/ __ `/ ___/ __ \
+ / /_/ / /_/ / /_/ __/__/ / /_/ /_/ (__ ) / / /
+/_____/\__, /\__/\___/____/\__/\__,_/____/_/ /_/
+ /____/
diff --git a/ct/headers/habitica b/ct/headers/habitica
new file mode 100644
index 000000000..144591bb5
--- /dev/null
+++ b/ct/headers/habitica
@@ -0,0 +1,6 @@
+ __ __ __ _ __ _
+ / / / /___ _/ /_ (_) /_(_)________ _
+ / /_/ / __ `/ __ \/ / __/ / ___/ __ `/
+ / __ / /_/ / /_/ / / /_/ / /__/ /_/ /
+/_/ /_/\__,_/_.___/_/\__/_/\___/\__,_/
+
diff --git a/ct/headers/jupyternotebook b/ct/headers/jupyternotebook
new file mode 100644
index 000000000..84965a56a
--- /dev/null
+++ b/ct/headers/jupyternotebook
@@ -0,0 +1,6 @@
+ __ __ _ __ __ __ __
+ / /_ ______ __ __/ /____ _____ / | / /___ / /____ / /_ ____ ____ / /__
+ __ / / / / / __ \/ / / / __/ _ \/ ___/ / |/ / __ \/ __/ _ \/ __ \/ __ \/ __ \/ //_/
+/ /_/ / /_/ / /_/ / /_/ / /_/ __/ / / /| / /_/ / /_/ __/ /_/ / /_/ / /_/ / ,<
+\____/\__,_/ .___/\__, /\__/\___/_/ /_/ |_/\____/\__/\___/_.___/\____/\____/_/|_|
+ /_/ /____/
diff --git a/ct/headers/outline b/ct/headers/outline
new file mode 100644
index 000000000..66e98f4d2
--- /dev/null
+++ b/ct/headers/outline
@@ -0,0 +1,6 @@
+ ____ __ ___
+ / __ \__ __/ /_/ (_)___ ___
+ / / / / / / / __/ / / __ \/ _ \
+/ /_/ / /_/ / /_/ / / / / / __/
+\____/\__,_/\__/_/_/_/ /_/\___/
+
diff --git a/ct/headers/pelican-panel b/ct/headers/pelican-panel
new file mode 100644
index 000000000..e38095db6
--- /dev/null
+++ b/ct/headers/pelican-panel
@@ -0,0 +1,6 @@
+ ____ ___ ____ __
+ / __ \___ / (_)________ _____ / __ \____ _____ ___ / /
+ / /_/ / _ \/ / / ___/ __ `/ __ \______/ /_/ / __ `/ __ \/ _ \/ /
+ / ____/ __/ / / /__/ /_/ / / / /_____/ ____/ /_/ / / / / __/ /
+/_/ \___/_/_/\___/\__,_/_/ /_/ /_/ \__,_/_/ /_/\___/_/
+
diff --git a/ct/headers/pelican-wings b/ct/headers/pelican-wings
new file mode 100644
index 000000000..888c4d388
--- /dev/null
+++ b/ct/headers/pelican-wings
@@ -0,0 +1,6 @@
+ ____ ___ _ ___
+ / __ \___ / (_)________ _____ | | / (_)___ ____ ______
+ / /_/ / _ \/ / / ___/ __ `/ __ \_____| | /| / / / __ \/ __ `/ ___/
+ / ____/ __/ / / /__/ /_/ / / / /_____/ |/ |/ / / / / / /_/ (__ )
+/_/ \___/_/_/\___/\__,_/_/ /_/ |__/|__/_/_/ /_/\__, /____/
+ /____/
diff --git a/ct/headers/victoriametrics b/ct/headers/victoriametrics
new file mode 100644
index 000000000..5e705603d
--- /dev/null
+++ b/ct/headers/victoriametrics
@@ -0,0 +1,6 @@
+ _ ___ __ _ __ ___ __ _
+| | / (_)____/ /_____ _____(_)___ _/ |/ /__ / /______(_)_________
+| | / / / ___/ __/ __ \/ ___/ / __ `/ /|_/ / _ \/ __/ ___/ / ___/ ___/
+| |/ / / /__/ /_/ /_/ / / / / /_/ / / / / __/ /_/ / / / /__(__ )
+|___/_/\___/\__/\____/_/ /_/\__,_/_/ /_/\___/\__/_/ /_/\___/____/
+
diff --git a/ct/headers/web-check b/ct/headers/web-check
new file mode 100644
index 000000000..371062cb9
--- /dev/null
+++ b/ct/headers/web-check
@@ -0,0 +1,6 @@
+ __ __ __
+ _ _____ / /_ _____/ /_ ___ _____/ /__
+| | /| / / _ \/ __ \______/ ___/ __ \/ _ \/ ___/ //_/
+| |/ |/ / __/ /_/ /_____/ /__/ / / / __/ /__/ ,<
+|__/|__/\___/_.___/ \___/_/ /_/\___/\___/_/|_|
+
diff --git a/ct/headers/wger b/ct/headers/wger
new file mode 100644
index 000000000..85e0a5dd3
--- /dev/null
+++ b/ct/headers/wger
@@ -0,0 +1,6 @@
+
+ _ ______ ____ _____
+| | /| / / __ `/ _ \/ ___/
+| |/ |/ / /_/ / __/ /
+|__/|__/\__, /\___/_/
+ /____/
diff --git a/ct/heimdall-dashboard.sh b/ct/heimdall-dashboard.sh
index 7d03954a4..ba31c6bb4 100644
--- a/ct/heimdall-dashboard.sh
+++ b/ct/heimdall-dashboard.sh
@@ -44,8 +44,8 @@ function update_script() {
VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
cp -R Heimdall-${VER}/* /opt/Heimdall
cd /opt/Heimdall
- apt-get install -y composer &>/dev/null
- COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null
+ $STD apt-get install -y composer
+ $STD COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated Heimdall Dashboard to ${RELEASE}"
msg_info "Restoring Data"
diff --git a/ct/hivemq.sh b/ct/hivemq.sh
index 4a07b02bb..52ecea72b 100644
--- a/ct/hivemq.sh
+++ b/ct/hivemq.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/hoarder.sh b/ct/hoarder.sh
index 739bf59aa..cb69ec3b0 100644
--- a/ct/hoarder.sh
+++ b/ct/hoarder.sh
@@ -35,7 +35,7 @@ function update_script() {
msg_ok "Stopped Services"
msg_info "Updating ${APP} to v${RELEASE}"
if [[ $(corepack -v) < "0.31.0" ]]; then
- npm install -g corepack@0.31.0 &>/dev/null
+ $STD npm install -g corepack@0.31.0
fi
cd /opt
if [[ -f /opt/hoarder/.env ]] && [[ ! -f /etc/hoarder/hoarder.env ]]; then
@@ -47,14 +47,14 @@ function update_script() {
unzip -q v${RELEASE}.zip
mv hoarder-${RELEASE} /opt/hoarder
cd /opt/hoarder/apps/web
- pnpm install --frozen-lockfile &>/dev/null
- pnpm exec next build --experimental-build-mode compile &>/dev/null
+ $STD pnpm install --frozen-lockfile
+ $STD pnpm exec next build --experimental-build-mode compile
cp -r /opt/hoarder/apps/web/.next/standalone/apps/web/server.js /opt/hoarder/apps/web
cd /opt/hoarder/apps/workers
- pnpm install --frozen-lockfile &>/dev/null
+ $STD pnpm install --frozen-lockfile
export DATA_DIR=/opt/hoarder_data
cd /opt/hoarder/packages/db
- pnpm migrate &>/dev/null
+ $STD pnpm migrate
sed -i "s/SERVER_VERSION=${PREV_RELEASE}/SERVER_VERSION=${RELEASE}/" /etc/hoarder/hoarder.env
msg_ok "Updated ${APP} to v${RELEASE}"
diff --git a/ct/homarr.sh b/ct/homarr.sh
index fb6a3e8e9..ade524fff 100644
--- a/ct/homarr.sh
+++ b/ct/homarr.sh
@@ -38,14 +38,22 @@ fi
if [[ ! -f /opt/run_homarr.sh ]]; then
msg_info "Detected outdated and missing service files"
msg_error "Warning - The port of homarr changed from 3000 to 7575"
- apt-get install -y nginx gettext openssl gpg &>/dev/null
+ $STD apt-get install -y nginx gettext openssl gpg
sed -i '/^NODE_ENV=/d' /opt/homarr/.env && echo "NODE_ENV='production'" >> /opt/homarr/.env
sed -i '/^DB_DIALECT=/d' /opt/homarr/.env && echo "DB_DIALECT='sqlite'" >> /opt/homarr/.env
cat <<'EOF' >/opt/run_homarr.sh
#!/bin/bash
+set -a
+source /opt/homarr/.env
+set +a
export DB_DIALECT='sqlite'
export AUTH_SECRET=$(openssl rand -base64 32)
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
+for dir in $(find /opt/homarr_db/migrations/migrations -mindepth 1 -maxdepth 1 -type d); do
+ dirname=$(basename "$dir")
+ mkdir -p "/opt/homarr_db/migrations/$dirname"
+ cp -r "$dir"/* "/opt/homarr_db/migrations/$dirname/" 2>/dev/null || true
+done
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
nginx -g 'daemon off;' &
@@ -85,6 +93,30 @@ fi
msg_ok "Backup Data"
msg_info "Updating and rebuilding ${APP} to v${RELEASE} (Patience)"
+ rm /opt/run_homarr.sh
+ cat <<'EOF' >/opt/run_homarr.sh
+#!/bin/bash
+set -a
+source /opt/homarr/.env
+set +a
+export DB_DIALECT='sqlite'
+export AUTH_SECRET=$(openssl rand -base64 32)
+node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
+for dir in $(find /opt/homarr_db/migrations/migrations -mindepth 1 -maxdepth 1 -type d); do
+ dirname=$(basename "$dir")
+ mkdir -p "/opt/homarr_db/migrations/$dirname"
+ cp -r "$dir"/* "/opt/homarr_db/migrations/$dirname/" 2>/dev/null || true
+done
+export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
+envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
+nginx -g 'daemon off;' &
+redis-server /opt/homarr/packages/redis/redis.conf &
+node apps/tasks/tasks.cjs &
+node apps/websocket/wssServer.cjs &
+node apps/nextjs/server.js & PID=$!
+wait $PID
+EOF
+ chmod +x /opt/run_homarr.sh
wget -q "https://github.com/homarr-labs/homarr/archive/refs/tags/v${RELEASE}.zip"
unzip -q v${RELEASE}.zip
rm -rf v${RELEASE}.zip
@@ -92,8 +124,8 @@ fi
mv homarr-${RELEASE} /opt/homarr
mv /opt/homarr-data-backup/.env /opt/homarr/.env
cd /opt/homarr
- pnpm install &>/dev/null
- pnpm build &>/dev/null
+ $STD pnpm install
+ $STD pnpm build
cp /opt/homarr/apps/nextjs/next.config.ts .
cp /opt/homarr/apps/nextjs/package.json .
cp -r /opt/homarr/packages/db/migrations /opt/homarr_db/migrations
@@ -116,6 +148,7 @@ fi
msg_info "Starting Services"
systemctl start homarr
+ systemctl restart homarr
msg_ok "Started Services"
msg_ok "Updated Successfully"
else
diff --git a/ct/homeassistant-core.sh b/ct/homeassistant-core.sh
index 78a8ac6f3..ccfd0859c 100644
--- a/ct/homeassistant-core.sh
+++ b/ct/homeassistant-core.sh
@@ -59,7 +59,7 @@ function update_script() {
msg_info "Updating Home Assistant"
source /srv/homeassistant/bin/activate
- pip install ${BR}--upgrade homeassistant &>/dev/null
+ $STD pip install ${BR}--upgrade homeassistant
msg_ok "Updated Home Assistant"
msg_info "Starting Home Assistant"
@@ -72,10 +72,10 @@ function update_script() {
fi
if [ "$UPD" == "2" ]; then
msg_info "Installing Home Assistant Community Store (HACS)"
- apt update &>/dev/null
- apt install -y unzip &>/dev/null
+ $STD apt update
+ $STD apt install -y unzip
cd .homeassistant
- bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null
+ $STD bash <(curl -fsSL https://get.hacs.xyz)
msg_ok "Installed Home Assistant Community Store (HACS)"
echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n"
exit
@@ -85,17 +85,17 @@ function update_script() {
read -r -p "Would you like to use No Authentication? " prompt
msg_info "Installing FileBrowser"
RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g')
- curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null
+ $STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
- filebrowser config init -a '0.0.0.0' &>/dev/null
- filebrowser config set -a '0.0.0.0' &>/dev/null
- filebrowser config set --auth.method=noauth &>/dev/null
- filebrowser users add ID 1 --perm.admin &>/dev/null
+ $STD filebrowser config init -a '0.0.0.0'
+ $STD filebrowser config set -a '0.0.0.0'
+ $STD filebrowser config set --auth.method=noauth
+ $STD filebrowser users add ID 1 --perm.admin
else
- filebrowser config init -a '0.0.0.0' &>/dev/null
- filebrowser config set -a '0.0.0.0' &>/dev/null
- filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null
+ $STD filebrowser config init -a '0.0.0.0'
+ $STD filebrowser config set -a '0.0.0.0'
+ $STD filebrowser users add admin helper-scripts.com --perm.admin
fi
msg_ok "Installed FileBrowser"
diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh
index f9fbeecf5..07751f4fe 100644
--- a/ct/homeassistant.sh
+++ b/ct/homeassistant.sh
@@ -61,10 +61,10 @@ function update_script() {
fi
if [ "$UPD" == "3" ]; then
msg_info "Installing Home Assistant Community Store (HACS)"
- apt update &>/dev/null
- apt install unzip &>/dev/null
+ $STD apt update
+ $STD apt install unzip
cd /var/lib/docker/volumes/hass_config/_data
- bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null
+ $STD bash <(curl -fsSL https://get.hacs.xyz)
msg_ok "Installed Home Assistant Community Store (HACS)"
echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n"
exit
@@ -73,10 +73,10 @@ function update_script() {
IP=$(hostname -I | awk '{print $1}')
msg_info "Installing FileBrowser"
RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g')
- curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null
- filebrowser config init -a '0.0.0.0' &>/dev/null
- filebrowser config set -a '0.0.0.0' &>/dev/null
- filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null
+ $STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin
+ $STD filebrowser config init -a '0.0.0.0'
+ $STD filebrowser config set -a '0.0.0.0'
+ $STD filebrowser users add admin helper-scripts.com --perm.admin
msg_ok "Installed FileBrowser"
msg_info "Creating Service"
@@ -91,7 +91,7 @@ ExecStart=/usr/local/bin/filebrowser -r /
[Install]
WantedBy=default.target" >$service_path
- systemctl enable --now filebrowser.service &>/dev/null
+ $STD systemctl enable --now filebrowser.service
msg_ok "Created Service"
msg_ok "Completed Successfully!\n"
diff --git a/ct/homebridge.sh b/ct/homebridge.sh
index abe603c81..b71758812 100644
--- a/ct/homebridge.sh
+++ b/ct/homebridge.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get install -y homebridge &>/dev/null
+ $STD apt-get update
+ $STD apt-get install -y homebridge
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/homepage.sh b/ct/homepage.sh
index 6adce7d1a..05c9f2494 100644
--- a/ct/homepage.sh
+++ b/ct/homepage.sh
@@ -30,8 +30,8 @@ function update_script() {
if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then
if ! command -v npm >/dev/null 2>&1; then
echo "Installing NPM..."
- apt-get install -y npm >/dev/null 2>&1
- npm install -g pnpm >/dev/null 2>&1
+ $STD apt-get install -y npm
+ $STD npm install -g pnpm
echo "Installed NPM..."
fi
fi
@@ -45,11 +45,11 @@ function update_script() {
cp -r homepage-${RELEASE}/* /opt/homepage/
rm -rf homepage-${RELEASE}
cd /opt/homepage
- npx --yes update-browserslist-db@latest >/dev/null 2>&1
- pnpm install >/dev/null 2>&1
+ $STD npx --yes update-browserslist-db@latest
+ $STD pnpm install
export NEXT_PUBLIC_VERSION="v$RELEASE"
export NEXT_PUBLIC_REVISION="source"
- pnpm build >/dev/null 2>&1
+ $STD pnpm build
systemctl start homepage
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated Homepage to v${RELEASE}"
diff --git a/ct/homer.sh b/ct/homer.sh
index 09f9a931b..950c04cd1 100644
--- a/ct/homer.sh
+++ b/ct/homer.sh
@@ -41,7 +41,7 @@ function update_script() {
rm -rf /opt/homer/*
cd /opt/homer
wget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip
- unzip homer.zip &>/dev/null
+ $STD unzip homer.zip
msg_ok "Updated ${APP}"
msg_info "Restoring assets directory"
diff --git a/ct/hyperhdr.sh b/ct/hyperhdr.sh
index 33c6216fe..f59a1f36f 100644
--- a/ct/hyperhdr.sh
+++ b/ct/hyperhdr.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/hyperion.sh b/ct/hyperion.sh
index 776e883bd..870690be9 100644
--- a/ct/hyperion.sh
+++ b/ct/hyperion.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get install -y hyperion &>/dev/null
+ $STD apt-get update
+ $STD apt-get install -y hyperion
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/influxdb.sh b/ct/influxdb.sh
index c3c88dbfa..17646b650 100644
--- a/ct/influxdb.sh
+++ b/ct/influxdb.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/inspircd.sh b/ct/inspircd.sh
index c187d0f51..a5e057c79 100644
--- a/ct/inspircd.sh
+++ b/ct/inspircd.sh
@@ -36,7 +36,7 @@ function update_script() {
msg_info "Updating ${APP} to v${RELEASE}"
cd /opt
wget -q https://github.com/inspircd/inspircd/releases/download/v${RELEASE}/inspircd_${RELEASE}.deb12u1_amd64.deb
- apt-get install "./inspircd_${RELEASE}.deb12u1_amd64.deb" -y &>/dev/nul
+ $STD apt-get install "./inspircd_${RELEASE}.deb12u1_amd64.deb" -y
echo "${RELEASE}" >"/opt/${APP}_version.txt"
msg_ok "Updated ${APP} to v${RELEASE}"
diff --git a/ct/iobroker.sh b/ct/iobroker.sh
index 5951b0b19..73d25ee5b 100644
--- a/ct/iobroker.sh
+++ b/ct/iobroker.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/iventoy.sh b/ct/iventoy.sh
index 2895e4cc6..dc6bd05dd 100644
--- a/ct/iventoy.sh
+++ b/ct/iventoy.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/jellyfin.sh b/ct/jellyfin.sh
index 2d789cb3f..8433d0cb9 100644
--- a/ct/jellyfin.sh
+++ b/ct/jellyfin.sh
@@ -28,9 +28,9 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
- apt-get -y --with-new-pkgs upgrade jellyfin jellyfin-server &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
+ $STD apt-get -y --with-new-pkgs upgrade jellyfin jellyfin-server
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/jellyseerr.sh b/ct/jellyseerr.sh
index 396f2bfb3..cfae7a323 100644
--- a/ct/jellyseerr.sh
+++ b/ct/jellyseerr.sh
@@ -35,8 +35,8 @@ function update_script() {
msg_ok "Updating Node.js Repository"
msg_info "Updating Packages"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updating Packages"
msg_info "Cleaning up"
@@ -53,10 +53,10 @@ function update_script() {
if [ -z "$pnpm_current" ]; then
msg_error "pnpm not found. Installing version $pnpm_desired..."
- npm install -g pnpm@"$pnpm_desired" &>/dev/null
+ $STD npm install -g pnpm@"$pnpm_desired"
elif ! node -e "const semver = require('semver'); process.exit(semver.satisfies('$pnpm_current', '$pnpm_desired') ? 0 : 1)" ; then
msg_error "Updating pnpm from version $pnpm_current to $pnpm_desired..."
- npm install -g pnpm@"$pnpm_desired" &>/dev/null
+ $STD npm install -g pnpm@"$pnpm_desired"
else
msg_ok "pnpm is already installed and satisfies version $pnpm_desired."
fi
@@ -70,9 +70,9 @@ function update_script() {
systemctl stop jellyseerr
rm -rf dist .next node_modules
export CYPRESS_INSTALL_BINARY=0
- pnpm install --frozen-lockfile &>/dev/null
+ $STD pnpm install --frozen-lockfile
export NODE_OPTIONS="--max-old-space-size=3072"
- pnpm build &>/dev/null
+ $STD pnpm build
cat </etc/systemd/system/jellyseerr.service
[Unit]
diff --git a/ct/jenkins.sh b/ct/jenkins.sh
index 391b70619..6d57346ec 100644
--- a/ct/jenkins.sh
+++ b/ct/jenkins.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/jupyternotebook.sh b/ct/jupyternotebook.sh
new file mode 100644
index 000000000..a40f3ac21
--- /dev/null
+++ b/ct/jupyternotebook.sh
@@ -0,0 +1,42 @@
+#!/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: Dave-code-creater (Tan Dat, Ta)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://jupyter.org/
+
+APP="Jupyter Notebook"
+var_tags="ai;dev-tools"
+var_cpu="2"
+var_ram="2048"
+var_disk="4"
+var_os="ubuntu"
+var_version="24.04"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+
+ msg_info "Updating ${APP} LXC"
+ $STD apt-get update
+ $STD apt-get install -y upgrade
+ $STD pip3 install jupyter --upgrade
+ msg_ok "Updated Successfully"
+ exit
+}
+
+start
+build_container
+description
+
+msg_ok "Completed Successfully!\n"
+echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8888${CL}"
diff --git a/ct/kavita.sh b/ct/kavita.sh
index 866f722d2..00ce169bf 100644
--- a/ct/kavita.sh
+++ b/ct/kavita.sh
@@ -30,7 +30,7 @@ function update_script() {
msg_info "Updating $APP LXC"
systemctl stop kavita
RELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
- tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) --no-same-owner &>/dev/null
+ $STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) --no-same-owner
rm -rf Kavita/config
cp -r Kavita/* /opt/Kavita
rm -rf Kavita
diff --git a/ct/keycloak.sh b/ct/keycloak.sh
index 09a44e49a..7a492c1ca 100644
--- a/ct/keycloak.sh
+++ b/ct/keycloak.sh
@@ -30,8 +30,8 @@ function update_script() {
msg_info "Updating ${APP} LXC"
msg_info "Updating packages"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
msg_info "Updating Keycloak to v$RELEASE"
diff --git a/ct/kimai.sh b/ct/kimai.sh
index 06313043b..396257b07 100644
--- a/ct/kimai.sh
+++ b/ct/kimai.sh
@@ -35,19 +35,22 @@ function update_script() {
msg_info "Updating ${APP} to ${RELEASE}"
cp /opt/kimai/.env /opt/.env
+ [ -f /opt/kimai/config/packages/local.yaml ] && cp /opt/kimai/config/packages/local.yaml /opt/local.yaml
rm -rf /opt/kimai
wget -q "https://github.com/kimai/kimai/archive/refs/tags/${RELEASE}.zip"
unzip -q ${RELEASE}.zip
mv kimai-${RELEASE} /opt/kimai
mv /opt/.env /opt/kimai/.env
+ [ -f /opt/local.yaml ] && mv /opt/local.yaml /opt/kimai/config/packages/local.yaml
cd /opt/kimai
- composer install --no-dev --optimize-autoloader &>/dev/null
- bin/console kimai:update &>/dev/null
+ $STD composer install --no-dev --optimize-autoloader
+ $STD bin/console kimai:update
chown -R :www-data .
chmod -R g+r .
chmod -R g+rw var/
- sudo chown -R www-data:www-data /opt/kimai
- sudo chmod -R 755 /opt/kimai
+ chmod -R 777 /opt/kimai/var/
+ chown -R www-data:www-data /opt/kimai
+ chmod -R 755 /opt/kimai
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to ${RELEASE}"
@@ -72,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}${CL}"
\ No newline at end of file
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/ct/koillection.sh b/ct/koillection.sh
index 64dfde90d..31af04542 100644
--- a/ct/koillection.sh
+++ b/ct/koillection.sh
@@ -43,12 +43,12 @@ function update_script() {
cp -r /opt/koillection-backup/.env.local /opt/koillection
cp -r /opt/koillection-backup/public/uploads/. /opt/koillection/public/uploads/
export COMPOSER_ALLOW_SUPERUSER=1
- composer install --no-dev -o --no-interaction --classmap-authoritative &>/dev/null
- php bin/console doctrine:migrations:migrate --no-interaction &>/dev/null
- php bin/console app:translations:dump &>/dev/null
+ $STD composer install --no-dev -o --no-interaction --classmap-authoritative
+ $STD php bin/console doctrine:migrations:migrate --no-interaction
+ $STD php bin/console app:translations:dump
cd assets/
- yarn install &>/dev/null
- yarn build &>/dev/null
+ $STD yarn install
+ $STD yarn build
chown -R www-data:www-data /opt/koillection/public/uploads
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to v${RELEASE}"
diff --git a/ct/kometa.sh b/ct/kometa.sh
index 76d4adba3..757ad69db 100644
--- a/ct/kometa.sh
+++ b/ct/kometa.sh
@@ -46,7 +46,7 @@ function update_script() {
mv Kometa-${RELEASE} /opt/kometa
cd /opt/kometa
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
- pip install -r requirements.txt --ignore-installed &> /dev/null
+ $STD pip install -r requirements.txt --ignore-installed
mkdir -p config/assets
cp /opt/config.yml config/config.yml
echo "${RELEASE}" >/opt/kometa_version.txt
diff --git a/ct/komodo.sh b/ct/komodo.sh
index d2069a282..2b59b6117 100644
--- a/ct/komodo.sh
+++ b/ct/komodo.sh
@@ -54,7 +54,7 @@ function update_script() {
exit 1
}
- docker compose -p komodo -f "/opt/komodo/$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d &>/dev/null
+ $STD docker compose -p komodo -f "/opt/komodo/$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
msg_ok "Updated ${APP}"
}
diff --git a/ct/kubo.sh b/ct/kubo.sh
index 2d387becd..0a3bac10a 100644
--- a/ct/kubo.sh
+++ b/ct/kubo.sh
@@ -30,8 +30,8 @@ function update_script() {
RELEASE=$(wget -q https://github.com/ipfs/kubo/releases/latest -O - | grep "title>Release" | cut -d " " -f 4)
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
wget -q "https://github.com/ipfs/kubo/releases/download/${RELEASE}/kubo_${RELEASE}_linux-amd64.tar.gz"
tar -xzf "kubo_${RELEASE}_linux-amd64.tar.gz" -C /usr/local
systemctl restart ipfs.service
diff --git a/ct/lazylibrarian.sh b/ct/lazylibrarian.sh
index 030831d4e..f648b2748 100644
--- a/ct/lazylibrarian.sh
+++ b/ct/lazylibrarian.sh
@@ -32,7 +32,7 @@ function update_script() {
msg_ok "LazyLibrarian Stopped"
msg_info "Updating $APP LXC"
- git -C /opt/LazyLibrarian pull origin master &>/dev/null
+ $STD git -C /opt/LazyLibrarian pull origin master
msg_ok "Updated $APP LXC"
msg_info "Starting LazyLibrarian"
diff --git a/ct/lidarr.sh b/ct/lidarr.sh
index da0a39214..f0878246b 100644
--- a/ct/lidarr.sh
+++ b/ct/lidarr.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/linkwarden.sh b/ct/linkwarden.sh
index 3c862bb5a..d8ae54934 100644
--- a/ct/linkwarden.sh
+++ b/ct/linkwarden.sh
@@ -32,6 +32,15 @@ function update_script() {
systemctl stop linkwarden
msg_ok "Stopped ${APP}"
+ msg_info "Updating Rust"
+ $STD apt-get install -y build-essential
+ $STD curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+ source $HOME/.cargo/env
+ echo 'export PATH=/usr/local/cargo/bin:$PATH' >> /etc/profile
+ source /etc/profile
+ $STD cargo install monolith
+ msg_ok "Updated Rust"
+
msg_info "Updating ${APP} to ${RELEASE}"
cd /opt
mv /opt/linkwarden/.env /opt/.env
@@ -41,12 +50,12 @@ function update_script() {
unzip -q ${RELEASE}.zip
mv linkwarden-${RELEASE:1} /opt/linkwarden
cd /opt/linkwarden
- yarn &>/dev/null
- npx playwright install-deps &>/dev/null
- yarn playwright install &>/dev/null
+ $STD yarn
+ $STD npx playwright install-deps
+ $STD yarn playwright install
cp /opt/.env /opt/linkwarden/.env
- yarn build &>/dev/null
- yarn prisma migrate deploy &>/dev/null
+ $STD yarn build
+ $STD yarn prisma migrate deploy
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to ${RELEASE}"
diff --git a/ct/listmonk.sh b/ct/listmonk.sh
index 9a1c0c156..e95f7e3f8 100644
--- a/ct/listmonk.sh
+++ b/ct/listmonk.sh
@@ -42,7 +42,7 @@ function update_script() {
tar -xzf "listmonk_${RELEASE}_linux_amd64.tar.gz" -C /opt/listmonk
mv /opt/listmonk-backup/config.toml /opt/listmonk/config.toml
mv /opt/listmonk-backup/uploads /opt/listmonk/uploads
- /opt/listmonk/listmonk --upgrade --yes --config /opt/listmonk/config.toml &>/dev/null
+ $STD /opt/listmonk/listmonk --upgrade --yes --config /opt/listmonk/config.toml
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to v${RELEASE}"
diff --git a/ct/magicmirror.sh b/ct/magicmirror.sh
index 3cbe6bf05..67ec9b0ce 100644
--- a/ct/magicmirror.sh
+++ b/ct/magicmirror.sh
@@ -50,7 +50,7 @@ function update_script() {
rm -rf /opt/magicmirror
mv MagicMirror-${RELEASE} /opt/magicmirror
cd /opt/magicmirror
- npm run install-mm &> /dev/null
+ $STD npm run install-mm
cp /opt/magicmirror-backup/config.js /opt/magicmirror/config/
if [[ -f /opt/magicmirror-backup/custom.css ]]; then
cp /opt/magicmirror-backup/custom.css /opt/magicmirror/css/
diff --git a/ct/mariadb.sh b/ct/mariadb.sh
index d1db6d030..76be07d9c 100644
--- a/ct/mariadb.sh
+++ b/ct/mariadb.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/mattermost.sh b/ct/mattermost.sh
index 485962870..910d00bd2 100644
--- a/ct/mattermost.sh
+++ b/ct/mattermost.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/mediamtx.sh b/ct/mediamtx.sh
index 05d3bfebb..f6022fc41 100644
--- a/ct/mediamtx.sh
+++ b/ct/mediamtx.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/memos.sh b/ct/memos.sh
index ef854296e..e10c300e3 100644
--- a/ct/memos.sh
+++ b/ct/memos.sh
@@ -37,13 +37,13 @@ function update_script() {
fi
systemctl stop memos
cd /opt/memos/web
- pnpm i --frozen-lockfile &>/dev/null
- pnpm build &>/dev/null
+ $STD pnpm i --frozen-lockfile
+ $STD pnpm build
cd /opt/memos
mkdir -p /opt/memos/server/dist
cp -r web/dist/* /opt/memos/server/dist/
cp -r web/dist/* /opt/memos/server/router/frontend/dist/
- go build -o /opt/memos/memos -tags=embed bin/memos/main.go &>/dev/null
+ $STD go build -o /opt/memos/memos -tags=embed bin/memos/main.go
systemctl start memos
msg_ok "Updated $APP"
exit
diff --git a/ct/meshcentral.sh b/ct/meshcentral.sh
index 77b6fb0d9..d945c021e 100644
--- a/ct/meshcentral.sh
+++ b/ct/meshcentral.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/metube.sh b/ct/metube.sh
index 45c9666f9..c6b838e92 100644
--- a/ct/metube.sh
+++ b/ct/metube.sh
@@ -37,14 +37,14 @@ function update_script() {
rm -rf metube_bak
fi
mv metube metube_bak
- git clone https://github.com/alexta69/metube /opt/metube >/dev/null 2>&1
+ $STD git clone https://github.com/alexta69/metube /opt/metube
cd /opt/metube/ui
- npm install >/dev/null 2>&1
- node_modules/.bin/ng build >/dev/null 2>&1
+ $STD npm install
+ $STD node_modules/.bin/ng build
cd /opt/metube
cp /opt/metube_bak/.env /opt/metube/
- pip3 install pipenv >/dev/null 2>&1
- pipenv install >/dev/null 2>&1
+ $STD pip3 install pipenv
+ $STD pipenv install
if [ -d "/opt/metube_bak" ]; then
rm -rf /opt/metube_bak
diff --git a/ct/mongodb.sh b/ct/mongodb.sh
index 5a3bbe3e3..8dbffca86 100644
--- a/ct/mongodb.sh
+++ b/ct/mongodb.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/monica.sh b/ct/monica.sh
index 3a43f7e1a..7c84f2197 100644
--- a/ct/monica.sh
+++ b/ct/monica.sh
@@ -42,10 +42,10 @@ function update_script() {
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
+ $STD composer install --no-interaction --no-dev
+ $STD yarn install
+ $STD yarn run production
+ $STD php artisan monica:update --force
chown -R www-data:www-data /opt/monica
chmod -R 775 /opt/monica/storage
echo "${RELEASE}" >/opt/${APP}_version.txt
diff --git a/ct/motioneye.sh b/ct/motioneye.sh
index 2b114a1d2..43fc6e242 100644
--- a/ct/motioneye.sh
+++ b/ct/motioneye.sh
@@ -28,7 +28,7 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- pip install motioneye --upgrade &>/dev/null
+ $STD pip install motioneye --upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/mqtt.sh b/ct/mqtt.sh
index 302fea243..327f3da04 100644
--- a/ct/mqtt.sh
+++ b/ct/mqtt.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/myspeed.sh b/ct/myspeed.sh
index 80fb0e01e..371389c63 100644
--- a/ct/myspeed.sh
+++ b/ct/myspeed.sh
@@ -41,7 +41,7 @@ function update_script() {
wget -q https://github.com/gnmyt/myspeed/releases/download/v$RELEASE/MySpeed-$RELEASE.zip
unzip -q MySpeed-$RELEASE.zip -d myspeed
cd myspeed
- npm install >/dev/null 2>&1
+ $STD npm install
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to ${RELEASE}"
diff --git a/ct/mysql.sh b/ct/mysql.sh
index a0e063c64..193144ed3 100644
--- a/ct/mysql.sh
+++ b/ct/mysql.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/n8n.sh b/ct/n8n.sh
index 9a75b2a2b..9182dc4f1 100644
--- a/ct/n8n.sh
+++ b/ct/n8n.sh
@@ -30,12 +30,12 @@ function update_script() {
if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then
if ! command -v npm >/dev/null 2>&1; then
echo "Installing NPM..."
- apt-get install -y npm >/dev/null 2>&1
+ $STD apt-get install -y npm
echo "Installed NPM..."
fi
fi
msg_info "Updating ${APP} LXC"
- npm update -g n8n &>/dev/null
+ $STD npm update -g n8n
systemctl restart n8n
msg_ok "Updated Successfully"
exit
diff --git a/ct/navidrome.sh b/ct/navidrome.sh
index a3577541a..e5099be4b 100644
--- a/ct/navidrome.sh
+++ b/ct/navidrome.sh
@@ -35,7 +35,7 @@ function update_script() {
msg_info "Updating to v${RELEASE}"
cd /opt
wget -q https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_linux_amd64.tar.gz -O Navidrome.tar.gz
- tar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null
+ $STD tar -xvzf Navidrome.tar.gz -C /opt/navidrome/
chmod +x /opt/navidrome/navidrome
msg_ok "Updated ${APP}"
rm -rf /opt/Navidrome.tar.gz
diff --git a/ct/neo4j.sh b/ct/neo4j.sh
index 80164322d..9ef98ecea 100644
--- a/ct/neo4j.sh
+++ b/ct/neo4j.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/netbox.sh b/ct/netbox.sh
index 240657fb6..f5ca61120 100644
--- a/ct/netbox.sh
+++ b/ct/netbox.sh
@@ -56,7 +56,7 @@ function update_script() {
cp -r /opt/netbox-backup/netbox/netbox/ldap_config.py /opt/netbox/netbox/netbox/
fi
- /opt/netbox/upgrade.sh &>/dev/null
+ $STD /opt/netbox/upgrade.sh
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to v${RELEASE}"
diff --git a/ct/nextcloudpi.sh b/ct/nextcloudpi.sh
index f2bd834d0..69d5fa070 100644
--- a/ct/nextcloudpi.sh
+++ b/ct/nextcloudpi.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/nextpvr.sh b/ct/nextpvr.sh
index 99b5656c3..36b38b27b 100644
--- a/ct/nextpvr.sh
+++ b/ct/nextpvr.sh
@@ -32,14 +32,14 @@ function update_script() {
msg_ok "Stopped ${APP}"
msg_info "Updating LXC packages"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated LXC packages"
msg_info "Updating ${APP}"
cd /opt
wget -q https://nextpvr.com/nextpvr-helper.deb
- dpkg -i nextpvr-helper.deb &>/dev/null
+ $STD dpkg -i nextpvr-helper.deb
msg_ok "Updated ${APP}"
msg_info "Starting ${APP}"
diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh
index 717a4d95e..a01e7ac75 100644
--- a/ct/nginxproxymanager.sh
+++ b/ct/nginxproxymanager.sh
@@ -30,7 +30,7 @@ function update_script() {
if ! command -v pnpm &> /dev/null; then
msg_info "Installing pnpm"
#export NODE_OPTIONS=--openssl-legacy-provider
- npm install -g pnpm@8.15 &>/dev/null
+ $STD npm install -g pnpm@8.15
msg_ok "Installed pnpm"
fi
RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
@@ -47,11 +47,11 @@ function update_script() {
/etc/nginx \
/var/log/nginx \
/var/lib/nginx \
- /var/cache/nginx &>/dev/null
+ $STD /var/cache/nginx
msg_ok "Cleaned Old Files"
msg_info "Downloading NPM v${RELEASE}"
- wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null
+ $STD wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz
cd nginx-proxy-manager-${RELEASE}
msg_ok "Downloaded NPM v${RELEASE}"
@@ -96,25 +96,25 @@ function update_script() {
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
- openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null
+ $STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
fi
mkdir -p /app/global /app/frontend/images
cp -r backend/* /app
cp -r global/* /app/global
- python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null
+ $STD python3 -m pip install --no-cache-dir certbot-dns-cloudflare
msg_ok "Setup Enviroment"
msg_info "Building Frontend"
cd ./frontend
- pnpm install &>/dev/null
- pnpm upgrade &>/dev/null
- pnpm run build &>/dev/null
+ $STD pnpm install
+ $STD pnpm upgrade
+ $STD pnpm run build
cp -r dist/* /app/frontend
cp -r app-images/* /app/frontend/images
msg_ok "Built Frontend"
msg_info "Initializing Backend"
- rm -rf /app/config/default.json &>/dev/null
+ $STD rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
@@ -131,7 +131,7 @@ function update_script() {
EOF
fi
cd /app
- pnpm install &>/dev/null
+ $STD pnpm install
msg_ok "Initialized Backend"
msg_info "Starting Services"
diff --git a/ct/node-red.sh b/ct/node-red.sh
index 0bde53d89..dcb1ab380 100644
--- a/ct/node-red.sh
+++ b/ct/node-red.sh
@@ -35,7 +35,7 @@ function update_script() {
if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then
if ! command -v npm >/dev/null 2>&1; then
msg_info "Installing NPM"
- apt-get install -y npm >/dev/null 2>&1
+ $STD apt-get install -y npm
msg_ok "Installed NPM"
fi
fi
@@ -44,7 +44,7 @@ function update_script() {
msg_ok "Stopped ${APP}"
msg_info "Updating ${APP}"
- npm install -g --unsafe-perm node-red &>/dev/null
+ $STD npm install -g --unsafe-perm node-red
msg_ok "Updated ${APP}"
msg_info "Starting ${APP}"
@@ -84,7 +84,7 @@ function update_script() {
msg_info "Installing ${THEME} Theme"
cd /root/.node-red
sed -i 's|// theme: ".*",|theme: "",|g' /root/.node-red/settings.js
- npm install @node-red-contrib-themes/theme-collection &>/dev/null
+ $STD npm install @node-red-contrib-themes/theme-collection
sed -i "{s/theme: ".*"/theme: '${THEME}',/g}" /root/.node-red/settings.js
systemctl restart nodered
msg_ok "Installed ${THEME} Theme"
diff --git a/ct/nodebb.sh b/ct/nodebb.sh
index 7317abe7f..4b79273a8 100644
--- a/ct/nodebb.sh
+++ b/ct/nodebb.sh
@@ -39,7 +39,7 @@ function update_script() {
msg_info "Updating ${APP} to v${RELEASE}"
cd /opt/nodebb
- ./nodebb upgrade >/dev/null 2>&1
+ $STD ./nodebb upgrade
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to v${RELEASE}"
diff --git a/ct/notifiarr.sh b/ct/notifiarr.sh
index de9f241f2..64e037b57 100644
--- a/ct/notifiarr.sh
+++ b/ct/notifiarr.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP"
exit
}
diff --git a/ct/ntfy.sh b/ct/ntfy.sh
index 324fcc2ac..f66dbe96a 100644
--- a/ct/ntfy.sh
+++ b/ct/ntfy.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/nxwitness.sh b/ct/nxwitness.sh
index 35fb307a8..ebcbe69cd 100644
--- a/ct/nxwitness.sh
+++ b/ct/nxwitness.sh
@@ -41,7 +41,7 @@ function update_script() {
wget -q "$DOWNLOAD_URL" -O "nxwitness-server-$RELEASE-linux_x64.deb"
export DEBIAN_FRONTEND=noninteractive
export DEBCONF_NOWARNINGS=yes
- dpkg -i nxwitness-server-$RELEASE-linux_x64.deb >/dev/null 2>&1
+ $STD dpkg -i nxwitness-server-$RELEASE-linux_x64.deb
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP}"
diff --git a/ct/nzbget.sh b/ct/nzbget.sh
index 2413dd34c..c6beadcba 100644
--- a/ct/nzbget.sh
+++ b/ct/nzbget.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/octoprint.sh b/ct/octoprint.sh
index 2a453c070..43363f594 100644
--- a/ct/octoprint.sh
+++ b/ct/octoprint.sh
@@ -33,7 +33,7 @@ function update_script() {
msg_info "Updating OctoPrint"
source /opt/octoprint/bin/activate
- pip3 install octoprint --upgrade &>/dev/null
+ $STD pip3 install octoprint --upgrade
msg_ok "Updated OctoPrint"
msg_info "Starting OctoPrint"
diff --git a/ct/ollama.sh b/ct/ollama.sh
index 03de9be5d..d591edbde 100644
--- a/ct/ollama.sh
+++ b/ct/ollama.sh
@@ -27,8 +27,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/omada.sh b/ct/omada.sh
index 29268da20..b539c9374 100644
--- a/ct/omada.sh
+++ b/ct/omada.sh
@@ -27,18 +27,33 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
+
+ msg_info "Updating MongoDB"
+ MONGODB_VERSION="7.0"
+ if ! lscpu | grep -q 'avx'; then
+ MONGODB_VERSION="4.4"
+ msg_error "No AVX detected: TP-Link Canceled Support for Old MongoDB for Debian 12\n https://www.tp-link.com/baltic/support/faq/4160/"
+ exit 1
+ fi
+
+ wget -qO- https://www.mongodb.org/static/pgp/server-${MONGODB_VERSION}.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-${MONGODB_VERSION}.gpg
+ echo "deb [signed-by=/usr/share/keyrings/mongodb-server-${MONGODB_VERSION}.gpg] http://repo.mongodb.org/apt/debian $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/${MONGODB_VERSION} main" >/etc/apt/sources.list.d/mongodb-org-${MONGODB_VERSION}.list
+ $STD apt-get update
+ $STD apt-get install -y --only-upgrade mongodb-org
+ msg_ok "Updated MongoDB to $MONGODB_VERSION"
+
+ msg_info "Updating Omada Controller"
latest_url=$(curl -s "https://support.omadanetworks.com/en/product/omada-software-controller/?resourceType=download" | grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' | head -n 1)
latest_version=$(basename "$latest_url")
if [ -z "${latest_version}" ]; then
msg_error "It seems that the server (tp-link.com) might be down. Please try again at a later time."
exit
fi
- echo -e "Updating Omada Controller"
+
wget -qL ${latest_url}
dpkg -i ${latest_version}
rm -rf ${latest_version}
- echo -e "Updated Omada Controller"
- exit
+ msg_ok "Updated Omada Controller"
}
start
diff --git a/ct/omv.sh b/ct/omv.sh
index b8636f69b..1df48a1d5 100644
--- a/ct/omv.sh
+++ b/ct/omv.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/onedev.sh b/ct/onedev.sh
index 4b095a8c2..1b6289575 100644
--- a/ct/onedev.sh
+++ b/ct/onedev.sh
@@ -37,7 +37,7 @@ function update_script() {
cd /opt
wget -q https://code.onedev.io/onedev/server/~site/onedev-latest.tar.gz
tar -xzf onedev-latest.tar.gz
- /opt/onedev-latest/bin/upgrade.sh /opt/onedev >/dev/null
+ $STD /opt/onedev-latest/bin/upgrade.sh /opt/onedev
RELEASE=$(cat /opt/onedev/release.properties | grep "version" | cut -d'=' -f2)
echo "${RELEASE}" >"/opt/${APP}_version.txt"
msg_ok "Updated ${APP} to v${RELEASE}"
diff --git a/ct/opengist.sh b/ct/opengist.sh
index 56d130f77..d49ffda65 100644
--- a/ct/opengist.sh
+++ b/ct/opengist.sh
@@ -34,8 +34,8 @@ function update_script() {
msg_ok "Stopped Service"
msg_info "Updating ${APP} to v${RELEASE}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
cd /opt
mv /opt/opengist /opt/opengist-backup
wget -q "https://github.com/thomiceli/opengist/releases/download/v${RELEASE}/opengist${RELEASE}-linux-arm64.tar.gz"
@@ -52,8 +52,8 @@ function update_script() {
msg_info "Cleaning up"
rm -rf /opt/opengist${RELEASE}-linux-amd64.tar.gz
rm -rf /opt/opengist-backup
- apt-get -y autoremove &>/dev/null
- apt-get -y autoclean &>/dev/null
+ $STD apt-get -y autoremove
+ $STD apt-get -y autoclean
msg_ok "Cleaned"
msg_ok "Updated Successfully"
else
diff --git a/ct/openhab.sh b/ct/openhab.sh
index 52335d7f8..827235bff 100644
--- a/ct/openhab.sh
+++ b/ct/openhab.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/openwebui.sh b/ct/openwebui.sh
index 96efd35d1..950b93ccd 100644
--- a/ct/openwebui.sh
+++ b/ct/openwebui.sh
@@ -35,11 +35,11 @@ function update_script() {
exit
fi
systemctl stop open-webui.service
- npm install &>/dev/null
+ $STD npm install
export NODE_OPTIONS="--max-old-space-size=3584"
- npm run build &>/dev/null
+ $STD npm run build
cd ./backend
- pip install -r requirements.txt -U &>/dev/null
+ $STD pip install -r requirements.txt -U
systemctl start open-webui.service
msg_ok "Updated Successfully"
exit
diff --git a/ct/outline.sh b/ct/outline.sh
new file mode 100644
index 000000000..a303be7e9
--- /dev/null
+++ b/ct/outline.sh
@@ -0,0 +1,71 @@
+#!/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: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/outline/outline
+
+APP="Outline"
+var_tags="documentation"
+var_disk="8"
+var_cpu="2"
+var_ram="4096"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /opt/outline ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/outline/outline/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 outline
+ msg_ok "Services Stopped"
+
+ msg_info "Updating ${APP} to ${RELEASE}"
+ temp_file=$(mktemp)
+ rm -rf /opt/outline/node_modules
+ wget -q "https://github.com/outline/outline/archive/refs/tags/v${RELEASE}.tar.gz" -O $temp_file
+ tar zxf $temp_file
+ cp -rf outline-${RELEASE}/* /opt/outline
+ cd /opt/outline
+ export NODE_OPTIONS="--max-old-space-size=3584"
+ $STD yarn install --frozen-lockfile
+ $STD yarn build
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated ${APP}"
+
+ msg_info "Starting Services"
+ systemctl start outline
+ msg_ok "Started Services"
+
+ msg_info "Cleaning Up"
+ rm -rf $temp_file
+ rm -rf $HOME/outline-${RELEASE}
+ msg_ok "Cleaned"
+ msg_ok "Updated Successfully"
+ 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} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/overseerr.sh b/ct/overseerr.sh
index 74f9dd523..ee30d7553 100644
--- a/ct/overseerr.sh
+++ b/ct/overseerr.sh
@@ -31,14 +31,14 @@ function update_script() {
systemctl stop overseerr
cd /opt/overseerr
output=$(git pull)
- git pull &>/dev/null
+ $STD git pull
if echo "$output" | grep -q "Already up to date."; then
msg_ok " $APP is already up to date."
systemctl start overseerr
exit
fi
- yarn install &>/dev/null
- yarn build &>/dev/null
+ $STD yarn install
+ $STD yarn build
systemctl start overseerr
msg_ok "Updated $APP"
exit
diff --git a/ct/owncast.sh b/ct/owncast.sh
index 7ac45b0c9..6bca61e23 100644
--- a/ct/owncast.sh
+++ b/ct/owncast.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/paperless-ai.sh b/ct/paperless-ai.sh
index c4e02d1d5..60cd99faf 100644
--- a/ct/paperless-ai.sh
+++ b/ct/paperless-ai.sh
@@ -42,7 +42,7 @@ function update_script() {
mkdir -p /opt/paperless-ai/data
cp -a /opt/paperless-ai_bak/data/. /opt/paperless-ai/data/
cd /opt/paperless-ai
- npm install &>/dev/null
+ $STD npm install
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to v${RELEASE}"
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 7bde9b7e5..429cfa0a6 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -41,9 +41,9 @@ function update_script() {
wget -q https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz
tar -xzf ghostscript-10.04.0.tar.gz
cd ghostscript-10.04.0
- ./configure &>/dev/null
- make &>/dev/null
- sudo make install &>/dev/null
+ $STD ./configure
+ $STD make
+ $STD sudo make install
rm -rf /tmp/ghostscript*
msg_ok "Ghostscript updated to 10.04.0"
fi
@@ -58,9 +58,9 @@ function update_script() {
cp -r /opt/paperless/paperless.conf paperless-ngx/
cp -r paperless-ngx/* /opt/paperless/
cd /opt/paperless
- pip install -r requirements.txt &>/dev/null
+ $STD pip install -r requirements.txt
cd /opt/paperless/src
- /usr/bin/python3 manage.py migrate &>/dev/null
+ $STD /usr/bin/python3 manage.py migrate
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated to ${RELEASE}"
diff --git a/ct/part-db.sh b/ct/part-db.sh
index 542642bb4..16fe9d720 100644
--- a/ct/part-db.sh
+++ b/ct/part-db.sh
@@ -46,11 +46,11 @@ function update_script() {
cp -r "/opt/partdb-backup/config/banner.md" /opt/partdb/config/
export COMPOSER_ALLOW_SUPERUSER=1
- composer install --no-dev -o --no-interaction &>/dev/null
- yarn install &>/dev/null
- yarn build &>/dev/null
- php bin/console cache:clear &>/dev/null
- php bin/console doctrine:migrations:migrate -n &>/dev/null
+ $STD composer install --no-dev -o --no-interaction
+ $STD yarn install
+ $STD yarn build
+ $STD php bin/console cache:clear
+ $STD php bin/console doctrine:migrations:migrate -n
chown -R www-data:www-data /opt/partdb
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to v${RELEASE}"
diff --git a/ct/paymenter.sh b/ct/paymenter.sh
index fbdf78466..9bab05f48 100644
--- a/ct/paymenter.sh
+++ b/ct/paymenter.sh
@@ -33,7 +33,7 @@ function update_script() {
msg_info "Updating ${APP} to ${RELEASE}"
echo "${RELEASE}" >/opt/${APP}_version.txt
cd /opt/paymenter
- php artisan p:upgrade --no-interaction &>/dev/null
+ $STD php artisan p:upgrade --no-interaction
msg_ok "Updated Successfully"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}."
diff --git a/ct/peanut.sh b/ct/peanut.sh
index eabec1d95..3d4a28c26 100644
--- a/ct/peanut.sh
+++ b/ct/peanut.sh
@@ -35,8 +35,8 @@ function update_script() {
tar -xzf peanut.tar.gz -C /opt/peanut --strip-components 1
rm peanut.tar.gz
cd /opt/peanut
- pnpm i &>/dev/null
- pnpm run build &>/dev/null
+ $STD pnpm i
+ $STD pnpm run build
cp -r .next/static .next/standalone/.next/
mkdir -p /opt/peanut/.next/standalone/config
ln -sf /etc/peanut/settings.yml /opt/peanut/.next/standalone/config/settings.yml
diff --git a/ct/pelican-panel.sh b/ct/pelican-panel.sh
new file mode 100644
index 000000000..bb7467511
--- /dev/null
+++ b/ct/pelican-panel.sh
@@ -0,0 +1,76 @@
+#!/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://github.com/pelican-dev/panel
+
+APP="Pelican-Panel"
+var_tags="Gaming"
+var_cpu="2"
+var_ram="1024"
+var_disk="4"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /opt/pelican-panel ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/pelican-dev/panel/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"
+ cd /opt/pelican-panel
+ $STD php artisan down
+ msg_ok "Stopped Service"
+
+ msg_info "Updating ${APP} to v${RELEASE}"
+ cp -r /opt/pelican-panel/.env /opt/
+ rm -rf * .*
+ wget -q "https://github.com/pelican-dev/panel/releases/download/v${RELEASE}/panel.tar.gz"
+ tar -xzf "panel.tar.gz"
+ mv /opt/.env /opt/pelican-panel/
+ $STD composer install --no-dev --optimize-autoloader --no-interaction
+ $STD php artisan p:environment:setup
+ $STD php artisan view:clear
+ $STD php artisan config:clear
+ $STD php artisan filament:optimize
+ $STD php artisan migrate --seed --force
+ chown -R www-data:www-data /opt/pelican-panel
+ chmod -R 755 /opt/pelican-panel/storage /opt/pelican-panel/bootstrap/cache/
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated $APP to v${RELEASE}"
+
+ msg_info "Starting Service"
+ $STD php artisan queue:restart
+ $STD php artisan up
+ msg_ok "Started Service"
+
+ msg_info "Cleaning up"
+ rm -rf "/opt/pelican-panel/panel.tar.gz"
+ 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}/installer${CL}"
diff --git a/ct/pelican-wings.sh b/ct/pelican-wings.sh
new file mode 100644
index 000000000..ff871626a
--- /dev/null
+++ b/ct/pelican-wings.sh
@@ -0,0 +1,58 @@
+#!/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://github.com/pelican-dev/wings
+
+APP="Pelican-Wings"
+var_tags="Gaming"
+var_cpu="2"
+var_ram="4096"
+var_disk="8"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -f /usr/local/bin/wings ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/pelican-dev/wings/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 wings
+ msg_ok "Stopped Service"
+
+ msg_info "Updating ${APP} to v${RELEASE}"
+ rm /usr/local/bin/wings
+ wget -q -O /usr/local/bin/wings "https://github.com/pelican-dev/wings/releases/download/v${RELEASE}/wings_linux_amd64"
+ chmod u+x /usr/local/bin/wings
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated $APP to v${RELEASE}"
+
+ msg_info "Starting Service"
+ systemctl start wings
+ msg_ok "Started Service"
+ 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}"
\ No newline at end of file
diff --git a/ct/pf2etools.sh b/ct/pf2etools.sh
index c5d1ab3ae..937e4d767 100644
--- a/ct/pf2etools.sh
+++ b/ct/pf2etools.sh
@@ -32,8 +32,8 @@ function update_script() {
RELEASE=$(curl -s https://api.github.com/repos/Pf2eToolsOrg/Pf2eTools/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f "/opt/${APP}_version.txt" ]]; then
msg_info "Updating System"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated System"
msg_info "Updating ${APP}"
@@ -43,8 +43,8 @@ function update_script() {
rm -rf "/opt/${APP}"
mv ${APP}-${RELEASE:1} /opt/${APP}
cd /opt/Pf2eTools
- npm install &>/dev/null
- npm run build &>/dev/null
+ $STD npm install
+ $STD npm run build
chown -R www-data: "/opt/${APP}"
chmod -R 755 "/opt/${APP}"
echo "${RELEASE}" >"/opt/${APP}_version.txt"
diff --git a/ct/photoprism.sh b/ct/photoprism.sh
index d9631d65d..1d3e2ba2d 100644
--- a/ct/photoprism.sh
+++ b/ct/photoprism.sh
@@ -32,7 +32,7 @@ function update_script() {
msg_ok "Stopped PhotoPrism"
msg_info "Updating PhotoPrism"
- apt-get install -y libvips42 &>/dev/null
+ $STD apt-get install -y libvips42
wget -q -cO - https://dl.photoprism.app/pkg/linux/amd64.tar.gz | tar -xzf - -C /opt/photoprism --strip-components=1
msg_ok "Updated PhotoPrism"
diff --git a/ct/pingvin.sh b/ct/pingvin.sh
index 6b1487a11..dbc7937a4 100644
--- a/ct/pingvin.sh
+++ b/ct/pingvin.sh
@@ -42,11 +42,11 @@ function update_script() {
cp -rf pingvin-share-${RELEASE}/* /opt/pingvin-share
cd /opt/pingvin-share
cd backend
- npm install &>/dev/null
- npm run build &>/dev/null
+ $STD npm install
+ $STD npm run build
cd ../frontend
- npm install &>/dev/null
- npm run build &>/dev/null
+ $STD npm install
+ $STD npm run build
echo "${RELEASE}" >"/opt/pingvin_version.txt"
rm -rf /opt/v${RELEASE}.zip
rm -rf /opt/pingvin-share-${RELEASE}
diff --git a/ct/plex.sh b/ct/plex.sh
index 7f6fbaee3..4e2a5cce1 100644
--- a/ct/plex.sh
+++ b/ct/plex.sh
@@ -33,8 +33,8 @@ function update_script() {
3>&1 1>&2 2>&3)
if [ "$UPD" == "1" ]; then
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
fi
diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh
index f09fa6cd0..0354924c1 100644
--- a/ct/podman-homeassistant.sh
+++ b/ct/podman-homeassistant.sh
@@ -33,8 +33,8 @@ check_container_resources
if [ "$UPD" == "1" ]; then
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
msg_info "Updating All Containers\n"
@@ -54,10 +54,10 @@ if [ "$UPD" == "1" ]; then
fi
if [ "$UPD" == "2" ]; then
msg_info "Installing Home Assistant Community Store (HACS)"
- apt update &>/dev/null
- apt install unzip &>/dev/null
+ $STD apt update
+ $STD apt install unzip
cd /var/lib/containers/storage/volumes/hass_config/_data
- bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null
+ $STD bash <(curl -fsSL https://get.hacs.xyz)
msg_ok "Installed Home Assistant Community Store (HACS)"
echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n"
exit
@@ -65,10 +65,10 @@ fi
if [ "$UPD" == "3" ]; then
IP=$(hostname -I | awk '{print $1}')
msg_info "Installing FileBrowser"
- curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null
- filebrowser config init -a '0.0.0.0' &>/dev/null
- filebrowser config set -a '0.0.0.0' &>/dev/null
- filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null
+ $STD curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
+ $STD filebrowser config init -a '0.0.0.0'
+ $STD filebrowser config set -a '0.0.0.0'
+ $STD filebrowser users add admin helper-scripts.com --perm.admin
msg_ok "Installed FileBrowser"
msg_info "Creating Service"
@@ -83,7 +83,7 @@ if [ "$UPD" == "3" ]; then
[Install]
WantedBy=default.target" >$service_path
- systemctl enable --now filebrowser.service &>/dev/null
+ $STD systemctl enable --now filebrowser.service
msg_ok "Created Service"
msg_ok "Completed Successfully!\n"
diff --git a/ct/podman.sh b/ct/podman.sh
index 5d4fce123..1f98b13fd 100644
--- a/ct/podman.sh
+++ b/ct/podman.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/postgresql.sh b/ct/postgresql.sh
index d07f34751..cc9c63541 100644
--- a/ct/postgresql.sh
+++ b/ct/postgresql.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/prometheus-pve-exporter.sh b/ct/prometheus-pve-exporter.sh
index 69b10a582..4987f816a 100644
--- a/ct/prometheus-pve-exporter.sh
+++ b/ct/prometheus-pve-exporter.sh
@@ -32,7 +32,7 @@ function update_script() {
msg_ok "Stopped ${APP}"
msg_info "Updating ${APP}"
- pip install prometheus-pve-exporter --default-timeout=300 --upgrade --root-user-action=ignore &>/dev/null
+ $STD pip install prometheus-pve-exporter --default-timeout=300 --upgrade --root-user-action=ignore
msg_ok "Updated ${APP}"
msg_info "Starting ${APP}"
diff --git a/ct/prowlarr.sh b/ct/prowlarr.sh
index c8719c92f..85d371574 100644
--- a/ct/prowlarr.sh
+++ b/ct/prowlarr.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/proxmox-backup-server.sh b/ct/proxmox-backup-server.sh
index fc4199d87..f81185acc 100644
--- a/ct/proxmox-backup-server.sh
+++ b/ct/proxmox-backup-server.sh
@@ -25,8 +25,8 @@ function update_script() {
check_container_resources
if [[ ! -e /usr/sbin/proxmox-backup-manager ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/proxmox-datacenter-manager.sh b/ct/proxmox-datacenter-manager.sh
index 4d2cab0fc..4ae89d055 100644
--- a/ct/proxmox-datacenter-manager.sh
+++ b/ct/proxmox-datacenter-manager.sh
@@ -25,8 +25,8 @@ function update_script() {
check_container_resources
if [[ ! -e /usr/sbin/proxmox-datacenter-manager-admin ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/proxmox-mail-gateway.sh b/ct/proxmox-mail-gateway.sh
index 654bbc4b1..30b1656a3 100644
--- a/ct/proxmox-mail-gateway.sh
+++ b/ct/proxmox-mail-gateway.sh
@@ -25,8 +25,8 @@ function update_script() {
check_container_resources
if [[ ! -e /usr/bin/pmgproxy ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP}"
exit
}
diff --git a/ct/ps5-mqtt.sh b/ct/ps5-mqtt.sh
index 2cf6bf5a9..c963e5b98 100644
--- a/ct/ps5-mqtt.sh
+++ b/ct/ps5-mqtt.sh
@@ -47,8 +47,8 @@ function update_script() {
msg_info "Building new PS5-MQTT version"
cd /opt/ps5-mqtt/ps5-mqtt/
- npm install &>/dev/null
- npm run build &>/dev/null
+ $STD npm install
+ $STD npm run build
msg_ok "Built new PS5-MQTT version"
msg_info "Starting service"
diff --git a/ct/qbittorrent.sh b/ct/qbittorrent.sh
index 94a4f645f..3d59d6010 100644
--- a/ct/qbittorrent.sh
+++ b/ct/qbittorrent.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/rabbitmq.sh b/ct/rabbitmq.sh
index 8b6fb156f..a9fa9d71f 100644
--- a/ct/rabbitmq.sh
+++ b/ct/rabbitmq.sh
@@ -32,7 +32,7 @@ function update_script() {
msg_ok "Stopped ${APP} Service"
msg_info "Updating..."
- apt install --only-upgrade rabbitmq-server &>/dev/null
+ $STD apt install --only-upgrade rabbitmq-server
msg_ok "Update Successfully"
msg_info "Starting ${APP}"
diff --git a/ct/radarr.sh b/ct/radarr.sh
index 6920406f3..b76b21e9d 100644
--- a/ct/radarr.sh
+++ b/ct/radarr.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/rdtclient.sh b/ct/rdtclient.sh
index ecb83e633..d7806ae2f 100755
--- a/ct/rdtclient.sh
+++ b/ct/rdtclient.sh
@@ -33,8 +33,8 @@ function update_script() {
msg_info "Updating ${APP}"
if dpkg-query -W dotnet-sdk-8.0 >/dev/null 2>&1; then
- apt-get remove --purge -y dotnet-sdk-8.0 &>/dev/null
- apt-get install -y dotnet-sdk-9.0 &>/dev/null
+ $STD apt-get remove --purge -y dotnet-sdk-8.0
+ $STD apt-get install -y dotnet-sdk-9.0
fi
mkdir -p rdtc-backup
cp -R /opt/rdtc/appsettings.json rdtc-backup/
diff --git a/ct/readarr.sh b/ct/readarr.sh
index 6a5adf414..4225ac9d4 100644
--- a/ct/readarr.sh
+++ b/ct/readarr.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/redis.sh b/ct/redis.sh
index a9eb8e4c9..3fe232b4e 100644
--- a/ct/redis.sh
+++ b/ct/redis.sh
@@ -27,7 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/rtsptoweb.sh b/ct/rtsptoweb.sh
index 791a64934..8d2a3fdec 100644
--- a/ct/rtsptoweb.sh
+++ b/ct/rtsptoweb.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/rustdeskserver.sh b/ct/rustdeskserver.sh
index b98543283..16e306126 100644
--- a/ct/rustdeskserver.sh
+++ b/ct/rustdeskserver.sh
@@ -40,7 +40,7 @@ function update_script() {
wget -q "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-hbbr_${RELEASE}_amd64.deb" -P $TEMPDIR
wget -q "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-hbbs_${RELEASE}_amd64.deb" -P $TEMPDIR
wget -q "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-utils_${RELEASE}_amd64.deb" -P $TEMPDIR
- dpkg -i $TEMPDIR/*.deb &> /dev/null
+ $STD dpkg -i $TEMPDIR/*.deb
msg_ok "Updated $APP to v${RELEASE}"
msg_info "Cleaning Up"
diff --git a/ct/sabnzbd.sh b/ct/sabnzbd.sh
index fbc789a98..ff884bbaa 100644
--- a/ct/sabnzbd.sh
+++ b/ct/sabnzbd.sh
@@ -31,16 +31,16 @@ function update_script() {
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating $APP to ${RELEASE}"
systemctl stop sabnzbd.service
- tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) &>/dev/null
- \cp -r SABnzbd-${RELEASE}/* /opt/sabnzbd &>/dev/null
+ tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz)
+ cp -rf SABnzbd-${RELEASE}/* /opt/sabnzbd
rm -rf SABnzbd-${RELEASE}
cd /opt/sabnzbd
- python3 -m pip install -r requirements.txt &>/dev/null
+ $STD python3 -m pip install -r requirements.txt
echo "${RELEASE}" >/opt/${APP}_version.txt
systemctl start sabnzbd.service
msg_ok "Updated ${APP} to ${RELEASE}"
else
- msg_info "No update required. ${APP} is already at ${RELEASE}"
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit
}
diff --git a/ct/seelf.sh b/ct/seelf.sh
index 481d6287f..40d0a47a0 100644
--- a/ct/seelf.sh
+++ b/ct/seelf.sh
@@ -44,7 +44,7 @@ function update_script() {
tar -xzf v${RELEASE}.tar.gz
cp -r seelf-${RELEASE}/ /opt/seelf
cd /opt/seelf
- make build &> /dev/null
+ $STD make build
msg_ok "Updated $APP to v${RELEASE}"
msg_info "Starting $APP"
diff --git a/ct/semaphore.sh b/ct/semaphore.sh
index 75d9ead1c..1524f4d82 100644
--- a/ct/semaphore.sh
+++ b/ct/semaphore.sh
@@ -37,7 +37,7 @@ function update_script() {
msg_info "Updating ${APP} to v${RELEASE}"
cd /opt
wget -q https://github.com/semaphoreui/semaphore/releases/download/v${RELEASE}/semaphore_${RELEASE}_linux_amd64.deb
- dpkg -i semaphore_${RELEASE}_linux_amd64.deb &>/dev/null
+ $STD dpkg -i semaphore_${RELEASE}_linux_amd64.deb
echo "${RELEASE}" >"/opt/${APP}_version.txt"
msg_ok "Updated ${APP} to v${RELEASE}"
diff --git a/ct/sftpgo.sh b/ct/sftpgo.sh
index a4417a21f..6dc2ccc13 100644
--- a/ct/sftpgo.sh
+++ b/ct/sftpgo.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/smokeping.sh b/ct/smokeping.sh
index 9527c9f95..ee53f0a35 100644
--- a/ct/smokeping.sh
+++ b/ct/smokeping.sh
@@ -29,8 +29,8 @@ function update_script() {
fi
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/snipeit.sh b/ct/snipeit.sh
index dd37443de..d6d74eba3 100644
--- a/ct/snipeit.sh
+++ b/ct/snipeit.sh
@@ -30,11 +30,11 @@ function update_script() {
RELEASE=$(curl -s https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating ${APP} to v${RELEASE}"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
mv /opt/snipe-it /opt/snipe-it-backup
cd /opt
- wget -q "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip" &>/dev/null
+ $STD wget -q "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip"
unzip -q v${RELEASE}.zip
mv snipe-it-${RELEASE} /opt/snipe-it
cp /opt/snipe-it-backup/.env /opt/snipe-it/.env
@@ -42,13 +42,13 @@ function update_script() {
cp -r /opt/snipe-it-backup/storage/private_uploads /opt/snipe-it/storage/private_uploads
cd /opt/snipe-it/
export COMPOSER_ALLOW_SUPERUSER=1
- composer install --no-dev --prefer-source &>/dev/null
- composer dump-autoload &>/dev/null
- php artisan migrate --force &>/dev/null
- php artisan config:clear &>/dev/null
- php artisan route:clear &>/dev/null
- php artisan cache:clear &>/dev/null
- php artisan view:clear &>/dev/null
+ $STD composer install --no-dev --prefer-source
+ $STD composer dump-autoload
+ $STD php artisan migrate --force
+ $STD php artisan config:clear
+ $STD php artisan route:clear
+ $STD php artisan cache:clear
+ $STD php artisan view:clear
chown -R www-data: /opt/snipe-it
chmod -R 755 /opt/snipe-it
rm -rf /opt/v${RELEASE}.zip
diff --git a/ct/spoolman.sh b/ct/spoolman.sh
index e82fee712..5527ce9a9 100644
--- a/ct/spoolman.sh
+++ b/ct/spoolman.sh
@@ -41,7 +41,7 @@ function update_script() {
wget -q https://github.com/Donkie/Spoolman/releases/download/${RELEASE}/spoolman.zip
unzip -q spoolman.zip -d spoolman
cd spoolman
- pip3 install -r requirements.txt >/dev/null 2>&1
+ $STD pip3 install -r requirements.txt
wget -q https://raw.githubusercontent.com/Donkie/Spoolman/master/.env.example -O .env
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to ${RELEASE}"
diff --git a/ct/sqlserver2022.sh b/ct/sqlserver2022.sh
index e5cd23c6f..bf5d2c74d 100644
--- a/ct/sqlserver2022.sh
+++ b/ct/sqlserver2022.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/stirling-pdf.sh b/ct/stirling-pdf.sh
index d4ee45fc1..ea9429f9d 100644
--- a/ct/stirling-pdf.sh
+++ b/ct/stirling-pdf.sh
@@ -30,15 +30,15 @@ function update_script() {
msg_info "Updating ${APP}"
systemctl stop stirlingpdf
if [[ -n $(dpkg -l | grep -w ocrmypdf) ]] && [[ -z $(dpkg -l | grep -w qpdf) ]]; then
- apt-get remove -y ocrmypdf &>/dev/null
- apt-get install -y qpdf &>/dev/null
+ $STD apt-get remove -y ocrmypdf
+ $STD apt-get install -y qpdf
fi
RELEASE=$(curl -s https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
wget -q https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz
tar -xzf v$RELEASE.tar.gz
cd Stirling-PDF-$RELEASE
chmod +x ./gradlew
- ./gradlew build &>/dev/null
+ $STD ./gradlew build
cp -r ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/
cp -r scripts /opt/Stirling-PDF/
cd ~
diff --git a/ct/syncthing.sh b/ct/syncthing.sh
index 8b9bb075f..900e92729 100644
--- a/ct/syncthing.sh
+++ b/ct/syncthing.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/tandoor.sh b/ct/tandoor.sh
index d271c01d2..68fa4459a 100644
--- a/ct/tandoor.sh
+++ b/ct/tandoor.sh
@@ -33,15 +33,15 @@ function update_script() {
msg_info "Updating ${APP} (Patience)"
export $(cat /opt/tandoor/.env | grep "^[^#]" | xargs)
cd /opt/tandoor/
- pip3 install -r requirements.txt >/dev/null 2>&1
- /usr/bin/python3 /opt/tandoor/manage.py migrate >/dev/null 2>&1
- /usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input >/dev/null 2>&1
- /usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse >/dev/null 2>&1
+ $STD pip3 install -r requirements.txt
+ $STD /usr/bin/python3 /opt/tandoor/manage.py migrate
+ $STD /usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input
+ $STD /usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse
cd /opt/tandoor/vue
- yarn install >/dev/null 2>&1
- yarn build >/dev/null 2>&1
+ $STD yarn install
+ $STD yarn build
cd /opt/tandoor
- python3 version.py &>/dev/null
+ $STD python3 version.py
systemctl restart gunicorn_tandoor
msg_ok "Updated ${APP}"
fi
diff --git a/ct/tasmoadmin.sh b/ct/tasmoadmin.sh
index e351bd8c6..23bd7eb5c 100644
--- a/ct/tasmoadmin.sh
+++ b/ct/tasmoadmin.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/tasmocompiler.sh b/ct/tasmocompiler.sh
index 275b31fa0..6bbc0b498 100644
--- a/ct/tasmocompiler.sh
+++ b/ct/tasmocompiler.sh
@@ -40,10 +40,10 @@ function update_script() {
tar xzf v${RELEASE}.tar.gz
mv tasmocompiler-${RELEASE}/ /opt/tasmocompiler/
cd /opt/tasmocompiler
- yarn install &> /dev/null
+ $STD yarn install
export NODE_OPTIONS=--openssl-legacy-provider
- npm i &> /dev/null
- yarn build &> /dev/null
+ $STD npm i
+ $STD yarn build
msg_ok "Updated $APP to v${RELEASE}"
msg_info "Starting $APP"
systemctl start tasmocompiler
diff --git a/ct/tautulli.sh b/ct/tautulli.sh
index 2d62bc91b..11c6c8f90 100644
--- a/ct/tautulli.sh
+++ b/ct/tautulli.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/tdarr.sh b/ct/tdarr.sh
index cdd894c3b..e0cf0c480 100644
--- a/ct/tdarr.sh
+++ b/ct/tdarr.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/technitiumdns.sh b/ct/technitiumdns.sh
index 52d2e9a05..5bdb26719 100644
--- a/ct/technitiumdns.sh
+++ b/ct/technitiumdns.sh
@@ -31,12 +31,12 @@ function update_script() {
if ! dpkg -s aspnetcore-runtime-8.0 >/dev/null 2>&1; then
wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb
- dpkg -i packages-microsoft-prod.deb &>/dev/null
- apt-get update &>/dev/null
- apt-get install -y aspnetcore-runtime-8.0 &>/dev/null
+ $STD dpkg -i packages-microsoft-prod.deb
+ $STD apt-get update
+ $STD apt-get install -y aspnetcore-runtime-8.0
rm packages-microsoft-prod.deb
fi
- bash <(curl -fsSL https://download.technitium.com/dns/install.sh) &>/dev/null
+ $STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh)
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/the-lounge.sh b/ct/the-lounge.sh
index 23cc28820..6ec2eab9e 100644
--- a/ct/the-lounge.sh
+++ b/ct/the-lounge.sh
@@ -34,7 +34,7 @@ function update_script() {
msg_ok "Stopped Service"
msg_info "Updating ${APP} to v${RELEASE}"
- apt-get install --only-upgrade nodejs &>/dev/null
+ $STD apt-get install --only-upgrade nodejs
cd /opt
wget -q https://github.com/thelounge/thelounge-deb/releases/download/v${RELEASE}/thelounge_${RELEASE}_all.deb
dpkg -i ./thelounge_${RELEASE}_all.deb
diff --git a/ct/tianji.sh b/ct/tianji.sh
index fc5a443b2..628bd47e0 100644
--- a/ct/tianji.sh
+++ b/ct/tianji.sh
@@ -41,15 +41,15 @@ function update_script() {
mv tianji-${RELEASE} /opt/tianji
cd tianji
export NODE_OPTIONS="--max_old_space_size=4096"
- pnpm install --filter @tianji/client... --config.dedupe-peer-dependents=false --frozen-lockfile >/dev/null 2>&1
- pnpm build:static >/dev/null 2>&1
- pnpm install --filter @tianji/server... --config.dedupe-peer-dependents=false >/dev/null 2>&1
- mkdir -p ./src/server/public >/dev/null 2>&1
- cp -r ./geo ./src/server/public >/dev/null 2>&1
- pnpm build:server >/dev/null 2>&1
+ $STD pnpm install --filter @tianji/client... --config.dedupe-peer-dependents=false --frozen-lockfile
+ $STD pnpm build:static
+ $STD pnpm install --filter @tianji/server... --config.dedupe-peer-dependents=false
+ mkdir -p ./src/server/public
+ cp -r ./geo ./src/server/public
+ $STD pnpm build:server
mv /opt/.env /opt/tianji/src/server/.env
cd src/server
- pnpm db:migrate:apply >/dev/null 2>&1
+ $STD pnpm db:migrate:apply
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to v${RELEASE}"
diff --git a/ct/traccar.sh b/ct/traccar.sh
index b7aae151a..ad7db8c4b 100644
--- a/ct/traccar.sh
+++ b/ct/traccar.sh
@@ -27,8 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "There is currently no update path available."
- exit
+ msg_error "Currently we don't provide an update function for this ${APP}."
exit
}
diff --git a/ct/transmission.sh b/ct/transmission.sh
index 4cbc6398f..bc0376c85 100644
--- a/ct/transmission.sh
+++ b/ct/transmission.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/typesense.sh b/ct/typesense.sh
index f17dbce9e..8aed10a67 100644
--- a/ct/typesense.sh
+++ b/ct/typesense.sh
@@ -30,8 +30,8 @@ function update_script() {
RELEASE=$(curl -s https://api.github.com/repos/typesense/typesense/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
diff --git a/ct/ubuntu.sh b/ct/ubuntu.sh
index 6be9d3acf..3e089012e 100644
--- a/ct/ubuntu.sh
+++ b/ct/ubuntu.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/umbrel.sh b/ct/umbrel.sh
index 49a6527fd..2b5758d73 100644
--- a/ct/umbrel.sh
+++ b/ct/umbrel.sh
@@ -24,8 +24,8 @@ function update_script() {
check_container_storage
check_container_resources
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/unbound.sh b/ct/unbound.sh
index 27e684ee8..448dbb2c2 100644
--- a/ct/unbound.sh
+++ b/ct/unbound.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/unifi.sh b/ct/unifi.sh
index 9895c0428..985e352d0 100644
--- a/ct/unifi.sh
+++ b/ct/unifi.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP}"
- apt-get update --allow-releaseinfo-change &>/dev/null
- apt-get install -y unifi &>/dev/null
+ $STD apt-get update --allow-releaseinfo-change
+ $STD apt-get install -y unifi
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/unmanic.sh b/ct/unmanic.sh
index 9050225e1..c488a39c9 100644
--- a/ct/unmanic.sh
+++ b/ct/unmanic.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- pip3 install -U unmanic &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD pip3 install -U unmanic
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/uptimekuma.sh b/ct/uptimekuma.sh
index 5c8669555..c1660497a 100644
--- a/ct/uptimekuma.sh
+++ b/ct/uptimekuma.sh
@@ -30,29 +30,29 @@ function update_script() {
if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then
if ! command -v npm >/dev/null 2>&1; then
echo "Installing NPM..."
- apt-get install -y npm >/dev/null 2>&1
+ $STD apt-get install -y npm
echo "Installed NPM..."
fi
fi
LATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
msg_info "Stopping ${APP}"
- sudo systemctl stop uptime-kuma &>/dev/null
+ $STD sudo systemctl stop uptime-kuma
msg_ok "Stopped ${APP}"
cd /opt/uptime-kuma
msg_info "Pulling ${APP} ${LATEST}"
- git fetch --all &>/dev/null
- git checkout $LATEST --force &>/dev/null
+ $STD git fetch --all
+ $STD git checkout $LATEST --force
msg_ok "Pulled ${APP} ${LATEST}"
msg_info "Updating ${APP} to ${LATEST}"
- npm install --production &>/dev/null
- npm run download-dist &>/dev/null
+ $STD npm install --production
+ $STD npm run download-dist
msg_ok "Updated ${APP}"
msg_info "Starting ${APP}"
- sudo systemctl start uptime-kuma &>/dev/null
+ $STD sudo systemctl start uptime-kuma
msg_ok "Started ${APP}"
msg_ok "Updated Successfully"
exit
diff --git a/ct/urbackupserver.sh b/ct/urbackupserver.sh
index 5383002b3..d60372faf 100644
--- a/ct/urbackupserver.sh
+++ b/ct/urbackupserver.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh
index 9e317c7ae..4cb7565eb 100644
--- a/ct/vaultwarden.sh
+++ b/ct/vaultwarden.sh
@@ -48,9 +48,9 @@ function update_script() {
msg_info "Updating VaultWarden to $VAULT (Patience)"
cd ~ && rm -rf vaultwarden
- git clone https://github.com/dani-garcia/vaultwarden &>/dev/null
+ $STD git clone https://github.com/dani-garcia/vaultwarden
cd vaultwarden
- cargo build --features "sqlite,mysql,postgresql" --release &>/dev/null
+ $STD cargo build --features "sqlite,mysql,postgresql" --release
DIR=/usr/bin/vaultwarden
if [ -d "$DIR" ]; then
cp target/release/vaultwarden /usr/bin/
@@ -76,8 +76,8 @@ function update_script() {
msg_ok "Stopped Vaultwarden"
msg_info "Updating Web-Vault to $WVRELEASE"
- curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WVRELEASE/bw_web_$WVRELEASE.tar.gz &>/dev/null
- tar -zxf bw_web_$WVRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null
+ $STD curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WVRELEASE/bw_web_$WVRELEASE.tar.gz
+ $STD tar -zxf bw_web_$WVRELEASE.tar.gz -C /opt/vaultwarden/
msg_ok "Updated Web-Vault"
msg_info "Cleaning up"
@@ -93,7 +93,7 @@ function update_script() {
if [ "$UPD" == "3" ]; then
if NEWTOKEN=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Set the ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then
if [[ -z "$NEWTOKEN" ]]; then exit; fi
- if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi
+ if ! command -v argon2 >/dev/null 2>&1; then $STD apt-get install -y argon2; fi
TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e)
sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env
if [[ -f /opt/vaultwarden/data/config.json ]]; then
diff --git a/ct/victoriametrics.sh b/ct/victoriametrics.sh
new file mode 100644
index 000000000..10ef77c40
--- /dev/null
+++ b/ct/victoriametrics.sh
@@ -0,0 +1,69 @@
+#!/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: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/VictoriaMetrics/VictoriaMetrics
+
+APP="VictoriaMetrics"
+var_tags="database"
+var_cpu="2"
+var_ram="2048"
+var_disk="16"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /opt/victoriametrics ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/VictoriaMetrics/VictoriaMetrics/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 $APP"
+ systemctl stop victoriametrics
+ msg_ok "Stopped $APP"
+
+ msg_info "Updating ${APP} to v${RELEASE}"
+ temp_dir=$(mktemp -d)
+ cd $temp_dir
+ wget -q https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v${RELEASE}/victoria-metrics-linux-amd64-v${RELEASE}.tar.gz
+ wget -q https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v${RELEASE}/vmutils-linux-amd64-v${RELEASE}.tar.gz
+ find /opt/victoriametrics -maxdepth 1 -type f -executable -delete
+ tar -xf victoria-metrics-linux-amd64-v${RELEASE}.tar.gz -C /opt/victoriametrics
+ tar -xf vmutils-linux-amd64-v${RELEASE}.tar.gz -C /opt/victoriametrics
+ chmod +x /opt/victoriametrics/*
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated $APP to v${RELEASE}"
+
+ msg_info "Starting $APP"
+ systemctl start victoriametrics
+ msg_ok "Started $APP"
+
+ msg_info "Cleaning Up"
+ rm -rf $temp_dir
+ msg_ok "Cleaned"
+ msg_ok "Updated Successfully"
+ 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} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8428/vmui${CL}"
diff --git a/ct/vikunja.sh b/ct/vikunja.sh
index 62da510c8..b7aaac3b0 100644
--- a/ct/vikunja.sh
+++ b/ct/vikunja.sh
@@ -37,7 +37,8 @@ function update_script() {
cd /opt
rm -rf /opt/vikunja/vikunja
wget -q "https://dl.vikunja.io/vikunja/$RELEASE/vikunja-$RELEASE-amd64.deb"
- DEBIAN_FRONTEND=noninteractive dpkg -i vikunja-$RELEASE-amd64.deb &>/dev/null
+ export DEBIAN_FRONTEND=noninteractive
+ $STD dpkg -i vikunja-$RELEASE-amd64.deb
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP}"
diff --git a/ct/wallos.sh b/ct/wallos.sh
index 59e5be581..5407cd6ef 100644
--- a/ct/wallos.sh
+++ b/ct/wallos.sh
@@ -44,7 +44,7 @@ function update_script() {
chown -R www-data:www-data /opt/wallos
chmod -R 755 /opt/wallos
mkdir -p /var/log/cron
- curl http://localhost/endpoints/db/migrate.php &>/dev/null
+ $STD curl http://localhost/endpoints/db/migrate.php
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP}"
diff --git a/ct/watcharr.sh b/ct/watcharr.sh
index dd0f7835a..73daf7fc3 100644
--- a/ct/watcharr.sh
+++ b/ct/watcharr.sh
@@ -45,8 +45,8 @@ function update_script() {
cp -rf ${temp_folder}/Watcharr-${RELEASE}/* /opt/watcharr
cd /opt/watcharr
export GOOS=linux
- npm i &> /dev/null
- npm run build &> /dev/null
+ $STD npm i
+ $STD npm run build
mv ./build ./server/ui
cd server
go mod download
diff --git a/ct/web-check.sh b/ct/web-check.sh
new file mode 100644
index 000000000..fe4428fd4
--- /dev/null
+++ b/ct/web-check.sh
@@ -0,0 +1,41 @@
+#!/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: CrazyWolf13
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/Lissy93/web-check
+
+APP="web-check"
+TAGS="network;analysis"
+var_cpu="2"
+var_ram="2048"
+var_disk="12"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /opt/web-check ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ msg_error "Currently we don't provide an update function for this ${APP}."
+ 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}:3000${CL}"
diff --git a/ct/wger.sh b/ct/wger.sh
new file mode 100644
index 000000000..3b017dd76
--- /dev/null
+++ b/ct/wger.sh
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+source <(curl -s https://raw.githubusercontent.com/tremor021/ProxmoxVE/refs/heads/wger/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/wger-project/wger
+
+APP="wger"
+var_tags="management;fitness"
+var_cpu="1"
+var_ram="1024"
+var_disk="6"
+var_os="debian"
+var_version="12"
+var_unprivileged="1"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /home/wger ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/wger-project/wger/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
+ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
+ msg_info "Stopping $APP"
+ systemctl stop wger
+ msg_ok "Stopped $APP"
+
+ msg_info "Updating $APP to v${RELEASE}"
+ temp_file=$(mktemp)
+ cd $temp_file
+ wget -q "https://github.com/wger-project/wger/archive/refs/tags/$RELEASE.tar.gz" -O $temp_file
+ tar xzf $temp_file
+ cp -rf wger-$RELEASE/* /home/wger/src
+ cd /home/wger/src
+ python3 manage.py migrate &>/dev/null
+ yarn install &>/dev/null
+ yarn build:css:sass &>/dev/null
+ python3 manage.py collectstatic --noinput &>/dev/null
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated $APP to v${RELEASE}"
+
+ msg_info "Starting $APP"
+ systemctl start wger
+ msg_ok "Started $APP"
+
+ msg_info "Cleaning Up"
+ rm -rf $temp_file
+ msg_ok "Cleanup Completed"
+
+ msg_ok "Update Successful"
+ 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}:3000${CL}"
diff --git a/ct/whisparr.sh b/ct/whisparr.sh
index aa6e02349..e128d3d5b 100644
--- a/ct/whisparr.sh
+++ b/ct/whisparr.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/whoogle.sh b/ct/whoogle.sh
index e7071043f..2b21b8dcf 100644
--- a/ct/whoogle.sh
+++ b/ct/whoogle.sh
@@ -28,7 +28,7 @@ function update_script() {
exit
fi
msg_info "Updating ${APP} LXC"
- pip3 install whoogle-search --upgrade &>/dev/null
+ $STD pip3 install whoogle-search --upgrade
systemctl restart whoogle.service
msg_ok "Updated Successfully"
exit
diff --git a/ct/wikijs.sh b/ct/wikijs.sh
index 4fab17d2e..ee65e4c86 100644
--- a/ct/wikijs.sh
+++ b/ct/wikijs.sh
@@ -46,7 +46,7 @@ function update_script() {
msg_info "Restoring Data"
cp -R ~/data-backup/* /opt/wikijs
rm -rf ~/data-backup
- npm rebuild sqlite3 &>/dev/null
+ $STD npm rebuild sqlite3
msg_ok "Restored Data"
msg_info "Starting ${APP}"
diff --git a/ct/wireguard.sh b/ct/wireguard.sh
index 9016b96d5..36c75a9e7 100644
--- a/ct/wireguard.sh
+++ b/ct/wireguard.sh
@@ -32,6 +32,7 @@ function update_script() {
sleep 2
cd /etc/wgdashboard/src
./wgd.sh update
+ ./wgd.sh start
exit
}
@@ -42,4 +43,4 @@ description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} WGDashboard Access it using the following URL:${CL}"
-echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:10086${CL}"
\ No newline at end of file
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:10086${CL}"
diff --git a/ct/yunohost.sh b/ct/yunohost.sh
index 7a31e4d5f..ad7d7583d 100644
--- a/ct/yunohost.sh
+++ b/ct/yunohost.sh
@@ -28,8 +28,8 @@ function update_script() {
exit
fi
msg_info "Updating $APP LXC"
- apt-get update &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit
}
diff --git a/ct/zabbix.sh b/ct/zabbix.sh
index f4770a919..bac537bd2 100644
--- a/ct/zabbix.sh
+++ b/ct/zabbix.sh
@@ -40,9 +40,9 @@ function update_script() {
rm -Rf /etc/apt/sources.list.d/zabbix.list
cd /tmp
wget -q https://repo.zabbix.com/zabbix/7.2/release/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian12_all.deb
- dpkg -i zabbix-release_latest+debian12_all.deb &>/dev/null
- apt-get update &>/dev/null
- apt-get install --only-upgrade zabbix-server-pgsql zabbix-frontend-php zabbix-agent2 zabbix-agent2-plugin-* &>/dev/null
+ $STD dpkg -i zabbix-release_latest+debian12_all.deb
+ $STD apt-get update
+ $STD apt-get install --only-upgrade zabbix-server-pgsql zabbix-frontend-php zabbix-agent2 zabbix-agent2-plugin-*
msg_info "Starting ${APP} Services"
systemctl start zabbix-server zabbix-agent2
diff --git a/ct/zammad.sh b/ct/zammad.sh
index a28662a4b..3e3e355b4 100644
--- a/ct/zammad.sh
+++ b/ct/zammad.sh
@@ -28,15 +28,15 @@ function update_script() {
exit
fi
msg_info "Stopping Service"
- systemctl stop zammad &>/dev/null
+ $STD systemctl stop zammad
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
- apt-mark hold zammad &>/dev/null
- apt-get -y upgrade &>/dev/null
- apt-mark unhold zammad &>/dev/null
- apt-get -y upgrade &>/dev/null
+ $STD apt-get update
+ $STD apt-mark hold zammad
+ $STD apt-get -y upgrade
+ $STD apt-mark unhold zammad
+ $STD apt-get -y upgrade
msg_info "Starting Service"
- systemctl start zammad &>/dev/null
+ $STD systemctl start zammad
msg_ok "Updated ${APP} LXC"
exit
}
diff --git a/ct/zerotier-one.sh b/ct/zerotier-one.sh
index f8a94787d..ecbd8ac0e 100644
--- a/ct/zerotier-one.sh
+++ b/ct/zerotier-one.sh
@@ -33,7 +33,7 @@ function update_script() {
systemctl stop zerotier-one
msg_ok "Stopping Service"
msg_info "Updating ${APP}"
- apt-get update &>/dev/null
+ $STD apt-get update
apt-get -y upgrade
msg_ok "Updated ${APP}"
diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh
index 8af3d1719..b45f34eee 100644
--- a/ct/zigbee2mqtt.sh
+++ b/ct/zigbee2mqtt.sh
@@ -33,10 +33,14 @@ function update_script() {
systemctl stop zigbee2mqtt
msg_ok "Stopped Service"
+ msg_info "Updating pnpm"
+ $STD npm install -g pnpm@10.4.1
+ msg_ok "Updated pnpm"
+
msg_info "Creating Backup"
rm -rf /opt/${APP}_backup*.tar.gz
mkdir -p /opt/z2m_backup
- tar -czf /opt/z2m_backup/${APP}_backup_$(date +%Y%m%d%H%M%S).tar.gz -C /opt zigbee2mqtt &>/dev/null
+ $STD tar -czf /opt/z2m_backup/${APP}_backup_$(date +%Y%m%d%H%M%S).tar.gz -C /opt zigbee2mqtt
mv /opt/zigbee2mqtt/data /opt/z2m_backup
msg_ok "Backup Created"
@@ -49,8 +53,8 @@ function update_script() {
rm -rf /opt/zigbee2mqtt/data
mv /opt/z2m_backup/data /opt/zigbee2mqtt
cd /opt/zigbee2mqtt
- pnpm install --frozen-lockfile &>/dev/null
- pnpm build &>/dev/null
+ $STD pnpm install --frozen-lockfile
+ $STD pnpm build
msg_ok "Updated Zigbee2MQTT"
msg_info "Starting Service"
diff --git a/ct/zipline.sh b/ct/zipline.sh
index fce9027db..11a86a390 100644
--- a/ct/zipline.sh
+++ b/ct/zipline.sh
@@ -29,7 +29,7 @@ function update_script() {
if ! command -v pnpm &>/dev/null; then
msg_info "Installing pnpm"
#export NODE_OPTIONS=--openssl-legacy-provider
- npm install -g pnpm@latest &>/dev/null
+ $STD npm install -g pnpm@latest
msg_ok "Installed pnpm"
fi
RELEASE=$(curl -s https://api.github.com/repos/diced/zipline/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
@@ -46,8 +46,8 @@ function update_script() {
mv zipline-${RELEASE} /opt/zipline
cd /opt/zipline
mv /opt/.env /opt/zipline/.env
- pnpm install &>/dev/null
- pnpm build &>/dev/null
+ $STD pnpm install
+ $STD pnpm build
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP}"
diff --git a/ct/zitadel.sh b/ct/zitadel.sh
index ce97e205a..f3f99c361 100644
--- a/ct/zitadel.sh
+++ b/ct/zitadel.sh
@@ -37,7 +37,7 @@ function update_script() {
cd /tmp
wget -qc https://github.com/zitadel/zitadel/releases/download/$RELEASE/zitadel-linux-amd64.tar.gz -O - | tar -xz
mv zitadel-linux-amd64/zitadel /usr/local/bin
- zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml --init-projections=true &>/dev/null
+ $STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml --init-projections=true
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to ${RELEASE}"
diff --git a/frontend/src/app/data/page.tsx b/frontend/src/app/data/page.tsx
index e78b4a675..b75246484 100644
--- a/frontend/src/app/data/page.tsx
+++ b/frontend/src/app/data/page.tsx
@@ -1,6 +1,6 @@
"use client";
-import React, { useEffect, useState } from "react";
+import React, { JSX, useEffect, useState } from "react";
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import ApplicationChart from "../../components/ApplicationChart";
@@ -21,28 +21,45 @@ interface DataModel {
status: string;
error: string;
type: string;
+ [key: string]: any;
}
+interface SummaryData {
+ total_entries: number;
+ status_count: Record;
+ nsapp_count: Record;
+}
const DataFetcher: React.FC = () => {
const [data, setData] = useState([]);
+ const [summary, setSummary] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
- const [searchQuery, setSearchQuery] = useState('');
- const [startDate, setStartDate] = useState(null);
- const [endDate, setEndDate] = useState(null);
- const [sortConfig, setSortConfig] = useState<{ key: keyof DataModel | null, direction: 'ascending' | 'descending' }>({ key: 'id', direction: 'descending' });
- const [itemsPerPage, setItemsPerPage] = useState(25);
const [currentPage, setCurrentPage] = useState(1);
-
- const [showErrorRow, setShowErrorRow] = useState(null);
-
+ const [itemsPerPage, setItemsPerPage] = useState(25);
+ const [sortConfig, setSortConfig] = useState<{ key: string; direction: 'ascending' | 'descending' } | null>(null);
useEffect(() => {
- const fetchData = async () => {
+ const fetchSummary = async () => {
try {
- const response = await fetch("https://api.htl-braunau.at/data/json");
- if (!response.ok) throw new Error("Failed to fetch data: ${response.statusText}");
+ const response = await fetch("https://api.htl-braunau.at/data/summary");
+ if (!response.ok) throw new Error(`Failed to fetch summary: ${response.statusText}`);
+ const result: SummaryData = await response.json();
+ setSummary(result);
+ } catch (err) {
+ setError((err as Error).message);
+ }
+ };
+
+ fetchSummary();
+ }, []);
+
+ useEffect(() => {
+ const fetchPaginatedData = async () => {
+ setLoading(true);
+ try {
+ const response = await fetch(`https://api.htl-braunau.at/data/paginated?page=${currentPage}&limit=${itemsPerPage === 0 ? '' : itemsPerPage}`);
+ if (!response.ok) throw new Error(`Failed to fetch data: ${response.statusText}`);
const result: DataModel[] = await response.json();
setData(result);
} catch (err) {
@@ -52,52 +69,34 @@ const DataFetcher: React.FC = () => {
}
};
- fetchData();
- }, []);
-
-
- const filteredData = data.filter(item => {
- const matchesSearchQuery = Object.values(item).some(value =>
- value.toString().toLowerCase().includes(searchQuery.toLowerCase())
- );
- const itemDate = new Date(item.created_at);
- const matchesDateRange = (!startDate || itemDate >= startDate) && (!endDate || itemDate <= endDate);
- return matchesSearchQuery && matchesDateRange;
- });
+ fetchPaginatedData();
+ }, [currentPage, itemsPerPage]);
const sortedData = React.useMemo(() => {
- let sortableData = [...filteredData];
- if (sortConfig.key !== null) {
- sortableData.sort((a, b) => {
- if (sortConfig.key !== null && a[sortConfig.key] < b[sortConfig.key]) {
- return sortConfig.direction === 'ascending' ? -1 : 1;
- }
- if (sortConfig.key !== null && a[sortConfig.key] > b[sortConfig.key]) {
- return sortConfig.direction === 'ascending' ? 1 : -1;
- }
- return 0;
- });
- }
- return sortableData;
- }, [filteredData, sortConfig]);
+ if (!sortConfig) return data;
+ const sorted = [...data].sort((a, b) => {
+ if (a[sortConfig.key] < b[sortConfig.key]) {
+ return sortConfig.direction === 'ascending' ? -1 : 1;
+ }
+ if (a[sortConfig.key] > b[sortConfig.key]) {
+ return sortConfig.direction === 'ascending' ? 1 : -1;
+ }
+ return 0;
+ });
+ return sorted;
+ }, [data, sortConfig]);
- const requestSort = (key: keyof DataModel | null) => {
+ if (loading) return Loading...
;
+ if (error) return Error: {error}
;
+
+ const requestSort = (key: string) => {
let direction: 'ascending' | 'descending' = 'ascending';
- if (sortConfig.key === key && sortConfig.direction === 'ascending') {
- direction = 'descending';
- } else if (sortConfig.key === key && sortConfig.direction === 'descending') {
- direction = 'ascending';
- } else {
+ if (sortConfig && sortConfig.key === key && sortConfig.direction === 'ascending') {
direction = 'descending';
}
setSortConfig({ key, direction });
};
- interface SortConfig {
- key: keyof DataModel | null;
- direction: 'ascending' | 'descending';
- }
-
const formatDate = (dateString: string): string => {
const date = new Date(dateString);
const year = date.getFullYear();
@@ -109,86 +108,15 @@ const DataFetcher: React.FC = () => {
return `${day}.${month}.${year} ${hours}:${minutes} ${timezoneOffset} GMT`;
};
- const handleItemsPerPageChange = (event: React.ChangeEvent) => {
- setItemsPerPage(Number(event.target.value));
- setCurrentPage(1);
- };
-
- const paginatedData = sortedData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
-
-
- if (loading) return Loading...
;
- if (error) return Error: {error}
;
-
- var installingCounts: number = 0;
- var failedCounts: number = 0;
- var doneCounts: number = 0
- var unknownCounts: number = 0;
- data.forEach((item) => {
- if (item.status === "installing") {
- installingCounts += 1;
- } else if (item.status === "failed") {
- failedCounts += 1;
- }
- else if (item.status === "done") {
- doneCounts += 1;
- }
- else {
- unknownCounts += 1;
- }
- });
-
return (
Created LXCs
-
-
- setSearchQuery(e.target.value)}
- className="p-2 border"
- />
-
-
-
- setStartDate(date)}
- selectsStart
- startDate={startDate}
- endDate={endDate}
- placeholderText="Start date"
- className="p-2 border"
- />
-
-
-
-
- setEndDate(date)}
- selectsEnd
- startDate={startDate}
- endDate={endDate}
- placeholderText="End date"
- className="p-2 border"
- />
-
-
-
-
+
+
-
{filteredData.length} results found
-
Status Legend: π installing {installingCounts} | βοΈ completetd {doneCounts} | β failed {failedCounts} | β unknown {unknownCounts}
-
-
+
{summary?.total_entries} results found
+
Status Legend: π installing {summary?.status_count["installing"] ?? 0} | βοΈ completed {summary?.status_count["done"] ?? 0} | β failed {summary?.status_count["failed"] ?? 0} | β unknown
+
@@ -209,7 +137,7 @@ const DataFetcher: React.FC = () => {
- {paginatedData.map((item, index) => (
+ {sortedData.map((item, index) => (
|
{item.status === "done" ? (
@@ -237,20 +165,7 @@ const DataFetcher: React.FC = () => {
| {item.ram_size} |
{item.method} |
{item.pve_version} |
-
- {item.error && item.error !== "none" ? (
- showErrorRow === index ? (
- <>
- {item.error}
-
- >
- ) : (
-
- )
- ) : (
- "none"
- )}
- |
+ {item.error} |
{formatDate(item.created_at)} |
))}
@@ -259,26 +174,25 @@ const DataFetcher: React.FC = () => {
-
+
Page {currentPage}
-
+
+
+
+
+
+
+
+
);
};
-
-
export default DataFetcher;
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
index ef6ac54b5..657f23721 100644
--- a/frontend/src/app/page.tsx
+++ b/frontend/src/app/page.tsx
@@ -116,19 +116,15 @@ export default function Page() {
Make managing your Homelab a breeze
-
- This project aims to take the community-made Proxmox Helper Scripts, originally started by tteck, and port it to arm64.
-
-
- Originally created by{" "}
-
- tteck
-
- , these scripts automate and streamline
-
- the process of creating and configuring Linux containers (LXC) and
- virtual machines (VMs) on Proxmox VE.
-
+
+ We are a community-driven initiative that simplifies the setup
+ of Proxmox Virtual Environment (VE).
+
+
+ With 300+ scripts to help you manage your{" "}
+ Proxmox VE environment. Whether you're a seasoned
+ user or a newcomer, we've got you covered.
+
diff --git a/frontend/src/app/scripts/_components/ScriptItem.tsx b/frontend/src/app/scripts/_components/ScriptItem.tsx
index 1dd416c40..6b1a73c47 100644
--- a/frontend/src/app/scripts/_components/ScriptItem.tsx
+++ b/frontend/src/app/scripts/_components/ScriptItem.tsx
@@ -28,6 +28,10 @@ function ScriptItem({
setSelectedScript(null);
};
+ const defaultInstallMethod = item.install_methods?.[0];
+ const os = defaultInstallMethod?.resources?.os || "Proxmox Node";
+ const version = defaultInstallMethod?.resources?.version || "";
+
return (
@@ -60,6 +64,9 @@ function ScriptItem({
Date added: {extractDate(item.date_created)}
+
+ Default OS: {os} {version}
+
diff --git a/frontend/src/app/scripts/_components/ScriptItems/Buttons.tsx b/frontend/src/app/scripts/_components/ScriptItems/Buttons.tsx
index 94964fb6d..127ccf330 100644
--- a/frontend/src/app/scripts/_components/ScriptItems/Buttons.tsx
+++ b/frontend/src/app/scripts/_components/ScriptItems/Buttons.tsx
@@ -1,14 +1,23 @@
import { Button } from "@/components/ui/button";
import { basePath } from "@/config/siteConfig";
import { Script } from "@/lib/types";
-import { BookOpenText, Code, Globe } from "lucide-react";
+import { BookOpenText, Code, Globe, RefreshCcw } from "lucide-react";
import Link from "next/link";
+const generateInstallSourceUrl = (slug: string) => {
+ const baseUrl = `https://raw.githubusercontent.com/asykynexo/${basePath}/main`;
+ return `${baseUrl}/install/${slug}-install.sh`;
+};
+
const generateSourceUrl = (slug: string, type: string) => {
const baseUrl = `https://raw.githubusercontent.com/asylumexp/${basePath}/main`;
- return type === "ct"
- ? `${baseUrl}/install/${slug}-install.sh`
- : `${baseUrl}/${type}/${slug}.sh`;
+ return type === "vm" ? `${baseUrl}/vm/${slug}.sh` : `${baseUrl}/misc/${slug}.sh`;
+ return `${baseUrl}/misc/${slug}.sh`;
+};
+
+const generateUpdateUrl = (slug: string) => {
+ const baseUrl = `https://raw.githubusercontent.com/asylumexp/${basePath}/main`;
+ return `${baseUrl}/ct/${slug}.sh`;
};
interface ButtonLinkProps {
@@ -29,20 +38,35 @@ const ButtonLink = ({ href, icon, text }: ButtonLinkProps) => (
);
export default function Buttons({ item }: { item: Script }) {
+ const isCtOrDefault = ["ct"].includes(item.type);
+ const installSourceUrl = isCtOrDefault ? generateInstallSourceUrl(item.slug) : null;
+ const updateSourceUrl = isCtOrDefault ? generateUpdateUrl(item.slug) : null;
+ const sourceUrl = !isCtOrDefault ? generateSourceUrl(item.slug, item.type) : null;
+
const buttons = [
item.website && {
href: item.website,
- icon:
,
+ icon:
,
text: "Website",
},
item.documentation && {
href: item.documentation,
- icon:
,
+ icon:
,
text: "Documentation",
},
- {
- href: generateSourceUrl(item.slug, item.type),
- icon:
,
+ installSourceUrl && {
+ href: installSourceUrl,
+ icon:
,
+ text: "Install-Source",
+ },
+ updateSourceUrl && {
+ href: updateSourceUrl,
+ icon:
,
+ text: "Update-Source",
+ },
+ sourceUrl && {
+ href: sourceUrl,
+ icon:
,
text: "Source Code",
},
].filter(Boolean) as ButtonLinkProps[];
diff --git a/frontend/src/components/ApplicationChart.tsx b/frontend/src/components/ApplicationChart.tsx
index e62c10961..f70fa7098 100644
--- a/frontend/src/components/ApplicationChart.tsx
+++ b/frontend/src/components/ApplicationChart.tsx
@@ -25,12 +25,16 @@ import { Chart as ChartJS, ArcElement, Tooltip as ChartTooltip, Legend } from "c
import ChartDataLabels from "chartjs-plugin-datalabels";
import { BarChart3, PieChart } from "lucide-react";
import React, { useState } from "react";
-import { Pie } from "react-chartjs-2";
+import { Pie, Bar } from "react-chartjs-2";
ChartJS.register(ArcElement, ChartTooltip, Legend, ChartDataLabels);
+interface SummaryData {
+ nsapp_count: Record
;
+}
+
interface ApplicationChartProps {
- data: { nsapp: string }[];
+ data: SummaryData | null;
}
const ITEMS_PER_PAGE = 20;
@@ -57,13 +61,9 @@ export default function ApplicationChart({ data }: ApplicationChartProps) {
const [chartStartIndex, setChartStartIndex] = useState(0);
const [tableLimit, setTableLimit] = useState(ITEMS_PER_PAGE);
- // Calculate application counts
- const appCounts = data.reduce((acc, item) => {
- acc[item.nsapp] = (acc[item.nsapp] || 0) + 1;
- return acc;
- }, {} as Record);
+ if (!data) return null;
- const sortedApps = Object.entries(appCounts)
+ const sortedApps = Object.entries(data.nsapp_count)
.sort(([, a], [, b]) => b - a);
const chartApps = sortedApps.slice(
diff --git a/frontend/src/components/ui/code-copy-button.tsx b/frontend/src/components/ui/code-copy-button.tsx
index 6c79ce793..edcf0d0e4 100644
--- a/frontend/src/components/ui/code-copy-button.tsx
+++ b/frontend/src/components/ui/code-copy-button.tsx
@@ -37,10 +37,6 @@ export default function CodeCopyButton({
);
}, 500);
}
-
- // toast.success(`copied ${type} to clipboard`, {
- // icon: ,
- // });
};
return (
@@ -49,17 +45,17 @@ export default function CodeCopyButton({
{!isMobile && children ? children : "Copy install command"}
- handleCopy("install command", children)}
+ className={cn("bg-muted px-3 py-4")}
+ title="Copy"
>
{hasCopied ? (
) : (
)}
- Copy
-
+
);
diff --git a/install/actualbudget-install.sh b/install/actualbudget-install.sh
index 0aab11297..142e91c21 100644
--- a/install/actualbudget-install.sh
+++ b/install/actualbudget-install.sh
@@ -40,9 +40,9 @@ msg_ok "Installed Node.js"
msg_info "Installing Actual Budget"
cd /opt
RELEASE=$(curl -s https://api.github.com/repos/actualbudget/actual/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
-wget -q https://github.com/actualbudget/actual-server/archive/refs/tags/v${RELEASE}.tar.gz
+wget -q https://github.com/actualbudget/actual/archive/refs/tags/v${RELEASE}.tar.gz
tar -xzf v${RELEASE}.tar.gz
-mv *ctual-server-* /opt/actualbudget
+mv actual-${RELEASE} /opt/actualbudget
mkdir -p /opt/actualbudget-data/{server-files,upload,migrate,user-files,migrations,config}
chown -R root:root /opt/actualbudget-data
@@ -59,7 +59,7 @@ ACTUAL_HTTPS_KEY=/opt/actualbudget/selfhost.key
ACTUAL_HTTPS_CERT=/opt/actualbudget/selfhost.crt
EOF
cd /opt/actualbudget
-$STD yarn install
+$STD yarn workspaces focus @actual-app/sync-server --production
$STD openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout selfhost.key -out selfhost.crt <
/etc/authelia/users.yml
+users:
+ authelia:
+ disabled: false
+ displayname: "Authelia Admin"
+ password: "\$argon2id\$v=19\$m=65536,t=3,p=4\$ZBopMzXrzhHXPEZxRDVT2w\$SxWm96DwhOsZyn34DLocwQEIb4kCDsk632PuiMdZnig"
+ groups: []
+EOF
+
+cat </etc/authelia/configuration.yml
+authentication_backend:
+ file:
+ path: /etc/authelia/users.yml
+access_control:
+ default_policy: one_factor
+session:
+ secret: "${SESSION_SECRET}"
+ name: 'authelia_session'
+ same_site: 'lax'
+ inactivity: '5m'
+ expiration: '1h'
+ remember_me: '1M'
+ cookies:
+ - domain: "${DOMAIN}"
+ authelia_url: "https://auth.${DOMAIN}"
+storage:
+ encryption_key: "${STORAGE_KEY}"
+ local:
+ path: /etc/authelia/db.sqlite
+identity_validation:
+ reset_password:
+ jwt_secret: "${JWT_SECRET}"
+ jwt_lifespan: '5 minutes'
+ jwt_algorithm: 'HS256'
+notifier:
+ filesystem:
+ filename: /etc/authelia/emails.txt
+EOF
+systemctl enable -q --now authelia
+msg_ok "Authelia Setup completed"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -f "authelia_${RELEASE}_amd64.deb"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/install/bytestash-install.sh b/install/bytestash-install.sh
new file mode 100644
index 000000000..8d4d01b81
--- /dev/null
+++ b/install/bytestash-install.sh
@@ -0,0 +1,86 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/jordan-dalby/ByteStash
+
+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 \
+ sudo \
+ curl \
+ mc \
+ gnupg
+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 ByteStash"
+temp_file=$(mktemp)
+RELEASE=$(curl -s https://api.github.com/repos/jordan-dalby/ByteStash/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+wget -q "https://github.com/jordan-dalby/ByteStash/archive/refs/tags/v${RELEASE}.tar.gz" -O $temp_file
+tar zxf $temp_file
+mv ByteStash-${RELEASE} /opt/bytestash
+cd /opt/bytestash/server
+$STD npm install
+cd /opt/bytestash/client
+$STD npm install
+echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
+msg_ok "Installed ByteStash"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/bytestash-backend.service
+[Unit]
+Description=ByteStash Backend Service
+After=network.target
+
+[Service]
+WorkingDirectory=/opt/bytestash/server
+ExecStart=/usr/bin/node src/app.js
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+cat </etc/systemd/system/bytestash-frontend.service
+[Unit]
+Description=ByteStash Frontend Service
+After=network.target bytestash-backend.service
+
+[Service]
+WorkingDirectory=/opt/bytestash/client
+ExecStart=/usr/bin/npx vite --host
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now bytestash-backend
+systemctl enable -q --now bytestash-frontend
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -f $temp_file
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/install/docmost-install.sh b/install/docmost-install.sh
index 3007b0140..298dba62e 100644
--- a/install/docmost-install.sh
+++ b/install/docmost-install.sh
@@ -61,8 +61,11 @@ tar -xzf "$temp_file"
mv docmost-${RELEASE} /opt/docmost
cd /opt/docmost
mv .env.example .env
-sed -i "s|APP_SECRET=.*|APP_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)|" /opt/docmost/.env
-sed -i "s|DATABASE_URL=.*|DATABASE_URL=postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME|" /opt/docmost/.env
+mkdir data
+sed -i -e "s|APP_SECRET=.*|APP_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)|" \
+ -e "s|DATABASE_URL=.*|DATABASE_URL=postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME|" \
+ -e "s|FILE_UPLOAD_SIZE_LIMIT=.*|FILE_UPLOAD_SIZE_LIMIT=50mb|" \
+ /opt/docmost/.env
export NODE_OPTIONS="--max-old-space-size=2048"
$STD pnpm install
$STD pnpm build
diff --git a/install/firefly-install.sh b/install/firefly-install.sh
index 703d979e0..5ae7cb8ab 100644
--- a/install/firefly-install.sh
+++ b/install/firefly-install.sh
@@ -86,6 +86,7 @@ cat </etc/apache2/sites-available/firefly.conf
EOF
+chown www-data:www-data /opt/firefly/storage/oauth-*.key
$STD a2enmod php8.4
$STD a2enmod rewrite
$STD a2ensite firefly.conf
diff --git a/install/habitica-install.sh b/install/habitica-install.sh
new file mode 100644
index 000000000..9aaf92939
--- /dev/null
+++ b/install/habitica-install.sh
@@ -0,0 +1,110 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/HabitRPG/habitica
+
+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 \
+ libkrb5-dev \
+ gnupg \
+ build-essential \
+ git
+wget -q http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb
+$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
+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
+msg_ok "Set up Node.js Repository"
+
+msg_info "Setup Node.js"
+$STD apt-get update
+$STD apt-get install -y nodejs
+msg_ok "Setup Node.js"
+
+msg_info "Setup ${APPLICATION}"
+temp_file=$(mktemp)
+RELEASE=$(curl -s https://api.github.com/repos/HabitRPG/habitica/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+wget -q "https://github.com/HabitRPG/habitica/archive/refs/tags/v${RELEASE}.tar.gz" -O $temp_file
+tar zxf $temp_file
+mv habitica-${RELEASE}/ /opt/habitica
+cd /opt/habitica
+$STD npm i
+cp config.json.example config.json
+echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
+msg_ok "Setup ${APPLICATION}"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/habitica-mongodb.service
+[Unit]
+Description=Habitica MongoDB Service
+After=network.target
+
+[Service]
+Type=simple
+User=root
+WorkingDirectory=/opt/habitica
+ExecStart=/usr/bin/npm run mongo:dev
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+cat </etc/systemd/system/habitica.service
+[Unit]
+Description=Habitica Service
+After=habitica-mongodb.service
+
+[Service]
+Type=simple
+User=root
+WorkingDirectory=/opt/habitica
+ExecStart=/usr/bin/npm start
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+cat </etc/systemd/system/habitica-client.service
+[Unit]
+Description=Habitica Client Service
+After=habitica.service
+
+[Service]
+Type=simple
+User=root
+WorkingDirectory=/opt/habitica
+ExecStart=/usr/bin/npm run client:dev
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now habitica-mongodb
+systemctl enable -q --now habitica
+systemctl enable -q --now habitica-client
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -f $temp_file
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/install/homarr-install.sh b/install/homarr-install.sh
index da2c07fe3..0a1c3cf09 100644
--- a/install/homarr-install.sh
+++ b/install/homarr-install.sh
@@ -88,9 +88,17 @@ msg_ok "Finished copying"
msg_info "Creating Services"
cat <<'EOF' >/opt/run_homarr.sh
#!/bin/bash
+set -a
+source /opt/homarr/.env
+set +a
export DB_DIALECT='sqlite'
export AUTH_SECRET=$(openssl rand -base64 32)
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
+for dir in $(find /opt/homarr_db/migrations/migrations -mindepth 1 -maxdepth 1 -type d); do
+ dirname=$(basename "$dir")
+ mkdir -p "/opt/homarr_db/migrations/$dirname"
+ cp -r "$dir"/* "/opt/homarr_db/migrations/$dirname/" 2>/dev/null || true
+done
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
nginx -g 'daemon off;' &
diff --git a/install/jupyternotebook-install.sh b/install/jupyternotebook-install.sh
new file mode 100644
index 000000000..3be8e1ee5
--- /dev/null
+++ b/install/jupyternotebook-install.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: [Dave-code-creater (Tan Dat, Ta)]
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: [https://jupyter.org/]
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Dependencies"
+$STD apt-get install -y \
+ curl \
+ sudo \
+ mc \
+ python3 \
+ python3-pip
+msg_ok "Installed Dependencies"
+
+msg_info "Setting up Jupyter Notebook"
+$STD pip3 install jupyter
+msg_ok "Setup Jupyter Notebook"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/jupyternotebook.service
+[Unit]
+Description=Jupyter Notebook Server
+After=network.target
+
+[Service]
+Type=simple
+ExecStart=jupyter notebook --ip=0.0.0.0 --port=8888 --allow-root
+Restart=always
+RestartSec=10
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now jupyternotebook
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/install/keycloak-install.sh b/install/keycloak-install.sh
index fc24183aa..39d070c7f 100644
--- a/install/keycloak-install.sh
+++ b/install/keycloak-install.sh
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
-# Copyright (c) 2021-2024 tteck
-# Author: tteck (tteckster)
-# License: MIT
-# https://github.com/tteck/Proxmox/raw/main/LICENSE
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: tteck (tteckster) | Co-Author: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/keycloak/keycloak
-source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
@@ -13,42 +13,53 @@ setting_up_container
network_check
update_os
-msg_info "Installing Dependencies (Patience)"
-$STD apt-get install -y curl
-$STD apt-get install -y sudo
-$STD apt-get install -y mc
-$STD apt-get install -y ca-certificates-java
-$STD apt-get install -y openjdk-17-jre-headless
-$STD apt-get install -y wget
-$STD apt-get install -y openssh-server
+msg_info "Installing Dependencies"
+$STD apt-get install -y \
+curl \
+sudo \
+mc \
+gnupg \
+wget \
+openssh-server
msg_ok "Installed Dependencies"
+msg_info "Installing OpenJDK"
+wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg
+echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list
+$STD apt-get update
+$STD apt-get install -y temurin-21-jre
+msg_ok "Installed OpenJDK"
+
+msg_info "Installing Keycloak"
+temp_file=$(mktemp)
RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
-msg_info "Installing Keycloak v$RELEASE"
-cd /opt
-wget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz
-$STD tar -xvf keycloak-$RELEASE.tar.gz
-mv keycloak-$RELEASE keycloak
+wget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz -O $temp_file
+tar xzf $temp_file
+mv keycloak-$RELEASE /opt/keycloak
msg_ok "Installed Keycloak"
msg_info "Creating Service"
-service_path="/etc/systemd/system/keycloak.service"
-echo "[Unit]
-Description=Keycloak
-After=network-online.target
+cat </etc/systemd/system/keycloak.service
+[Unit]
+Description=Keycloak Service
+After=network.target
+
[Service]
User=root
WorkingDirectory=/opt/keycloak
ExecStart=/opt/keycloak/bin/kc.sh start-dev
+
[Install]
-WantedBy=multi-user.target" >$service_path
-$STD systemctl enable --now keycloak.service
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now keycloak
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
+rm -f $temp_file
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
diff --git a/install/kimai-install.sh b/install/kimai-install.sh
index 2a31aa06f..f7d9b49d1 100644
--- a/install/kimai-install.sh
+++ b/install/kimai-install.sh
@@ -76,8 +76,9 @@ $STD bin/console kimai:install -n
chown -R :www-data /opt/*
chmod -R g+r /opt/*
chmod -R g+rw /opt/*
-sudo chown -R www-data:www-data /opt/*
-sudo chmod -R 755 /opt/*
+chown -R www-data:www-data /opt/*
+chmod -R 755 /opt/*
+chmod -R 777 /opt/kimai/var/
$STD expect </opt/kimai/config/packages/local.yaml
+kimai:
+ timesheet:
+ rounding:
+ default:
+ begin: 15
+ end: 15
+
+admin_lte:
+ options:
+ default_avatar: build/apple-touch-icon.png
+EOF
+
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
msg_ok "Installed Kimai"
diff --git a/install/linkwarden-install.sh b/install/linkwarden-install.sh
index 3d4c515cf..b83e6c0e1 100644
--- a/install/linkwarden-install.sh
+++ b/install/linkwarden-install.sh
@@ -20,7 +20,9 @@ $STD apt-get install -y \
sudo \
mc \
make \
+ git \
postgresql \
+ build-essential \
cargo \
gnupg \
wget \
@@ -39,10 +41,13 @@ $STD apt-get install -y nodejs
$STD npm install -g yarn
msg_ok "Installed Node.js/Yarn"
-msg_info "Installing Monolith"
+msg_info "Installing Rust"
+$STD curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+source $HOME/.cargo/env
+echo 'export PATH=/usr/local/cargo/bin:$PATH' >> /etc/profile
+source /etc/profile
$STD cargo install monolith
-export PATH=~/.cargo/bin:$PATH
-msg_ok "Installed Monolith"
+msg_ok "Installed Rust"
msg_info "Setting up PostgreSQL DB"
DB_NAME=linkwardendb
diff --git a/install/minio-install.sh b/install/minio-install.sh
index 6dd7b947c..f06b1b3b8 100644
--- a/install/minio-install.sh
+++ b/install/minio-install.sh
@@ -57,7 +57,7 @@ After=network-online.target
User=minio-user
Group=minio-user
EnvironmentFile=-/etc/default/minio
-ExecStart=/usr/local/bin/minio server /data
+ExecStart=/usr/local/bin/minio server --console-address ":9001" /data
Restart=always
RestartSec=5
LimitNOFILE=65536
@@ -74,4 +74,4 @@ customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
-msg_ok "Cleaned"
\ No newline at end of file
+msg_ok "Cleaned"
diff --git a/install/nzbget-install.sh b/install/nzbget-install.sh
index 8ccc90716..af1d25562 100644
--- a/install/nzbget-install.sh
+++ b/install/nzbget-install.sh
@@ -33,7 +33,7 @@ msg_ok "Installed Dependencies"
msg_info "Installing NZBGet"
mkdir -p /etc/apt/keyrings
curl -fsSL https://nzbgetcom.github.io/nzbgetcom.asc | gpg --dearmor -o /etc/apt/keyrings/nzbgetcom.gpg
-echo "deb [signed-by=/etc/apt/keyrings/nzbgetcom.gpg] https://nzbgetcom.github.io/deb stable main" >/etc/apt/sources.list.d/nzbgetcom.list
+echo "deb [arch=all signed-by=/etc/apt/keyrings/nzbgetcom.gpg] https://nzbgetcom.github.io/deb stable main" >/etc/apt/sources.list.d/nzbgetcom.list
$STD apt-get update
$STD apt-get install -y nzbget
msg_ok "Installed NZBGet"
diff --git a/install/omada-install.sh b/install/omada-install.sh
index 84f906d10..3a50e0714 100644
--- a/install/omada-install.sh
+++ b/install/omada-install.sh
@@ -14,34 +14,50 @@ 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 gnupg
-$STD apt-get install -y jsvc
-$STD apt-get install -y wget
-$STD apt-get install -y openssh-server
+$STD apt-get install -y curl sudo mc gnupg jsvc wget openssh-server
msg_ok "Installed Dependencies"
-msg_info "Installing Azul Zulu"
+msg_info "Checking CPU Features"
+if lscpu | grep -q 'avx'; then
+ USE_AVX=true
+ MONGODB_VERSION="7.0"
+ msg_ok "AVX detected: Using MongoDB 7.0"
+else
+ USE_AVX=false
+ MONGODB_VERSION="4.4"
+ msg_error "No AVX detected: TP-Link Canceled Support for Old MongoDB for Debian 12\n https://www.tp-link.com/baltic/support/faq/4160/"
+ exit 1
+fi
+
+msg_info "Installing Azul Zulu Java"
wget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9"
wget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb
$STD dpkg -i zulu-repo_1.0.0-3_all.deb
$STD apt-get update
$STD apt-get -y install zulu8-jdk
-msg_ok "Installed Azul Zulu"
+msg_ok "Installed Azul Zulu Java"
-msg_info "Installing MongoDB"
-wget -qL http://ports.ubuntu.com/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_arm64.deb
-$STD dpkg -i libssl1.1_1.1.1f-1ubuntu2_arm64.deb
-wget -qL https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-arm64/mongodb-org-server_4.4.29_arm64.deb
-$STD dpkg -i mongodb-org-server_4.4.29_arm64.deb
-msg_ok "Installed MongoDB"
+msg_info "Installing libssl (if needed)"
+if ! dpkg -l | grep -q 'libssl1.1'; then
+ wget -qO /tmp/libssl.deb "https://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1w-0+deb11u2_arm64.deb"
+ $STD dpkg -i /tmp/libssl.deb
+ rm -f /tmp/libssl.deb
+ msg_ok "Installed libssl1.1"
+else
+ msg_ok "libssl1.1 already installed"
+fi
-latest_url=$(curl -fsSL "https://www.tp-link.com/en/support/download/omada-software-controller/" | grep -o 'https://.*x64.deb' | head -n1)
-latest_version=$(basename "$latest_url")
+msg_info "Installing MongoDB $MONGODB_VERSION"
+wget -qO- https://www.mongodb.org/static/pgp/server-${MONGODB_VERSION}.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-${MONGODB_VERSION}.gpg
+echo "deb [signed-by=/usr/share/keyrings/mongodb-server-${MONGODB_VERSION}.gpg] http://repo.mongodb.org/apt/debian $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/${MONGODB_VERSION} main" >/etc/apt/sources.list.d/mongodb-org-${MONGODB_VERSION}.list
+$STD apt-get update
+$STD apt-get install -y mongodb-org
+msg_ok "Installed MongoDB $MONGODB_VERSION"
msg_info "Installing Omada Controller"
+latest_url=$(curl -s "https://support.omadanetworks.com/en/product/omada-software-controller/?resourceType=download" | grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' | head -n 1)
+latest_version=$(basename "$latest_url")
+
wget -qL ${latest_url}
$STD dpkg -i --ignore-depends=jsvc,mongodb-server ${latest_version}
msg_ok "Installed Omada Controller"
@@ -50,7 +66,7 @@ motd_ssh
customize
msg_info "Cleaning up"
-rm -rf ${latest_version} mongodb-org-server_4.4.29_arm64.deb zulu-repo_1.0.0-3_all.deb libssl1.1_1.1.1f-1ubuntu2_arm64.deb
+rm -rf ${latest_version} zulu-repo_1.0.0-3_all.deb
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
diff --git a/install/outline-install.sh b/install/outline-install.sh
new file mode 100644
index 000000000..436f4aadf
--- /dev/null
+++ b/install/outline-install.sh
@@ -0,0 +1,106 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/outline/outline
+
+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 \
+gnupg \
+mkcert \
+git \
+redis
+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
+msg_ok "Set up Node.js Repository"
+
+msg_info "Setting up PostgreSQL Repository"
+curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
+echo "deb https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" >/etc/apt/sources.list.d/pgdg.list
+msg_ok "Set up PostgreSQL Repository"
+
+msg_info "Installing Node.js"
+$STD apt-get update
+$STD apt-get install -y nodejs
+$STD npm install -g yarn
+msg_ok "Installed Node.js"
+
+msg_info "Install/Set up PostgreSQL Database"
+$STD apt-get install -y postgresql-16
+DB_NAME="outline"
+DB_USER="outline"
+DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
+SECRET_KEY="$(openssl rand -hex 32)"
+$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
+$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
+msg_ok "Set up PostgreSQL"
+
+msg_info "Setup Outline (Patience)"
+temp_file=$(mktemp)
+LOCAL_IP="$(hostname -I | awk '{print $1}')"
+RELEASE=$(curl -s https://api.github.com/repos/outline/outline/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+wget -q "https://github.com/outline/outline/archive/refs/tags/v${RELEASE}.tar.gz" -O $temp_file
+tar zxf $temp_file
+mv outline-${RELEASE} /opt/outline
+cd /opt/outline
+cp .env.sample .env
+sed -i 's/NODE_ENV=production/NODE_ENV=development/g' /opt/outline/.env
+sed -i "s/generate_a_new_key/${SECRET_KEY}/g" /opt/outline/.env
+sed -i "s/user:pass@postgres/${DB_USER}:${DB_PASS}@localhost/g" /opt/outline/.env
+sed -i 's/redis:6379/localhost:6379/g' /opt/outline/.env
+sed -i "32s#URL=#URL=http://${LOCAL_IP}#g" /opt/outline/.env
+sed -i 's/FORCE_HTTPS=true/FORCE_HTTPS=false/g' /opt/outline/.env
+$STD yarn install --frozen-lockfile
+export NODE_OPTIONS="--max-old-space-size=3584"
+$STD yarn build
+sed -i 's/NODE_ENV=development/NODE_ENV=production/g' /opt/outline/.env
+echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
+msg_ok "Setup Outline"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/outline.service
+[Unit]
+Description=Outline Service
+After=network.target
+
+[Service]
+Type=simple
+User=root
+WorkingDirectory=/opt/outline
+ExecStart=/usr/bin/node ./build/server/index.js
+Restart=always
+EnvironmentFile=/opt/outline/.env
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now outline
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -rf $temp_file
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
\ No newline at end of file
diff --git a/install/pelican-panel-install.sh b/install/pelican-panel-install.sh
new file mode 100644
index 000000000..a64aa9446
--- /dev/null
+++ b/install/pelican-panel-install.sh
@@ -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 \
+ lsb-release \
+ mariadb-server \
+ mariadb-client \
+ apache2 \
+ composer
+msg_ok "Installed Dependencies"
+
+msg_info "Adding PHP8.3 Repository"
+$STD curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
+$STD dpkg -i /tmp/debsuryorg-archive-keyring.deb
+$STD sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
+$STD apt-get update
+msg_ok "Added PHP8.3 Repository"
+
+msg_info "Installing PHP"
+$STD apt-get remove -y php8.2*
+$STD apt-get install -y \
+ php8.3 \
+ php8.3-{gd,mysql,mbstring,bcmath,xml,curl,zip,intl,sqlite3,fpm} \
+ libapache2-mod-php8.3
+msg_info "Installed PHP"
+
+msg_info "Setting up MariaDB"
+DB_NAME=panel
+DB_USER=pelican
+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 "Pelican Panel-Credentials"
+ echo "Pelican Panel Database User: $DB_USER"
+ echo "Pelican Panel Database Password: $DB_PASS"
+ echo "Pelican Panel Database Name: $DB_NAME"
+} >> ~/pelican-panel.creds
+msg_ok "Set up MariaDB"
+
+msg_info "Installing Pelican Panel"
+RELEASE=$(curl -s https://api.github.com/repos/pelican-dev/panel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+mkdir /opt/pelican-panel
+cd /opt/pelican-panel
+wget -q "https://github.com/pelican-dev/panel/releases/download/v${RELEASE}/panel.tar.gz"
+tar -xzf "panel.tar.gz"
+$STD composer install --no-dev --optimize-autoloader --no-interaction
+$STD php artisan p:environment:setup
+$STD php artisan p:environment:queue-service --no-interaction
+echo "* * * * * php /opt/pelican-panel/artisan schedule:run >> /dev/null 2>&1" | crontab -u www-data -
+chown -R www-data:www-data /opt/pelican-panel
+chmod -R 755 /opt/pelican-panel/storage /opt/pelican-panel/bootstrap/cache/
+echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
+msg_ok "Installed Pelican Panel"
+
+msg_info "Creating Service"
+cat </etc/apache2/sites-available/pelican.conf
+
+ ServerName pelican
+ DocumentRoot /opt/pelican-panel/public
+ AllowEncodedSlashes On
+ php_value upload_max_filesize 100M
+ php_value post_max_size 100M
+
+
+ Options Indexes FollowSymLinks
+ AllowOverride All
+ Require all granted
+
+
+ ErrorLog /var/log/apache2/pelican_error.log
+ CustomLog /var/log/apache2/pelican_access.log combined
+
+EOF
+$STD a2ensite pelican
+$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/pelican-panel/panel.tar.gz"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/install/pelican-wings-install.sh b/install/pelican-wings-install.sh
new file mode 100644
index 000000000..1a1e938e3
--- /dev/null
+++ b/install/pelican-wings-install.sh
@@ -0,0 +1,69 @@
+#!/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
+msg_ok "Installed Dependencies"
+
+msg_info "Installing Docker"
+DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
+mkdir -p $(dirname $DOCKER_CONFIG_PATH)
+echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json
+$STD sh <(curl -sSL https://get.docker.com)
+systemctl enable -q --now docker
+msg_ok "Installed Docker"
+
+msg_info "Installing Pelican Wings"
+RELEASE=$(curl -s https://api.github.com/repos/pelican-dev/wings/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+wget -q -O /usr/local/bin/wings "https://github.com/pelican-dev/wings/releases/download/v${RELEASE}/wings_linux_amd64"
+chmod u+x /usr/local/bin/wings
+mkdir -p /etc/pelican /var/run/wings
+echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
+msg_ok "Installed Pelican Wings"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/wings.service
+[Unit]
+Description=Wings Daemon
+After=docker.service
+Requires=docker.service
+PartOf=docker.service
+
+[Service]
+User=root
+WorkingDirectory=/etc/pelican
+LimitNOFILE=4096
+PIDFile=/var/run/wings/daemon.pid
+ExecStart=/usr/local/bin/wings
+Restart=on-failure
+StartLimitInterval=180
+StartLimitBurst=30
+RestartSec=5s
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now wings
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/install/pihole-install.sh b/install/pihole-install.sh
index fcde213f8..d3c64e58f 100644
--- a/install/pihole-install.sh
+++ b/install/pihole-install.sh
@@ -143,7 +143,7 @@ server=8.8.8.8
server=8.8.4.4
EOF
- sed -i -E "s|^(upstreams =).*|\1 [\"127.0.0.1#5335\", \"8.8.4.4\"]|" /etc/pihole/pihole.toml
+ sed -i -E '/^\s*upstreams\s*=\s*\[/,/^\s*\]/c\ upstreams = [\n "127.0.0.1#5335",\n "8.8.4.4"\n ]' /etc/pihole/pihole.toml
systemctl enable -q --now unbound
systemctl restart pihole-FTL.service
msg_ok "Installed Unbound"
diff --git a/install/sftpgo-install.sh b/install/sftpgo-install.sh
index 2a513d0f5..93e17cf5a 100644
--- a/install/sftpgo-install.sh
+++ b/install/sftpgo-install.sh
@@ -41,7 +41,6 @@ motd_ssh
customize
msg_info "Cleaning up"
-rm -rf $RELEASE
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
diff --git a/install/unbound-install.sh b/install/unbound-install.sh
index 387e57e75..4506a4111 100644
--- a/install/unbound-install.sh
+++ b/install/unbound-install.sh
@@ -63,7 +63,7 @@ EOF
touch /var/log/unbound.log
chown unbound:unbound /var/log/unbound.log
-
+sleep 5
systemctl restart unbound
msg_ok "Installed Unbound"
diff --git a/install/victoriametrics-install.sh b/install/victoriametrics-install.sh
new file mode 100644
index 000000000..4ba74fb8d
--- /dev/null
+++ b/install/victoriametrics-install.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/VictoriaMetrics/VictoriaMetrics
+
+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 \
+ sudo \
+ curl \
+ mc
+msg_ok "Installed Dependencies"
+
+msg_info "Setup VictoriaMetrics"
+temp_dir=$(mktemp -d)
+cd $temp_dir
+mkdir -p /opt/victoriametrics/data
+RELEASE=$(curl -s https://api.github.com/repos/VictoriaMetrics/VictoriaMetrics/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+wget -q https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v${RELEASE}/victoria-metrics-linux-amd64-v${RELEASE}.tar.gz
+wget -q https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v${RELEASE}/vmutils-linux-amd64-v${RELEASE}.tar.gz
+tar -xf victoria-metrics-linux-amd64-v${RELEASE}.tar.gz -C /opt/victoriametrics
+tar -xf vmutils-linux-amd64-v${RELEASE}.tar.gz -C /opt/victoriametrics
+chmod +x /opt/victoriametrics/*
+msg_ok "Setup VictoriaMetrics"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/victoriametrics.service
+[Unit]
+Description=VictoriaMetrics Service
+
+[Service]
+Type=simple
+Restart=always
+User=root
+WorkingDirectory=/opt/victoriametrics
+ExecStart=/opt/victoriametrics/victoria-metrics-prod --storageDataPath="/opt/victoriametrics/data"
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now victoriametrics
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -rf $temp_dir
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/install/web-check-install.sh b/install/web-check-install.sh
new file mode 100644
index 000000000..0333aa89a
--- /dev/null
+++ b/install/web-check-install.sh
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: CrazyWolf13
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/lissy93/web-check
+source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
+
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Dependencies"
+export DEBIAN_FRONTEND=noninteractive
+$STD apt-get -y install --no-install-recommends \
+ curl \
+ sudo \
+ mc \
+ git \
+ gnupg \
+ traceroute \
+ make \
+ g++ \
+ traceroute \
+ xvfb \
+ dbus \
+ xorg \
+ xvfb \
+ gtk2-engines-pixbuf \
+ dbus-x11 \
+ xfonts-base \
+ xfonts-100dpi \
+ xfonts-75dpi \
+ xfonts-scalable \
+ imagemagick \
+ x11-apps
+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 "Setup Python3"
+$STD apt-get install -y python3
+rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
+msg_ok "Setup Python3"
+
+msg_info "Installing Chromium"
+curl -fsSL https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /etc/apt/trusted.gpg.d/google-archive.gpg
+echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >/etc/apt/sources.list.d/google.list
+$STD apt-get update
+$STD apt-get -y install \
+ chromium \
+ libxss1 \
+ lsb-release
+msg_ok "Installed Chromium"
+
+msg_info "Installing Node.js"
+$STD apt-get update
+$STD apt-get install -y nodejs
+$STD npm install -g yarn
+msg_ok "Installed Node.js"
+
+msg_info "Setting up Chromium"
+/usr/bin/chromium --no-sandbox --version > /etc/chromium-version
+chmod 755 /usr/bin/chromium
+msg_ok "Setup Chromium"
+
+msg_info "Installing Web-Check (Patience)"
+temp_file=$(mktemp)
+RELEASE="patch-1"
+wget -q "https://github.com/CrazyWolf13/web-check/archive/refs/heads/${RELEASE}.tar.gz" -O $temp_file
+tar xzf $temp_file
+mv web-check-${RELEASE} /opt/web-check
+cd /opt/web-check
+cat <<'EOF' > /opt/web-check/.env
+CHROME_PATH=/usr/bin/chromium
+PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
+HEADLESS=true
+GOOGLE_CLOUD_API_KEY=''
+REACT_APP_SHODAN_API_KEY=''
+REACT_APP_WHO_API_KEY=''
+SECURITY_TRAILS_API_KEY=''
+CLOUDMERSIVE_API_KEY=''
+TRANCO_USERNAME=''
+TRANCO_API_KEY=''
+URL_SCAN_API_KEY=''
+BUILT_WITH_API_KEY=''
+TORRENT_IP_API_KEY=''
+PORT='3000'
+DISABLE_GUI='false'
+API_TIMEOUT_LIMIT='10000'
+API_CORS_ORIGIN='*'
+API_ENABLE_RATE_LIMIT='false'
+REACT_APP_API_ENDPOINT='/api'
+ENABLE_ANALYTICS='false'
+EOF
+$STD yarn install --frozen-lockfile --network-timeout 100000
+echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
+msg_ok "Installed Web-Check"
+
+msg_info "Building Web-Check"
+$STD yarn build --production
+msg_ok "Built Web-Check"
+
+msg_info "Creating Service"
+cat <<'EOF' > /opt/run_web-check.sh
+#!/bin/bash
+SCREEN_RESOLUTION="1280x1024x24"
+if ! systemctl is-active --quiet dbus; then
+ echo "Warning: dbus service is not running. Some features may not work properly."
+fi
+[[ -z "${DISPLAY}" ]] && export DISPLAY=":99"
+Xvfb "${DISPLAY}" -screen 0 "${SCREEN_RESOLUTION}" &
+XVFB_PID=$!
+sleep 2
+cd /opt/web-check
+exec yarn start
+EOF
+chmod +x /opt/run_web-check.sh
+cat <<'EOF' > /etc/systemd/system/web-check.service
+[Unit]
+Description=Web Check Service
+After=network.target
+
+[Service]
+Type=simple
+User=root
+Group=root
+WorkingDirectory=/opt/web-check
+EnvironmentFile=/opt/web-check/.env
+ExecStartPre=/bin/bash -c "service dbus start || true"
+ExecStartPre=/bin/bash -c "if ! pgrep -f 'Xvfb.*:99' > /dev/null; then Xvfb :99 -screen 0 1280x1024x24 & fi"
+ExecStart=/opt/run_web-check.sh
+Restart=on-failure
+Environment=DISPLAY=:99
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now web-check
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -rf $temp_file
+rm -rf /var/lib/apt/lists/* /app/node_modules/.cache
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
+
+motd_ssh
+customize
diff --git a/install/wger-install.sh b/install/wger-install.sh
new file mode 100644
index 000000000..7ffcdfbca
--- /dev/null
+++ b/install/wger-install.sh
@@ -0,0 +1,128 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: SlaviΕ‘a AreΕΎina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/wger-project/wger
+
+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 \
+ git \
+ gnupg \
+ apache2 \
+ libapache2-mod-wsgi-py3
+msg_ok "Installed Dependencies"
+
+msg_info "Installing Python"
+$STD apt-get install -y python3-pip
+rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
+msg_ok "Installed Python"
+
+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
+$STD npm install -g yarn sass
+msg_ok "Installed Node.js"
+
+msg_info "Setting up wger"
+$STD adduser wger --disabled-password --gecos ""
+mkdir /home/wger/db
+touch /home/wger/db/database.sqlite
+chown :www-data -R /home/wger/db
+chmod g+w /home/wger/db /home/wger/db/database.sqlite
+mkdir /home/wger/{static,media}
+chmod o+w /home/wger/media
+temp_dir=$(mktemp -d)
+cd $temp_dir
+RELEASE=$(curl -s https://api.github.com/repos/wger-project/wger/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
+wget -q "https://github.com/wger-project/wger/archive/refs/tags/$RELEASE.tar.gz"
+tar xzf $RELEASE.tar.gz
+mv wger-$RELEASE /home/wger/src
+cd /home/wger/src
+$STD pip install -r requirements_prod.txt
+$STD pip install -e .
+$STD wger create-settings --database-path /home/wger/db/database.sqlite
+sed -i "s#home/wger/src/media#home/wger/media#g" /home/wger/src/settings.py
+sed -i "/MEDIA_ROOT = '\/home\/wger\/media'/a STATIC_ROOT = '/home/wger/static'" /home/wger/src/settings.py
+$STD wger bootstrap
+$STD python3 manage.py collectstatic
+echo "${RELEASE}" >/opt/wger_version.txt
+msg_ok "Finished setting up wger"
+
+msg_info "Creating Service"
+cat </etc/apache2/sites-available/wger.conf
+
+
+ Require all granted
+
+
+
+
+ WSGIApplicationGroup %{GLOBAL}
+ WSGIDaemonProcess wger python-path=/home/wger/src python-home=/home/wger
+ WSGIProcessGroup wger
+ WSGIScriptAlias / /home/wger/src/wger/wsgi.py
+ WSGIPassAuthorization On
+
+ Alias /static/ /home/wger/static/
+
+ Require all granted
+
+
+ Alias /media/ /home/wger/media/
+
+ Require all granted
+
+
+ ErrorLog /var/log/apache2/wger-error.log
+ CustomLog /var/log/apache2/wger-access.log combined
+
+EOF
+$STD a2dissite 000-default.conf
+$STD a2ensite wger
+systemctl restart apache2
+cat </etc/systemd/system/wger.service
+[Unit]
+Description=wger Service
+After=network.target
+
+[Service]
+Type=simple
+User=root
+ExecStart=/usr/local/bin/wger start -a 0.0.0.0 -p 3000
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now wger
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -rf $temp_dir
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
+
+motd_ssh
+customize
diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh
index 8dc8cedb6..839d0fb0e 100644
--- a/install/zigbee2mqtt-install.sh
+++ b/install/zigbee2mqtt-install.sh
@@ -52,7 +52,7 @@ mv zigbee2mqtt-${RELEASE} /opt/zigbee2mqtt
cd /opt/zigbee2mqtt/data
mv configuration.example.yaml configuration.yaml
cd /opt/zigbee2mqtt
-$STD pnpm install --frozen-lockfile
+$STD pnpm install --no-frozen-lockfile
$STD pnpm build
msg_ok "Installed Zigbee2MQTT"
diff --git a/install/zitadel-install.sh b/install/zitadel-install.sh
index 6ee097ca4..340ec3a42 100644
--- a/install/zitadel-install.sh
+++ b/install/zitadel-install.sh
@@ -46,7 +46,6 @@ msg_info "Installing Zitadel"
RELEASE=$(curl -si https://github.com/zitadel/zitadel/releases/latest | grep location: | cut -d '/' -f 8 | tr -d '\r')
wget -qc https://github.com/zitadel/zitadel/releases/download/$RELEASE/zitadel-linux-amd64.tar.gz -O - | tar -xz
mv zitadel-linux-amd64/zitadel /usr/local/bin
-echo "${RELEASE}" >"/opt/zitadel_version.txt"
msg_ok "Installed Zitadel"
msg_info "Setting up Zitadel Environments"
@@ -126,7 +125,7 @@ zitadel start-from-init --masterkeyFile /opt/zitadel/.masterkey --config /opt/zi
sleep 60
kill $(lsof -i | awk '/zitadel/ {print $2}' | head -n1)
useradd zitadel
-echo -e "$(zitadel -v | grep -oP 'v\d+\.\d+\.\d+')" > /opt/Zitadel_version.txt
+echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
msg_ok "Zitadel initialized"
msg_info "Set ExternalDomain to current IP and restart Zitadel"
diff --git a/json/add-tailscale-lxc.json b/json/add-tailscale-lxc.json
index d95295da4..3a6099cb3 100644
--- a/json/add-tailscale-lxc.json
+++ b/json/add-tailscale-lxc.json
@@ -31,6 +31,10 @@
"password": null
},
"notes": [
+ {
+ "text": "Only supported on Debian 12 LXCs",
+ "type": "warning"
+ },
{
"text": "After the script finishes, reboot the LXC then run `tailscale up` in the LXC console",
"type": "info"
@@ -41,4 +45,4 @@
}
],
"status": "β
"
-}
\ No newline at end of file
+}
diff --git a/json/authelia.json b/json/authelia.json
new file mode 100644
index 000000000..95ed5dbff
--- /dev/null
+++ b/json/authelia.json
@@ -0,0 +1,39 @@
+{
+ "name": "Authelia",
+ "slug": "authelia",
+ "categories": [
+ 6
+ ],
+ "date_created": "2025-02-24",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 9091,
+ "documentation": "https://www.authelia.com/integration/deployment/bare-metal/",
+ "website": "https://www.authelia.com/",
+ "logo": "https://www.authelia.com/images/branding/logo.png",
+ "description": "Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management (IAM) role of information security in providing multi-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for common reverse proxies.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/authelia.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 512,
+ "hdd": 2,
+ "os": "Debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": "authelia",
+ "password": "authelia"
+ },
+ "notes": [
+ {
+ "text": "During installation, you will have to input your domain (ex. domain.com). Authelia will use auth.domain.com",
+ "type": "info"
+ }
+ ]
+}
diff --git a/json/bytestash.json b/json/bytestash.json
new file mode 100644
index 000000000..a88f04914
--- /dev/null
+++ b/json/bytestash.json
@@ -0,0 +1,34 @@
+{
+ "name": "ByteStash",
+ "slug": "bytestash",
+ "categories": [
+ 20
+ ],
+ "date_created": "2025-02-27",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 3000,
+ "documentation": "https://github.com/jordan-dalby/ByteStash/wiki",
+ "website": "https://github.com/jordan-dalby/ByteStash",
+ "logo": "https://raw.githubusercontent.com/jordan-dalby/ByteStash/refs/heads/main/client/public/logo192.png",
+ "description": "ByteStash is a self-hosted web application designed to store, organise, and manage your code snippets efficiently. With support for creating, editing, and filtering snippets, ByteStash helps you keep track of your code in one secure place.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/bytestash.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 1024,
+ "hdd": 4,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+}
diff --git a/json/graylog.json b/json/graylog.json
index 66cb9c13d..7258b2d15 100644
--- a/json/graylog.json
+++ b/json/graylog.json
@@ -12,7 +12,7 @@
"documentation": "https://go2docs.graylog.org/current/home.htm",
"website": "https://graylog.org/",
"logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/graylog.svg",
- "description": "Graylog is a free and open log management platform.",
+ "description": "Graylog is an open-source log management and analysis platform that centralizes and processes log data from various sources, enabling real-time search, analysis, and alerting for IT infrastructure monitoring and troubleshooting.",
"install_methods": [
{
"type": "default",
diff --git a/json/habitica.json b/json/habitica.json
new file mode 100644
index 000000000..0b8b0521c
--- /dev/null
+++ b/json/habitica.json
@@ -0,0 +1,43 @@
+{
+ "name": "Habitica",
+ "slug": "habitica",
+ "categories": [
+ 24
+ ],
+ "date_created": "2025-03-03",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 8080,
+ "documentation": "https://github.com/HabitRPG/habitica/wiki",
+ "website": "https://habitica.com/",
+ "logo": "https://github.com/HabitRPG/habitica/raw/refs/heads/develop/website/client/src/assets/svg/logo.svg",
+ "description": "Habitica is an open-source habit-building program that treats your life like a role-playing game. Level up as you succeed, lose HP as you fail, and earn Gold to buy weapons and armor!",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/habitica.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 4096,
+ "hdd": 8,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "It takes a minute or two after installation for web UI to start, please be patient.",
+ "type": "info"
+ },
+ {
+ "text": "Config file is at `/opt/habitica/config.json`",
+ "type": "info"
+ }
+ ]
+}
diff --git a/json/jupyternotebook.json b/json/jupyternotebook.json
new file mode 100644
index 000000000..0ebf71f46
--- /dev/null
+++ b/json/jupyternotebook.json
@@ -0,0 +1,39 @@
+{
+ "name": "Jupyter Notebook",
+ "slug": "jupyter-notebook",
+ "categories": [
+ 20
+ ],
+ "date_created": "2025-02-24",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 8888,
+ "documentation": "https://jupyter-notebook.readthedocs.io/en/stable/",
+ "website": "https://jupyter.org/",
+ "logo": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Jupyter_logo.svg/800px-Jupyter_logo.svg.png",
+ "description": "The Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and narrative text. Uses include: data cleaning and transformation, numerical simulation, statistical modeling, data visualization, machine learning, and much more.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/jupyternotebook.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 4,
+ "os": "ubuntu",
+ "version": "24.04"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "To get the token to access the Jupyter Notebook, run the following command: jupyter notebook list.",
+ "type": "info"
+ }
+ ]
+}
diff --git a/json/linkwarden.json b/json/linkwarden.json
index 3ec555040..93d305e0e 100644
--- a/json/linkwarden.json
+++ b/json/linkwarden.json
@@ -31,10 +31,7 @@
"password": null
},
"notes": [
- {
- "text": "Linkwarden > 2.8.2 needs Monolith, More info: `https://github.com/community-scripts/ProxmoxVE/discussions/305`",
- "type": "info"
- }
+ {}
],
"status": "β
"
-}
\ No newline at end of file
+}
diff --git a/json/minio.json b/json/minio.json
index 5d307bb32..dc8075a9c 100644
--- a/json/minio.json
+++ b/json/minio.json
@@ -8,7 +8,7 @@
"type": "ct",
"updateable": true,
"privileged": false,
- "interface_port": 9000,
+ "interface_port": 9001,
"documentation": "https://min.io/docs/minio/linux/index.html",
"website": "https://min.io/",
"logo": "https://raw.githubusercontent.com/minio/minio/refs/heads/master/.github/logo.svg",
diff --git a/json/outline.json b/json/outline.json
new file mode 100644
index 000000000..b167040b7
--- /dev/null
+++ b/json/outline.json
@@ -0,0 +1,43 @@
+{
+ "name": "Outline",
+ "slug": "outline",
+ "categories": [
+ 12
+ ],
+ "date_created": "2025-02-26",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 3000,
+ "documentation": "https://docs.getoutline.com/s/hosting/",
+ "website": "https://www.getoutline.com",
+ "logo": "https://www.getoutline.com/images/logo.svg",
+ "description": "The fastest knowledge base for growing teams. Beautiful, realtime collaborative, feature packed, and markdown compatible. Itβs time to get your teamβs knowledge organized.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/outline.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 4096,
+ "hdd": 8,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "After installation finishes, application will do a database migration so web UI might be unavailable for a minute or two. Also you need to manually add authentication and/or enable HTTPS.",
+ "type": "info"
+ },
+ {
+ "text": "Configuration file is at: `/opt/outline/.env`. Modify to suit your environment.",
+ "type": "info"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/json/pelican-panel.json b/json/pelican-panel.json
new file mode 100644
index 000000000..510626c14
--- /dev/null
+++ b/json/pelican-panel.json
@@ -0,0 +1,43 @@
+{
+ "name": "Pelican Panel",
+ "slug": "pelican-panel",
+ "categories": [
+ 24
+ ],
+ "date_created": "2025-02-27",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 80,
+ "documentation": "https://pelican.dev/docs/panel/getting-started",
+ "website": "https://pelican.dev/",
+ "logo": "https://pelican.dev/img/logo.png",
+ "description": "Pelican Panel is a web-based control panel for managing game and application servers. It provides an intuitive interface to start, stop, configure, and monitor servers easily. It works alongside Pelican Wings, a lightweight daemon that handles server deployments and resource management.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/pelican-panel.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 1024,
+ "hdd": 4,
+ "os": "Debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "Database credentials: `cat ~/pelican-panel.creds`",
+ "type": "info"
+ },
+ {
+ "text": "Step 5 of the Panel installer can be skipped because it has already been set up by the script.",
+ "type": "info"
+ }
+ ]
+}
diff --git a/json/pelican-wings.json b/json/pelican-wings.json
new file mode 100644
index 000000000..b587ef304
--- /dev/null
+++ b/json/pelican-wings.json
@@ -0,0 +1,39 @@
+{
+ "name": "Pelican Wings",
+ "slug": "pelican-wings",
+ "categories": [
+ 24
+ ],
+ "date_created": "2025-02-27",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": null,
+ "documentation": "https://pelican.dev/docs/wings/install",
+ "website": "https://pelican.dev/",
+ "logo": "https://pelican.dev/img/logo.png",
+ "description": "Pelican Wings is Pelican's server control plane, built for the rapidly changing gaming industry and designed to be highly performant and secure. Wings provides an HTTP API allowing you to interface directly with running server instances, fetch server logs, generate backups, and control all aspects of the server lifecycle.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/pelican-wings.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 4096,
+ "hdd": 8,
+ "os": "Debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "After installation, you need to use the Auto Deploy command generated by Pelican Panel and, after running the command, restart the Wings service with `systemctl restart wings.service`",
+ "type": "info"
+ }
+ ]
+}
diff --git a/json/pihole.json b/json/pihole.json
index 19124d1ed..17fc88530 100644
--- a/json/pihole.json
+++ b/json/pihole.json
@@ -32,7 +32,7 @@
},
"notes": [
{
- "text": "To set your password, log in to the container, and type the following: `pihole -a -p`",
+ "text": "To set your password, log in to the container, and type the following: `pihole setpassword`",
"type": "info"
},
{
diff --git a/json/pocketid.json b/json/pocketid.json
index 58fd59067..465b09ecd 100644
--- a/json/pocketid.json
+++ b/json/pocketid.json
@@ -9,8 +9,8 @@
"updateable": true,
"privileged": false,
"interface_port": 80,
- "documentation": "https://stonith404.github.io/pocket-id/introduction",
- "website": "https://github.com/stonith404/pocket-id",
+ "documentation": "https://pocket-id.org/docs/",
+ "website": "https://github.com/pocket-id/pocket-id",
"logo": "https://raw.githubusercontent.com/pocket-id/pocket-id/refs/heads/main/backend/resources/images/logoDark.svg",
"description": "Pocket ID is a simple OIDC provider that allows users to authenticate with their passkeys to your services.",
"install_methods": [
diff --git a/json/victoriametrics.json b/json/victoriametrics.json
new file mode 100644
index 000000000..43955e6ca
--- /dev/null
+++ b/json/victoriametrics.json
@@ -0,0 +1,34 @@
+{
+ "name": "VictoriaMetrics",
+ "slug": "victoria",
+ "categories": [
+ 8
+ ],
+ "date_created": "2025-02-24",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 8428,
+ "documentation": "https://docs.victoriametrics.com/",
+ "website": "https://victoriametrics.com/",
+ "logo": "https://marketplace-assets.digitalocean.com/logos/victoriametrics-victoriametricss.png",
+ "description": "VictoriaMetrics is a fast, cost-saving, and scalable solution for monitoring and managing time series data. It delivers high performance and reliability, making it an ideal choice for businesses of all sizes.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/victoriametrics.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 16,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+}
diff --git a/json/web-check.json b/json/web-check.json
new file mode 100644
index 000000000..53cda3439
--- /dev/null
+++ b/json/web-check.json
@@ -0,0 +1,34 @@
+{
+ "name": "Web-Check",
+ "slug": "web-check",
+ "categories": [
+ 4
+ ],
+ "date_created": "2025-02-27",
+ "type": "ct",
+ "updateable": false,
+ "privileged": false,
+ "interface_port": 3000,
+ "documentation": "https://github.com/Lissy93/web-check/blob/master/.github/README.md",
+ "website": "https://github.com/lissy93/web-check",
+ "logo": "https://raw.githubusercontent.com/Lissy93/web-check/refs/heads/master/.github/web-check-logo.png",
+ "description": "Get an insight into the inner-workings of a given website: uncover potential attack vectors, analyse server architecture, view security configurations, and learn what technologies a site is using.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/web-check.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 12,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+}
diff --git a/json/wger.json b/json/wger.json
new file mode 100644
index 000000000..c3282dfa4
--- /dev/null
+++ b/json/wger.json
@@ -0,0 +1,39 @@
+{
+ "name": "wger",
+ "slug": "wger",
+ "categories": [
+ 24
+ ],
+ "date_created": "2025-02-24",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 3000,
+ "documentation": "https://wger.readthedocs.io/en/latest/index.html#",
+ "website": "https://wger.de",
+ "logo": "https://avatars.githubusercontent.com/u/17430347?s=48&v=4",
+ "description": "wger (ΛvΙΙ‘Ι) Workout Manager is a free, open source web application that helps you manage your personal workouts, weight and diet plans and can also be used as a simple gym management utility. It offers a REST API as well, for easy integration with other projects and tools.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/wger.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 1024,
+ "hdd": 6,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": "admin",
+ "password": "adminadmin"
+ },
+ "notes": [
+ {
+ "text": "Enable proxy support by uncommenting this line in `/home/wger/src/settings.py` and pointing it to your URL: `# CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1', 'https://my.domain.example.com']`, then restart the service `systemctl restart wger`.",
+ "type": "info"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/json/zigbee2mqtt.json b/json/zigbee2mqtt.json
index 30b2bdf68..2379a4a7d 100644
--- a/json/zigbee2mqtt.json
+++ b/json/zigbee2mqtt.json
@@ -43,7 +43,7 @@
},
"notes": [
{
- "text": "You can find the post-install guide here: https://github.com/community-scripts/ProxmoxVE/discussions/410",
+ "text": "You can find the post-install guide here: `https://github.com/community-scripts/ProxmoxVE/discussions/410`",
"type": "info"
}
],
diff --git a/misc/add-tailscale-lxc.sh b/misc/add-tailscale-lxc.sh
index 36d148e40..93f37b9cd 100644
--- a/misc/add-tailscale-lxc.sh
+++ b/misc/add-tailscale-lxc.sh
@@ -67,6 +67,9 @@ echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://
apt-get update &>/dev/null
apt-get install -y tailscale &>/dev/null
' || exit
+TAGS=$(awk -F': ' '/^tags:/ {print $2}' /etc/pve/lxc/${CTID}.conf)
+TAGS="${TAGS:+$TAGS; }tailscale"
+pct set "$CTID" -tags "${TAGS}"
msg "\e[1;32m β Installed Tailscale\e[0m"
msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run tailscale up in the LXC console\e[0m"
diff --git a/misc/alpine-install.func b/misc/alpine-install.func
index b727b8eca..c00474a66 100644
--- a/misc/alpine-install.func
+++ b/misc/alpine-install.func
@@ -17,7 +17,7 @@ color() {
BFR="\\r\\033[K"
BOLD=$(echo "\033[1m")
TAB=" "
-
+
# System
RETRY_NUM=10
RETRY_EVERY=3
@@ -35,12 +35,24 @@ color() {
DEFAULT="${TAB}βοΈ${TAB}${CL}"
}
-# This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to "yes"
-verb_ip6() {
+# Function to set STD mode based on verbosity
+set_std_mode() {
if [ "$VERBOSE" = "yes" ]; then
STD=""
- else STD="silent"; fi
- silent() { "$@" >/dev/null 2>&1; }
+ else
+ STD="silent"
+ fi
+}
+
+# Silent execution function
+silent() {
+ "$@" >/dev/null 2>&1
+}
+
+# This function enables IPv6 if it's not disabled and sets verbose mode
+verb_ip6() {
+ set_std_mode # Set STD mode based on VERBOSE
+
if [ "$DISABLEIPV6" == "yes" ]; then
$STD sysctl -w net.ipv6.conf.all.disable_ipv6=1
echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf
@@ -106,15 +118,15 @@ setting_up_container() {
network_check() {
set +e
trap - ERR
- if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
- msg_ok "Internet Connected";
+ if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
+ msg_ok "Internet Connected"
else
msg_error "Internet NOT Connected"
read -r -p "Would you like to continue anyway? " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
else
- echo -e "${NETWORK}Check Network Settings"
+ echo -e "${NETWORK}Check Network Settings"
exit 1
fi
fi
@@ -147,13 +159,13 @@ motd_ssh() {
fi
PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
- echo "echo -e \"\"" > "$PROFILE_FILE"
- echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts & pimox-scripts ${YW}| GitHub: ${GN}https://github.com/asylumexp/Proxmox${CL}\"" >> "$PROFILE_FILE"
- echo "echo \"\"" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${OS}${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(ip -4 addr show eth0 | awk '/inet / {print \$2}' | cut -d/ -f1 | head -n 1)${CL}\"" >> "$PROFILE_FILE"
+ echo "echo -e \"\"" >"$PROFILE_FILE"
+ echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts & pimox-scripts ${YW}| GitHub: ${GN}https://github.com/asylumexp/ProxmoxVE${CL}\"" >>"$PROFILE_FILE"
+ echo "echo \"\"" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${OS}${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(ip -4 addr show eth0 | awk '/inet / {print \$2}' | cut -d/ -f1 | head -n 1)${CL}\"" >>"$PROFILE_FILE"
# Configure SSH if enabled
if [[ "${SSH_ROOT}" == "yes" ]]; then
@@ -169,8 +181,8 @@ motd_ssh() {
# This function customizes the container and enables passwordless login for the root user
customize() {
if [[ "$PASSWORD" == "" ]]; then
- msg_info "Customizing Container"
- bash -c "passwd -d root" >/dev/null 2>&1
- msg_ok "Customized Container"
+ msg_info "Customizing Container"
+ bash -c "passwd -d root" >/dev/null 2>&1
+ msg_ok "Customized Container"
fi
}
diff --git a/misc/build.func b/misc/build.func
index 9cba9936d..cd244f53c 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -4,16 +4,16 @@
# https://github.com/asylumexp/Proxmox/raw/main/LICENSE
variables() {
- NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
- var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
- INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
- PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase
- DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call.
- METHOD="default" # sets the METHOD variable to "default", used for the API call.
+ NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
+ var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
+ INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
+ PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase
+ DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call.
+ METHOD="default" # sets the METHOD variable to "default", used for the API call.
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
}
-source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
+source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/api.func)
# This function sets various color variables using ANSI escape codes for formatting text in the terminal.
color() {
@@ -68,55 +68,86 @@ catch_errors() {
# This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message.
error_handler() {
- source /dev/stdin <<< $(wget -qLO - https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
+ source /dev/stdin <<<$(wget -qLO - https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/api.func)
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
local exit_code="$?"
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
- post_update_to_api "failed" "${command}"
+ post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
}
-# This function displays a spinner.
-spinner() {
+# This function displays an informational message with logging support.
+start_spinner() {
+ local msg="$1"
local frames=('β ' 'β ' 'β Ή' 'β Έ' 'β Ό' 'β ΄' 'β ¦' 'β §' 'β ' 'β ')
local spin_i=0
local interval=0.1
- printf "\e[?25l"
+ local term_width=$(tput cols)
- local color="${YWB}"
+ {
+ while [ "${SPINNER_ACTIVE:-1}" -eq 1 ]; do
+ printf "\r\e[2K${frames[spin_i]} ${YW}%b${CL}" "$msg" >&2
+ spin_i=$(((spin_i + 1) % ${#frames[@]}))
+ sleep "$interval"
+ done
+ } &
- while true; do
- printf "\r ${color}%s${CL}" "${frames[spin_i]}"
- spin_i=$(( (spin_i + 1) % ${#frames[@]} ))
- sleep "$interval"
- done
-}
-
-# This function displays an informational message with a yellow color.
-msg_info() {
- local msg="$1"
- echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
- spinner &
SPINNER_PID=$!
}
-# This function displays a success message with a green color.
-msg_ok() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
- printf "\e[?25h"
+msg_info() {
local msg="$1"
- echo -e "${BFR}${CM}${GN}${msg}${CL}"
+ if [ "${SPINNER_ACTIVE:-0}" -eq 1 ]; then
+ return
+ fi
+
+ SPINNER_ACTIVE=1
+ start_spinner "$msg"
}
-# This function displays a error message with a red color.
-msg_error() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
- printf "\e[?25h"
+msg_ok() {
+ if [ -n "${SPINNER_PID:-}" ] && ps -p "$SPINNER_PID" >/dev/null 2>&1; then
+ kill "$SPINNER_PID" >/dev/null 2>&1
+ wait "$SPINNER_PID" 2>/dev/null || true
+ fi
+
local msg="$1"
- echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
+ printf "\r\e[2K${CM}${GN}%b${CL}\n" "$msg" >&2
+ unset SPINNER_PID
+ SPINNER_ACTIVE=0
+
+ log_message "OK" "$msg"
+}
+
+msg_error() {
+ if [ -n "${SPINNER_PID:-}" ] && ps -p "$SPINNER_PID" >/dev/null 2>&1; then
+ kill "$SPINNER_PID" >/dev/null 2>&1
+ wait "$SPINNER_PID" 2>/dev/null || true
+ fi
+
+ local msg="$1"
+ printf "\r\e[2K${CROSS}${RD}%b${CL}\n" "$msg" >&2
+ unset SPINNER_PID
+ SPINNER_ACTIVE=0
+ log_message "ERROR" "$msg"
+}
+
+log_message() {
+ local level="$1"
+ local message="$2"
+ local timestamp
+ local logdate
+ timestamp=$(date '+%Y-%m-%d %H:%M:%S')
+ logdate=$(date '+%Y-%m-%d')
+
+ LOGDIR="/usr/local/community-scripts/logs"
+ mkdir -p "$LOGDIR"
+
+ LOGFILE="${LOGDIR}/${logdate}_${NSAPP}.log"
+ echo "$timestamp - $level: $message" >>"$LOGFILE"
}
# Check if the shell is using bash
@@ -235,14 +266,14 @@ update_motd_ip() {
IP=$(get_current_ip)
# Add the new IP address
- echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >> "$MOTD_FILE"
+ echo -e "${TAB}${NETWORK}${YW} IP Address: ${GN}${IP}${CL}" >>"$MOTD_FILE"
fi
}
# 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 app_name=$(echo ${APP,,} | tr -d ' ')
+ local header_url="https://github.com/asylumexp/Proxmox/raw/main/ct/headers/${app_name}"
local local_header_path="/usr/local/community-scripts/headers/${app_name}"
mkdir -p "/usr/local/community-scripts/headers"
@@ -260,7 +291,7 @@ get_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 app_name=$(echo ${APP,,} | tr -d ' ')
local header_content
# Download & save Header-File locally
@@ -794,14 +825,14 @@ advanced_settings() {
fi
}
-diagnostics_check(){
+diagnostics_check() {
if ! [ -d "/usr/local/community-scripts" ]; then
- mkdir -p /usr/local/community-scripts
- fi
+ mkdir -p /usr/local/community-scripts
+ fi
- if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then
- if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then
- cat </usr/local/community-scripts/diagnostics
+ if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then
+ if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then
+ cat </usr/local/community-scripts/diagnostics
DIAGNOSTICS=yes
#This file is used to store the diagnostics settings for the Community-Scripts API.
@@ -918,23 +949,24 @@ install_script() {
advanced_settings
break
;;
- 4)
- if [[ $DIAGNOSTICS == "yes" ]]; then
- if whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \
- --yes-button "No" --no-button "Back" ; then
- DIAGNOSTICS="no"
- sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics
- whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58
- fi
- else
- if whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \
- --yes-button "Yes" --no-button "Back" ; then
- DIAGNOSTICS="yes"
- sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics
- whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58
- fi
- fi
- ;;
+ 4)
+ if [[ $DIAGNOSTICS == "yes" ]]; then
+ if whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \
+ --yes-button "No" --no-button "Back"; then
+ DIAGNOSTICS="no"
+ sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics
+ whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58
+ fi
+ else
+ if whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \
+ --yes-button "Yes" --no-button "Back"; then
+ DIAGNOSTICS="yes"
+ sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics
+ whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --msgbox "Diagnostics settings changed to ${DIAGNOSTICS}." 8 58
+ fi
+ fi
+
+ ;;
5)
echo -e "${CROSS}${RD}Exiting.${CL}"
exit 0
@@ -971,8 +1003,8 @@ check_container_storage() {
# Check if the /boot partition is more than 80% full
total_size=$(df /boot --output=size | tail -n 1)
local used_size=$(df /boot --output=used | tail -n 1)
- usage=$(( 100 * used_size / total_size ))
- if (( usage > 80 )); then
+ usage=$((100 * used_size / total_size))
+ if ((usage > 80)); then
# Prompt the user for confirmation to continue
echo -e "${INFO}${HOLD} ${YWB}Warning: Storage is dangerously low (${usage}%).${CL}"
echo -ne "Continue anyway? "
@@ -986,6 +1018,9 @@ check_container_storage() {
}
start() {
+ LOGDIR="/usr/local/community-scripts/logs"
+ mkdir -p "$LOGDIR"
+
if command -v pveversion >/dev/null 2>&1; then
if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then
clear
@@ -1002,11 +1037,32 @@ start() {
elif [ -f /etc/alpine-release ]; then
apk add --no-cache whiptail &>/dev/null
fi
- if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC UPDATE" --yesno "Support/Update functions for ${APP} LXC. Proceed?" 10 58); then
+ CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP} LXC Update/Setting" --menu \
+ "Support/Update functions for ${APP} LXC. Choose an option:" \
+ 12 60 3 \
+ "1" "YES (Silent Mode)" \
+ "2" "YES (Verbose Mode)" \
+ "3" "NO (Cancel Update)" --nocancel --default-item "1" 3>&1 1>&2 2>&3)
+
+ case "$CHOICE" in
+ 1)
+ VERB="no"
+ set_std_mode
+ log_message "INFO" "Update started (Silent Mode)"
+ ;;
+ 2)
+ VERB="yes"
+ set_std_mode
+ log_message "INFO" "Update started (Verbose Mode)"
+ ;;
+ 3)
clear
+ log_message "INFO" "Update aborted."
exit_script
exit
- fi
+ ;;
+ esac
+
SPINNER_PID=""
update_script
fi
@@ -1138,7 +1194,7 @@ description() {
cat <
-
+
${APP} LXC
@@ -1171,36 +1227,52 @@ EOF
if [[ -f /etc/systemd/system/ping-instances.service ]]; then
systemctl start ping-instances.service
fi
-
+
post_update_to_api "done" "none"
}
+set_std_mode() {
+ if [ "$VERB" = "yes" ]; then
+ STD=""
+ else
+ STD="silent"
+ fi
+}
+
+# Silent execution function
+silent() {
+ if [ "$VERB" = "no" ]; then
+ "$@" >>"$LOGFILE" 2>&1
+ else
+ "$@" 2>&1 | tee -a "$LOGFILE"
+ fi
+}
exit_script() {
- exit_code=$? # Capture the exit status of the last executed command
+ exit_code=$? # Capture the exit status of the last executed command
#200 exit codes indicate error in create_lxc.sh
#100 exit codes indicate error in install.func
-if [ $exit_code -ne 0 ]; then # Check if exit code is nonzero
+ if [ $exit_code -ne 0 ]; then
case $exit_code in
- 200) post_update_to_api "failed" "create_lxc.sh: Error during LXC creation" ;;
- 201) post_update_to_api "failed" "create_lxc.sh Invalid Storage class" ;;
- 202) post_update_to_api "failed" "create_lxc.sh Invalid Menu aborted" ;;
- 203) post_update_to_api "failed" "create_lxc.sh CTID was unset" ;;
- 204) post_update_to_api "failed" "create_lxc.sh PCT_OSTYPE was unset" ;;
- 205) post_update_to_api "failed" "create_lxc.sh ID cannot be less than 100" ;;
- 206) post_update_to_api "failed" "create_lxc.sh ID already in use" ;;
- 207) post_update_to_api "failed" "create_lxc.sh Template not found" ;;
- 208) post_update_to_api "failed" "create_lxc.sh Error downloading template" ;;
- 101) post_update_to_api "failed" "create_lxc.sh No Network connection" ;;
- *) post_update_to_api "failed" "Unknown error, exit code: $exit_code" ;;
+ 100) post_update_to_api "failed" "100: Unexpected error in create_lxc.sh" ;;
+ 101) post_update_to_api "failed" "101: No network connection detected in create_lxc.sh" ;;
+ 200) post_update_to_api "failed" "200: LXC creation failed in create_lxc.sh" ;;
+ 201) post_update_to_api "failed" "201: Invalid Storage class in create_lxc.sh" ;;
+ 202) post_update_to_api "failed" "202: User aborted menu in create_lxc.sh" ;;
+ 203) post_update_to_api "failed" "203: CTID not set in create_lxc.sh" ;;
+ 204) post_update_to_api "failed" "204: PCT_OSTYPE not set in create_lxc.sh" ;;
+ 205) post_update_to_api "failed" "205: CTID cannot be less than 100 in create_lxc.sh" ;;
+ 206) post_update_to_api "failed" "206: CTID already in use in create_lxc.sh" ;;
+ 207) post_update_to_api "failed" "207: Template not found in create_lxc.sh" ;;
+ 208) post_update_to_api "failed" "208: Error downloading template in create_lxc.sh" ;;
+ 209) post_update_to_api "failed" "209: Container creation failed, but template is intact in create_lxc.sh" ;;
+ *) post_update_to_api "failed" "Unknown error, exit code: $exit_code in create_lxc.sh" ;;
esac
-fi
+ fi
}
-
trap 'exit_script' EXIT
trap 'post_update_to_api "failed" "$BASH_COMMAND"' ERR
-trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
+trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
-
diff --git a/misc/install.func b/misc/install.func
index 4ee21fec4..ca20669bb 100644
--- a/misc/install.func
+++ b/misc/install.func
@@ -18,7 +18,7 @@ color() {
BOLD=$(echo "\033[1m")
HOLD=" "
TAB=" "
-
+
# System
RETRY_NUM=10
RETRY_EVERY=3
@@ -35,12 +35,24 @@ color() {
DEFAULT="${TAB}βοΈ${TAB}${CL}"
}
-# This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to "yes"
-verb_ip6() {
+# Function to set STD mode based on verbosity
+set_std_mode() {
if [ "$VERBOSE" = "yes" ]; then
STD=""
- else STD="silent"; fi
- silent() { "$@" >/dev/null 2>&1; }
+ else
+ STD="silent"
+ fi
+}
+
+# Silent execution function
+silent() {
+ "$@" >/dev/null 2>&1
+}
+
+# This function enables IPv6 if it's not disabled and sets verbose mode
+verb_ip6() {
+ set_std_mode # Set STD mode based on VERBOSE
+
if [ "$DISABLEIPV6" == "yes" ]; then
echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf
$STD sysctl -p
@@ -56,14 +68,14 @@ catch_errors() {
# This function handles errors
error_handler() {
source <(wget -qLO - https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
local exit_code="$?"
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message"
- if [[ "$line_number" -eq 44 ]]; then
+ if [[ "$line_number" -eq 50 ]]; then
echo -e "The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\n"
post_update_to_api "failed" "No error message, script ran in silent mode"
else
@@ -82,7 +94,7 @@ spinner() {
while true; do
printf "\r ${color}%s${CL}" "${frames[spin_i]}"
- spin_i=$(( (spin_i + 1) % ${#frames[@]} ))
+ spin_i=$(((spin_i + 1) % ${#frames[@]}))
sleep "$interval"
done
}
@@ -97,7 +109,7 @@ msg_info() {
# This function displays a success message with a green color.
msg_ok() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
local msg="$1"
echo -e "${BFR}${CM}${GN}${msg}${CL}"
@@ -105,7 +117,7 @@ msg_ok() {
# This function displays a error message with a red color.
msg_error() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
local msg="$1"
echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
@@ -146,23 +158,23 @@ network_check() {
ipv4_connected=false
ipv6_connected=false
sleep 1
-# Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers.
- if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
- msg_ok "IPv4 Internet Connected";
+ # Check IPv4 connectivity to Google, Cloudflare & Quad9 DNS servers.
+ if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
+ msg_ok "IPv4 Internet Connected"
ipv4_connected=true
else
- msg_error "IPv4 Internet Not Connected";
+ msg_error "IPv4 Internet Not Connected"
fi
-# Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers.
+ # Check IPv6 connectivity to Google, Cloudflare & Quad9 DNS servers.
if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null || ping6 -c 1 -W 1 2001:4860:4860::8888 &>/dev/null || ping6 -c 1 -W 1 2620:fe::fe &>/dev/null; then
- msg_ok "IPv6 Internet Connected";
+ msg_ok "IPv6 Internet Connected"
ipv6_connected=true
else
- msg_error "IPv6 Internet Not Connected";
+ msg_error "IPv6 Internet Not Connected"
fi
-# If both IPv4 and IPv6 checks fail, prompt the user
+ # If both IPv4 and IPv6 checks fail, prompt the user
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
read -r -p "No Internet detected,would you like to continue anyway? " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
@@ -192,7 +204,7 @@ else
echo -n "DIRECT"
fi
EOF
- chmod +x /usr/local/bin/apt-proxy-detect.sh
+ chmod +x /usr/local/bin/apt-proxy-detect.sh
fi
$STD apt-get update
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
@@ -203,7 +215,7 @@ EOF
# This function modifies the message of the day (motd) and SSH settings
motd_ssh() {
# Set terminal to 256-color mode
- grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >> /root/.bashrc
+ grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc
# Get OS information (Debian / Ubuntu)
if [ -f "/etc/os-release" ]; then
@@ -215,13 +227,13 @@ motd_ssh() {
fi
PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
- echo "echo -e \"\"" > "$PROFILE_FILE"
- echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts & pimox-scripts ${YW}| GitHub: ${GN}https://github.com/asylumexp/Proxmox${CL}\"" >> "$PROFILE_FILE"
- echo "echo \"\"" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${OS}${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >> "$PROFILE_FILE"
- echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >> "$PROFILE_FILE"
+ echo "echo -e \"\"" >"$PROFILE_FILE"
+ echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts & pimox-scripts ${YW}| GitHub: ${GN}https://github.com/asylumexp/ProxmoxVE${CL}\"" >>"$PROFILE_FILE"
+ echo "echo \"\"" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${OS}${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
+ echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE"
# Disable default MOTD scripts
chmod -x /etc/update-motd.d/*
@@ -252,7 +264,7 @@ EOF
if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then
mkdir -p /root/.ssh
- echo "${SSH_AUTHORIZED_KEY}" > /root/.ssh/authorized_keys
+ echo "${SSH_AUTHORIZED_KEY}" >/root/.ssh/authorized_keys
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
fi