diff --git a/.devcontainer/.dockerignore b/.devcontainer/.dockerignore new file mode 100644 index 0000000..611e18a --- /dev/null +++ b/.devcontainer/.dockerignore @@ -0,0 +1,8 @@ +# ignore vars files +*.vars +# ignore tarballs +*.tar.* +# ignore kclvm dir +.kclvm +# ignore test generation +_lxc* \ No newline at end of file diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 6c8c386..fea2455 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,17 +3,21 @@ FROM ubuntu:latest RUN apt-get update && apt-get upgrade -y && \ apt-get install -y \ build-essential \ + gnupg2 \ debootstrap \ + squashfs-tools \ + make \ + rsync \ curl \ wget \ git \ vim \ unzip \ - squashfs-tools \ && apt-get clean all \ && rm -rf /var/lib/apt/lists/* RUN wget -q https://kcl-lang.io/script/install-cli.sh -O - | bash && \ + wget -q https://kcl-lang.io/script/install-kcl-lsp.sh -O - | bash && \ wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && \ chmod +x /usr/bin/yq diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8946b37..a5ce59b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,8 +6,14 @@ "dockerfile": "Dockerfile" }, "remoteUser": "root", - "workspaceMount": "source=${localWorkspaceFolder},target=/workspace/homelab-lxc,type=bind,consistency=cached,Z=true", - "workspaceFolder": "/workspace/homelab-lxc", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/homelab-lxc,type=bind,consistency=cached,Z=true", + "workspaceFolder": "/workspaces/homelab-lxc", + "initializeCommand": { + "clean_kcl": "rm -rf ${localWorkspaceFolder}/.kclvm", + "clean_partial": "rm -f ${localWorkspaceFolder}/_lxc-partial.yml", + "clean_template": "rm -f ${localWorkspaceFolder}/_lxc-template.yml", + "clean_image": "rm -f ${localWorkspaceFolder}/*.tar.*" + }, "customizations": { "vscode": { "extensions": [ @@ -15,7 +21,8 @@ "eamodio.gitlens", "kcl.kcl-vscode-extension", "redhat.vscode-yaml", - "stateful.runme" + "stateful.runme", + "github.vscode-github-actions" ] } } diff --git a/renovate.json b/.github/renovate.json similarity index 100% rename from renovate.json rename to .github/renovate.json diff --git a/.github/workflows/build-apisix.yml b/.github/workflows/build-apisix.yml deleted file mode 100644 index 3424c27..0000000 --- a/.github/workflows/build-apisix.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build APISIX LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-apisix.yml' - - 'templates/apisix.yml' - schedule: - - cron: '0 2 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/apache/apisix/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/apisix.yml - app_name: apisix - app_version: ${{needs.init.outputs.app_version}} - description: Full Lifecycle API Management platform to help you manage microservices, delivering the ultimate performance and security. - categories: Loadbalancer, API Gateway, Reverse Proxy - project_source: https://github.com/apache/apisix - distribution: debian - release: bullseye - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-codeserver.yml b/.github/workflows/build-codeserver.yml deleted file mode 100644 index ab4f2eb..0000000 --- a/.github/workflows/build-codeserver.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Code-Server LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-codeserver.yml' - - 'templates/code-server.yml' - schedule: - - cron: '0 2 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/code-server.yml - app_name: code-server - app_version: ${{needs.init.outputs.app_version}} - description: Coder is an open source cloud development environment (CDE), based on VS Code. - categories: IDE, Dev - project_source: https://github.com/coder/code-server - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-gitea.yml b/.github/workflows/build-gitea.yml deleted file mode 100644 index 1af89b3..0000000 --- a/.github/workflows/build-gitea.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Gitea LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-gitea.yml' - - 'templates/gitea.yml' - schedule: - - cron: '0 2 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://dl.gitea.com/gitea/version.json| jq -r '.latest.version' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/gitea.yml - app_name: gitea - app_version: ${{needs.init.outputs.app_version}} - description: Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD. - categories: Git, CI CD, Dev - project_source: https://github.com/go-gitea/gitea - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-homarr.yml b/.github/workflows/build-homarr.yml deleted file mode 100644 index 0e265e5..0000000 --- a/.github/workflows/build-homarr.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Homarr LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-homarr.yml' - - 'templates/homarr.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/homarr.yml - app_name: homarr - app_version: ${{needs.init.outputs.app_version}} - description: A simple, yet powerful dashboard for your server. - categories: Homepage - project_source: https://github.com/ajnart/homarr - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-infisical.yml b/.github/workflows/build-infisical.yml deleted file mode 100644 index ce05fc0..0000000 --- a/.github/workflows/build-infisical.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Build Infisical LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-infisical.yml' - - 'templates/infisical.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - DG=$(curl -s "https://hub.docker.com/v2/repositories/infisical/infisical/tags/" | jq -r '.results[] | select(.name |contains("latest-postgres"))|.digest') - echo "APP_VERSION=$(curl -s "https://hub.docker.com/v2/repositories/infisical/infisical/tags/"| jq --arg digest $DG -r '.results[] | select(.digest |contains($digest)) | select(.name |test("^v")) | .name' | sed -E 's/^(v|V)//' | sed -E 's/-postgres//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/infisical.yml - app_name: infisical - app_version: ${{needs.init.outputs.app_version}} - description: Open Source all-in-one secret management platform to securely manage application configuration and secrets across your team and infrastructure. - categories: Secrets management, Security - project_source: https://github.com/Infisical/infisical - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-ittools.yml b/.github/workflows/build-ittools.yml deleted file mode 100644 index a42b629..0000000 --- a/.github/workflows/build-ittools.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build IT-Tools LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-ittools.yml' - - 'templates/ittools.yml' - schedule: - - cron: '0 0 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/CorentinTh/it-tools/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/ittools.yml - app_name: it-tools - app_version: ${{needs.init.outputs.app_version}} - description: Useful tools for developers and peoples working in IT. - categories: Dev, Collection - project_source: https://github.com/CorentinTh/it-tools - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-jellyfin.yml b/.github/workflows/build-jellyfin.yml deleted file mode 100644 index 988605a..0000000 --- a/.github/workflows/build-jellyfin.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Jellyfin LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-jellyfin.yml' - - 'templates/jellyfin.yml' - schedule: - - cron: '0 0 */15 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/jellyfin/jellyfin/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/jellyfin.yml - app_name: jellyfin - app_version: ${{needs.init.outputs.app_version}} - description: A Free Software Media System to collect, manage, and stream your media. - categories: Media, Streaming - project_source: https://github.com/jellyfin/jellyfin - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-jellyseerr.yml b/.github/workflows/build-jellyseerr.yml deleted file mode 100644 index 35cd529..0000000 --- a/.github/workflows/build-jellyseerr.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Jellyseerr LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-jellyseerr.yml' - - 'templates/jellyseerr.yml' - schedule: - - cron: '0 0 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/Fallenbagel/jellyseerr/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/jellyseerr.yml - app_name: jellyseerr - app_version: ${{needs.init.outputs.app_version}} - description: Open source software application for managing requests for your media library. - categories: Media, Streaming - project_source: https://github.com/Fallenbagel/jellyseerr - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-jenkins.yml b/.github/workflows/build-jenkins.yml deleted file mode 100644 index 4a7cb7c..0000000 --- a/.github/workflows/build-jenkins.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Jenkins LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-jenkins.yml' - - 'templates/jenkins.yml' - schedule: - - cron: '0 0 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -Ls https://updates.jenkins.io/stable/latestCore.txt | sed -E 's/^v|V//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/jenkins.yml - app_name: jenkins - app_version: ${{needs.init.outputs.app_version}} - description: The leading open source automation server. Build great things at any scale. - categories: Automation, CI CD, Dev - project_source: https://github.com/jenkinsci/jenkins - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-jupyterlab.yml b/.github/workflows/build-jupyterlab.yml deleted file mode 100644 index b4345fe..0000000 --- a/.github/workflows/build-jupyterlab.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build JupyterLab LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-jupyterlab.yml' - - 'templates/jupyterlab.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/jupyterlab/jupyterlab/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/jupyterlab.yml - app_name: jupyterlab - app_version: ${{needs.init.outputs.app_version}} - description: JupyterLab is the latest web-based interactive development environment for notebooks, code, and data. - categories: IDE, Python, Dev - project_source: https://github.com/jupyterlab/jupyterlab - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-kestra.yml b/.github/workflows/build-kestra.yml deleted file mode 100644 index c59d5b9..0000000 --- a/.github/workflows/build-kestra.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Kestra LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-kestra.yml' - - 'templates/kestra.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/kestra-io/kestra/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/kestra.yml - app_name: kestra - app_version: ${{needs.init.outputs.app_version}} - description: Kestra is a free and open-source workflow orchestrator and automation tool. - categories: Automation, Workflows - project_source: https://github.com/kestra-io/kestra - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-keycloak.yml b/.github/workflows/build-keycloak.yml deleted file mode 100644 index a2703d8..0000000 --- a/.github/workflows/build-keycloak.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Keycloak LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-keycloak.yml' - - 'templates/keycloak.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -Ls https://api.github.com/repos/keycloak/keycloak/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/keycloak.yml - app_name: keycloak - app_version: ${{needs.init.outputs.app_version}} - description: Open Source Identity and Access Management. - categories: Identity, IAM, IDP, Security - project_source: https://github.com/keycloak/keycloak - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-matomo.yml b/.github/workflows/build-matomo.yml deleted file mode 100644 index 71f89ab..0000000 --- a/.github/workflows/build-matomo.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Matomo LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-matomo.yml' - - 'templates/matomo.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/matomo-org/matomo/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/matomo.yml - app_name: matomo - app_version: ${{needs.init.outputs.app_version}} - description: Google Analytics alternative that protects your data and your customers' privacy. - categories: Analytics, SEO, Tracking - project_source: https://github.com/matomo-org/matomo - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-n8n.yml b/.github/workflows/build-n8n.yml deleted file mode 100644 index 7e2184e..0000000 --- a/.github/workflows/build-n8n.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build n8n LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-n8n.yml' - - 'templates/n8n.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/n8n-io/n8n/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/n8n.yml - app_name: n8n - app_version: ${{needs.init.outputs.app_version}} - description: n8n is a free and source-available workflow automation tool. - categories: Automation, Workflows - project_source: https://github.com/n8n-io/n8n - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-nextcloud.yml b/.github/workflows/build-nextcloud.yml deleted file mode 100644 index ff6dd97..0000000 --- a/.github/workflows/build-nextcloud.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build NextCloud LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-nextcloud.yml' - - 'templates/nextcloud.yml' - schedule: - - cron: '0 1 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/nextcloud/server/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/nextcloud.yml - app_name: nextcloud - app_version: ${{needs.init.outputs.app_version}} - description: Fully open-source, on-premises content collaboration platform. - categories: Personal Cloud, Data Privacy - project_source: https://github.com/nextcloud/server - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-servarr.yml b/.github/workflows/build-servarr.yml deleted file mode 100644 index b231e4e..0000000 --- a/.github/workflows/build-servarr.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build ServARR LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-servarr.yml' - - 'templates/servarr.yml' - schedule: - - cron: '0 0 1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(date +%Y-%m)" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/servarr.yml - app_name: servarr - app_version: ${{needs.init.outputs.app_version}} - description: Media organizer/manager stack (ARR) for usenet and torrent users. This stack includes QBitTorrent, SABnzbd, FlareSolverr, Bazarr and the ARR stack. - categories: Movies, TV, Torrent - project_source: https://wiki.servarr.com - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-tester.yml b/.github/workflows/build-tester.yml index a5fa838..1d6c192 100644 --- a/.github/workflows/build-tester.yml +++ b/.github/workflows/build-tester.yml @@ -10,28 +10,22 @@ on: branches: - main paths: - - '.github/publish_build.hurl' - - '.github/workflows/builder.yml' - - '.github/workflows/build-tester.yml' + - ".github/publish_build.hurl" + - ".github/workflows/builder.yml" + - ".github/workflows/build-tester.yml" jobs: + init: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + image-build: if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - strategy: - matrix: - architectures: - - amd64 uses: ./.github/workflows/builder.yml with: config_path: templates/debian-test.yml - app_name: dummy_app - app_version: '0.0.0' - description: Dummy test - categories: test, dummy - project_source: https://github.com/soubinan/homelab-lxc - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} branch_name: test is_merged: false secrets: inherit diff --git a/.github/workflows/build-vault.yml b/.github/workflows/build-vault.yml deleted file mode 100644 index baf49ad..0000000 --- a/.github/workflows/build-vault.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Vault LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-vault.yml' - - 'templates/vault.yml' - schedule: - - cron: '0 0 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/hashicorp/vault/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/vault.yml - app_name: vault - app_version: ${{needs.init.outputs.app_version}} - description: Vault is a free and source-available secrets management tool / secrets store. - categories: Secrets management, Security - project_source: https://github.com/hashicorp/vault - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/build-zitadel.yml b/.github/workflows/build-zitadel.yml deleted file mode 100644 index ac244d5..0000000 --- a/.github/workflows/build-zitadel.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Zitadel LXC Image - -on: - pull_request: - types: - - opened - - synchronize - - reopened - - closed - branches: - - main - paths: - - '.github/workflows/build-zitadel.yml' - - 'templates/zitadel.yml' - schedule: - - cron: '0 0 */1 * *' - -jobs: - init: - if: github.event.action != 'closed' || (github.event.action == 'closed' && github.event.pull_request.merged) - runs-on: ubuntu-latest - steps: - - name: Get Application version - id: get-app-version - run: | - echo "APP_VERSION=$(curl -s https://api.github.com/repos/zitadel/zitadel/releases/latest | jq -r '.tag_name' | sed -E 's/^v|V|.+@//')" >> $GITHUB_OUTPUT - outputs: - app_version: ${{steps.get-app-version.outputs.APP_VERSION}} - - image-build: - needs: init - strategy: - matrix: - architectures: - - amd64 - uses: ./.github/workflows/builder.yml - with: - config_path: templates/zitadel.yml - app_name: zitadel - app_version: ${{needs.init.outputs.app_version}} - description: Zitadel is a free and open-source secure authentication management tool. - categories: IAM, Authentication - project_source: https://github.com/zitadel/zitadel - distribution: debian - release: bookworm - architecture: ${{matrix.architectures}} - branch_name: ${{github.event.pull_request.base.ref}} - is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} - secrets: inherit diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index eb46a4a..0d12868 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -6,30 +6,6 @@ on: config_path: required: true type: string - app_name: - required: true - type: string - app_version: - required: true - type: string - description: - required: true - type: string - categories: - required: true - type: string - project_source: - required: true - type: string - distribution: - required: true - type: string - architecture: - required: true - type: string - release: - required: true - type: string branch_name: required: true type: string @@ -47,62 +23,100 @@ on: required: true jobs: + init: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Get params + id: get-params + run: | + GET_VERSION_COMMAND=$(eval "$(cat ${{inputs.config_path}} | yq -r '.metadata.get_version_command') | sed -E 's/^[vV]//'") + + echo "APP_VERSION=$(echo $GET_VERSION_COMMAND)" | tee -a $GITHUB_OUTPUT + echo "APP_NAME=$(cat ${{inputs.config_path}} | yq -r '.metadata.name = (.metadata.name | downcase) | .metadata.name')" | tee -a $GITHUB_OUTPUT + echo "DESCRIPTION=$(cat ${{inputs.config_path}} | yq -r '.metadata.description = (.metadata.description | downcase) | .metadata.description')" | tee -a $GITHUB_OUTPUT + echo "CATEGORIES=$(cat ${{inputs.config_path}} | yq -r '.metadata.categories = (.metadata.categories | downcase) | .metadata.categories')" | tee -a $GITHUB_OUTPUT + echo "PROJECT_SOURCE=$(cat ${{inputs.config_path}} | yq -r '.metadata.project_source = (.metadata.project_source | downcase) | .metadata.project_source')" | tee -a $GITHUB_OUTPUT + echo "DISTRIBUTION=$(cat ${{inputs.config_path}} | yq -r '.metadata.distribution = (.metadata.distribution | downcase) | .metadata.distribution')" | tee -a $GITHUB_OUTPUT + echo "ARCHITECTURES=$(cat ${{inputs.config_path}} | yq -r '.metadata.architectures' -o json -I=0)" | tee -a $GITHUB_OUTPUT + echo "RELEASE=$(cat ${{inputs.config_path}} | yq -r '.metadata.release = (.metadata.release | downcase) | .metadata.release')" | tee -a $GITHUB_OUTPUT + outputs: + app_name: ${{steps.get-params.outputs.APP_NAME}} + app_version: ${{steps.get-params.outputs.APP_VERSION}} + description: ${{steps.get-params.outputs.DESCRIPTION}} + categories: ${{steps.get-params.outputs.CATEGORIES}} + project_source: ${{steps.get-params.outputs.PROJECT_SOURCE}} + distribution: ${{steps.get-params.outputs.DISTRIBUTION}} + architectures: ${{steps.get-params.outputs.ARCHITECTURES}} + release: ${{steps.get-params.outputs.RELEASE}} + image-build: - if: ${{inputs.app_version}} != "null" && ${{inputs.app_version}} != "" + needs: init + if: ${{needs.init.outputs.app_version}} != "null" && ${{needs.init.outputs.app_version}} != "" runs-on: ubuntu-latest + strategy: + matrix: + architectures: ${{ fromJson(needs.init.outputs.architectures) }} steps: - name: Check submitted version id: version-check run: | - SUBMITTED_BUILD_ID=${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}} - CHECKED_BUILD_ID=$(curl -sLX POST $HOMELAB_LXC_EP -H "Content-Type: application/json" -d '{"query":"query CheckBuildID { build(where: {buildId: \"${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}}\"}) { buildId } }"}'| jq -r '.data.build.buildId') + SUBMITTED_BUILD_ID=${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}} + CHECKED_BUILD_ID=$(curl -sLX POST $HOMELAB_LXC_EP -H "Content-Type: application/json" -d '{"query":"query CheckBuildID { build(where: {buildId: \"${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}}\"}) { buildId } }"}' | jq -r '.data.build.buildId') echo "SUBMITTED_BUILD_ID=$SUBMITTED_BUILD_ID" >> $GITHUB_OUTPUT echo "CHECKED_BUILD_ID=$CHECKED_BUILD_ID" >> $GITHUB_OUTPUT env: HOMELAB_LXC_EP: ${{secrets.HOMELAB_LXC_EP}} + - name: Check necessary steps + id: validity-checks + run: | + echo "IS_BUILDABLE=${{github.event_name != 'schedule' || (steps.version-check.outputs.SUBMITTED_BUILD_ID != steps.version-check.outputs.CHECKED_BUILD_ID && github.event_name == 'schedule')}}" >> $GITHUB_OUTPUT + echo "IS_PUBLISHABLE=${{inputs.branch_name == 'test' || (steps.version-check.outputs.SUBMITTED_BUILD_ID != steps.version-check.outputs.CHECKED_BUILD_ID && github.event_name == 'schedule') || (inputs.branch_name == 'main' && inputs.is_merged == true)}}" >> $GITHUB_OUTPUT + - name: Check out repository uses: actions/checkout@v4 + if: ${{steps.validity-checks.outputs.IS_BUILDABLE}} == true - name: Install required tools - if: github.event_name != 'schedule' || (steps.version-check.outputs.SUBMITTED_BUILD_ID != steps.version-check.outputs.CHECKED_BUILD_ID && github.event_name == 'schedule') + if: ${{steps.validity-checks.outputs.IS_BUILDABLE}} == true run: | sudo apt-get update -y - sudo apt-get install -y debootstrap squashfs-tools jq wget curl unzip python3 python3-pip + sudo apt-get install -y debootstrap squashfs-tools wget unzip python3 python3-pip sudo snap install distrobuilder --classic - mkdir -p /tmp/output/${{inputs.app_name}} - mkdir -p /tmp/cache/${{inputs.app_name}} - HURL_VERSION=$(curl -s https://api.github.com/repos/Orange-OpenSource/hurl/releases/latest |jq -r '.tag_name') + mkdir -p /tmp/output/${{needs.init.outputs.app_name}} + mkdir -p /tmp/cache/${{needs.init.outputs.app_name}} + HURL_VERSION=$(curl -s https://api.github.com/repos/Orange-OpenSource/hurl/releases/latest | jq -r '.tag_name') curl --silent --location https://github.com/Orange-OpenSource/hurl/releases/download/${HURL_VERSION}/hurl-${HURL_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar xvz -C /tmp sudo cp /tmp/hurl-${HURL_VERSION}-x86_64-unknown-linux-gnu/bin/* /usr/bin/ sudo -v ; curl https://rclone.org/install.sh | sudo bash sudo -v ; wget -q https://kcl-lang.io/script/install-cli.sh -O - | sudo bash - sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq - name: Create Distrobuilder LXC template file - if: github.event_name != 'schedule' || (steps.version-check.outputs.SUBMITTED_BUILD_ID != steps.version-check.outputs.CHECKED_BUILD_ID && github.event_name == 'schedule') + if: ${{steps.validity-checks.outputs.IS_BUILDABLE}} == true run: | - yq eval '. as $root | {"kcl_options": [{"key": "build-instructions", "value": $root}]}' ${{github.workspace}}/${{inputs.config_path}} > ${{github.workspace}}/${{inputs.config_path}}_repacked.yaml - kcl ${{github.workspace}}/templates/__debian_base.k -Y ${{github.workspace}}/${{inputs.config_path}}_repacked.yaml > ${{github.workspace}}/lxc-template.yml + kcl run ${{github.workspace}}/__layout.k -D input=${{github.workspace}}/${{inputs.config_path}} -o /tmp/${{needs.init.outputs.app_name}}.build - name: Build Image - if: github.event_name != 'schedule' || (steps.version-check.outputs.SUBMITTED_BUILD_ID != steps.version-check.outputs.CHECKED_BUILD_ID && github.event_name == 'schedule') + if: ${{steps.validity-checks.outputs.IS_BUILDABLE}} == true run: | - sudo distrobuilder --cache-dir /tmp/cache/${{inputs.app_name}} build-lxc ${{github.workspace}}/lxc-template.yml -o image.distribution=${{inputs.distribution}} -o image.architecture=${{inputs.architecture}} -o image.release=${{inputs.release}} -o image.serial="${{inputs.app_version}}" -o source.url="http://ftp.us.debian.org/debian" /tmp/output/${{inputs.app_name}}/ - mv /tmp/output/${{inputs.app_name}}/rootfs.tar.xz ./${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}}-root.tar.xz - mv /tmp/output/${{inputs.app_name}}/meta.tar.xz ./${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}}-meta.tar.xz - echo "ARTIFACT_SIZE=$(du -sh ./${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}}-root.tar.xz| cut -f 1)" >> $GITHUB_ENV + sudo distrobuilder --cache-dir /tmp/cache/${{needs.init.outputs.app_name}} build-lxc /tmp/${{needs.init.outputs.app_name}}.build -o image.serial="${{needs.init.outputs.app_version}}" -o image.architecture=${{matrix.architectures}} /tmp/output/${{needs.init.outputs.app_name}}/ + mv /tmp/output/${{needs.init.outputs.app_name}}/rootfs.tar.xz ./${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}}-root.tar.xz + mv /tmp/output/${{needs.init.outputs.app_name}}/meta.tar.xz ./${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}}-meta.tar.xz + echo "ARTIFACT_SIZE=$(du -sh ./${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}}-root.tar.xz | cut -f 1)" >> $GITHUB_ENV pwd && ls -lash - name: Publish Image files - if: inputs.branch_name == 'test' || (steps.version-check.outputs.SUBMITTED_BUILD_ID != steps.version-check.outputs.CHECKED_BUILD_ID && github.event_name == 'schedule') || (inputs.branch_name == 'main' && inputs.is_merged == true) + if: ${{steps.validity-checks.outputs.IS_PUBLISHABLE}} == true run: | cat << EOF > /tmp/rclone.conf $RCLONE_CONFIG EOF echo - rclone copy ./${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}}-root.tar.xz cloudflare:lxc-images --config /tmp/rclone.conf - rclone copy ./${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}}-meta.tar.xz cloudflare:lxc-images --config /tmp/rclone.conf + rclone copy ./${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}}-root.tar.xz cloudflare:lxc-images --config /tmp/rclone.conf + rclone copy ./${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}}-meta.tar.xz cloudflare:lxc-images --config /tmp/rclone.conf echo echo 'LXC Image published successfully !' env: @@ -110,17 +124,17 @@ jobs: RCLONE_CONFIG_PASS: ${{secrets.RCLONE_CONFIG_PASS}} - name: Publish Image metadata - if: inputs.branch_name == 'test' || (steps.version-check.outputs.SUBMITTED_BUILD_ID != steps.version-check.outputs.CHECKED_BUILD_ID && github.event_name == 'schedule') || (inputs.branch_name == 'main' && inputs.is_merged == true) + if: ${{steps.validity-checks.outputs.IS_PUBLISHABLE}} == true run: | - CATEGORIES_STR="${{inputs.categories}}" - CATEGORIES_FMT=$(echo "[\"$CATEGORIES_STR\"]" | sed -E 's/^\["[ ,]+/["/g' | sed -E 's/[ ,]+"]$/"]/g'| sed -E 's/ *, */","/g') + CATEGORIES_STR="${{needs.init.outputs.categories}}" + CATEGORIES_FMT=$(echo "[\"$CATEGORIES_STR\"]" | sed -E 's/^\["[ ,]+/["/g' | sed -E 's/[ ,]+"]$/"]/g' | sed -E 's/ *, */","/g') hurl -v --variable endpoint_url=$HOMELAB_LXC_EP --variable token=$HOMELAB_LXC_TOKEN \ - --variable app_name=${{inputs.app_name}} --variable app_version=${{inputs.app_version}} \ - --variable arch=${{inputs.architecture}} --variable dist=${{inputs.distribution}} \ - --variable dist_release=${{inputs.release}} --variable build_id=${{inputs.app_name}}-${{inputs.app_version}}-${{inputs.architecture}} \ - --variable size=$ARTIFACT_SIZE --variable source=${{inputs.project_source}} --variable is_for_test=${{inputs.branch_name == 'test'}} \ - --variable categories="$CATEGORIES_FMT" --variable description="${{inputs.description}}" \ + --variable app_name=${{needs.init.outputs.app_name}} --variable app_version=${{needs.init.outputs.app_version}} \ + --variable arch=${{matrix.architectures}} --variable dist=${{needs.init.outputs.distribution}} \ + --variable dist_release=${{needs.init.outputs.release}} --variable build_id=${{needs.init.outputs.app_name}}-${{needs.init.outputs.app_version}}-${{matrix.architectures}} \ + --variable size=$ARTIFACT_SIZE --variable source=${{needs.init.outputs.project_source}} --variable is_for_test=${{inputs.branch_name == 'test'}} \ + --variable categories="$CATEGORIES_FMT" --variable description="${{needs.init.outputs.description}}" \ .github/publish_build.hurl echo echo 'LXC build details published successfully !' diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml new file mode 100644 index 0000000..6c4bd99 --- /dev/null +++ b/.github/workflows/trigger.yml @@ -0,0 +1,45 @@ +name: Build Trigger + +on: + workflow_dispatch: + pull_request: + types: + - opened + - synchronize + - reopened + - closed + branches: + - main + paths: + - ".github/workflows/trigger.yml" + - "./templates/*" + schedule: + - cron: "0 0 */7 * *" + +jobs: + init: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: List templates + id: templates-list + run: | + sudo apt-get install -y jq + echo TEMPLATES_LIST="$(ls templates/* | jq -Rsc 'split("\n")[:-1]')" | tee -a $GITHUB_OUTPUT + outputs: + templates_list: ${{steps.templates-list.outputs.TEMPLATES_LIST}} + + image-build: + needs: init + strategy: + fail-fast: false + matrix: + templates: ${{ fromJson(needs.init.outputs.templates_list) }} + uses: ./.github/workflows/builder.yml + with: + config_path: ${{matrix.templates}} + branch_name: ${{github.event.pull_request.base.ref}} + is_merged: ${{github.event.pull_request.merged || github.event_name == 'schedule'}} + secrets: inherit diff --git a/.gitignore b/.gitignore index 611e18a..00fb890 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,4 @@ # ignore tarballs *.tar.* # ignore kclvm dir -.kclvm -# ignore test generation -_lxc* \ No newline at end of file +.kclvm \ No newline at end of file diff --git a/README.md b/README.md index b3aa4f7..c31b79b 100644 --- a/README.md +++ b/README.md @@ -17,18 +17,27 @@ This started as a personal project built for my own needs, then shared because i ## Your favorite application is missing here ? -Open an issue to submit the application details and we will try to add it as soon as possible. +[Open an issue](https://github.com/soubinan/homelab-lxc/issues/new?assignees=&labels=&projects=&template=new-application-request.md&title=Add+%3Capplication_name%3E+template) to submit the application details and we will try to add it as soon as possible. ## Contributions It is very straight forward to add a new build template: -- Create a distrobuilder template - - - check the `templates/` directory to see some examples of already existing builds - - check the [distrobuilder](https://linuxcontainers.org/distrobuilder/docs/latest/) docs about how to use the keys `files` and `actions` - -- Create a job to build the LXC image (check the `.github/workflows/` to see some examples of already existing builds) +- Create a [distrobuilder](https://linuxcontainers.org/distrobuilder/docs/latest/) template + + - Check the `templates/` directory to see some examples of already existing builds (you can take the template `templates/apisix.yml` as a solid example). + - Check the [distrobuilder](https://linuxcontainers.org/distrobuilder/docs/latest/) docs about how to use the keys `files` and `actions` to see all possibilities available to you. Only both are using [distrobuilder](https://linuxcontainers.org/distrobuilder/docs/latest/) directly. Other keys like `repositories` and `packages` are preprocessed before to be used by [distrobuilder](https://linuxcontainers.org/distrobuilder/docs/latest/) but are pretty easy to use (again `templates/apisix.yml` is a good example about how it works). + - Give the metadata info below (all fields are required) + - name (str) + - get_version_command (str) + - description (str) + - categories (str) + - project_source (str) + - distribution (str) + - release (str) + - architectures (list) + - Name your file according to the application name + - That it, the automation will do the rest ! ### Local test @@ -36,28 +45,43 @@ It is very straight forward to add a new build template: - [Install distrobuilder](https://linuxcontainers.org/distrobuilder/docs/latest/howto/install/) - [Install KCL](https://www.kcl-lang.io/docs/user_docs/getting-started/install) -- [Install yq](https://mikefarah.gitbook.io/yq#install) - -[Step 2] Create your LXC template (checck the `templates/` directory to see the already existing examples) - -[ Step 3] Run the following commands - -```sh {"id":"01J0MNYBZ7PPTE87YJCNJPC101"} -# Your template should be in the ./templates directory -read -p "Your template filepath (ie. ./templates/myapp.yml): " templatepath && yq eval '. as $root | {"kcl_options": [{"key": "build-instructions", "value": $root}]}' ./templates/${templatepath} > _lxc-partial.yml && echo "_lxc-partial.yml has been successfully generated !" -ls -lash ./_lxc-partial.yml -``` +- [Install yq](https://mikefarah.gitbook.io/yq#install) (optional) +- [Install jq](https://jqlang.github.io/jq/download/) (optional) + +[Step 2] [Create your LXC template](#contributions) (check the `templates/` directory to see the already existing examples) or select an existing one + +> Note: the base template already has some packages in its definition so you don't need to add them twice, those packages are: +> * fuse +> * openssh-server +> * lsb-release +> * openssl +> * ca-certificates +> * apt-transport-https +> * cloud-init +> * curl +> * wget +> * gnupg2 +> * gzip +> * vim +> * software-properties-common +> * tzdata +> + +[ Step 3] Run the following command to build the final LXC template ```sh {"id":"01J0MPD5W78R3GD6JKZRV9WHHS"} # Render to final LXC template -kcl ./templates/__debian_base.k -Y _lxc-partial.yml > _lxc-template.yml && echo "_lxc-template.yml has been successfully generated !" -ls -lash ./_lxc-template.yml +kcl run __layout.k -D input=templates/.yml > _lxc-template.yml + +# ie: kcl run __layout.k -D input=templates/apisix.yml > apisix-template.yml ``` -Check the content of `_lxc-template` file to verify all is as expected. It should contains the conplete configuration (based on `./templates/__debian_base.k`) +Check the content of `_lxc-template` file to verify all is as expected. It should contains the conplete configuration (based on `__layout.k` and the application specific inputs.) -```sh {"excludeFromRunAll":"false","id":"01J0MPGBG024BTJHTE54YMJP97"} +```sh {"excludeFromRunAll":"true","id":"01J0MPGBG024BTJHTE54YMJP97"} # Build your LXC image -# Do not work if exected into a container -read -p "Enter the application version to build: " version && distrobuilder build-lxc _lxc-template.yml -o image.architecture=amd64 -o image.release=bookworm -o image.serial="${version}" -o source.url="http://ftp.us.debian.org/debian" +# Do not work if executed into a container (need chroot) +sudo distrobuilder build-lxc _lxc-template.yml -o image.architecture=amd64 -o image.serial="" + +# ie: sudo distrobuilder build-lxc apisix-template.yml -o image.architecture=amd64 -o image.serial="3.8.0" ``` diff --git a/templates/__debian_base.k b/__layout.k similarity index 93% rename from templates/__debian_base.k rename to __layout.k index 62684c3..2b8ae99 100644 --- a/templates/__debian_base.k +++ b/__layout.k @@ -1,14 +1,65 @@ -_application = option("build-instructions", required=True) -_app_name = option("app_name") or _application.name or "App" -_repositories_add = _application.repositories or Undefined -_packages = _application.packages or [] +import yaml +import file + +schema File: + path: str + generator: str + mode?: str + source?: str + content?: str + +schema Repo: + name: str + url: str + key: str + +schema Action: + trigger: str + pongo?: bool = False + action: str + +schema Metadata: + name: str + get_version_command: str + description: str + project_source: str + categories: str + distribution: str + release: str + architectures: [str] + + check: + distribution != Undefined, "Distribution should be explicitely set" + distribution == "debian", "Only debian distribution is allowed" + +schema Instructions: + files?: [File] + packages?: [str] + repositories?: [Repo] + actions?: [Action] + +schema Inputs: + metadata: Metadata + instructions?: Instructions + +_inputs_file: str = option("input", default="./templates/debian-test.yml", help="Input file path") +_inputs_str: str = file.read(filepath=_inputs_file) +_inputs = Inputs {**yaml.decode(_inputs_str)} + +_metadata = _inputs.metadata +_instructions = _inputs.instructions +_app_name = _metadata.name or "App" +_distirbution = "debian" +_repositories_add = _instructions.repositories or [] +_packages = _instructions.packages or Undefined _packages_install = { packages = _packages action = "install" } if _packages else Undefined -_files_add = _application.files or Undefined -_actions_add = _application.actions or Undefined -_key1 = """-----BEGIN PGP PUBLIC KEY BLOCK----- +_files_add = _instructions.files or [] +_actions_add = _instructions.actions or [] +_key1 = """\ +-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBFRvqBkBEADAe63Jl0pw5Ry9LDwn31BJSBat+2WYJXT4Iqsgtmm79drvAcVU JjtGZX11XdJj/aIVxeafghYxVj4Ld+yxiB25GAcxGr5O3Acv7DOlBQnqFZ7jvZUd @@ -197,8 +248,10 @@ cYE0lv+TUU0OpbxwGEea2d+YaBS/ZSy3yGMrv8kf4VM/iZUDYWsrB/0q+SRQeaKE utERYOxjvA+geNHpBZa1LdKg1KWeZI7PpaHE19N53u8hSeFMkaTCqFLhk2WmEYyU tizqJW3oSFiqIcpiyfN+0rLetGa0WslDnSIhyclfxOPMH14= =k46C ------END PGP PUBLIC KEY BLOCK-----""" -_key2 = """-----BEGIN PGP PUBLIC KEY BLOCK----- +-----END PGP PUBLIC KEY BLOCK----- +""" +_key2 = """\ +-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBE+a7rUBEADQiEKtLOgqiq8YY/p7IFODMqGPR+o1vtXaksie8iTOh3Vxab38 cA3kK1iB5XYElbZ5b/x3vWiufHK2semOpn5MG2GRJUwmKxZbt3HLZiHtAadkby2l @@ -544,8 +597,10 @@ TgECAPFpPDjYlf7ZIGKrOWYX7vhmGqA/oytxueIrG1AS66zB8MlfnrXPgDgun9cd Gjbs3Bh4bJrvoCvhWAf9kIEnShX69NQbfZFvfG2b9WocV5yMLH0bZ/tCa1hFRMpc qCTHsZBLcjOQhV5Ubg== =L+5x ------END PGP PUBLIC KEY BLOCK-----""" -_key3 = """-----BEGIN PGP PUBLIC KEY BLOCK----- +-----END PGP PUBLIC KEY BLOCK----- +""" +_key3 = """\ +-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBFxZ9FABEADPEDVwAUd10zcdnQJF7klaxK1mcTEUd+xfNAKBjhvP69XdAf54 7PS8Xid9zMAK/JARzLsZj5STy1VQQrPGOkSqPKA+gSpW8CmEWwfL/VTfQFFrJ9kb @@ -597,8 +652,10 @@ MnjVJCXOIls7rkI2128c2cQSeUNBW8N/dXTthE0SAqTek5jGGgJ5oo7brPFmJLhD 2ywOhgdo65iPihKiqLGr2pSrcmwJ3LvHpCgQldjqZfF9dmJAqdoO+WDYBU3pTQGV idjr8CGNeffTyeMJbSniGisGOkhiX9TLbz8ufw== =a2kx ------END PGP PUBLIC KEY BLOCK-----""" -_key4 = """-----BEGIN PGP PUBLIC KEY BLOCK----- +-----END PGP PUBLIC KEY BLOCK----- +""" +_key4 = """\ +-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBFyy5ecBEACxXGKUyi5dFjPhEFoz3IwKlVfDxySVg+hlhcUEO657UHf/7Ba5 wr9eHxjlbpxetAymSNnptgh8oaJWcokr9UjeaTbKrYGpRra7Wd1W+f++9tF7BVvV @@ -771,8 +828,10 @@ calvWyo8N+XrZKD8NQnWQ/BocU9r5S5aJFcovdcmm1s1Ymdlo5Yuk8WHZDOsSf38 VzY12szoQ9eMbBJOH7MhseS/gIWC/4x1eEEhGbPQbkzKZlJifv+55Mqqq7emGyBG qn8+ouVQUr65+xcIST13Ffg80zc= =lfn1 ------END PGP PUBLIC KEY BLOCK-----""" -_key5 = """-----BEGIN PGP PUBLIC KEY BLOCK----- +-----END PGP PUBLIC KEY BLOCK----- +""" +_key5 = """\ +-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBF/7h7cBEAC9H4Seq0jkv3r3P+JNAoHi2O+X8Q3upG+JUnek3p8dNl+JyTEw hVkDNttWhoqZOH+QLcL5oMd0Nr1zM9ng3pmarmX2DFk+aO95pnCoIlpA/nr0SQV/ @@ -801,8 +860,10 @@ xllJFHFCxU+0t0ImEW7Uk7rojIBluDZdRfwliI7fDCCnTFf1fF9e6gJUrKUNZFTp yoUM8+FwlIhpEGhn4o8+ezyG83IebGVDxydnX1rrph+eZ9BvWWjesHo8R5FDvoPV oPh9t/VGRvdQHA== =KM28 ------END PGP PUBLIC KEY BLOCK-----""" -_key6 = """-----BEGIN PGP PUBLIC KEY BLOCK----- +-----END PGP PUBLIC KEY BLOCK----- +""" +_key6 = """\ +-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBGPL0BUBEADmW5NdOOHwPIJlgPu6JDcKw/NZJPR8lsD3K87ZM18gzyQZJD+w ns6TSXOsx+BmpouHZgvh3FQADj/hhLjpNSqH5IH0xY7nic9BuSeyKx2WvfG62yxw @@ -927,23 +988,26 @@ s8bp4jKtODbPQBxRPQ4MUtLNZsHf6K05NPyB2aRUPP9FLBu6Zqv7YkT+PS1fxuCr gwyb6WzC7OpdW9MHhVBP+5BPExPZmVRl8o1t5vzBgxhDgbE+uB2S7HbpY2BVubVU 22lSkijKki64QmcUnp84EDZQdk+myhnGBqi+yw== =swbo ------END PGP PUBLIC KEY BLOCK-----""" -_create_message = """You just created an {{ image.description }} container. +-----END PGP PUBLIC KEY BLOCK----- +""" +_create_message = """\ +You just created an {{ image.description }} container. To enable SSH, run: apt install openssh-server -No default root or user password are set by LXC.""" -_network_interfaces = """# This file describes the network interfaces available on your system +No default root or user password are set by LXC. +""" +_network_interfaces = """\ +# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). - # The loopback network interface auto lo iface lo inet loopback - auto eth0 iface eth0 inet dhcp - -source /etc/network/interfaces.d/*""" -_eth0 = """[Match] +source /etc/network/interfaces.d/* +""" +_eth0 = """\ +[Match] Name=eth0 [Network] @@ -953,7 +1017,8 @@ DHCP=true UseDomains=true [DHCP] -ClientIdentifier=mac""" +ClientIdentifier=mac +""" _welcome_msg_issue = """\ | Built by: | @@ -963,21 +1028,22 @@ _welcome_msg_issue = """\ | ░▓█▓░▓█▓░▓█▓░▓█▓▒▓█▓░▓█▓▒▓█▓░▓█▓░▓█▓░ ░▓█▓▒▓█▓░▓█▓▒▓█▓░ ░▓█▓ | ▒▓████▓░ ░▓███▓░ ▒▓███▓▒ ▓████▓░ ▓█▓░▓████▓░▓█▓▒▓█▓░▓████▓▒░▓████▓░ | -Welcome on your {} LXC\n""".format(_app_name) +Welcome to your ${_app_name} LXC +""" _welcome_msg_cron = """\ @reboot root /etc/profile.d/50-welcome.sh > /etc/issue.d/51-welcome.issue -* * * * * root /etc/profile.d/50-welcome.sh > /etc/issue.d/51-welcome.issue""" +* * * * * root /etc/profile.d/50-welcome.sh > /etc/issue.d/51-welcome.issue +""" _welcome_msg_script = """\ #!/bin/bash ports=$(ss -ptuln | grep -vE 'systemd|next-router|next-render|127.0.0.|%lo' | awk '/^tcp/ && $4 !~ /^(127\.|::1|0\.0\.0\.0)/ {print $5}' | awk -F: '{print $NF}' | sort -u) - num_ports=$(echo $ports | wc -l) ips=$(ip a|grep 'inet '|awk '{print $2}') printf '\\n' printf '+-----------------------------------+\\n' -printf '| %-33s |\\n' '""" + _app_name + """ is listening on' +printf '| %-33s |\\n' '${_app_name} is listening on' while read -r ip; do printf '| %-33s |\\n' \" => $ip\" @@ -994,41 +1060,65 @@ done <<< $ports # Print table footer printf '+------------+----------------------+\\n' -printf '\\n'""" +printf '\\n' +""" +_dynamic_components = "" +_dynamic_repos = "" +if (_metadata.release == "buster"): + _dynamic_repos = "deb http://deb.debian.org/debian-security/ {{ image.release }}/updates non-free contrib main" + +if (_metadata.release != "buster" and _metadata.release != "sid"): + _dynamic_repos = "deb http://deb.debian.org/debian-security/ {{ image.release }}-security non-free contrib main" + +if (_metadata.release != "buster" and _metadata.release != "bullseye" and _metadata.release != "sid"): + _dynamic_components = "non-free-firmware" + _debian_repositories = """\ -deb http://deb.debian.org/debian {{ image.release }} main non-free non-free-firmware bookworm-backports contrib -deb http://deb.debian.org/debian {{ image.release }}-updates main non-free non-free-firmware bookworm-backports contrib -deb http://deb.debian.org/debian-security/ {{ image.release }}-security main non-free non-free-firmware bookworm-backports contrib""" +deb http://deb.debian.org/debian {{ image.release }} non-free ${_dynamic_components} contrib main +deb http://deb.debian.org/debian {{ image.release }}-updates non-free ${_dynamic_components} contrib main +${_dynamic_repos} +""" _script_set_resolvconf = """\ #!/bin/bash set -eux + cat /etc/resolv.conf > /tmp/resolv.conf umount -l /etc/resolv.conf || true -mv /tmp/resolv.conf /etc/""" +mv /tmp/resolv.conf /etc/ +""" _script_reset_resolvconf_new = """\ #!/bin/bash set -eux + umount -l /etc/resolv.conf || true -ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf""" +ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf +""" _script_reset_resolvconf_old = """\ #!/bin/bash set -eux + umount -l /etc/resolv.conf || true -ln -sf /run/resolvconf/resolv.conf /etc/resolv.conf""" +ln -sf /run/resolvconf/resolv.conf /etc/resolv.conf +""" _script_enable_networkd = """\ #!/bin/bash set -eux + # Enable networkd socket systemctl enable systemd-networkd.socket -systemctl enable systemd-networkd.service""" +systemctl enable systemd-networkd.service +""" _script_enable_resolved = """\ #!/bin/bash set -eux + # Enable systemd-resolved -systemctl enable systemd-resolved.service""" +systemctl enable systemd-resolved.service +""" _script_update_locale = """\ #!/bin/bash set -eux + # Make sure the locale is built and functional echo en_US.UTF-8 UTF-8 >> /etc/locale.gen locale-gen en_US.UTF-8 UTF-8 @@ -1038,25 +1128,46 @@ mount -o bind / /mnt rm -rf /mnt/run/* umount /mnt # Cleanup temporary shadow paths -rm /etc/*-""" +rm /etc/*- +""" +_script_preparations = """\ +#!/bin/bash +set -eux + +tee /usr/sbin/systemctl </dev/null + echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list + + apt update + FULL_VERSION=$(apt-cache madison nginx | grep 1.26.2 | head -n1 | awk '{print $3}') + apt install -y nginx=$FULL_VERSION + + export UI_WIZARD=1 + curl -s https://repo.bunkerweb.io/install/script.deb.sh | bash + apt install -y bunkerweb={{image.serial}} + apt-mark hold nginx bunkerweb + + systemctl disable nginx.service + systemctl mask nginx-debug.service + systemctl enable bunkerweb.service bunkerweb-ui.service diff --git a/templates/code-server.yml b/templates/code-server.yml index d423c2f..5837ba8 100644 --- a/templates/code-server.yml +++ b/templates/code-server.yml @@ -1,42 +1,51 @@ -name: Code-Server - -files: -- path: /etc/issue.d/99_default-password-info.issue - generator: dump - mode: '0440' - content: |- - Find your initial password in ~/.config/code-server/config.yaml - -- path: /etc/systemd/system/code-server.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Code-Server - After=network-online.target - - [Service] - WorkingDirectory=/opt/code - ExecStart=code-server --bind-addr 0.0.0.0:8080 --cert - - [Install] - WantedBy=multi-user.target - -packages: -- jq -- git - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - mkdir /opt/code - wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && chmod +x /usr/bin/yq - - curl -fOL https://github.com/coder/code-server/releases/download/v{{image.serial}}/code-server_{{image.serial}}_{{image.architecture}}.deb - apt install ./code-server_{{image.serial}}_{{image.architecture}}.deb - systemctl enable code-server - # Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +metadata: + name: Code-Server + get_version_command: curl -s https://api.github.com/repos/coder/code-server/releases/latest | jq -r '.tag_name' + description: Coder is an open source cloud development environment (CDE), based on VS Code. + categories: IDE, Dev + project_source: https://github.com/coder/code-server + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/issue.d/99_default-password-info.issue + generator: dump + mode: "0440" + content: |- + Find your initial password in ~/.config/code-server/config.yaml + + - path: /etc/systemd/system/code-server.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Code-Server + After=network-online.target + + [Service] + WorkingDirectory=/opt/code + ExecStart=code-server --bind-addr 0.0.0.0:8080 --cert + + [Install] + WantedBy=multi-user.target + + packages: + - jq + - git + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + mkdir /opt/code + wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && chmod +x /usr/bin/yq + + curl -fOL https://github.com/coder/code-server/releases/download/v{{image.serial}}/code-server_{{image.serial}}_{{image.architecture}}.deb + apt-get install ./code-server_{{image.serial}}_{{image.architecture}}.deb + systemctl enable code-server + # Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml diff --git a/templates/debian-test.yml b/templates/debian-test.yml index f9afc36..324d3bc 100644 --- a/templates/debian-test.yml +++ b/templates/debian-test.yml @@ -1,2 +1,17 @@ ---- -name: Test \ No newline at end of file +metadata: + name: Test + get_version_command: echo "V1.0.0" + description: Test + categories: Dummy + project_source: https://example.com + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux diff --git a/templates/downloadarr.yml b/templates/downloadarr.yml new file mode 100644 index 0000000..f8ba9ec --- /dev/null +++ b/templates/downloadarr.yml @@ -0,0 +1,131 @@ +metadata: + name: Downloadarr + get_version_command: date +%Y-%m + description: Downloadarr is the collection of three tools (QBitTorrent, SabNZBd and FlareSolverr) for Usenet and BitTorrent users. + categories: Torrent, Usenet + project_source: https://wiki.servarr.com + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/flaresolverr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=FlareSolverr Daemon + After=syslog.target network.target + [Service] + User=flaresolverr + Group=media + Type=simple + ExecStart=/opt/FlareSolverr/venv/bin/python3 -u /opt/FlareSolverr/src/flaresolverr.py + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/qbittorrent.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=QBitTorrent Daemon + After=syslog.target network.target + [Service] + User=qbittorrent + Group=media + Type=simple + ExecStart=/usr/bin/qbittorrent-nox --first-and-last --skip-dialog=true + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/sabnzbdplus.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=SABnzbdplus Daemon + After=syslog.target network.target + [Service] + User=sabnzbdplus + Group=media + Type=simple + ExecStart=/usr/bin/sabnzbdplus -s 0.0.0.0:8081 + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + packages: + - git + - sqlite3 + - python3-pip + - python3-venv + - python3-distutils + - python3-dev + - equivs + - 7zip + - unrar-free + - unzip + - qbittorrent-nox + - sabnzbdplus + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + + mkdir /downloads + groupadd media + chown -R :media /downloads + + cd /opt + + mkdir -p /tmp/{libgl1-mesa-dri,adwaita-icon-theme} /pkgs + cd /tmp/libgl1-mesa-dri + equivs-control libgl1-mesa-dri + printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: libgl1-mesa-dri\nVersion: 99.0.0\nDescription: Dummy package for libgl1-mesa-dri\n' >> libgl1-mesa-dri + equivs-build libgl1-mesa-dri + mv libgl1-mesa-dri_*.deb /pkgs/libgl1-mesa-dri.deb + cd /tmp/adwaita-icon-theme + equivs-control adwaita-icon-theme + printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: adwaita-icon-theme\nVersion: 99.0.0\nDescription: Dummy package for adwaita-icon-theme\n' >> adwaita-icon-theme + equivs-build adwaita-icon-theme + mv adwaita-icon-theme_*.deb /pkgs/adwaita-icon-theme.deb + dpkg -i /pkgs/libgl1-mesa-dri.deb + dpkg -i /pkgs/adwaita-icon-theme.deb + apt-get install -y --no-install-recommends chromium chromium-common chromium-driver xvfb dumb-init procps curl vim xauth + useradd --home-dir /opt/FlareSolverr --shell /bin/sh flaresolverr + usermod -aG media flaresolverr + git clone -b master --depth 1 https://github.com/FlareSolverr/FlareSolverr.git /opt/FlareSolverr + cd /opt/FlareSolverr + python3 -m venv venv + /opt/FlareSolverr/venv/bin/python3 -m pip install -r requirements.txt + mv /usr/bin/chromedriver /opt/FlareSolverr/chromedriver + mkdir -p "/opt/FlareSolverr/.config/chromium/Crash Reports/pending" + chown -R flaresolverr:flaresolverr /opt/FlareSolverr + + rm -f /usr/lib/x86_64-linux-gnu/libmfxhw* + rm -f /usr/lib/x86_64-linux-gnu/mfx/* + rm -rf /pkgs + + useradd -m --home-dir /opt/qbittorrent qbittorrent + usermod -aG media qbittorrent + + useradd -m --home-dir /opt/sabnzbdplus sabnzbdplus + usermod -aG media sabnzbdplus + + systemctl enable sabnzbdplus.service qbittorrent.service flaresolverr.service diff --git a/templates/gitea.yml b/templates/gitea.yml index d8af98f..2db5ae4 100644 --- a/templates/gitea.yml +++ b/templates/gitea.yml @@ -1,48 +1,57 @@ -name: Gitea - -files: -- path: /etc/systemd/system/gitea.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Gitea (Git with a cup of tea) - After=network.target - - [Service] - User=git - Group=git - LimitNOFILE=524288:524288 - RestartSec=2s - Type=simple - WorkingDirectory=/var/lib/gitea/ - ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini - Restart=always - Environment=USER=root HOME=/root GITEA_WORK_DIR=/var/lib/gitea - - [Install] - WantedBy=multi-user.target - -packages: -- git - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - wget -O /usr/local/bin/gitea https://dl.gitea.com/gitea/{{image.serial}}/gitea-{{image.serial}}-linux-amd64 - chmod +x /usr/local/bin/gitea - - adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git - - mkdir -p /var/lib/gitea/{custom,data,log} - chown -R git:git /var/lib/gitea/ - chmod -R 750 /var/lib/gitea/ - mkdir /etc/gitea - chown root:git /etc/gitea - chmod 770 /etc/gitea - - systemctl enable gitea.service +metadata: + name: Gitea + get_version_command: curl -s https://dl.gitea.com/gitea/version.json| jq -r '.latest.version' + description: Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD. + categories: Git, CI CD, Dev + project_source: https://github.com/go-gitea/gitea + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/gitea.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Gitea (Git with a cup of tea) + After=network.target + + [Service] + User=git + Group=git + LimitNOFILE=524288:524288 + RestartSec=2s + Type=simple + WorkingDirectory=/var/lib/gitea/ + ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini + Restart=always + Environment=USER=root HOME=/root GITEA_WORK_DIR=/var/lib/gitea + + [Install] + WantedBy=multi-user.target + + packages: + - git + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + wget -O /usr/local/bin/gitea https://dl.gitea.com/gitea/{{image.serial}}/gitea-{{image.serial}}-linux-amd64 + chmod +x /usr/local/bin/gitea + + adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git + + mkdir -p /var/lib/gitea/{custom,data,log} + chown -R git:git /var/lib/gitea/ + chmod -R 750 /var/lib/gitea/ + mkdir /etc/gitea + chown root:git /etc/gitea + chmod 770 /etc/gitea + + systemctl enable gitea.service diff --git a/templates/grafana.yml b/templates/grafana.yml new file mode 100644 index 0000000..caba225 --- /dev/null +++ b/templates/grafana.yml @@ -0,0 +1,27 @@ +metadata: + name: Grafana + get_version_command: curl -s https://api.github.com/repos/grafana/grafana/releases/latest | jq -r '.tag_name' + description: The open and composable observability and data visualization platform. + categories: Monitoring, Dashboard, Analytics + project_source: https://github.com/grafana/grafana + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + mkdir -p /etc/apt/keyrings/ + wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | tee /etc/apt/keyrings/grafana.gpg > /dev/null + + echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | tee -a /etc/apt/sources.list.d/grafana.list + + apt-get update + apt-get install -y grafana + + systemctl enable grafana-server.service diff --git a/templates/homarr.yml b/templates/homarr.yml index 4da5360..1155b65 100644 --- a/templates/homarr.yml +++ b/templates/homarr.yml @@ -1,328 +1,337 @@ -name: Homarr +metadata: + name: Homarr + get_version_command: curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | jq -r '.tag_name' + description: A simple, yet powerful dashboard for your server. + categories: Homepage + project_source: https://github.com/ajnart/homarr + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /opt/homarr/settings.env + generator: dump + mode: "0440" + content: |- + PORT=7575 + NEXT_TELEMETRY_DISABLED=1 + NODE_ENV="production" + NODE_OPTIONS="--no-experimental-fetch" + DATABASE_URL="file:/data/db.sqlite" + NEXTAUTH_URL="http://localhost:7575" + NEXTAUTH_SECRET="NOT_IN_USE_BECAUSE_JWTS_ARE_UNUSE" + NEXT_PUBLIC_DISABLE_ANALYTICS="true" + HOSTNAME="127.0.0.1" + DEFAULT_COLOR_SCHEME="dark" -files: -- path: /opt/homarr/settings.env - generator: dump - mode: '0440' - content: |- - PORT=7575 - NEXT_TELEMETRY_DISABLED=1 - NODE_ENV="production" - NODE_OPTIONS="--no-experimental-fetch" - DATABASE_URL="file:/data/db.sqlite" - NEXTAUTH_URL="http://localhost:7575" - NEXTAUTH_SECRET="NOT_IN_USE_BECAUSE_JWTS_ARE_UNUSE" - NEXT_PUBLIC_DISABLE_ANALYTICS="true" - HOSTNAME="127.0.0.1" - DEFAULT_COLOR_SCHEME="dark" + - path: /etc/systemd/system/homarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Homarr Dashboard + After=network.target + ConditionPathExists=/app/.installed__ -- path: /etc/systemd/system/homarr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Homarr Dashboard - After=network.target - ConditionPathExists=/app/.installed__ + [Service] + Type=simple + WorkingDirectory=/app + EnvironmentFile=/app/.env + PIDFile=/opt/homarr/homarr.pid + ExecStart=/usr/bin/bash scripts/run.sh + Restart=always - [Service] - Type=simple - WorkingDirectory=/app - EnvironmentFile=/app/.env - PIDFile=/opt/homarr/homarr.pid - ExecStart=/usr/bin/bash scripts/run.sh - Restart=always + [Install] + WantedBy=multi-user.target - [Install] - WantedBy=multi-user.target + packages: + - git + - nodejs + - yarn -packages: -- git -- nodejs -- yarn + repositories: + - name: nodejs + url: |- + deb http://deb.nodesource.com/node_20.x nodistro main + key: |- + -----BEGIN PGP PUBLIC KEY BLOCK----- -repositories: - - name: nodejs - url: |- - deb http://deb.nodesource.com/node_20.x nodistro main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- + mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B + hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM + Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 + 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR + TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z + E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk + LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI + AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc + NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o + xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk + Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 + hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg + BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 + AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u + JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu + ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi + 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp + Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ + YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb + DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE + IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet + y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao + x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 + K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw + FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa + =MARt + -----END PGP PUBLIC KEY BLOCK----- - mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B - hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM - Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 - 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR - TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z - E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk - LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI - AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc - NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o - xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk - Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 - hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg - BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 - AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u - JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu - ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi - 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp - Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ - YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb - DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE - IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet - y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao - x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 - K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw - FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa - =MARt - -----END PGP PUBLIC KEY BLOCK----- + - name: yarn + url: |- + deb http://dl.yarnpkg.com/debian stable main + key: |- + -----BEGIN PGP PUBLIC KEY BLOCK----- - - name: yarn - url: |- - deb http://dl.yarnpkg.com/debian stable main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- + 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 + =e4wy + -----END PGP PUBLIC KEY BLOCK----- - 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 - =e4wy - -----END PGP PUBLIC KEY BLOCK----- + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux + mkdir /data + git clone https://github.com/ajnart/homarr -b v{{ image.serial }} --depth 1 /app - mkdir /data - git clone https://github.com/ajnart/homarr -b v{{ image.serial }} --depth 1 /app + cd /app + yarn install + cp /opt/homarr/settings.env .env + yarn build + cp -r drizzle/migrate/ migrate/ + cp tsconfig.json migrate/tsconfig.json + touch migrate/yarn.lock + yarn db:migrate + yarn cache clean + rm -rf node_modules + cp -r .next/standalone/* . + chmod +x scripts/run.sh + touch .installed__ - cd /app - yarn install - cp /opt/homarr/settings.env .env - yarn build - cp -r drizzle/migrate/ migrate/ - cp tsconfig.json migrate/tsconfig.json - touch migrate/yarn.lock - yarn db:migrate - yarn cache clean - rm -rf node_modules - cp -r .next/standalone/* . - chmod +x scripts/run.sh - touch .installed__ - - systemctl enable homarr.service + systemctl enable homarr.service diff --git a/templates/infisical.yml b/templates/infisical.yml index ffe3552..fbaff52 100644 --- a/templates/infisical.yml +++ b/templates/infisical.yml @@ -1,352 +1,219 @@ -name: Infisical - -files: -- path: /opt/infisical/settings.env - generator: dump - mode: '0440' - content: |- - PORT=8080 - HOST=0.0.0.0 - HTTPS_ENABLED=false - STANDALONE_BUILD=true - STANDALONE_MODE=true - TELEMETRY_ENABLED=true - NODE_ENV=production - NEXT_PUBLIC_ENV=production - NEXT_TELEMETRY_DISABLED=1 - POSTGRES_USER=infuser - POSTGRES_DB=infisical - -- path: /etc/systemd/system/infisical-initdb.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=DB initializer for Infisical in postgresql - After=network.target postgresql.service - Wants=postgresql.service - ConditionPathExists=/backend/.installed__ - ConditionPathExists=!/var/lib/postgresql/.db_initialized__ - - [Service] - Type=oneshot - RemainAfterExit=yes - WorkingDirectory=/ - User=postgres - EnvironmentFile=/opt/infisical/settings.env - ExecStart=/usr/bin/createdb ${POSTGRES_DB} - ExecStart=/usr/bin/createuser -s ${POSTGRES_USER} - ExecStart=/usr/bin/psql -c "GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_USER};" - ExecStart=/usr/bin/touch /var/lib/postgresql/.db_initialized__ - - [Install] - WantedBy=multi-user.target - -- path: /etc/systemd/system/infisical-migrator.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=DB migrator for Infisical - After=network.target infisical-initdb.service - Wants=infisical-initdb.service - ConditionPathExists=/var/lib/postgresql/.db_initialized__ - ConditionPathExists=!/backend/.migrated__ - - [Service] - Type=oneshot - RemainAfterExit=yes - WorkingDirectory=/backend - EnvironmentFile=/opt/infisical/settings.env - Environment=DB_CONNECTION_URI=postgres://postgres@127.0.0.1:5432/infisical - ExecStart=/usr/bin/npm run migration:latest - ExecStart=/usr/bin/touch /backend/.migrated__ - - [Install] - WantedBy=multi-user.target - -- path: /etc/systemd/system/infisical.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Open Source Secret Management - After=network.target infisical-migrator.service - ConditionPathExists=/backend/.migrated__ - - [Service] - Type=simple - WorkingDirectory=/backend - EnvironmentFile=/opt/infisical/settings.env - Environment=DB_CONNECTION_URI=postgres://infuser@127.0.0.1:5432/infisical - Environment=REDIS_URL=redis://127.0.0.1:6379 - Environment=SITE_URL=http://0.0.0.0:8080 - PIDFile=/opt/infisical/infisical.pid - ExecStart=/backend/standalone-entrypoint.sh - Restart=always - - [Install] - WantedBy=multi-user.target - -packages: -- software-properties-common -- apt-transport-https -- git -- nodejs -- redis -- redis-server -- postgresql-16 - -repositories: - - name: nodejs - url: |- - deb http://deb.nodesource.com/node_20.x nodistro main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- - - mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B - hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM - Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 - 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR - TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z - E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk - LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI - AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc - NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o - xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk - Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 - hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg - BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 - AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u - JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu - ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi - 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp - Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ - YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb - DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE - IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet - y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao - x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 - K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw - FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa - =MARt - -----END PGP PUBLIC KEY BLOCK----- - - - name: redis - url: |- - deb http://packages.redis.io/deb {{image.release}} main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- - - 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 - Oi5R+3n0UUbz020kbQ== - =1K+h - -----END PGP PUBLIC KEY BLOCK----- - - - name: postgresql - url: |- - deb http://apt.postgresql.org/pub/repos/apt {{image.release}}-pgdg main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- - - 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 - =DA1T - -----END PGP PUBLIC KEY BLOCK----- - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - export NODE_ENV=production - export NEXT_PUBLIC_ENV=production - export NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com - export NEXT_PUBLIC_POSTHOG_API_KEY=posthog-api-key - export NEXT_PUBLIC_INTERCOM_ID=intercom-id - export NEXT_PUBLIC_INFISICAL_PLATFORM_VERSION=v{{image.serial}} - export NEXT_TELEMETRY_DISABLED=1 - - npm config delete http-proxy - npm config delete https-proxy - - npm config rm proxy - npm config rm https-proxy - - set HTTP_PROXY=null - set HTTPS_PROXY=null - - npm config set fetch-timeout 90000 - - git clone https://github.com/Infisical/infisical -b infisical/v{{ image.serial }}-postgres --depth 1 /tmp/app - - mkdir /build-frontend && cd /build-frontend - cp /tmp/app/frontend/{package.json,package-lock.json,next.config.js} . - npm ci --only-production --ignore-scripts - cp -r /tmp/app/frontend/* /build-frontend/ - npm run build - mkdir -p /infisical-frontend/.next/cache/images - cp -r /tmp/app/frontend/scripts /infisical-frontend/scripts - cp -r /build-frontend/public /infisical-frontend/public - cp -r /build-frontend/.next/standalone/* /infisical-frontend/ - cp -r /build-frontend/.next/* /infisical-frontend/.next/ && rm -rf /infisical-frontend/.next/standalone/ - npm cache clean --force - - export NODE_ENV= - export NEXT_PUBLIC_ENV= - - mkdir /backend && cd /backend - cp /tmp/app/backend/package*.json . - npm ci --only-production - cp -r /tmp/app/backend/* /backend/ - cp -r /tmp/app/standalone-entrypoint.sh /backend/ && chmod +x /backend/standalone-entrypoint.sh - npm i -D tsconfig-paths - npm run build - cp -r /infisical-frontend /backend/frontend-build - chmod +x -R /backend/scripts /backend/frontend-build/scripts - npm cache clean --force - - rm -rf /build-frontend /infisical-frontend/ - touch .installed__ - cd / - - cat <> /opt/infisical/settings.env - ENCRYPTION_KEY=$(/usr/bin/openssl rand -hex 16) - AUTH_SECRET=$(/usr/bin/openssl rand -hex 32) - EOF - - cat < /etc/postgresql/16/main/pg_hba.conf - local all postgres peer - local infisical infuser peer - local all all peer - host infisical infuser,postgres 127.0.0.1/32 trust - host all all 127.0.0.1/32 scram-sha-256 - host all all ::1/128 scram-sha-256 - local replication all peer - host replication all 127.0.0.1/32 scram-sha-256 - host replication all ::1/128 scram-sha-256 - EOF - - systemctl enable redis-server.service - systemctl enable postgresql.service - systemctl enable infisical-migrator.service - systemctl enable infisical.service +metadata: + name: Infisical + get_version_command: date +%Y-%m + description: Open Source all-in-one secret management platform to securely manage application configuration and secrets across your team and infrastructure. + categories: Secrets management, Security + project_source: https://github.com/Infisical/infisical + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /opt/infisical/settings.env + generator: dump + mode: "0440" + content: |- + PORT=8080 + HOST=0.0.0.0 + HTTPS_ENABLED=false + STANDALONE_BUILD=true + STANDALONE_MODE=true + TELEMETRY_ENABLED=true + NODE_ENV=production + NEXT_PUBLIC_ENV=production + NEXT_TELEMETRY_DISABLED=1 + POSTGRES_USER=infuser + POSTGRES_DB=infisical + + - path: /etc/systemd/system/infisical-initdb.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=DB initializer for Infisical in postgresql + After=network.target postgresql.service + Wants=postgresql.service + ConditionPathExists=/backend/.installed__ + ConditionPathExists=!/var/lib/postgresql/.db_initialized__ + + [Service] + Type=oneshot + RemainAfterExit=yes + WorkingDirectory=/ + User=postgres + EnvironmentFile=/opt/infisical/settings.env + ExecStart=/usr/bin/createdb ${POSTGRES_DB} + ExecStart=/usr/bin/createuser -s ${POSTGRES_USER} + ExecStart=/usr/bin/psql -c "GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_USER};" + ExecStart=/usr/bin/touch /var/lib/postgresql/.db_initialized__ + + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/infisical-migrator.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=DB migrator for Infisical + After=network.target infisical-initdb.service + Wants=infisical-initdb.service + ConditionPathExists=/var/lib/postgresql/.db_initialized__ + ConditionPathExists=!/backend/.migrated__ + + [Service] + Type=oneshot + RemainAfterExit=yes + WorkingDirectory=/backend + EnvironmentFile=/opt/infisical/settings.env + Environment=DB_CONNECTION_URI=postgres://postgres@127.0.0.1:5432/infisical + ExecStart=/usr/bin/npm run migration:latest + ExecStart=/usr/bin/touch /backend/.migrated__ + + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/infisical.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Open Source Secret Management + After=network.target infisical-migrator.service + ConditionPathExists=/backend/.migrated__ + + [Service] + Type=simple + WorkingDirectory=/backend + EnvironmentFile=/opt/infisical/settings.env + Environment=DB_CONNECTION_URI=postgres://infuser@127.0.0.1:5432/infisical + Environment=REDIS_URL=redis://127.0.0.1:6379 + Environment=SITE_URL=http://0.0.0.0:8080 + PIDFile=/opt/infisical/infisical.pid + ExecStart=/backend/standalone-entrypoint.sh + Restart=always + + [Install] + WantedBy=multi-user.target + + packages: + - git + - nodejs + - redis + - redis-server + - postgresql-15 + + repositories: + - name: nodejs + url: |- + deb http://deb.nodesource.com/node_20.x nodistro main + key: |- + -----BEGIN PGP PUBLIC KEY BLOCK----- + + mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B + hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM + Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 + 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR + TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z + E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk + LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI + AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc + NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o + xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk + Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 + hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg + BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 + AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u + JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu + ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi + 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp + Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ + YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb + DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE + IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet + y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao + x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 + K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw + FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa + =MARt + -----END PGP PUBLIC KEY BLOCK----- + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export NODE_ENV=production + export NEXT_PUBLIC_ENV=production + export NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com + export NEXT_PUBLIC_POSTHOG_API_KEY=posthog-api-key + export NEXT_PUBLIC_INTERCOM_ID=intercom-id + export NEXT_PUBLIC_INFISICAL_PLATFORM_VERSION=v{{image.serial}} + export NEXT_TELEMETRY_DISABLED=1 + + npm config delete http-proxy + npm config delete https-proxy + + npm config rm proxy + npm config rm https-proxy + + set HTTP_PROXY=null + set HTTPS_PROXY=null + + npm config set fetch-timeout 90000 + + git clone https://github.com/Infisical/infisical --depth 1 /tmp/app + + mkdir /build-frontend && cd /build-frontend + cp /tmp/app/frontend/{package.json,package-lock.json,next.config.js} . + npm ci --only-production --ignore-scripts + cp -r /tmp/app/frontend/* /build-frontend/ + npm run build + mkdir -p /infisical-frontend/.next/cache/images + cp -r /tmp/app/frontend/scripts /infisical-frontend/scripts + cp -r /build-frontend/public /infisical-frontend/public + cp -r /build-frontend/.next/standalone/* /infisical-frontend/ + cp -r /build-frontend/.next/* /infisical-frontend/.next/ && rm -rf /infisical-frontend/.next/standalone/ + npm cache clean --force + + export NODE_ENV= + export NEXT_PUBLIC_ENV= + + mkdir /backend && cd /backend + cp /tmp/app/backend/package*.json . + npm ci --only-production + cp -r /tmp/app/backend/* /backend/ + cp -r /tmp/app/standalone-entrypoint.sh /backend/ && chmod +x /backend/standalone-entrypoint.sh + npm i -D tsconfig-paths + npm run build + cp -r /infisical-frontend /backend/frontend-build + chmod +x -R /backend/scripts /backend/frontend-build/scripts + npm cache clean --force + + rm -rf /build-frontend /infisical-frontend/ + touch .installed__ + cd / + + cat <> /opt/infisical/settings.env + ENCRYPTION_KEY=$(/usr/bin/openssl rand -hex 16) + AUTH_SECRET=$(/usr/bin/openssl rand -hex 32) + EOF + + PG_VERSION=$(ls -1 /etc/postgresql) + + cat < /etc/postgresql/${PG_VERSION}/main/pg_hba.conf + local all postgres peer + local infisical infuser peer + local all all peer + host infisical infuser,postgres 127.0.0.1/32 trust + host all all 127.0.0.1/32 scram-sha-256 + host all all ::1/128 scram-sha-256 + local replication all peer + host replication all 127.0.0.1/32 scram-sha-256 + host replication all ::1/128 scram-sha-256 + EOF + + systemctl enable redis-server.service postgresql.service infisical-migrator.service infisical.service diff --git a/templates/ittools.yml b/templates/ittools.yml index 33dea77..6ed2eff 100644 --- a/templates/ittools.yml +++ b/templates/ittools.yml @@ -1,95 +1,104 @@ -name: IT-Tools +metadata: + name: IT-Tools + get_version_command: curl -s https://api.github.com/repos/CorentinTh/it-tools/releases/latest | jq -r '.tag_name' + description: Useful tools for developers and peoples working in IT. + categories: Dev, Toolkit + project_source: https://github.com/CorentinTh/it-tools + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /var/nginx.conf + generator: dump + mode: "0440" + content: |- + worker_processes 1; + worker_rlimit_nofile 8192; -files: -- path: /var/nginx.conf - generator: dump - mode: '0440' - content: |- - worker_processes 1; - worker_rlimit_nofile 8192; + events { + worker_connections 4096; + } - events { - worker_connections 4096; - } + http { + include /etc/nginx/mime.types; + index index.html index.htm index.php; - http { - include /etc/nginx/mime.types; - index index.html index.htm index.php; + server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; - server { - listen 80; - server_name localhost; - root /usr/share/nginx/html; - index index.html; - - location / { - try_files $uri $uri/ /index.html; + location / { + try_files $uri $uri/ /index.html; + } } - } - } + } -packages: -- git -- nodejs -- nginx + packages: + - git + - nodejs + - nginx -repositories: - - name: nodejs - url: |- - deb http://deb.nodesource.com/node_20.x nodistro main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- + repositories: + - name: nodejs + url: |- + deb http://deb.nodesource.com/node_20.x nodistro main + key: |- + -----BEGIN PGP PUBLIC KEY BLOCK----- - mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B - hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM - Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 - 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR - TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z - E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk - LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI - AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc - NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o - xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk - Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 - hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg - BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 - AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u - JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu - ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi - 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp - Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ - YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb - DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE - IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet - y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao - x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 - K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw - FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa - =MARt - -----END PGP PUBLIC KEY BLOCK----- + mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B + hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM + Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 + 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR + TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z + E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk + LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI + AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc + NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o + xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk + Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 + hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg + BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 + AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u + JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu + ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi + 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp + Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ + YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb + DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE + IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet + y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao + x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 + K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw + FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa + =MARt + -----END PGP PUBLIC KEY BLOCK----- -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux - export NPM_CONFIG_LOGLEVEL=warn - export CI=true - git clone https://github.com/CorentinTh/it-tools -b v{{ image.serial }} --depth 1 /tmp/app + export NPM_CONFIG_LOGLEVEL=warn + export CI=true + git clone https://github.com/CorentinTh/it-tools -b v{{ image.serial }} --depth 1 /tmp/app - mkdir /install - cd /install - cp /tmp/app/{package.json,pnpm-lock.yaml} . + mkdir /install + cd /install + cp /tmp/app/{package.json,pnpm-lock.yaml} . - npm install -g pnpm && pnpm i --frozen-lockfile - cp -r /tmp/app/* /install/ - pnpm build - cp -r dist/* /usr/share/nginx/html/ - mv /var/nginx.conf /etc/nginx/nginx.conf + npm install -g pnpm && pnpm i --frozen-lockfile + cp -r /tmp/app/* /install/ + pnpm build + cp -r dist/* /usr/share/nginx/html/ + mv /var/nginx.conf /etc/nginx/nginx.conf - cd / - rm -rf /install + cd / + rm -rf /install - systemctl enable nginx.service + systemctl enable nginx.service diff --git a/templates/jellyfin.yml b/templates/jellyfin.yml index e258534..9692c88 100644 --- a/templates/jellyfin.yml +++ b/templates/jellyfin.yml @@ -1,93 +1,21 @@ -name: Jenkins +metadata: + name: Jellyfin + get_version_command: curl -s https://api.github.com/repos/jellyfin/jellyfin/releases/latest | jq -r '.tag_name' + description: A Free Software Media System to collect, manage, and stream your media. + categories: Media management, Streaming + project_source: https://github.com/jellyfin/jellyfin + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux -files: -- path: /etc/systemd/system/jellyfin.service - generator: dump - content: |- - [Unit] - Description = Jellyfin Media Server - After = network-online.target + curl https://repo.jellyfin.org/install-debuntu.sh | sed '/echo -en \"If this looks correct/,/read < \/dev\/tty/d' | bash - [Service] - Type = simple - EnvironmentFile = /etc/default/jellyfin - WorkingDirectory = /var/lib/jellyfin - ExecStart = /usr/bin/jellyfin $JELLYFIN_WEB_OPT $JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLYFIN_NOWEBAPP_OPT $JELLYFIN_ADDITIONAL_OPTS - Restart = on-failure - TimeoutSec = 15 - SuccessExitStatus=0 143 - - [Install] - WantedBy = multi-user.target - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - cat < ./plugins-list + cat ./plugins-list | xargs -P 4 -I % bash -c 'echo "Install: %" && ./kestra plugins install % && echo "% installation done" || echo "% installation failed"' - curl -sL https://raw.githubusercontent.com/kestra-io/kestra/develop/.plugins | grep io.kestra | sed s,#,,g > ./plugins-list - - mv /tmp/kestra* ./kestra && chmod +x ./kestra - for i in $(cat ./plugins-list); do ./kestra plugins install $i; done - - systemctl enable kestra.service + systemctl enable kestra.service diff --git a/templates/keycloak.yml b/templates/keycloak.yml index f07cfe0..633850d 100644 --- a/templates/keycloak.yml +++ b/templates/keycloak.yml @@ -1,100 +1,109 @@ -name: Keycloak - -files: -- path: /etc/keycloak/creds.env - generator: dump - mode: '0440' - content: |- - KEYCLOAK_ADMIN= - KEYCLOAK_ADMIN_PASSWORD= - JAVA_OPTS_APPEND="-Djava.net.preferIPv4Stack=true" - -- path: /opt/utils/set-ip.sh - generator: dump - mode: '0755' - content: |- - sleep 5 - HOSTN=$(ip addr list eth0 | grep -E "inet .* metric" | cut -d' ' -f6 | cut -d/ -f1 | head -n 1) - sed -i "s/^hostname.*/hostname=$HOSTN/" /opt/keycloak/conf/keycloak.conf - -- path: /etc/systemd/system/keycloak-init.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Open Source Identity and Access Management - After=network.target - - [Service] - Type=oneshot - RemainAfterExit=yes - ExecStart=/opt/utils/set-ip.sh - - [Install] - WantedBy=multi-user.target - -- path: /etc/systemd/system/keycloak.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Open Source Identity and Access Management - After=network.target keycloak-init.service - PathChanged=/opt/keycloak/conf/keycloak.conf - - [Service] - Type=simple - Restart=always - # Update /etc/keycloak/creds.env with the admin credentials you want. - EnvironmentFile=/etc/keycloak/creds.env - Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 - ExecStart=/opt/keycloak/bin/kc.sh start - - [Install] - WantedBy=multi-user.target - -- path: /opt/certs/rootCA.config - generator: copy - source: assets/rootCA.config - -- path: /opt/certs/csr.config - generator: copy - source: assets/csr.config - -- path: /opt/certs/crt.config - generator: copy - source: assets/crt.config - -packages: -- openjdk-17-jre -- fontconfig - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - mkdir -p /opt/keycloak - - openssl req -x509 -newkey rsa:4096 -keyout /opt/certs/rootCA.key -out /opt/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config - openssl genrsa -out /etc/ssl/private/keycloak.key 2048 - openssl req -new -key /etc/ssl/private/keycloak.key -out /etc/ssl/private/keycloak.csr -config /opt/certs/csr.config - openssl x509 -req -in /etc/ssl/private/keycloak.csr -CA /opt/certs/rootCA.crt -CAkey /opt/certs/rootCA.key -CAcreateserial -out /etc/ssl/private/keycloak.crt -days 1825 -sha256 -extfile /opt/certs/crt.config - - wget -O /tmp/keycloak.tar.gz https://github.com/keycloak/keycloak/releases/download/{{image.serial}}/keycloak-{{image.serial}}.tar.gz - tar -xvf /tmp/keycloak.tar.gz -C /tmp && cp -r /tmp/keycloak-{{image.serial}}/* /opt/keycloak/ - - cat < /opt/keycloak/conf/keycloak.conf - hostname=0.0.0.0 - https-certificate-file=/etc/ssl/private/keycloak.crt - https-certificate-key-file=/etc/ssl/private/keycloak.key - EOF - - export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 - - cd /opt/keycloak/bin && ./kc.sh build - - systemctl enable keycloak-init.service - systemctl enable keycloak.service +metadata: + name: Keycloak + get_version_command: curl -Ls https://api.github.com/repos/keycloak/keycloak/releases/latest | jq -r '.tag_name' + description: Open Source Identity and Access Management. + categories: Identity, IAM, IDP, Security + project_source: https://github.com/keycloak/keycloak + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/keycloak/creds.env + generator: dump + mode: "0440" + content: |- + KEYCLOAK_ADMIN= + KEYCLOAK_ADMIN_PASSWORD= + JAVA_OPTS_APPEND="-Djava.net.preferIPv4Stack=true" + + - path: /opt/utils/set-ip.sh + generator: dump + mode: "0755" + content: |- + sleep 5 + HOSTN=$(ip addr list eth0 | grep -E "inet .* metric" | cut -d' ' -f6 | cut -d/ -f1 | head -n 1) + sed -i "s/^hostname.*/hostname=$HOSTN/" /opt/keycloak/conf/keycloak.conf + + - path: /etc/systemd/system/keycloak-init.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Open Source Identity and Access Management + After=network.target + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=/opt/utils/set-ip.sh + + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/keycloak.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Open Source Identity and Access Management + After=network.target keycloak-init.service + PathChanged=/opt/keycloak/conf/keycloak.conf + + [Service] + Type=simple + Restart=always + # Update /etc/keycloak/creds.env with the admin credentials you want. + EnvironmentFile=/etc/keycloak/creds.env + Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 + ExecStart=/opt/keycloak/bin/kc.sh start + + [Install] + WantedBy=multi-user.target + + - path: /opt/certs/rootCA.config + generator: copy + source: assets/rootCA.config + + - path: /opt/certs/csr.config + generator: copy + source: assets/csr.config + + - path: /opt/certs/crt.config + generator: copy + source: assets/crt.config + + packages: + - openjdk-17-jre + - fontconfig + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + mkdir -p /opt/keycloak + + openssl req -x509 -newkey rsa:4096 -keyout /opt/certs/rootCA.key -out /opt/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config + openssl genrsa -out /etc/ssl/private/keycloak.key 2048 + openssl req -new -key /etc/ssl/private/keycloak.key -out /etc/ssl/private/keycloak.csr -config /opt/certs/csr.config + openssl x509 -req -in /etc/ssl/private/keycloak.csr -CA /opt/certs/rootCA.crt -CAkey /opt/certs/rootCA.key -CAcreateserial -out /etc/ssl/private/keycloak.crt -days 1825 -sha256 -extfile /opt/certs/crt.config + + wget -O /tmp/keycloak.tar.gz https://github.com/keycloak/keycloak/releases/download/{{image.serial}}/keycloak-{{image.serial}}.tar.gz + tar -xvf /tmp/keycloak.tar.gz -C /tmp && cp -r /tmp/keycloak-{{image.serial}}/* /opt/keycloak/ + + cat < /opt/keycloak/conf/keycloak.conf + hostname=0.0.0.0 + https-certificate-file=/etc/ssl/private/keycloak.crt + https-certificate-key-file=/etc/ssl/private/keycloak.key + EOF + + export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 + + cd /opt/keycloak/bin && ./kc.sh build + + systemctl enable keycloak-init.service + systemctl enable keycloak.service diff --git a/templates/lidarr.yml b/templates/lidarr.yml new file mode 100644 index 0000000..2a08549 --- /dev/null +++ b/templates/lidarr.yml @@ -0,0 +1,60 @@ +metadata: + name: Lidarr + get_version_command: curl -s https://api.github.com/repos/Lidarr/Lidarr/releases/latest | jq -r '.tag_name' + description: Lidarr is a music collection manager for Usenet and BitTorrent users. + categories: Media management + project_source: https://wiki.servarr.com/lidarr + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/lidarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Lidarr Daemon + After=syslog.target network.target + [Service] + User=lidarr + Group=media + Type=simple + ExecStart=/opt/Lidarr/Lidarr -nobrowser -data=/var/lib/lidarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + packages: + - git + - sqlite3 + - mediainfo + - libchromaprint-tools + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + + mkdir /downloads + groupadd media + chown -R :media /downloads + + cd /opt + + useradd lidarr + usermod -aG media lidarr + mkdir -p /var/lib/lidarr + chown lidarr:lidarr -R /var/lib/lidarr + wget --content-disposition "http://lidarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Lidarr.linux.tar.gz + tar -xvzf Lidarr*.linux*.tar.gz + chown lidarr:lidarr -R /opt/Lidarr + systemctl enable lidarr.service diff --git a/templates/matomo.yml b/templates/matomo.yml index 320649c..4ade34a 100644 --- a/templates/matomo.yml +++ b/templates/matomo.yml @@ -1,113 +1,122 @@ -name: Matomo - -files: -- path: /opt/certs/rootCA.config - generator: copy - source: assets/rootCA.config - -- path: /opt/ssl.conf - generator: dump - content: |- - - ServerAdmin webmaster@localhost - DocumentRoot /var/www/html - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined - SSLEngine on - SSLCertificateFile /etc/ssl/certs/rootCA.crt - SSLCertificateKeyFile /etc/ssl/private/rootCA.key - - SSLOptions +StdEnvVars - - - SSLOptions +StdEnvVars - - - -- path: /var/matomo/init.sh - generator: dump - mode: '0755' - content: |- - #!/bin/bash - - sed -i "/'tables_prefix' => 'matomo_'/ r /var/matomo/re.php" /var/www/html/plugins/Installation/FormDatabaseSetup.php - sed -i "/

{{ 'Installation/ r /var/matomo/re.twig" /var/www/html/plugins/Installation/templates/databaseSetup.twig - sed -i "s|File integrity check failed and reported some errors. You should fix this issue and then refresh this page until it shows no error.|File integrity check failed and reported some errors. But this is expected due to some changes done on DB the setup form default values during the LXC packaging. The expected modified files are: /var/www/html/lang/en.json, /var/www/html/plugins/Installation/FormDatabaseSetup.php and /var/www/html/plugins/Installation/templates/databaseSetup.twig|" /var/www/html/lang/en.json - - mysql -e "CREATE DATABASE matomo_db;" - mysql -e "CREATE USER 'matomo_u'@'localhost';" - mysql -e "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON matomo_db.* TO 'matomo_u'@'localhost';" - mysql -e "GRANT FILE ON *.* TO 'matomo_u'@'localhost';" - - a2enmod ssl - a2ensite default-ssl - a2dissite 000-default.conf - systemctl reload apache2 - -- path: /var/matomo/re.twig - generator: dump - mode: '0644' - content: |- +metadata: + name: Matomo + get_version_command: curl -s https://api.github.com/repos/matomo-org/matomo/releases/latest | jq -r '.tag_name' + description: Google Analytics alternative that protects your data and your customers' privacy. + categories: Analytics, SEO, Tracking + project_source: https://github.com/matomo-org/matomo + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /opt/certs/rootCA.config + generator: copy + source: assets/rootCA.config + + - path: /opt/ssl.conf + generator: dump + content: |- + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + SSLEngine on + SSLCertificateFile /etc/ssl/certs/rootCA.crt + SSLCertificateKeyFile /etc/ssl/private/rootCA.key + + SSLOptions +StdEnvVars + + + SSLOptions +StdEnvVars + + + + - path: /var/matomo/init.sh + generator: dump + mode: "0755" + content: |- + #!/bin/bash + + sed -i "/'tables_prefix' => 'matomo_'/ r /var/matomo/re.php" /var/www/html/plugins/Installation/FormDatabaseSetup.php + sed -i "/

{{ 'Installation/ r /var/matomo/re.twig" /var/www/html/plugins/Installation/templates/databaseSetup.twig + sed -i "s|File integrity check failed and reported some errors. You should fix this issue and then refresh this page until it shows no error.|File integrity check failed and reported some errors. But this is expected due to some changes done on DB the setup form default values during the LXC packaging. The expected modified files are: /var/www/html/lang/en.json, /var/www/html/plugins/Installation/FormDatabaseSetup.php and /var/www/html/plugins/Installation/templates/databaseSetup.twig|" /var/www/html/lang/en.json + + mysql -e "CREATE DATABASE matomo_db;" + mysql -e "CREATE USER 'matomo_u'@'localhost';" + mysql -e "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON matomo_db.* TO 'matomo_u'@'localhost';" + mysql -e "GRANT FILE ON *.* TO 'matomo_u'@'localhost';" + + a2enmod ssl + a2ensite default-ssl + a2dissite 000-default.conf + systemctl reload apache2 + + - path: /var/matomo/re.twig + generator: dump + mode: "0644" + content: |-

You can use the pre-configured MySQL database below:
Database Server: 127.0.0.1, Database Name: matomo_db, Login: matomo_u

-- path: /var/matomo/re.php - generator: dump - mode: '0644' - content: |- - 'username' => 'matomo_u', - 'password' => '', - 'dbname' => 'matomo_db', - -- path: /etc/systemd/system/matomo-init.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=DB init for Matomo - After=network.target mariadb.service apache2.service - ConditionPathExists=!/var/matomo/.initialized__ - - [Service] - Type=oneshot - RemainAfterExit=yes - ExecStart=/var/matomo/init.sh - ExecStart=/usr/bin/touch /var/matomo/.initialized__ - - [Install] - WantedBy=multi-user.target - -packages: -- unzip -- php -- php-mysql -- php-curl -- php-cli -- php-gd -- php-xml -- php-mbstring -- libapache2-mod-php -- mariadb-server - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/rootCA.key -out /etc/ssl/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config - - wget -O /tmp/matomo.zip https://builds.matomo.org/matomo-{{image.serial}}.zip - unzip /tmp/matomo.zip -d /tmp - rm -rf /var/www/html/* - cp -r /tmp/matomo/* /var/www/html/ - chown www-data: -R /var/www/ - - cp /opt/ssl.conf /etc/apache2/sites-available/default-ssl.conf - - systemctl enable matomo-init - systemctl enable mariadb - systemctl enable apache2 + - path: /var/matomo/re.php + generator: dump + mode: "0644" + content: |- + 'username' => 'matomo_u', + 'password' => '', + 'dbname' => 'matomo_db', + + - path: /etc/systemd/system/matomo-init.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=DB init for Matomo + After=network.target mariadb.service apache2.service + ConditionPathExists=!/var/matomo/.initialized__ + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=/var/matomo/init.sh + ExecStart=/usr/bin/touch /var/matomo/.initialized__ + + [Install] + WantedBy=multi-user.target + + packages: + - unzip + - php + - php-mysql + - php-curl + - php-cli + - php-gd + - php-xml + - php-mbstring + - libapache2-mod-php + - mariadb-server + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/rootCA.key -out /etc/ssl/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config + + wget -O /tmp/matomo.zip https://builds.matomo.org/matomo-{{image.serial}}.zip + unzip /tmp/matomo.zip -d /tmp + rm -rf /var/www/html/* + cp -r /tmp/matomo/* /var/www/html/ + chown www-data: -R /var/www/ + + cp /opt/ssl.conf /etc/apache2/sites-available/default-ssl.conf + + systemctl enable matomo-init + systemctl enable mariadb + systemctl enable apache2 diff --git a/templates/n8n.yml b/templates/n8n.yml index 168a874..f5061dc 100644 --- a/templates/n8n.yml +++ b/templates/n8n.yml @@ -1,85 +1,94 @@ -name: n8n +metadata: + name: n8n + get_version_command: curl -s https://api.github.com/repos/n8n-io/n8n/releases/latest | jq -r '.tag_name' | sed -E 's/.+@//' + description: n8n is a free and source-available workflow automation tool. + categories: Automation, Workflows + project_source: https://github.com/n8n-io/n8n + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /opt/n8n/.env + generator: dump + mode: "0440" + content: |- + PORT=5678 + NODE_ENV="production" + NODE_OPTIONS="--no-experimental-fetch" + N8N_RELEASE_TYPE=stable -files: -- path: /opt/n8n/.env - generator: dump - mode: '0440' - content: |- - PORT=5678 - NODE_ENV="production" - NODE_OPTIONS="--no-experimental-fetch" - N8N_RELEASE_TYPE=stable + - path: /etc/systemd/system/n8n.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=n8n - Workflow automation tool + After=network.target + ConditionPathExists=/opt/n8n/.installed__ -- path: /etc/systemd/system/n8n.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=n8n - Workflow automation tool - After=network.target - ConditionPathExists=/opt/n8n/.installed__ + [Service] + Type=simple + EnvironmentFile=/opt/n8n/.env + PIDFile=/opt/n8n/n8n.pid + ExecStart=/usr/bin/n8n start + Restart=always - [Service] - Type=simple - EnvironmentFile=/opt/n8n/.env - PIDFile=/opt/n8n/n8n.pid - ExecStart=/usr/bin/n8n start - Restart=always + [Install] + WantedBy=multi-user.target - [Install] - WantedBy=multi-user.target + packages: + - git + - nodejs -packages: -- git -- nodejs + repositories: + - name: nodejs + url: |- + deb http://deb.nodesource.com/node_20.x nodistro main + key: |- + -----BEGIN PGP PUBLIC KEY BLOCK----- -repositories: - - name: nodejs - url: |- - deb http://deb.nodesource.com/node_20.x nodistro main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- + mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B + hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM + Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 + 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR + TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z + E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk + LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI + AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc + NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o + xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk + Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 + hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg + BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 + AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u + JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu + ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi + 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp + Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ + YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb + DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE + IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet + y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao + x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 + K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw + FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa + =MARt + -----END PGP PUBLIC KEY BLOCK----- - mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B - hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM - Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 - 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR - TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z - E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk - LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI - AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc - NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o - xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk - Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 - hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg - BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 - AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u - JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu - ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi - 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp - Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ - YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb - DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE - IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet - y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao - x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 - K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw - FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa - =MARt - -----END PGP PUBLIC KEY BLOCK----- + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux + PORT=5678 + NODE_ENV=production + N8N_RELEASE_TYPE=stable - PORT=5678 - NODE_ENV=production - N8N_RELEASE_TYPE=stable + npm install -g n8n@v{{ image.serial }} + touch /opt/n8n/.installed__ - npm install -g n8n@v{{ image.serial }} - touch /opt/n8n/.installed__ - - systemctl enable n8n.service + systemctl enable n8n.service diff --git a/templates/nextcloud.yml b/templates/nextcloud.yml index 6d174c1..bbf83ff 100644 --- a/templates/nextcloud.yml +++ b/templates/nextcloud.yml @@ -1,159 +1,168 @@ -name: NextCloud - -files: -- path: /opt/certs/rootCA.config - generator: copy - source: assets/rootCA.config - -- path: /opt/ssl.conf - generator: dump - content: |- - - ServerAdmin webmaster@localhost - - DocumentRoot /var/www/html - - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined - SSLEngine on - - SSLCertificateFile /etc/ssl/certs/rootCA.crt - SSLCertificateKeyFile /etc/ssl/private/rootCA.key - - - SSLOptions +StdEnvVars - - - - SSLOptions +StdEnvVars - - - Options MultiViews FollowSymlinks - Order allow,deny - Allow from all - AllowOverride All - - - Deny from all - - - - Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" - - - -- path: /etc/systemd/system/nextcloud-init.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=DB init for NextCloud - After=network.target mariadb.service apache2.service - ConditionPathExists=!/var/nextcloud/.initialized__ - - [Service] - Type=oneshot - RemainAfterExit=yes - ExecStart=/var/nextcloud/init.sh - - [Install] - WantedBy=multi-user.target - -- path: /etc/systemd/system/nextcloud-optimize.timer - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Run perf optimization for NextCloud periodically - - [Timer] - Unit=nextcloud-optimize.service - OnCalendar=*-*-* *:*:00,30 - - [Install] - WantedBy=multi-user.target - -- path: /etc/systemd/system/nextcloud-optimize.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Perf optimization for NextCloud - After=network.target mariadb.service apache2.service - ConditionPathExists=/var/www/html/config/config.php - ConditionPathExists=!/var/nextcloud/.optimized__ - - [Service] - Type=oneshot - ExecStart=/usr/bin/sed -i "/'instanceid' => '/ a 'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis'," /var/www/html/config/config.php - ExecStart=/usr/bin/sed -i "/'instanceid' => '/ a 'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu'," /var/www/html/config/config.php - ExecStart=/usr/bin/chmod 660 /var/www/html/config/config.php - ExecStart=/usr/bin/chown root:www-data /var/www/html/config/config.php - ExecStart=/usr/bin/touch /var/nextcloud/.optimized__ - - [Install] - WantedBy=multi-user.target - -packages: -- unzip -- mariadb-server -- redis -- php -- php-common -- php-cli -- php-mysql -- php-redis -- php-imagick -- php-curl -- php-zip -- php-xml -- php-apcu -- php-gd -- php-gmp -- php-intl -- php-mbstring -- php-bcmath -- libapache2-mod-php - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/rootCA.key -out /etc/ssl/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config - - wget -O /tmp/nextcloud.zip https://download.nextcloud.com/server/releases/nextcloud-{{image.serial}}.zip - unzip /tmp/nextcloud.zip -d /tmp - rm -rf /var/www/html - cp -r /tmp/nextcloud /var/www/html - mkdir -p /var/www/html/data - chown www-data: -R /var/www/ - - cp /opt/ssl.conf /etc/apache2/sites-available/default-ssl.conf - - PHP_VERSION=$(php -v|grep cli|awk '{print $2}'|cut -d . -f1-2) - - sed -iE "s|^output_buffering.*|output_buffering = Off|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^memory_limit.*|memory_limit = 512M|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^upload_max_filesize.*|upload_max_filesize = 256M|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^max_file_uploads.*|max_file_uploads = 100|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^max_execution_time.*|max_execution_time = 360|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^post_max_size.*|post_max_size = 256M|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^;date.timezone.*|date.timezone = UTC|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^;opcache.enable.*|opcache.enable = 1|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^;opcache.interned_strings_buffer.*|opcache.interned_strings_buffer = 16|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^;opcache.max_accelerated_files.*|opcache.max_accelerated_files = 10000|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^;opcache.memory_consumption.*|opcache.memory_consumption = 128|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^;opcache.save_comments.*|opcache.save_comments = 1|" /etc/php/$PHP_VERSION/apache2/php.ini - sed -iE "s|^;opcache.revalidate_freq.*|opcache.revalidate_freq = 1|" /etc/php/$PHP_VERSION/apache2/php.ini - - sed -iE "s|'dbname' => '',|'dbname' => 'nextcloud_db',|" /var/www/html/core/Controller/SetupController.php - sed -iE "s|'dbuser' => '',|'dbuser' => 'nextcloud_u',|" /var/www/html/core/Controller/SetupController.php - - systemctl enable mariadb - systemctl enable redis-server - systemctl enable apache2 - systemctl enable nextcloud-init - systemctl enable nextcloud-optimize.timer +metadata: + name: NextCloud + get_version_command: curl -s https://api.github.com/repos/nextcloud/server/releases/latest | jq -r '.tag_name' + description: Fully open-source, on-premises content collaboration platform. + categories: Personal Cloud, Data Privacy + project_source: https://github.com/nextcloud/server + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /opt/certs/rootCA.config + generator: copy + source: assets/rootCA.config + + - path: /opt/ssl.conf + generator: dump + content: |- + + ServerAdmin webmaster@localhost + + DocumentRoot /var/www/html + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + SSLEngine on + + SSLCertificateFile /etc/ssl/certs/rootCA.crt + SSLCertificateKeyFile /etc/ssl/private/rootCA.key + + + SSLOptions +StdEnvVars + + + + SSLOptions +StdEnvVars + + + Options MultiViews FollowSymlinks + Order allow,deny + Allow from all + AllowOverride All + + + Deny from all + + + + Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" + + + + - path: /etc/systemd/system/nextcloud-init.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=DB init for NextCloud + After=network.target mariadb.service apache2.service + ConditionPathExists=!/var/nextcloud/.initialized__ + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=/var/nextcloud/init.sh + + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/nextcloud-optimize.timer + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Run perf optimization for NextCloud periodically + + [Timer] + Unit=nextcloud-optimize.service + OnCalendar=*-*-* *:*:00,30 + + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/nextcloud-optimize.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Perf optimization for NextCloud + After=network.target mariadb.service apache2.service + ConditionPathExists=/var/www/html/config/config.php + ConditionPathExists=!/var/nextcloud/.optimized__ + + [Service] + Type=oneshot + ExecStart=/usr/bin/sed -i "/'instanceid' => '/ a 'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis'," /var/www/html/config/config.php + ExecStart=/usr/bin/sed -i "/'instanceid' => '/ a 'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu'," /var/www/html/config/config.php + ExecStart=/usr/bin/chmod 660 /var/www/html/config/config.php + ExecStart=/usr/bin/chown root:www-data /var/www/html/config/config.php + ExecStart=/usr/bin/touch /var/nextcloud/.optimized__ + + [Install] + WantedBy=multi-user.target + + packages: + - unzip + - mariadb-server + - redis + - php + - php-common + - php-cli + - php-mysql + - php-redis + - php-imagick + - php-curl + - php-zip + - php-xml + - php-apcu + - php-gd + - php-gmp + - php-intl + - php-mbstring + - php-bcmath + - libapache2-mod-php + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/rootCA.key -out /etc/ssl/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config + + wget -O /tmp/nextcloud.zip https://download.nextcloud.com/server/releases/nextcloud-{{image.serial}}.zip + unzip /tmp/nextcloud.zip -d /tmp + rm -rf /var/www/html + cp -r /tmp/nextcloud /var/www/html + mkdir -p /var/www/html/data + chown www-data: -R /var/www/ + + cp /opt/ssl.conf /etc/apache2/sites-available/default-ssl.conf + + PHP_VERSION=$(php -v|grep cli|awk '{print $2}'|cut -d . -f1-2) + + sed -iE "s|^output_buffering.*|output_buffering = Off|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^memory_limit.*|memory_limit = 512M|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^upload_max_filesize.*|upload_max_filesize = 256M|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^max_file_uploads.*|max_file_uploads = 100|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^max_execution_time.*|max_execution_time = 360|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^post_max_size.*|post_max_size = 256M|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^;date.timezone.*|date.timezone = UTC|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^;opcache.enable.*|opcache.enable = 1|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^;opcache.interned_strings_buffer.*|opcache.interned_strings_buffer = 16|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^;opcache.max_accelerated_files.*|opcache.max_accelerated_files = 10000|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^;opcache.memory_consumption.*|opcache.memory_consumption = 128|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^;opcache.save_comments.*|opcache.save_comments = 1|" /etc/php/$PHP_VERSION/apache2/php.ini + sed -iE "s|^;opcache.revalidate_freq.*|opcache.revalidate_freq = 1|" /etc/php/$PHP_VERSION/apache2/php.ini + + sed -iE "s|'dbname' => '',|'dbname' => 'nextcloud_db',|" /var/www/html/core/Controller/SetupController.php + sed -iE "s|'dbuser' => '',|'dbuser' => 'nextcloud_u',|" /var/www/html/core/Controller/SetupController.php + + systemctl enable mariadb + systemctl enable redis-server + systemctl enable apache2 + systemctl enable nextcloud-init + systemctl enable nextcloud-optimize.timer diff --git a/templates/nodered.yml b/templates/nodered.yml new file mode 100644 index 0000000..c09b734 --- /dev/null +++ b/templates/nodered.yml @@ -0,0 +1,84 @@ +metadata: + name: Node-RED + get_version_command: curl -s https://api.github.com/repos/node-red/node-red/releases/latest | jq -r '.tag_name' + description: Low-code programming for event-driven applications + categories: Automation, Workflows + project_source: https://github.com/node-red/node-red + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/nodered.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Node-RED + After=syslog.target network.target + + [Service] + ExecStart=/usr/bin/node-red --max-old-space-size=128 -v + Restart=on-failure + KillSignal=SIGINT + + SyslogIdentifier=node-red + StandardOutput=syslog + + WorkingDirectory=/root/ + User=root + Group=root + + [Install] + WantedBy=multi-user.target + + packages: + - git + - nodejs + + repositories: + - name: nodejs + url: |- + deb http://deb.nodesource.com/node_20.x nodistro main + key: |- + -----BEGIN PGP PUBLIC KEY BLOCK----- + + mQENBFdDN1ABCADaNd/I3j3tn40deQNgz7hB2NvT+syXe6k4ZmdiEcOfBvFrkS8B + hNS67t93etHsxEy7E0qwsZH32bKazMqe9zDwoa3aVImryjh6SHC9lMtW27JPHFeM + Srkt9YmH1WMwWcRO6eSY9B3PpazquhnvbammLuUojXRIxkDroy6Fw4UKmUNSRr32 + 9Ej87jRoR1B2/57Kfp2Y4+vFGGzSvh3AFQpBHq51qsNHALU6+8PjLfIt+5TPvaWR + TB+kAZnQZkaIQM2nr1n3oj6ak2RATY/+kjLizgFWzgEfbCrbsyq68UoY5FPBnu4Z + E3iDZpaIqwKr0seUC7iA1xM5eHi5kty1oB7HABEBAAG0Ik5Tb2xpZCA8bnNvbGlk + LWdwZ0Bub2Rlc291cmNlLmNvbT6JATgEEwECACIFAldDN1ACGwMGCwkIBwMCBhUI + AgkKCwQWAgMBAh4BAheAAAoJEC9ZtfmbG+C0y7wH/i4xnab36dtrYW7RZwL8i6Sc + NjMx4j9+U1kr/F6YtqWd+JwCbBdar5zRghxPcYEq/qf7MbgAYcs1eSOuTOb7n7+o + xUwdH2iCtHhKh3Jr2mRw1ks7BbFZPB5KmkxHaEBfLT4d+I91ZuUdPXJ+0SXs9gzk + Dbz65Uhoz3W03aiF8HeL5JNARZFMbHHNVL05U1sTGTCOtu+1c/33f3TulQ/XZ3Y4 + hwGCpLe0Tv7g7Lp3iLMZMWYPEa0a7S4u8he5IEJQLd8bE8jltcQvrdr3Fm8kI2Jg + BJmUmX4PSfhuTCFaR/yeCt3UoW883bs9LfbTzIx9DJGpRIu8Y0IL3b4sj/GoZVq5 + AQ0EV0M3UAEIAKrTaC62ayzqOIPa7nS90BHHck4Z33a2tZF/uof38xNOiyWGhT8u + JeFoTTHn5SQq5Ftyu4K3K2fbbpuu/APQF05AaljzVkDGNMW4pSkgOasdysj831cu + ssrHX2RYS22wg80k6C/Hwmh5F45faEuNxsV+bPx7oPUrt5n6GMx84vEP3i1+FDBi + 0pt/B/QnDFBXki1BGvJ35f5NwDefK8VaInxXP3ZN/WIbtn5dqxppkV/YkO7GiJlp + Jlju9rf3kKUIQzKQWxFsbCAPIHoWv7rH9RSxgDithXtG6Yg5R1aeBbJaPNXL9wpJ + YBJbiMjkAFaz4B95FOqZm3r7oHugiCGsHX0AEQEAAYkBHwQYAQIACQUCV0M3UAIb + DAAKCRAvWbX5mxvgtE/OB/0VN88DR3Y3fuqy7lq/dthkn7Dqm9YXdorZl3L152eE + IF882aG8FE3qZdaLGjQO4oShAyNWmRfSGuoH0XERXAI9n0r8m4mDMxE6rtP7tHet + y/5M8x3CTyuMgx5GLDaEUvBusnTD+/v/fBMwRK/cZ9du5PSG4R50rtst+oYyC2ao + x4I2SgjtF/cY7bECsZDplzatN3gv34PkcdIg8SLHAVlL4N5tzumDeizRspcSyoy2 + K2+hwKU4C4+dekLLTg8rjnRROvplV2KtaEk6rxKtIRFDCoQng8wfJuIMrDNKvqZw + FRGt7cbvW5MCnuH8MhItOl9Uxp1wHp6gtav/h8Gp6MBa + =MARt + -----END PGP PUBLIC KEY BLOCK----- + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + npm install -g --unsafe-perm node-red + + systemctl enable nodered.service diff --git a/templates/omada.yml b/templates/omada.yml new file mode 100644 index 0000000..271b466 --- /dev/null +++ b/templates/omada.yml @@ -0,0 +1,56 @@ +metadata: + name: Omada + get_version_command: curl -fsSL "https://www.tp-link.com/en/support/download/omada-software-controller/"|grep -io "https.*Omada_SDN_Controller.*linux_x64.deb"|head -n1|grep -oE "v[0-9]+.[0-9]+.[0-9]+" + description: TP-Link Omada SDN Controller Solution offers centralized and efficient management for gateways, switches, and wAP. + categories: SDN, Networks + project_source: https://www.tp-link.com/en/support/download/omada-software-controller + distribution: debian + release: buster + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/nodered.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Node-RED + After=syslog.target network.target + + [Service] + ExecStart=/usr/bin/node-red --max-old-space-size=128 -v + Restart=on-failure + KillSignal=SIGINT + + SyslogIdentifier=node-red + StandardOutput=syslog + + WorkingDirectory=/root/ + User=root + Group=root + + [Install] + WantedBy=multi-user.target + + packages: + - jsvc + - nvidia-openjdk-8-jre + - libssl-dev + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + cd /tmp + + wget -qL https://repo.mongodb.org/apt/debian/dists/buster/mongodb-org/4.4/main/binary-amd64/mongodb-org-server_4.4.29_amd64.deb + apt-get install -fy ./mongodb-org-server*_amd64.deb + + wget -qL $(curl -fsSL "https://www.tp-link.com/en/support/download/omada-software-controller/"|grep -io "https.*Omada_SDN_Controller.*linux_x64.deb"|head -n1) + apt-get install -fy ./*Omada_SDN_Controller*.deb + + systemctl enable mongod.service diff --git a/templates/prowlarr.yml b/templates/prowlarr.yml new file mode 100644 index 0000000..ea90926 --- /dev/null +++ b/templates/prowlarr.yml @@ -0,0 +1,58 @@ +metadata: + name: Prowlarr + get_version_command: curl -s https://api.github.com/repos/Prowlarr/Prowlarr/releases/latest | jq -r '.tag_name' + description: Prowlarr is an indexer manager/proxy built on the popular arr .net/reactjs base stack to integrate with your various PVR apps. + categories: Media management + project_source: https://wiki.servarr.com/prowlarr + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/prowlarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Prowlarr Daemon + After=syslog.target network.target + [Service] + User=prowlarr + Group=media + Type=simple + ExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + packages: + - git + - sqlite3 + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + + mkdir /downloads + groupadd media + chown -R :media /downloads + + cd /opt + + useradd prowlarr + usermod -aG media prowlarr + mkdir -p /var/lib/prowlarr + chown prowlarr:prowlarr -R /var/lib/prowlarr + wget --content-disposition "http://prowlarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Prowlarr.linux.tar.gz + tar -xvzf Prowlarr*.linux*.tar.gz + chown prowlarr:prowlarr -R /opt/Prowlarr + systemctl enable prowlarr.service diff --git a/templates/radarr.yml b/templates/radarr.yml new file mode 100644 index 0000000..0defa6f --- /dev/null +++ b/templates/radarr.yml @@ -0,0 +1,95 @@ +metadata: + name: Radarr + get_version_command: curl -s https://api.github.com/repos/Radarr/Radarr/releases/latest | jq -r '.tag_name' + description: Radarr is a movie collection manager for Usenet and BitTorrent users. + categories: Media management + project_source: https://wiki.servarr.com/radarr + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/radarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Radarr Daemon + After=syslog.target network.target + [Service] + User=radarr + Group=media + Type=simple + ExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/bazarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Bazarr Daemon + After=syslog.target network.target + [Service] + User=bazarr + Group=media + Type=simple + ExecStart=/opt/bazarr/venv/bin/python3 -u /opt/bazarr/bazarr.py + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + packages: + - git + - sqlite3 + - python3-pip + - python3-venv + - python3-distutils + - python3-dev + - 7zip + - unrar-free + - unzip + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + + mkdir /downloads + groupadd media + chown -R :media /downloads + + cd /opt + + useradd radarr + usermod -aG media radarr + mkdir -p /var/lib/radarr + chown radarr:radarr -R /var/lib/radarr + wget --content-disposition "http://radarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Radarr.linux.tar.gz + tar -xvzf Radarr*.linux*.tar.gz + chown radarr:radarr -R /opt/Radarr + systemctl enable radarr.service + + mkdir /opt/bazarr + useradd --home-dir /opt/bazarr --shell /bin/sh bazarr + usermod -aG media bazarr + wget https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip -O /opt/bazarr.zip + unzip /opt/bazarr.zip -d /opt/bazarr + cd /opt/bazarr + python3 -m venv venv + /opt/bazarr/venv/bin/python3 -m pip install -r requirements.txt + chown -R bazarr:bazarr /opt/bazarr + systemctl enable bazarr.service + rm -rf /opt/*.zip diff --git a/templates/readarr.yml b/templates/readarr.yml new file mode 100644 index 0000000..566c6c9 --- /dev/null +++ b/templates/readarr.yml @@ -0,0 +1,58 @@ +metadata: + name: Readarr + get_version_command: curl -s https://api.github.com/repos/Readarr/Readarr/releases?per_page=1 | jq -r '.[0].tag_name' + description: Readarr is an eBook and audiobook collection manager for Usenet and BitTorrent users. + categories: Media management + project_source: https://wiki.servarr.com/readarr + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/readarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Readarr Daemon + After=syslog.target network.target + [Service] + User=readarr + Group=media + Type=simple + ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + packages: + - git + - sqlite3 + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + + mkdir /downloads + groupadd media + chown -R :media /downloads + + cd /opt + + useradd readarr + usermod -aG media readarr + mkdir -p /var/lib/readarr + chown readarr:readarr -R /var/lib/readarr + wget --content-disposition "http://readarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Readarr.linux.tar.gz + tar -xvzf Readarr*.linux*.tar.gz + chown readarr:readarr -R /opt/Readarr + systemctl enable readarr.service diff --git a/templates/servarr.yml b/templates/servarr.yml index 2c5756b..018d8b6 100644 --- a/templates/servarr.yml +++ b/templates/servarr.yml @@ -1,313 +1,318 @@ -files: -- path: /etc/systemd/system/readarr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Readarr Daemon - After=syslog.target network.target - [Service] - User=readarr - Group=media - Type=simple - ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/ - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target +metadata: + name: Servarr + get_version_command: date +%Y-%m + description: Media organizer/manager stack (ARR) for usenet and torrent users. This stack includes QBitTorrent, SABnzbd, FlareSolverr, Bazarr and the ARR stack. + categories: Media management + project_source: https://wiki.servarr.com + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/readarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Readarr Daemon + After=syslog.target network.target + [Service] + User=readarr + Group=media + Type=simple + ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/sonarr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Sonarr Daemon - After=syslog.target network.target - [Service] - User=sonarr - Group=media - Type=simple - ExecStart=/opt/Sonarr/Sonarr -nobrowser -data=/var/lib/sonarr/ - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/sonarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Sonarr Daemon + After=syslog.target network.target + [Service] + User=sonarr + Group=media + Type=simple + ExecStart=/opt/Sonarr/Sonarr -nobrowser -data=/var/lib/sonarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/radarr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Radarr Daemon - After=syslog.target network.target - [Service] - User=radarr - Group=media - Type=simple - ExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr/ - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/radarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Radarr Daemon + After=syslog.target network.target + [Service] + User=radarr + Group=media + Type=simple + ExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/lidarr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Lidarr Daemon - After=syslog.target network.target - [Service] - User=lidarr - Group=media - Type=simple - ExecStart=/opt/Lidarr/Lidarr -nobrowser -data=/var/lib/lidarr/ - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/lidarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Lidarr Daemon + After=syslog.target network.target + [Service] + User=lidarr + Group=media + Type=simple + ExecStart=/opt/Lidarr/Lidarr -nobrowser -data=/var/lib/lidarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/prowlarr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Prowlarr Daemon - After=syslog.target network.target - [Service] - User=prowlarr - Group=media - Type=simple - ExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr/ - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/prowlarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Prowlarr Daemon + After=syslog.target network.target + [Service] + User=prowlarr + Group=media + Type=simple + ExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/whisparr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Whisparr Daemon - After=syslog.target network.target - [Service] - User=whisparr - Group=media - Type=simple - ExecStart=/opt/Whisparr/Whisparr -nobrowser -data=/var/lib/whisparr/ - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target -- path: /etc/systemd/system/flaresolverr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=FlareSolverr Daemon - After=syslog.target network.target - [Service] - User=flaresolverr - Group=media - Type=simple - ExecStart=/opt/FlareSolverr/venv/bin/python -u /opt/FlareSolverr/src/flaresolverr.py - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/whisparr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Whisparr Daemon + After=syslog.target network.target + [Service] + User=whisparr + Group=media + Type=simple + ExecStart=/opt/Whisparr/Whisparr -nobrowser -data=/var/lib/whisparr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/bazarr.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Bazarr Daemon - After=syslog.target network.target - [Service] - User=bazarr - Group=media - Type=simple - ExecStart=/opt/bazarr/venv/bin/python -u /opt/bazarr/bazarr.py - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/bazarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Bazarr Daemon + After=syslog.target network.target + [Service] + User=bazarr + Group=media + Type=simple + ExecStart=/opt/bazarr/venv/bin/python3 -u /opt/bazarr/bazarr.py + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/qbittorrent.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=QBitTorrent Daemon - After=syslog.target network.target - [Service] - User=qbittorrent - Group=media - Type=simple - ExecStart=/usr/bin/qbittorrent-nox --first-and-last --skip-dialog=true - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/flaresolverr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=FlareSolverr Daemon + After=syslog.target network.target + [Service] + User=flaresolverr + Group=media + Type=simple + ExecStart=/opt/FlareSolverr/venv/bin/python3 -u /opt/FlareSolverr/src/flaresolverr.py + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -- path: /etc/systemd/system/sabnzbdplus.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=SABnzbdplus Daemon - After=syslog.target network.target - [Service] - User=sabnzbdplus - Group=media - Type=simple - ExecStart=/usr/bin/sabnzbdplus -s 0.0.0.0:8081 - TimeoutStopSec=20 - KillMode=process - Restart=on-failure - [Install] - WantedBy=multi-user.target + - path: /etc/systemd/system/qbittorrent.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=QBitTorrent Daemon + After=syslog.target network.target + [Service] + User=qbittorrent + Group=media + Type=simple + ExecStart=/usr/bin/qbittorrent-nox --first-and-last --skip-dialog=true + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -packages: -- software-properties-common -- git -- sqlite3 -- python3-pip -- python3-venv -- python3-distutils -- python3-dev -- equivs -- 7zip -- unrar-free -- unzip -- qbittorrent-nox -- sabnzbdplus + - path: /etc/systemd/system/sabnzbdplus.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=SABnzbdplus Daemon + After=syslog.target network.target + [Service] + User=sabnzbdplus + Group=media + Type=simple + ExecStart=/usr/bin/sabnzbdplus -s 0.0.0.0:8081 + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux + packages: + - git + - sqlite3 + - python3-pip + - python3-venv + - python3-distutils + - python3-dev + - equivs + - 7zip + - unrar-free + - unzip + - qbittorrent-nox + - sabnzbdplus - export ARCH={{ image.architecture }} - if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux - mkdir /downloads - groupadd media - chown -R :media /downloads + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi - cd /opt + mkdir /downloads + groupadd media + chown -R :media /downloads - useradd readarr - usermod -aG media readarr - mkdir -p /var/lib/readarr - chown readarr:readarr -R /var/lib/readarr - wget --content-disposition "http://readarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Readarr.linux.tar.gz - tar -xvzf Readarr*.linux*.tar.gz - chown readarr:readarr -R /opt/Readarr - systemctl enable readarr.service + cd /opt - useradd sonarr - usermod -aG media sonarr - mkdir -p /var/lib/sonarr - chown sonarr:sonarr -R /var/lib/sonarr - wget --content-disposition "https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=${ARCH}" -O Sonarr.linux.tar.gz - tar -xvzf Sonarr*.linux*.tar.gz - chown sonarr:sonarr -R /opt/Sonarr - systemctl enable sonarr.service + useradd readarr + usermod -aG media readarr + mkdir -p /var/lib/readarr + chown readarr:readarr -R /var/lib/readarr + wget --content-disposition "http://readarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Readarr.linux.tar.gz + tar -xvzf Readarr*.linux*.tar.gz + chown readarr:readarr -R /opt/Readarr - useradd radarr - usermod -aG media radarr - mkdir -p /var/lib/radarr - chown radarr:radarr -R /var/lib/radarr - wget --content-disposition "http://radarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Radarr.linux.tar.gz - tar -xvzf Radarr*.linux*.tar.gz - chown radarr:radarr -R /opt/Radarr - systemctl enable radarr.service + useradd sonarr + usermod -aG media sonarr + mkdir -p /var/lib/sonarr + chown sonarr:sonarr -R /var/lib/sonarr + wget --content-disposition "https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=${ARCH}" -O Sonarr.linux.tar.gz + tar -xvzf Sonarr*.linux*.tar.gz + chown sonarr:sonarr -R /opt/Sonarr - useradd lidarr - usermod -aG media lidarr - mkdir -p /var/lib/lidarr - chown lidarr:lidarr -R /var/lib/lidarr - wget --content-disposition "http://lidarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Lidarr.linux.tar.gz - tar -xvzf Lidarr*.linux*.tar.gz - chown lidarr:lidarr -R /opt/Lidarr - systemctl enable lidarr.service + useradd radarr + usermod -aG media radarr + mkdir -p /var/lib/radarr + chown radarr:radarr -R /var/lib/radarr + wget --content-disposition "http://radarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Radarr.linux.tar.gz + tar -xvzf Radarr*.linux*.tar.gz + chown radarr:radarr -R /opt/Radarr - useradd prowlarr - usermod -aG media prowlarr - mkdir -p /var/lib/prowlarr - chown prowlarr:prowlarr -R /var/lib/prowlarr - wget --content-disposition "http://prowlarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Prowlarr.linux.tar.gz - tar -xvzf Prowlarr*.linux*.tar.gz - chown prowlarr:prowlarr -R /opt/Prowlarr - systemctl enable prowlarr.service + useradd lidarr + usermod -aG media lidarr + mkdir -p /var/lib/lidarr + chown lidarr:lidarr -R /var/lib/lidarr + wget --content-disposition "http://lidarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Lidarr.linux.tar.gz + tar -xvzf Lidarr*.linux*.tar.gz + chown lidarr:lidarr -R /opt/Lidarr - useradd whisparr - usermod -aG media whisparr - mkdir -p /var/lib/whisparr - chown whisparr:whisparr -R /var/lib/whisparr - wget --content-disposition "http://whisparr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Whisparr.linux.tar.gz - tar -xvzf Whisparr*.linux*.tar.gz - chown whisparr:whisparr -R /opt/Whisparr - systemctl enable whisparr.service - rm -rf *.tar.gz + useradd prowlarr + usermod -aG media prowlarr + mkdir -p /var/lib/prowlarr + chown prowlarr:prowlarr -R /var/lib/prowlarr + wget --content-disposition "http://prowlarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Prowlarr.linux.tar.gz + tar -xvzf Prowlarr*.linux*.tar.gz + chown prowlarr:prowlarr -R /opt/Prowlarr - mkdir -p /tmp/{libgl1-mesa-dri,adwaita-icon-theme} /pkgs - cd /tmp/libgl1-mesa-dri - equivs-control libgl1-mesa-dri - printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: libgl1-mesa-dri\nVersion: 99.0.0\nDescription: Dummy package for libgl1-mesa-dri\n' >> libgl1-mesa-dri - equivs-build libgl1-mesa-dri - mv libgl1-mesa-dri_*.deb /pkgs/libgl1-mesa-dri.deb - cd /tmp/adwaita-icon-theme - equivs-control adwaita-icon-theme - printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: adwaita-icon-theme\nVersion: 99.0.0\nDescription: Dummy package for adwaita-icon-theme\n' >> adwaita-icon-theme - equivs-build adwaita-icon-theme - mv adwaita-icon-theme_*.deb /pkgs/adwaita-icon-theme.deb - dpkg -i /pkgs/libgl1-mesa-dri.deb - dpkg -i /pkgs/adwaita-icon-theme.deb - apt install -y --no-install-recommends chromium chromium-common chromium-driver xvfb dumb-init procps curl vim xauth - useradd --home-dir /opt/FlareSolverr --shell /bin/sh flaresolverr - usermod -aG media flaresolverr - git clone -b master --depth 1 https://github.com/FlareSolverr/FlareSolverr.git /opt/FlareSolverr - cd /opt/FlareSolverr - python3 -m venv venv - /opt/FlareSolverr/venv/bin/python -m pip install -r requirements.txt - mv /usr/bin/chromedriver /opt/FlareSolverr/chromedriver - mkdir -p "/opt/FlareSolverr/.config/chromium/Crash Reports/pending" - chown -R flaresolverr:flaresolverr /opt/FlareSolverr - systemctl enable flaresolverr.service - rm -f /usr/lib/x86_64-linux-gnu/libmfxhw* - rm -f /usr/lib/x86_64-linux-gnu/mfx/* - rm -rf /pkgs + useradd whisparr + usermod -aG media whisparr + mkdir -p /var/lib/whisparr + chown whisparr:whisparr -R /var/lib/whisparr + wget --content-disposition "http://whisparr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Whisparr.linux.tar.gz + tar -xvzf Whisparr*.linux*.tar.gz + chown whisparr:whisparr -R /opt/Whisparr + rm -rf *.tar.gz - mkdir /opt/bazarr - useradd --home-dir /opt/bazarr --shell /bin/sh bazarr - usermod -aG media bazarr - wget https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip -O /opt/bazarr.zip - unzip /opt/bazarr.zip -d /opt/bazarr - cd /opt/bazarr - python3 -m venv venv - /opt/bazarr/venv/bin/python -m pip install -r requirements.txt - chown -R bazarr:bazarr /opt/bazarr - systemctl enable bazarr.service - rm -rf /opt/*.zip + mkdir /opt/bazarr + useradd --home-dir /opt/bazarr --shell /bin/sh bazarr + usermod -aG media bazarr + wget https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip -O /opt/bazarr.zip + unzip /opt/bazarr.zip -d /opt/bazarr + cd /opt/bazarr + python3 -m venv venv + /opt/bazarr/venv/bin/python3 -m pip install -r requirements.txt + chown -R bazarr:bazarr /opt/bazarr + rm -rf /opt/*.zip - useradd -m --home-dir /opt/qbittorrent qbittorrent - usermod -aG media qbittorrent - systemctl enable qbittorrent.service + mkdir -p /tmp/{libgl1-mesa-dri,adwaita-icon-theme} /pkgs + cd /tmp/libgl1-mesa-dri + equivs-control libgl1-mesa-dri + printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: libgl1-mesa-dri\nVersion: 99.0.0\nDescription: Dummy package for libgl1-mesa-dri\n' >> libgl1-mesa-dri + equivs-build libgl1-mesa-dri + mv libgl1-mesa-dri_*.deb /pkgs/libgl1-mesa-dri.deb + cd /tmp/adwaita-icon-theme + equivs-control adwaita-icon-theme + printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: adwaita-icon-theme\nVersion: 99.0.0\nDescription: Dummy package for adwaita-icon-theme\n' >> adwaita-icon-theme + equivs-build adwaita-icon-theme + mv adwaita-icon-theme_*.deb /pkgs/adwaita-icon-theme.deb + dpkg -i /pkgs/libgl1-mesa-dri.deb + dpkg -i /pkgs/adwaita-icon-theme.deb + apt-get install -y --no-install-recommends chromium chromium-common chromium-driver xvfb dumb-init procps curl vim xauth + useradd --home-dir /opt/FlareSolverr --shell /bin/sh flaresolverr + usermod -aG media flaresolverr + git clone -b master --depth 1 https://github.com/FlareSolverr/FlareSolverr.git /opt/FlareSolverr + cd /opt/FlareSolverr + python3 -m venv venv + /opt/FlareSolverr/venv/bin/python3 -m pip install -r requirements.txt + mv /usr/bin/chromedriver /opt/FlareSolverr/chromedriver + mkdir -p "/opt/FlareSolverr/.config/chromium/Crash Reports/pending" + chown -R flaresolverr:flaresolverr /opt/FlareSolverr + rm -f /usr/lib/x86_64-linux-gnu/libmfxhw* + rm -f /usr/lib/x86_64-linux-gnu/mfx/* + rm -rf /pkgs - useradd -m --home-dir /opt/sabnzbdplus sabnzbdplus - usermod -aG media sabnzbdplus - systemctl enable sabnzbdplus.service + useradd -m --home-dir /opt/qbittorrent qbittorrent + usermod -aG media qbittorrent + + useradd -m --home-dir /opt/sabnzbdplus sabnzbdplus + usermod -aG media sabnzbdplus + + systemctl enable prowlarr.service sonarr.service radarr.service \ + bazarr.service readarr.service lidarr.service whisparr.service \ + flaresolverr.service qbittorrent.service sabnzbdplus.service diff --git a/templates/sonarr.yml b/templates/sonarr.yml new file mode 100644 index 0000000..39b8203 --- /dev/null +++ b/templates/sonarr.yml @@ -0,0 +1,95 @@ +metadata: + name: Sonarr + get_version_command: curl -s https://api.github.com/repos/Sonarr/Sonarr/releases/latest | jq -r '.tag_name' + description: Sonarr is a PVR for Usenet and BitTorrent users. + categories: Media management + project_source: https://wiki.servarr.com/sonarr + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/sonarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Sonarr Daemon + After=syslog.target network.target + [Service] + User=sonarr + Group=media + Type=simple + ExecStart=/opt/Sonarr/Sonarr -nobrowser -data=/var/lib/sonarr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + - path: /etc/systemd/system/bazarr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Bazarr Daemon + After=syslog.target network.target + [Service] + User=bazarr + Group=media + Type=simple + ExecStart=/opt/bazarr/venv/bin/python3 -u /opt/bazarr/bazarr.py + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + packages: + - git + - sqlite3 + - python3-pip + - python3-venv + - python3-distutils + - python3-dev + - 7zip + - unrar-free + - unzip + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + + mkdir /downloads + groupadd media + chown -R :media /downloads + + cd /opt + + useradd sonarr + usermod -aG media sonarr + mkdir -p /var/lib/sonarr + chown sonarr:sonarr -R /var/lib/sonarr + wget --content-disposition "https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=${ARCH}" -O Sonarr.linux.tar.gz + tar -xvzf Sonarr*.linux*.tar.gz + chown sonarr:sonarr -R /opt/Sonarr + systemctl enable sonarr.service + + mkdir /opt/bazarr + useradd --home-dir /opt/bazarr --shell /bin/sh bazarr + usermod -aG media bazarr + wget https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip -O /opt/bazarr.zip + unzip /opt/bazarr.zip -d /opt/bazarr + cd /opt/bazarr + python3 -m venv venv + /opt/bazarr/venv/bin/python3 -m pip install -r requirements.txt + chown -R bazarr:bazarr /opt/bazarr + systemctl enable bazarr.service + rm -rf /opt/*.zip diff --git a/templates/vault.yml b/templates/vault.yml index 10091f7..4198b4e 100644 --- a/templates/vault.yml +++ b/templates/vault.yml @@ -1,70 +1,79 @@ -name: Vault +metadata: + name: Vault + get_version_command: curl -s https://api.github.com/repos/hashicorp/vault/releases/latest | jq -r '.tag_name' + description: Vault is a free and source-available secrets management tool / secrets store. + categories: Secrets management, Security + project_source: https://github.com/hashicorp/vault + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /opt/certs/rootCA.config + generator: copy + source: assets/rootCA.config -files: -- path: /opt/certs/rootCA.config - generator: copy - source: assets/rootCA.config + - path: /opt/certs/csr.config + generator: copy + source: assets/csr.config -- path: /opt/certs/csr.config - generator: copy - source: assets/csr.config + - path: /opt/certs/crt.config + generator: copy + source: assets/crt.config -- path: /opt/certs/crt.config - generator: copy - source: assets/crt.config + - path: /opt/vault/.config + generator: dump + content: |- + ui = true + cluster_addr = "https://127.0.0.1:8201" + api_addr = "https://127.0.0.1:8200" + disable_mlock = true -- path: /opt/vault/.config - generator: dump - content: |- - ui = true - cluster_addr = "https://127.0.0.1:8201" - api_addr = "https://127.0.0.1:8200" - disable_mlock = true + storage "raft" { + path = "/opt/vault/data" + node_id = "vault01" + } - storage "raft" { - path = "/opt/vault/data" - node_id = "vault01" - } + listener "tcp" { + address = "0.0.0.0:8200" + tls_cert_file = "/etc/ssl/private/vault.crt" + tls_key_file = "/etc/ssl/private/vault.key" + } - listener "tcp" { - address = "0.0.0.0:8200" - tls_cert_file = "/etc/ssl/private/vault.crt" - tls_key_file = "/etc/ssl/private/vault.key" - } + - path: /etc/systemd/system/vault.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Vault - Secret management + After=network.target -- path: /etc/systemd/system/vault.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Vault - Secret management - After=network.target + [Service] + Type=simple + PIDFile=/opt/vault/vault.pid + ExecStart=/usr/bin/vault server -config /opt/vault/.config + Restart=always - [Service] - Type=simple - PIDFile=/opt/vault/vault.pid - ExecStart=/usr/bin/vault server -config /opt/vault/.config - Restart=always + [Install] + WantedBy=multi-user.target - [Install] - WantedBy=multi-user.target + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux + wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg + echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com {{image.release}} main" | tee /etc/apt/sources.list.d/hashicorp.list + apt-get update && apt-get install vault - wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg - echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com {{image.release}} main" | tee /etc/apt/sources.list.d/hashicorp.list - apt update && apt install vault + mkdir -p /opt/vault/data - mkdir -p /opt/vault/data + openssl req -x509 -newkey rsa:4096 -keyout /opt/certs/rootCA.key -out /opt/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config + openssl genrsa -out /etc/ssl/private/vault.key 2048 + openssl req -new -key /etc/ssl/private/vault.key -out /etc/ssl/private/vault.csr -config /opt/certs/csr.config + openssl x509 -req -in /etc/ssl/private/vault.csr -CA /opt/certs/rootCA.crt -CAkey /opt/certs/rootCA.key -CAcreateserial -out /etc/ssl/private/vault.crt -days 1825 -sha256 -extfile /opt/certs/crt.config - openssl req -x509 -newkey rsa:4096 -keyout /opt/certs/rootCA.key -out /opt/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config - openssl genrsa -out /etc/ssl/private/vault.key 2048 - openssl req -new -key /etc/ssl/private/vault.key -out /etc/ssl/private/vault.csr -config /opt/certs/csr.config - openssl x509 -req -in /etc/ssl/private/vault.csr -CA /opt/certs/rootCA.crt -CAkey /opt/certs/rootCA.key -CAcreateserial -out /etc/ssl/private/vault.crt -days 1825 -sha256 -extfile /opt/certs/crt.config - - systemctl enable vault.service + systemctl enable vault.service diff --git a/templates/whisparr.yml b/templates/whisparr.yml new file mode 100644 index 0000000..c86afa0 --- /dev/null +++ b/templates/whisparr.yml @@ -0,0 +1,59 @@ +metadata: + name: Whisparr + get_version_command: date +%Y-%m + description: Whisparr is an adult video collection manager for Usenet and BitTorrent users. + categories: Media management + project_source: https://wiki.servarr.com/whisparr + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /etc/systemd/system/whisparr.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Whisparr Daemon + After=syslog.target network.target + [Service] + User=whisparr + Group=media + Type=simple + ExecStart=/opt/Whisparr/Whisparr -nobrowser -data=/var/lib/whisparr/ + TimeoutStopSec=20 + KillMode=process + Restart=on-failure + [Install] + WantedBy=multi-user.target + + packages: + - git + - sqlite3 + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + export ARCH={{ image.architecture }} + if [[ "$ARCH" == "amd64" ]];then export ARCH="x64"; fi + + mkdir /downloads + groupadd media + chown -R :media /downloads + + cd /opt + + useradd whisparr + usermod -aG media whisparr + mkdir -p /var/lib/whisparr + chown whisparr:whisparr -R /var/lib/whisparr + wget --content-disposition "http://whisparr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=${ARCH}" -O Whisparr.linux.tar.gz + tar -xvzf Whisparr*.linux*.tar.gz + chown whisparr:whisparr -R /opt/Whisparr + systemctl enable whisparr.service + rm -rf *.tar.gz diff --git a/templates/zitadel.yml b/templates/zitadel.yml index 03d7a58..5488069 100644 --- a/templates/zitadel.yml +++ b/templates/zitadel.yml @@ -1,175 +1,101 @@ -name: Zitadel - -files: -- path: /opt/certs/rootCA.config - generator: copy - source: assets/rootCA.config - -- path: /opt/certs/csr.config - generator: copy - source: assets/csr.config - -- path: /opt/certs/crt.config - generator: copy - source: assets/crt.config - -- path: /opt/zitadel/.config - generator: dump - content: |- - ExternalDomain: localhost - ExternalSecure: true - TLS: - Enabled: true - KeyPath: /etc/ssl/private/zitadel.key - CertPath: /etc/ssl/private/zitadel.crt - -- path: /opt/zitadel/.env - generator: dump - mode: '0440' - content: |- - ZITADEL_DATABASE_POSTGRES_HOST=127.0.0.1 - ZITADEL_DATABASE_POSTGRES_PORT=5432 - ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel - ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel - ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable - ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=postgres - ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable - -- path: /etc/systemd/system/zitadel.service - generator: dump - mode: '0440' - content: |- - [Unit] - Description=Zitadel - Secure authentication management - After=network.target postgresql.service - - [Service] - Type=simple - EnvironmentFile=/opt/zitadel/.env - PIDFile=/opt/zitadel/zitadel.pid - ExecStart=/usr/local/bin/zitadel start-from-init --masterkeyFromEnv --config /opt/zitadel/.config - Restart=always - - [Install] - WantedBy=multi-user.target - -packages: -- postgresql-16 - -repositories: - - name: postgresql - url: |- - deb http://apt.postgresql.org/pub/repos/apt {{image.release}}-pgdg main - key: |- - -----BEGIN PGP PUBLIC KEY BLOCK----- - - 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 - =DA1T - -----END PGP PUBLIC KEY BLOCK----- - -actions: -- trigger: post-files - pongo: true - action: |- - #!/bin/bash - set -eux - - wget -c https://github.com/zitadel/zitadel/releases/download/v{{image.serial}}/zitadel-linux-{{image.architecture}}.tar.gz -O - | tar -xz && mv zitadel-linux-{{image.architecture}}/zitadel /usr/local/bin - - mkdir -p /opt/zitadel - echo "ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=$(/usr/bin/openssl rand -hex 16)" >> /opt/zitadel/.env - echo "ZITADEL_MASTERKEY=$(/usr/bin/openssl rand -hex 32)" >> /opt/zitadel/.env - - PG_VERSION=$(psql -V|awk '{print $3}'|cut -d . -f1) - - cat < /etc/postgresql/$PG_VERSION/main/pg_hba.conf - local all postgres peer - local zitadel zitadel peer - local all all peer - host zitadel zitadel,postgres 127.0.0.1/32 trust - host all all 127.0.0.1/32 scram-sha-256 - host all all ::1/128 scram-sha-256 - local replication all peer - host replication all 127.0.0.1/32 scram-sha-256 - host replication all ::1/128 scram-sha-256 - EOF - - openssl req -x509 -newkey rsa:4096 -keyout /opt/certs/rootCA.key -out /opt/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config - openssl genrsa -out /etc/ssl/private/zitadel.key 2048 - openssl req -new -key /etc/ssl/private/zitadel.key -out /etc/ssl/private/zitadel.csr -config /opt/certs/csr.config - openssl x509 -req -in /etc/ssl/private/zitadel.csr -CA /opt/certs/rootCA.crt -CAkey /opt/certs/rootCA.key -CAcreateserial -out /etc/ssl/private/zitadel.crt -days 1825 -sha256 -extfile /opt/certs/crt.config - - systemctl enable postgresql.service - systemctl enable zitadel.service +metadata: + name: Zitadel + get_version_command: curl -s https://api.github.com/repos/zitadel/zitadel/releases/latest | jq -r '.tag_name' + description: Zitadel is a free and open-source secure authentication management tool. + categories: IAM, Authentication + project_source: https://github.com/zitadel/zitadel + distribution: debian + release: bookworm + architectures: + - amd64 +instructions: + files: + - path: /opt/certs/rootCA.config + generator: copy + source: assets/rootCA.config + + - path: /opt/certs/csr.config + generator: copy + source: assets/csr.config + + - path: /opt/certs/crt.config + generator: copy + source: assets/crt.config + + - path: /opt/zitadel/.config + generator: dump + content: |- + ExternalDomain: localhost + ExternalSecure: true + TLS: + Enabled: true + KeyPath: /etc/ssl/private/zitadel.key + CertPath: /etc/ssl/private/zitadel.crt + + - path: /opt/zitadel/.env + generator: dump + mode: "0440" + content: |- + ZITADEL_DATABASE_POSTGRES_HOST=127.0.0.1 + ZITADEL_DATABASE_POSTGRES_PORT=5432 + ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel + ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel + ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable + ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=postgres + ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable + + - path: /etc/systemd/system/zitadel.service + generator: dump + mode: "0440" + content: |- + [Unit] + Description=Zitadel - Secure authentication management + After=network.target postgresql.service + + [Service] + Type=simple + EnvironmentFile=/opt/zitadel/.env + PIDFile=/opt/zitadel/zitadel.pid + ExecStart=/usr/local/bin/zitadel start-from-init --masterkeyFromEnv --config /opt/zitadel/.config + Restart=always + + [Install] + WantedBy=multi-user.target + + packages: + - postgresql-15 + + actions: + - trigger: post-files + pongo: true + action: |- + #!/bin/bash + set -eux + + wget -c https://github.com/zitadel/zitadel/releases/download/v{{image.serial}}/zitadel-linux-{{image.architecture}}.tar.gz -O - | tar -xz && mv zitadel-linux-{{image.architecture}}/zitadel /usr/local/bin + + mkdir -p /opt/zitadel + echo "ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=$(/usr/bin/openssl rand -hex 16)" >> /opt/zitadel/.env + echo "ZITADEL_MASTERKEY=$(/usr/bin/openssl rand -hex 32)" >> /opt/zitadel/.env + + PG_VERSION=$(ls -1 /etc/postgresql) + + cat < /etc/postgresql/$PG_VERSION/main/pg_hba.conf + local all postgres peer + local zitadel zitadel peer + local all all peer + host zitadel zitadel,postgres 127.0.0.1/32 trust + host all all 127.0.0.1/32 scram-sha-256 + host all all ::1/128 scram-sha-256 + local replication all peer + host replication all 127.0.0.1/32 scram-sha-256 + host replication all ::1/128 scram-sha-256 + EOF + + openssl req -x509 -newkey rsa:4096 -keyout /opt/certs/rootCA.key -out /opt/certs/rootCA.crt -sha256 -days 3650 -nodes -config /opt/certs/rootCA.config + openssl genrsa -out /etc/ssl/private/zitadel.key 2048 + openssl req -new -key /etc/ssl/private/zitadel.key -out /etc/ssl/private/zitadel.csr -config /opt/certs/csr.config + openssl x509 -req -in /etc/ssl/private/zitadel.csr -CA /opt/certs/rootCA.crt -CAkey /opt/certs/rootCA.key -CAcreateserial -out /etc/ssl/private/zitadel.crt -days 1825 -sha256 -extfile /opt/certs/crt.config + + systemctl enable postgresql.service + systemctl enable zitadel.service