From 623e70f62d58a1584b8491654004d97323b11491 Mon Sep 17 00:00:00 2001 From: Matt Reeves <admin@mafyuh.io> Date: Fri, 12 Jul 2024 23:57:29 -0400 Subject: [PATCH] init migration --- .forgejo/workflows/CD.yml | 97 + .forgejo/workflows/yamllint.yml | 30 + .github/ISSUE_TEMPLATE/adding.yml | 107 + .github/ISSUE_TEMPLATE/deletion.yml | 92 + .github/ISSUE_TEMPLATE/feature-request.yml | 50 + .github/renovate.json | 7 + .gitignore | 6 + ansible/playbooks/apt.yml | 7 + ansible/playbooks/deploy.yml | 33 + ansible/playbooks/git-pull-reset.yml | 24 + ansible/playbooks/qemu-guest-agent.yml | 15 + ansible/playbooks/timezone.yml | 16 + docker/AI/README.md | 11 + docker/AI/docker-compose.yml | 45 + docker/README.md | 312 ++ docker/ag-backup/docker-compose.yml | 22 + docker/ag-main/docker-compose.yml | 36 + docker/arm/README.md | 15 + docker/arm/docker-compose.yml | 165 + docker/arrs/README.md | 10 + docker/arrs/docker-compose.yml | 162 + docker/authentik/docker-compose.yml | 96 + docker/cf/.env.example | 1 + docker/cf/docker-compose.yml | 6 + docker/downloaders/README.md | 10 + docker/downloaders/docker-compose.yml | 79 + docker/jellyfin/README.md | 12 + docker/jellyfin/docker-compose.yml | 53 + docker/kasm/docker-compose.yml | 14 + docker/netboot/docker-compose.yml | 17 + docker/nexus/docker-compose.yml | 11 + docker/pages/docker-compose.yml | 21 + docker/portainer/docker-compose.yml | 15 + docker/scripts/CD.json | 4167 ++++++++++++++++++++ docker/scripts/README.md | 74 + docker/twingate/docker-compose.yml | 38 + docker/whisper/docker-compose.yml | 19 + terraform/AI.tf | 71 + terraform/README.md | 18 + terraform/adguard.tf | 64 + terraform/arrbuntu.tf | 66 + terraform/cloud-init.tf | 73 + terraform/docker-runner.tf | 64 + terraform/docker-runner2.tf | 64 + terraform/downloaders.tf | 66 + terraform/k3s-master.tf | 65 + terraform/k3s-master2.tf | 65 + terraform/k3s-master3.tf | 65 + terraform/kasm.tf | 62 + terraform/nexus.tf | 64 + terraform/npm.tf | 66 + terraform/provider.tf | 26 + terraform/runner.tf | 64 + terraform/ubuntu22-template.tf | 48 + terraform/ubuntu22-template2.tf | 40 + terraform/vars.tf | 47 + terraform/whisper.tf | 75 + terraform/windows.tf | 46 + 58 files changed, 7114 insertions(+) create mode 100644 .forgejo/workflows/CD.yml create mode 100644 .forgejo/workflows/yamllint.yml create mode 100644 .github/ISSUE_TEMPLATE/adding.yml create mode 100644 .github/ISSUE_TEMPLATE/deletion.yml create mode 100644 .github/ISSUE_TEMPLATE/feature-request.yml create mode 100644 .github/renovate.json create mode 100644 ansible/playbooks/apt.yml create mode 100644 ansible/playbooks/deploy.yml create mode 100644 ansible/playbooks/git-pull-reset.yml create mode 100644 ansible/playbooks/qemu-guest-agent.yml create mode 100644 ansible/playbooks/timezone.yml create mode 100644 docker/AI/README.md create mode 100644 docker/AI/docker-compose.yml create mode 100644 docker/README.md create mode 100644 docker/ag-backup/docker-compose.yml create mode 100644 docker/ag-main/docker-compose.yml create mode 100644 docker/arm/README.md create mode 100644 docker/arm/docker-compose.yml create mode 100644 docker/arrs/README.md create mode 100644 docker/arrs/docker-compose.yml create mode 100644 docker/authentik/docker-compose.yml create mode 100644 docker/cf/.env.example create mode 100644 docker/cf/docker-compose.yml create mode 100644 docker/downloaders/README.md create mode 100644 docker/downloaders/docker-compose.yml create mode 100644 docker/jellyfin/README.md create mode 100644 docker/jellyfin/docker-compose.yml create mode 100644 docker/kasm/docker-compose.yml create mode 100644 docker/netboot/docker-compose.yml create mode 100644 docker/nexus/docker-compose.yml create mode 100644 docker/pages/docker-compose.yml create mode 100644 docker/portainer/docker-compose.yml create mode 100644 docker/scripts/CD.json create mode 100644 docker/scripts/README.md create mode 100644 docker/twingate/docker-compose.yml create mode 100644 docker/whisper/docker-compose.yml create mode 100644 terraform/AI.tf create mode 100644 terraform/README.md create mode 100644 terraform/adguard.tf create mode 100644 terraform/arrbuntu.tf create mode 100644 terraform/cloud-init.tf create mode 100644 terraform/docker-runner.tf create mode 100644 terraform/docker-runner2.tf create mode 100644 terraform/downloaders.tf create mode 100644 terraform/k3s-master.tf create mode 100644 terraform/k3s-master2.tf create mode 100644 terraform/k3s-master3.tf create mode 100644 terraform/kasm.tf create mode 100644 terraform/nexus.tf create mode 100644 terraform/npm.tf create mode 100644 terraform/provider.tf create mode 100644 terraform/runner.tf create mode 100644 terraform/ubuntu22-template.tf create mode 100644 terraform/ubuntu22-template2.tf create mode 100644 terraform/vars.tf create mode 100644 terraform/whisper.tf create mode 100644 terraform/windows.tf diff --git a/.forgejo/workflows/CD.yml b/.forgejo/workflows/CD.yml new file mode 100644 index 00000000..8bb3a228 --- /dev/null +++ b/.forgejo/workflows/CD.yml @@ -0,0 +1,97 @@ +name: Deploy to Hosts +on: + pull_request: + types: [closed] + +jobs: + deploy: + if: github.event.pull_request.merged == true + runs-on: ubuntu-22.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Fetch all history for git diff + run: git fetch --depth=2 + + - name: Detect modified folders + id: detect-changes + run: | + if [ "$(git rev-parse --is-shallow-repository)" = "true" ]; then + git fetch --unshallow + fi + folders=$(git diff --name-only HEAD~1 HEAD | cut -d/ -f1 | sort | uniq) + echo "Modified folders: $folders" + echo "::set-output name=folders::$folders" + + - name: Deploy to hosts + run: | + IFS=' ' read -r -a folder_array <<< "${{ steps.detect-changes.outputs.folders }}" + for folder in "${folder_array[@]}"; do + case $folder in + arrs) + target_host="arrs.lan" + ;; + arm) + target_host="arm.lan" + ;; + downloaders) + target_host="downloaders.lan" + ;; + AI) + target_host="ai.lan" + ;; + authentik) + target_host="auth.lan" + ;; + cf) + target_host="cf.lan" + ;; + jellyfin) + target_host="jf.lan" + ;; + kasm) + target_host="kasm.lan" + ;; + netboot) + target_host="netboot.lan" + ;; + nexus) + target_host="nexus.lan" + ;; + pages) + target_host="pages.lan" + ;; + portainer) + target_host="port.lan" + ;; + twingate) + target_host="twingate.lan" + ;; + whisper) + target_host="whisper.lan" + ;; + # Add cases for other folders/hosts + *) + echo "Unknown folder: $folder" + continue + ;; + esac + echo "Triggering AWX Job with target host: $target_host and folder: $folder" + curl -X POST -k -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${{ secrets.AWX_API_TOKEN }}" \ + -d "{\"extra_vars\": {\"target_host\": \"$target_host\", \"folder\": \"$folder\"}}" \ + "https://awx.mafyuh.xyz/api/v2/job_templates/13/launch/" + + sleep 45 # Delay for 45 seconds before fetching logs + + job_id=$(curl -s -H "Authorization: Bearer ${{ secrets.AWX_API_TOKEN }}" https://awx.mafyuh.xyz/api/v2/job_templates/13/jobs/?order_by=-id | jq -r '.results[0].id') + logs=$(curl -s -H "Authorization: Bearer ${{ secrets.AWX_API_TOKEN }}" https://awx.mafyuh.xyz/api/v2/jobs/$job_id/stdout/?format=json) + echo "AWX Job Logs for folder: $folder" + echo "Range:" + echo "Start: $(echo "$logs" | jq -r '.range.start')" + echo "End: $(echo "$logs" | jq -r '.range.end')" + echo "Absolute End: $(echo "$logs" | jq -r '.range.absolute_end')" + echo "Content:" + echo "$(echo "$logs" | jq -r '.content')" + done diff --git a/.forgejo/workflows/yamllint.yml b/.forgejo/workflows/yamllint.yml new file mode 100644 index 00000000..ce53c2d9 --- /dev/null +++ b/.forgejo/workflows/yamllint.yml @@ -0,0 +1,30 @@ +name: Lint on PR + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + lint: + name: Lint YAML files + runs-on: docker + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 14 + + - name: Install yamllint + run: | + npm install -g yaml-lint + + - name: Show yamllint version + run: | + yamllint --version + + - name: Lint .yml files + run: | + yamllint -d "{extends: relaxed, rules: {line-length: {max: 120}}}" ./**/*.yml \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/adding.yml b/.github/ISSUE_TEMPLATE/adding.yml new file mode 100644 index 00000000..934f5708 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/adding.yml @@ -0,0 +1,107 @@ +name: 'Add Application' +description: 'Track the process of adding a new application' +title: 'Add Application: [Application Name]' +labels: + - addition +assignees: '' + +body: + - type: markdown + attributes: + value: | + ## Application Details + + - type: input + id: application-name + attributes: + label: Application Name + description: Name of the application to be added + placeholder: Name of the application + + - type: textarea + id: application-description + attributes: + label: Application Description + description: Provide a brief description of the application and its purpose + placeholder: Description of the application + + - type: checkboxes + id: application-reason + attributes: + label: Reason for Addition + description: Please select one or more reasons for adding the application + options: + - label: New functionality + - label: Performance improvement + - label: Security enhancement + - label: Replacing another application + description: Provide the name of the application being replaced, if applicable + - label: Other (please specify) + description: Provide additional details + + - type: dropdown + id: folder-added + attributes: + label: Folder Added To + description: Select the folder where the application was added + options: + - ag-backup + - ag-main + - AI + - arm + - arrs + - authentik + - cf + - downloaders + - jellyfin + - kasm + - netboot + - nexus + - pages + - portainer + - twingate + - whisper + - New Folder + + - type: input + id: new-folder-name + attributes: + label: New Folder Name + description: If you created a new folder, provide the name of the new folder + placeholder: Name of the new folder + validations: + required: false + + - type: markdown + attributes: + value: | + ## Steps to Add + + - type: checkboxes + id: steps-to-add + attributes: + label: Steps to Add + description: Please check off each step as it is completed + options: + - label: Add Configuration Files + description: Create and add configuration files for the new application + - label: Update Wiki + description: Create or update the Wiki page for the new application and update any relevant architecture diagrams or flowcharts + - label: Update README(s) + description: Add the new application to the main table and any other relevant sections + - label: Add to CD Platform Logic + description: Add necessary logic to the CD platform for the new application + - label: Testing and Validation + description: Ensure the application is tested and validated in the environment + + - type: markdown + attributes: + value: | + ## Commit IDs for Completed Steps + + - type: textarea + id: commit-ids + attributes: + label: Commit IDs + description: Enter the commit IDs for the completed steps above + placeholder: Enter commit IDs separated by commas diff --git a/.github/ISSUE_TEMPLATE/deletion.yml b/.github/ISSUE_TEMPLATE/deletion.yml new file mode 100644 index 00000000..e2d68329 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/deletion.yml @@ -0,0 +1,92 @@ +name: 'Delete Application' +description: 'Track the process of deleting an application' +title: 'Delete Application: [Application Name]' +labels: + - deletion +assignees: '' + +body: + - type: markdown + attributes: + value: | + ## Application Details + + - type: input + id: application-name + attributes: + label: Application Name + description: Name of the application to be deleted + placeholder: Name of the application + + - type: checkboxes + id: reason-for-deletion + attributes: + label: Reason for Deletion + description: Please select one or more reasons for the deletion + options: + - label: No longer needed + - label: Replaced by another application + description: Provide the name of the new application, if applicable + - label: Maintenance overhead + - label: Security vulnerabilities + - label: Performance issues + - label: Compatibility issues + - label: Licensing issues + - label: Other (please specify) + description: Provide additional details + + - type: checkboxes + id: impacted-folders + attributes: + label: Impacted Folders + description: Select the folders that are impacted by the deletion + options: + - label: ag-backup + - label: ag-main + - label: AI + - label: arm + - label: arrs + - label: authentik + - label: cf + - label: downloaders + - label: jellyfin + - label: kasm + - label: netboot + - label: nexus + - label: pages + - label: portainer + - label: twingate + - label: whisper + + - type: markdown + attributes: + value: | + ## Steps to Delete + + - type: checkboxes + id: steps-to-delete + attributes: + label: Steps to Delete + description: Please check off each step as it is completed + options: + - label: Remove Configuration Files + description: Locate and remove all configuration files related to the application + - label: Update Wiki + description: Add Archived tag to Wiki page and update any architecture diagrams or flowcharts + - label: Update README(s) + description: Remove app from main table + - label: Remove From CD Platform Logic + description: Remove unneeded if statement from CD platform + - label: Deletion from host + description: Ensure that the application and all related files have been successfully removed + - label: Close Related Issues + description: Close any open issues or tasks related to the application + - label: If you are deleting the entire folder check this box + description: Deleting entire folder + + - type: textarea + id: additional-notes + attributes: + label: Additional Notes + description: Add any additional comments or details here + placeholder: Comments diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 00000000..aa185d25 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,50 @@ +name: 'Feature Request' +description: 'Suggest a new feature for the project' +title: 'Feature Request: [Summary]' +labels: + - enhancement +assignees: '' + +body: + - type: markdown + attributes: + value: | + ## Feature Request + + **Please fill out this template with the requested information.** + + - type: input + id: summary + attributes: + label: Summary + description: A concise description of the feature you'd like to see added. + placeholder: Brief summary of the feature request + + - type: textarea + id: motivation + attributes: + label: Motivation + description: Explain why this feature would be beneficial to the project. What problem does it solve or what value does it bring? + placeholder: Describe the motivation behind the feature request + + - type: textarea + id: detailed-description + attributes: + label: Detailed Description + description: | + Provide a detailed explanation of the proposed feature. Include: + - How would this feature be used? + - What are the expected benefits of this feature? + - Are there any potential drawbacks or limitations to consider? + placeholder: Provide a detailed description of the feature + + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: | + Include any relevant information such as: + - Links to external resources (e.g., documentation, articles) + - Screenshots or mockups to illustrate the feature + - Use cases and examples of how the feature would be used + placeholder: Add any other context or screenshots about the feature request here diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 00000000..a19104d6 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "dependencyDashboardTitle": ":robot: Renovate Dashboard" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index a9e8a0c5..98806c6b 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,9 @@ override.tf.json .terraformrc terraform.rc +## Docker +.env + +## Kubernetes +/kubernetes/cluster/apps/staging + diff --git a/ansible/playbooks/apt.yml b/ansible/playbooks/apt.yml new file mode 100644 index 00000000..05311be5 --- /dev/null +++ b/ansible/playbooks/apt.yml @@ -0,0 +1,7 @@ +- hosts: "*" + become: yes + tasks: + - name: apt + apt: + update_cache: yes + upgrade: 'yes' \ No newline at end of file diff --git a/ansible/playbooks/deploy.yml b/ansible/playbooks/deploy.yml new file mode 100644 index 00000000..d9282aba --- /dev/null +++ b/ansible/playbooks/deploy.yml @@ -0,0 +1,33 @@ +--- +- name: Deploy application + hosts: "{{ target_host }}" + vars: + repo_path: "/home/{{ ansible_user }}/Auto-Homelab/{{ folder }}" + tasks: + - name: Ensure the repository is up-to-date + shell: git pull + args: + chdir: "{{ repo_path }}" + register: git_pull_output + + - name: Display git pull output + debug: + var: git_pull_output.stdout_lines + + - name: Restart services + command: docker compose up -d + args: + chdir: "{{ repo_path }}" + register: docker_compose_output + + - name: Display docker output + debug: + var: docker_compose_output.stdout_lines + + - name: Run Docker Command + command: docker ps + register: docker_output + + - name: Display Docker Output + debug: + var: docker_output.stdout_lines diff --git a/ansible/playbooks/git-pull-reset.yml b/ansible/playbooks/git-pull-reset.yml new file mode 100644 index 00000000..5f6257fc --- /dev/null +++ b/ansible/playbooks/git-pull-reset.yml @@ -0,0 +1,24 @@ +--- +- name: Reset and Pull Git Repository + hosts: all + tasks: + - name: Change to Auto-Homelab directory + shell: cd ~/Auto-Homelab + args: + chdir: "/home/{{ ansible_user }}" + environment: + HOME: "/home/{{ ansible_user }}" + + - name: Git Pull + shell: git pull + args: + chdir: "/home/{{ ansible_user }}/Auto-Homelab" + environment: + HOME: "/home/{{ ansible_user }}" + + - name: Git Reset + shell: git reset --hard origin/main + args: + chdir: "/home/{{ ansible_user }}/Auto-Homelab" + environment: + HOME: "/home/{{ ansible_user }}" \ No newline at end of file diff --git a/ansible/playbooks/qemu-guest-agent.yml b/ansible/playbooks/qemu-guest-agent.yml new file mode 100644 index 00000000..75e2cf46 --- /dev/null +++ b/ansible/playbooks/qemu-guest-agent.yml @@ -0,0 +1,15 @@ +- name: Install and start qemu-guest-agent + hosts: "*" + tasks: + - name: Install qemu-guest-agent + apt: + name: qemu-guest-agent + state: present + update_cache: true + become: true + + - name: Start qemu-guest-agent service + systemd: + name: qemu-guest-agent + state: started + become: true diff --git a/ansible/playbooks/timezone.yml b/ansible/playbooks/timezone.yml new file mode 100644 index 00000000..567dd670 --- /dev/null +++ b/ansible/playbooks/timezone.yml @@ -0,0 +1,16 @@ +- name: Set timezone and configure timesyncd + hosts: "*" + become: yes + tasks: + - name: set timezone + shell: timedatectl set-timezone America/New_York + + - name: Make sure timesyncd is stopped + systemd: + name: systemd-timesyncd.service + state: stopped + + - name: Make sure timesyncd is started + systemd: + name: systemd-timesyncd.service + state: started \ No newline at end of file diff --git a/docker/AI/README.md b/docker/AI/README.md new file mode 100644 index 00000000..2c40330b --- /dev/null +++ b/docker/AI/README.md @@ -0,0 +1,11 @@ +## VM +Self hosted on Proxmox Node 2. Has GPU passthrough +## Specs +- 6 core host +- 32GB RAM +- 256GB Storage +- Nvidia GTX 1660 6GB (Needs Upgrade) +## OS +[](https://releases.ubuntu.com/jammy/) +### Hypervisor +[](https://www.proxmox.com) \ No newline at end of file diff --git a/docker/AI/docker-compose.yml b/docker/AI/docker-compose.yml new file mode 100644 index 00000000..cc0f3408 --- /dev/null +++ b/docker/AI/docker-compose.yml @@ -0,0 +1,45 @@ +version: "3.8" + +services: + ollama: + image: docker.mafyuh.xyz/ollama/ollama:0.1.45 + container_name: ollama + restart: unless-stopped + volumes: + - ollama:/root/.ollama + ports: + - "11434:11434" + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + + open-webui: + image: ghcr.io/open-webui/open-webui:0.3.5 + container_name: open-webui + restart: unless-stopped + ports: + - 3000:8080 + volumes: + - open-webui:/app/backend/data + extra_hosts: + - host.docker.internal:host-gateway + + mindsdb: + image: docker.mafyuh.xyz/mindsdb/mindsdb:v24.6.3.1 + container_name: mindsdb + ports: + - 47334:47334 + - 47335:47335 + volumes: + - /home/mafyuh/mindsdb:/root/mindsdb + restart: unless-stopped + +volumes: + ollama: + external: true + open-webui: + external: true diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..4a6f8295 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,312 @@ +[](https://git.mafyuh.dev/mafyuh/Auto-Homelab/actions) +[](https://git.mafyuh.dev/mafyuh/Auto-Homelab/actions) +[](https://git.mafyuh.dev/renovatebot/renovate/actions) +[](https://git.mafyuh.dev/mafyuh/Auto-Homelab/pulls) + +<div align="center"> + +# Auto-Homelab + +Homelab docker-compose environment defined in code. Using Forgejo Actions and Renovate bot for CI, AWX Tower and Forgejo Actions for CD. This is how I keep my Homelab UTD. + +</div> +<p align="center"> + <a href="https://git.mafyuh.dev/mafyuh/Auto-Homelab/wiki">Wiki</a> | + <a href="https://loganmarchione.com/2022/10/how-to-run-renovate-on-a-self-hosted-gitea-and-drone-instance/">How to Setup</a> | + <a href="https://mafyuh.com">Blog</a> | + <a href="https://www.youtube.com/watch?v=5CkCr9U_Q1Y">Inspiration</a> | + <a href="https://git.mafyuh.dev/mafyuh/IaC-Homelab">Infrastructure</a> +</p> + +<div align="center"> + +| Hypervisor | OS | Tools | VPS (arm) | Firewall | +|---|---|---|---|---| +| [](https://www.proxmox.com) | [](https://releases.ubuntu.com/jammy/) [](https://releases.ubuntu.com/noble/) | [](https://forgejo.org/) [](https://www.docker.com/) | [](https://www.oracle.com/cloud/) | [](https://www.pfsense.org/) | + +</div> + +<div align="center"> + +## Apps in Repo: +<table> + <tr> + <th>Logo</th> + <th>Name</th> + <th>Description</th> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/adguardhome.svg"></td> + <td><a href="https://adguard.com/en/adguard-home/overview.html">AdGuard Home</a></td> + <td>Network Wide DNS adblock as well as my DNS server (2/2)</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/adguardhomesync-icon.png"></td> + <td><a href="https://docs.linuxserver.io/images/docker-adguardhome-sync/">AdGuard Home Sync</a></td> + <td>Syncs my instances of Adguard</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/authentik.svg"></td> + <td><a href="https://goauthentik.io/">authentik</a></td> + <td>Open Source Identity Provider </td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/bazarr.svg"></td> + <td><a href="https://www.bazarr.media/">Bazarr</a></td> + <td>Downloads subtitles for Radarr/Sonarr</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/cloudflare.svg"></td> + <td><a href="https://www.cloudflare.com/products/tunnel/">Cloudflare Tunnels</a></td> + <td>How I expose some of these services</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Codeberg_logo.svg/1200px-Codeberg_logo.svg.png"></td> + <td><a href="https://codeberg.org/Codeberg/pages-server">Codeberg Pages</a></td> + <td>Github Pages for Gitea installs. hosts https://mafyuh.co</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/kiranshila/Doplarr/main/logos/logo.svg"></td> + <td><a href="https://github.com/kiranshila/Doplarr">Doplarr</a></td> + <td>Allows my users to request content through Discord if they choose</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/FlareSolverr/FlareSolverr/master/resources/flaresolverr_logo.svg"></td> + <td><a href="https://github.com/FlareSolverr/FlareSolverr">FlareSolverr</a></td> + <td>Proxy server to bypass Cloudflare and DDoS-GUARD protection</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/forgejo.svg"></td> + <td><a href="https://forgejo.org/">Forgejo</a></td> + <td>This site</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/forgejo.svg"></td> + <td><a href="https://code.forgejo.org/forgejo/runner">Forgejo Runner</a></td> + <td>Runs CI/CD tasks Yamllint and Renovatebot and CD through AWX</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/gotify.svg"></td> + <td><a href="https://gotify.net/">Gotfiy</a></td> + <td>Self hosted notification service</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/homarr.svg"></td> + <td><a href="https://homarr.dev/docs/getting-started/installation/">Homarr</a></td> + <td>Homelab dashboard that integrates with the arr's so I see data in 1 place</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/jellyfin.svg"></td> + <td><a href="https://github.com/jellyfin/jellyfin">Jellyfin</a></td> + <td>Open Source Streaming Service for home media like Plex</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/jellyseerr.svg"></td> + <td><a href="https://github.com/Fallenbagel/jellyseerr">Jellyseerr</a></td> + <td>Request platform for my Jellyfin user's to request content</a></td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/docker.svg"></td> + <td><a href="https://github.com/hrfee/jfa-go">jfa-go</a></td> + <td>Used for some PPV/Live TV automations to create users for certain periods of time</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/kasm.svg"></td> + <td><a href="https://docs.linuxserver.io/images/docker-kasm/">Kasm</a></td> + <td>Docker container streaming platform for browser-based access to desktops, applications, and web services</a></td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/lidarr.svg"></td> + <td><a href="https://wiki.servarr.com/en/lidarr">Lidarr</a></td> + <td>Music Collection Manager</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/LinkStackOrg/branding/main/logo/svg/logo_animated.svg"></td> + <td><a href="https://github.com/LinkStackOrg/linkstack-docker">LinkStack</a></td> + <td>Creating a static links page for my Jellyfin users</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,w_60,h_60/https://dashboard.snapcraft.io/site_media/appmedia/2020/03/makemkv.png"></td> + <td><a href="https://github.com/jlesage/docker-makemkv">MakeMKV</a></td> + <td>Used to rip Bluray's with my LG BU40N drive </td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://avatars.githubusercontent.com/u/31035808?s=200&v=4"></td> + <td><a href="https://docs.mindsdb.com/what-is-mindsdb">mindsdb</a></td> + <td>Connects Ollama models to 100+ different databases, easy to use.</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/nbxyz-logo.svg"></td> + <td><a href="https://netboot.xyz/">Netboot.xyz</a></td> + <td>Network boot instead of using my ventoy USB</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/nginxproxymanager.svg"></td> + <td><a href="https://nginxproxymanager.com/">Nginx Proxy Manager</a></td> + <td>Reverse Proxy used for its simplicity (1/3)</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/n8n.svg"></td> + <td><a href="https://n8n.io">n8n</a></td> + <td>Self hosted automation platform, Zapier alternative, switched from ActivePieces</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://ollama.com/public/ollama.png"></td> + <td><a href="https://ollama.com/">Ollama</a></td> + <td>Easiest way to run LLM's on your own hardware</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://github.com/open-webui/open-webui/blob/main/static/favicon.png?raw=true"></td> + <td><a href="https://github.com/open-webui/open-webui">open-webui</a></td> + <td>Creates a ChatGPT like web interface for talking to Ollama models</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/portainer.svg"></td> + <td><a href="https://github.com/portainer/portainer">Portainer</a></td> + <td>Web-based management for learning Kubernetes, I learned Docker this way and will Kub as well</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/prowlarr.svg"></td> + <td><a href="https://prowlarr.com/">Prowlarr</a></td> + <td>Searches indexers for Radarr/Sonarr</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/qbittorrent.svg"></td> + <td><a href="https://github.com/binhex/arch-qbittorrentvpn">qBittorrent VPN</a></td> + <td>Modified qBittorrent with VPN killswitch enabled</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/radarr.svg"></td> + <td><a href="https://radarr.video/">Radarr</a></td> + <td>Movie Collection Manager</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/sabnzbd.svg"></td> + <td><a href="https://sabnzbd.org/">Sabnzbd</a></td> + <td>Usenet downloader to download content</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/sonarr.svg"></td> + <td><a href="https://wiki.servarr.com/sonarr">Sonarr</a></td> + <td>Radarr, but for TV Shows</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://www.gravatar.com/avatar/614e0f6491dbb293e540190b02b3024e?s=120&r=g&d=404"></td> + <td><a href="https://hub.docker.com/r/sonatype/nexus3/">Sonatype Nexus</a></td> + <td>Self-hosted Docker registry to help lower Docker pulls</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/syncthing.svg"></td> + <td><a href="https://syncthing.net/">Syncthing</a></td> + <td>How I backup all config files, following 3-2-1 backup procedure</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://play-lh.googleusercontent.com/GBhNhKgjfy6i6Ucc0hyB-79WmcV7LvKSfGSy8iStFdZSaLioKQp5rPWjqsh2YFRRZsE1"></td> + <td><a href="https://twingate.com">Twingate Connectors</a></td> + <td>Main VPN between homelab and cloud VPS's</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/uptimekuma.svg"></td> + <td><a href="https://github.com/louislam/uptime-kuma">Uptime Kuma</a></td> + <td>Self hosted service uptime tracker</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/openai-black.svg"></td> + <td><a href="https://github.com/ahmetoner/whisper-asr-webservice">Whisper</a></td> + <td>AI Model that I use to generate subtitles for Bazarr when they can't be found</td> + </tr> +</table> + +</div> + +<div align="center"> + +## Apps not yet in repo: +<table> + <tr> + <th>Logo</th> + <th>Name</th> + <th>Description</th> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/ansible-black.svg"></td> + <td><a href="https://github.com/ansible/awx">AWX (Ansible Tower)</a></td> + <td>Used to easily run Ansible playbooks on all my VM's, and now CD for this repo, installed on K3s</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/grafana.svg"></td> + <td><a href="https://hub.docker.com/r/grafana/grafana-oss">Grafana</a></td> + <td>Monitoring for various services</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/wordpress.svg"></td> + <td><a href="https://wordpress.org/">Wordpress</a></td> + <td>WooCommerce store setup for JF PPV access</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://upload.wikimedia.org/wikipedia/commons/3/31/Apache_Guacamole_logo.png"></td> + <td><a href="https://guacamole.apache.org/">Guacamole</a></td> + <td>Remote access in browser via SSH, RDP, VNC, etc</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/homeassistant.svg"></td> + <td><a href="https://www.home-assistant.io/">Home Assistant</a></td> + <td>Slowly migrating over to Home Assistant from Google Home</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/plausible.svg"></td> + <td><a href="https://plausible.io/">Plausible</a></td> + <td>Analytics tracker for certain websites (Blog)</td> + </tr> + <tr> + <td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/wazuh.svg"></td> + <td><a href="https://wazuh.com/">wazuh</a></td> + <td>Security platform monitoring everything with agents installed on all VM's</td> + </tr> +</table> + +</div> + +<div align="center"> + +## Full Workflow Chart + +</div> + +```mermaid +graph TD + A1((Renovate Bot Scans for Updates)) --> A2{Updates Found?} + A2 -- Yes --> B[Make PR] + A2 -- No --> C(End) + + B --> D{PR Merged?} + D -- No --> E(End) + + subgraph Handle Merged PR + D -- Yes --> F[Extract Host] + F --> G[SSH to Host Machine] + G --> H[Git Pull & Docker Compose Up] + H --> I(End) + end + + subgraph Notification on PR Creation + B --> P[Notify via Gotify] + end + + subgraph Release Notes Handling + Q((PR Webhook Received)) --> R{PR Open?} + R -- No --> S(End) + R -- Yes --> T[Hit GitHub API for Release Notes] + T --> U[Extract PR Number from webhook] + U --> W[API Call to Foregjo to leave Release Notes] + W --> S + end + + P --> Q + + +``` + +## To-Do + +[View Project Board](https://git.mafyuh.dev/mafyuh/Auto-Homelab/projects/1) \ No newline at end of file diff --git a/docker/ag-backup/docker-compose.yml b/docker/ag-backup/docker-compose.yml new file mode 100644 index 00000000..f01af6ad --- /dev/null +++ b/docker/ag-backup/docker-compose.yml @@ -0,0 +1,22 @@ +--- +services: + adguardhome: + image: docker.mafyuh.xyz/adguard/adguardhome:v0.107.51 + container_name: adguardhome + restart: unless-stopped + volumes: + - /home/mafyuh/adguard/work:/opt/adguardhome/work + - /home/mafyuh/adguard/conf:/opt/adguardhome/conf + ports: + - 53:53/tcp + - 53:53/udp + - 80:80/tcp + - 443:443/tcp + - 443:443/udp + - 3000:3000/tcp + - 853:853/tcp + - 784:784/udp + - 853:853/udp + - 8853:8853/udp + - 5443:5443/tcp + - 5443:5443/udp diff --git a/docker/ag-main/docker-compose.yml b/docker/ag-main/docker-compose.yml new file mode 100644 index 00000000..a1b3c2a8 --- /dev/null +++ b/docker/ag-main/docker-compose.yml @@ -0,0 +1,36 @@ +--- +services: + adguardhome: + image: docker.mafyuh.xyz/adguard/adguardhome:v0.107.51 + container_name: adguardhome + restart: unless-stopped + volumes: + - /home/mafyuh/adguard/work:/opt/adguardhome/work + - /home/mafyuh/adguard/conf:/opt/adguardhome/conf + ports: + - 53:53/tcp + - 53:53/udp + - 80:80/tcp + - 443:443/tcp + - 443:443/udp + - 3000:3000/tcp + - 853:853/tcp + - 784:784/udp + - 853:853/udp + - 8853:8853/udp + - 5443:5443/tcp + - 5443:5443/udp + + adguardhome-sync: + image: ghcr.io/linuxserver/adguardhome-sync@sha256:67962a0e15bf1a41e4bc0083d93d7e0268ad6431482c337ef49d5f2673c36c71 + container_name: adguardhome-sync + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + - CONFIGFILE=/config/adguardhome-sync.yaml + volumes: + - /home/mafyuh/adguard/sync:/config + ports: + - 8080:8080 + restart: unless-stopped diff --git a/docker/arm/README.md b/docker/arm/README.md new file mode 100644 index 00000000..4d5eafe4 --- /dev/null +++ b/docker/arm/README.md @@ -0,0 +1,15 @@ +## Cloud VM + +Part of Oracle's Always Free VM's I was able to grab with https://github.com/hitrov/oci-arm-host-capacity + +*Account is on PAYG but I don't have any monthly fees. Oracle likes to remove free tier accounts + +[](https://www.oracle.com/cloud/) + +## Specs +- 4 core ARM +- 24GB RAM +- Currently 150GB Storage (will expand) + +## OS +[](https://releases.ubuntu.com/jammy/) \ No newline at end of file diff --git a/docker/arm/docker-compose.yml b/docker/arm/docker-compose.yml new file mode 100644 index 00000000..2c96a42c --- /dev/null +++ b/docker/arm/docker-compose.yml @@ -0,0 +1,165 @@ +--- +services: + server: + image: codeberg.org/forgejo/forgejo:7.0.4 + container_name: forgejo + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__database__DB_TYPE=mysql + - GITEA__database__HOST=db:3306 + - GITEA__database__NAME=gitea + - GITEA__database__USER=gitea + - GITEA__database__PASSWD=$GITEA__database__PASSWD + restart: always + networks: + - gitea_main + volumes: + - /home/ubuntu/forgejo/data:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - "3002:3000" + - "23:22" + depends_on: + - db + + db: + image: mysql:8 + restart: always + environment: + - MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD + - MYSQL_USER=gitea + - MYSQL_PASSWORD=$MYSQL_PASSWORD + - MYSQL_DATABASE=gitea + networks: + - gitea_main + volumes: + - /home/ubuntu/forgejo/mysql:/var/lib/mysql + + gotify: + image: docker.mafyuh.xyz/gotify/server-arm7:2.4.0 + container_name: gotify + ports: + - 9008:80 + volumes: + - /docker/appdata/gotify:/app/data + restart: unless-stopped + environment: + - TZ=America/New_York + - GOTIFY_DEFAULTUSER_NAME=$GOTIFY_DEFAULTUSER_NAME + - GOTIFY_DEFAULTUSER_PASS=$GOTIFY_DEFAULTUSER_PASS + networks: + - gitea_main + + nginx-proxy-manager: + image: docker.mafyuh.xyz/jc21/nginx-proxy-manager:2.11.2 + container_name: nginx-proxy-manager + ports: + - 80:80 + - 81:81 + - 443:443 + volumes: + - /docker/appdata/nginx/data:/data + - /docker/appdata/nginx/letsencrypt:/etc/letsencrypt + restart: unless-stopped + networks: + - gitea_main + + uptime-kuma: + image: docker.mafyuh.xyz/louislam/uptime-kuma:1.23.13 + container_name: uptime-kuma + ports: + - 3001:3001 + volumes: + - /docker/appdata/kuma:/app/data + restart: unless-stopped + networks: + - gitea_main + + jellyseerr: + image: docker.mafyuh.xyz/fallenbagel/jellyseerr:1.9.2 + container_name: jellyseerr + ports: + - 5055:5055 + volumes: + - /docker/appdata/jellyseerr:/app/config + environment: + - TZ=America/New_York + - LOG_LEVEL=debug + restart: unless-stopped + networks: + - gitea_main + + linkstack: + image: docker.mafyuh.xyz/linkstackorg/linkstack@sha256:ad2ec7ffa69f4b04367313d1b95566bb00955b9670eb5467fd4fab39dd1f53c1 + container_name: linkstack + ports: + - 8005:80 + - 8006:443 + volumes: + - linkstack:/htdocs + environment: + - HTTP_SERVER_NAME=$HTTP_SERVER_NAME + - HTTPS_SERVER_NAME=$HTTP_SERVER_NAME + - SERVER_ADMIN=$SERVER_ADMIN + restart: unless-stopped + networks: + - gitea_main + n8n: + image: ghcr.io/n8n-io/n8n:1.47.0 + container_name: n8n + ports: + - 5678:5678 + volumes: + - n8n_data:/home/node/.n8n + environment: + - GENERIC_TIMEZONE=America/New_York + - TZ=America/New_York + - WEBHOOK_URL=$WEBHOOK_URL + restart: unless-stopped + networks: + - gitea_main + + vaultwarden: + image: docker.mafyuh.xyz/vaultwarden/server:1.30.5 + container_name: vaultwarden + ports: + - 8989:80 + volumes: + - /home/ubuntu/vw-data/:/data + environment: + - DOMAIN=$VWDOMAIN + - SIGNUPS_ALLOWED=false + restart: unless-stopped + networks: + gitea_main: + ipv4_address: 172.25.0.25 + + syncthing: + image: ghcr.io/linuxserver/syncthing@sha256:6e70dd0cc0ddb038a8f58cf0945d6659b13c984f11d708407469bf16d520574c + container_name: syncthing + hostname: ARM #optional + environment: + - PUID=0 + - PGID=0 + - TZ=Etc/UTC + volumes: + - /home/ubuntu/syncthing/config:/config + - /docker/appdata/:/docker/appdata/ + - /home/ubuntu/:/home/ubuntu/ + ports: + - 8384:8384 + - 22000:22000/tcp + - 22000:22000/udp + - 21027:21027/udp + restart: unless-stopped + + +networks: + gitea_main: + external: true + +volumes: + linkstack: + n8n_data: diff --git a/docker/arrs/README.md b/docker/arrs/README.md new file mode 100644 index 00000000..3e110767 --- /dev/null +++ b/docker/arrs/README.md @@ -0,0 +1,10 @@ +## VM +Self hosted on Proxmox Node 1. Full *arr suite +## Specs +- 4 core host +- 6GB RAM +- 128GB Storage +## OS +[](https://releases.ubuntu.com/jammy/) +### Hypervisor +[](https://www.proxmox.com) \ No newline at end of file diff --git a/docker/arrs/docker-compose.yml b/docker/arrs/docker-compose.yml new file mode 100644 index 00000000..f0e296cd --- /dev/null +++ b/docker/arrs/docker-compose.yml @@ -0,0 +1,162 @@ +--- +services: + bazarr: + image: ghcr.io/linuxserver/bazarr@sha256:6fb83511c0dca70a400fde79cb45ed59c4f66ea30dcba8c6f9274f01d77e5aef + container_name: bazarr + ports: + - "6767:6767" + volumes: + - /etc/localtime:/etc/localtime:ro + - /docker/appdata/bazarr:/config + - /data/media:/data/media + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + + lidarr: + image: ghcr.io/linuxserver/lidarr@sha256:a7d0282dcdbf5b11306cc4054c11b42252106b5e8494375231322822d31ac9f6 + container_name: lidarr + ports: + - "8686:8686" + volumes: + - /etc/localtime:/etc/localtime:ro + - /docker/appdata/lidarr:/config + - /data:/data + - /docker/appdata/lidarr-extended:/custom-services.d + - /docker/appdata/lidarr-extended1:/custom-cont-init.d + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + + prowlarr: + image: ghcr.io/linuxserver/prowlarr@sha256:237e9a72c11c5350bf22e355759436ecd4fd660e820d5b556d9a9e436f25f6b9 + container_name: prowlarr + ports: + - "9696:9696" + volumes: + - /docker/appdata/prowlarr:/config + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + + radarr: + image: ghcr.io/linuxserver/radarr@sha256:40f10a3d826f6c231d338738c3c86bf0d23a9546f20f8b1b504c6c579b79992c + container_name: radarr + ports: + - "7878:7878" + volumes: + - /etc/localtime:/etc/localtime:ro + - /docker/appdata/radarr:/config + - /data:/data + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + + sonarr: + image: ghcr.io/linuxserver/sonarr@sha256:275467ba17d990bbc6301dec3cc76b042969836749de39067818759d0f3b407f + container_name: sonarr + ports: + - "8989:8989" + volumes: + - /etc/localtime:/etc/localtime:ro + - /docker/appdata/sonarr:/config + - /data:/data + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + + homarr: + container_name: homarr + image: ghcr.io/ajnart/homarr:0.15.3 + restart: unless-stopped + volumes: + - /docker/appdata/homarr/configs:/app/data/configs + - /docker/appdata/homarr/icons:/app/public/icons + - /docker/appdata/homarr/data:/data + ports: + - '7575:7575' + environment: + - AUTH_PROVIDER=oidc + - AUTH_OIDC_URI=${AUTH_OIDC_URI} + - AUTH_OIDC_CLIENT_SECRET=${AUTH_OIDC_CLIENT_SECRET} + - AUTH_OIDC_CLIENT_ID=${AUTH_OIDC_CLIENT_ID} + - AUTH_OIDC_CLIENT_NAME=authentik + - BASE_URL=${BASE_URL} + - NEXTAUTH_URL=${NEXTAUTH_URL} + - AUTH_OIDC_ADMIN_GROUP=${AUTH_OIDC_ADMIN_GROUP} + + doplarr: + image: ghcr.io/linuxserver/doplarr@sha256:20981fa1a4087d5369b9eaf756ab179352e05fe914b88c36f468ee3cd9a1ce98 + container_name: doplarr + environment: + - PUID=1000 + - PGID=1000 + - TZ=${TZ} + - DISCORD__TOKEN=${DISCORD__TOKEN} + - RADARR__API=${RADARR__API} + - RADARR__URL=${RADARR__URL} + - SONARR__API=${SONARR__API} + - SONARR__URL=${SONARR__URL} + - DISCORD__MAX_RESULTS=${DISCORD__MAX_RESULTS} + - DISCORD__REQUESTED_MSG_STYLE=${DISCORD__REQUESTED_MSG_STYLE} + - SONARR__QUALITY_PROFILE=${SONARR__QUALITY_PROFILE} + - RADARR__QUALITY_PROFILE=${RADARR__QUALITY_PROFILE} + - SONARR__ROOTFOLDER=${SONARR__ROOTFOLDER} + - RADARR__ROOTFOLDER=${RADARR__ROOTFOLDER} + - PARTIAL_SEASONS=${PARTIAL_SEASONS} + - LOG_LEVEL=${LOG_LEVEL} + - JAVA_OPTS=${JAVA_OPTS} + volumes: + - /docker/appdata/doplarr/config:/config + restart: unless-stopped + + jfa-go: + image: docker.mafyuh.xyz/hrfee/jfa-go + container_name: jfa-go + ports: + - 8056:8056 + volumes: + - /docker/appdata/jfa-go/config:/data + - /etc/localtime:/etc/localtime:ro + + cadvisor: + volumes: + - /:/rootfs:ro + - /var/run:/var/run:ro + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + - /dev/disk/:/dev/disk:ro + ports: + - 9999:8080 + container_name: cadvisor + privileged: true + devices: + - /dev/kmsg + image: gcr.io/cadvisor/cadvisor:v0.49.1 + + syncthing: + image: ghcr.io/linuxserver/syncthing@sha256:6e70dd0cc0ddb038a8f58cf0945d6659b13c984f11d708407469bf16d520574c + container_name: syncthing + hostname: ARRS + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /docker/appdata/syncthing/config:/config + - /docker/appdata/:/docker/appdata/ + ports: + - 8384:8384 + - 22000:22000/tcp + - 22000:22000/udp + - 21027:21027/udp + restart: unless-stopped + +networks: + default: + name: arrs_default diff --git a/docker/authentik/docker-compose.yml b/docker/authentik/docker-compose.yml new file mode 100644 index 00000000..45590e20 --- /dev/null +++ b/docker/authentik/docker-compose.yml @@ -0,0 +1,96 @@ +--- +version: "3.4" + +services: + postgresql: + image: docker.io/library/postgres:12-alpine + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 5s + volumes: + - database:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: ${PG_PASS:?database password required} + POSTGRES_USER: ${PG_USER:-authentik} + POSTGRES_DB: ${PG_DB:-authentik} + env_file: + - .env + redis: + image: docker.io/library/redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 3s + volumes: + - redis:/data + server: + image: ghcr.io/goauthentik/server@sha256:a2e592a08eb3c9e3435aa4e6585d60cc1eb54850da9d1498d56a131bbfbe03ff + restart: unless-stopped + command: server + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + volumes: + - /home/mafyuh/media:/media + - /home/mafyuh/custom-templates:/templates + env_file: + - .env + ports: + - "${COMPOSE_PORT_HTTP:-9000}:9000" + - "${COMPOSE_PORT_HTTPS:-9443}:9443" + depends_on: + - postgresql + - redis + worker: + image: ghcr.io/goauthentik/server@sha256:a2e592a08eb3c9e3435aa4e6585d60cc1eb54850da9d1498d56a131bbfbe03ff + restart: unless-stopped + command: worker + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + # `user: root` and the docker socket volume are optional. + # See more for the docker socket integration here: + # https://goauthentik.io/docs/outposts/integrations/docker + # Removing `user: root` also prevents the worker from fixing the permissions + # on the mounted folders, so when removing this make sure the folders have the correct UID/GID + # (1000:1000 by default) + user: root + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /home/mafyuh/media:/media + - /home/mafyuh/certs:/certs + - /home/mafyuh/custom-templates:/templates + env_file: + - .env + depends_on: + - postgresql + - redis + authentik_ldap: + image: ghcr.io/goauthentik/ldap@sha256:7f317da9b736dec3e53b71b7face1787d4f15aee00e80d003e5ff3b2d49ee382 + ports: + - 389:3389 + - 636:6636 + environment: + AUTHENTIK_HOST: ${AUTH_HOST} + AUTHENTIK_INSECURE: "true" + AUTHENTIK_TOKEN: ${AUTH_TOKEN} + +volumes: + database: + driver: local + redis: + driver: local diff --git a/docker/cf/.env.example b/docker/cf/.env.example new file mode 100644 index 00000000..411ecce1 --- /dev/null +++ b/docker/cf/.env.example @@ -0,0 +1 @@ +CF_TOKEN=your-cf-tunnel-token diff --git a/docker/cf/docker-compose.yml b/docker/cf/docker-compose.yml new file mode 100644 index 00000000..6a7db96e --- /dev/null +++ b/docker/cf/docker-compose.yml @@ -0,0 +1,6 @@ +--- +services: + cf-tunnel: + restart: unless-stopped + image: docker.mafyuh.xyz/cloudflare/cloudflared@sha256:f6e9fff347602b8e70f1765127abc96f3b8d1af4cc46185913a043edab75ae5b + command: tunnel --no-autoupdate run --token $CF_TOKEN diff --git a/docker/downloaders/README.md b/docker/downloaders/README.md new file mode 100644 index 00000000..dd736b2b --- /dev/null +++ b/docker/downloaders/README.md @@ -0,0 +1,10 @@ +## VM +Self hosted on Proxmox Node 1. Downloads media as well as Flaresolverr. +## Specs +- 3 core host +- 8GB RAM +- 256GB Storage +## OS +[](https://releases.ubuntu.com/jammy/) +### Hypervisor +[](https://www.proxmox.com) \ No newline at end of file diff --git a/docker/downloaders/docker-compose.yml b/docker/downloaders/docker-compose.yml new file mode 100644 index 00000000..479bc9f4 --- /dev/null +++ b/docker/downloaders/docker-compose.yml @@ -0,0 +1,79 @@ +version: '3.9' +services: + sabnzbd: + image: ghcr.io/linuxserver/sabnzbd@sha256:4fb40ea724abc25cf9496cdbc8e528aa0882132737e49c5e712c264284fa7b94 + container_name: sabnzbd + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /etc/localtime:/etc/localtime:ro + - /docker/appdata/sabnzbd:/config + - /data/usenet:/data/usenet:rw + ports: + - 8080:8080 + restart: unless-stopped + + arch-qbittorrentvpn: + image: docker.mafyuh.xyz/binhex/arch-qbittorrentvpn:4.6.5-1-03 + container_name: qbittorrentvpn + volumes: + - '/docker/appdata/qbitty:/config' + - '/data/torrents/:/data/torrents' + - '/etc/localtime:/etc/localtime:ro' + ports: + - '49550:49550' + - '49551:8118' + environment: + - VPN_ENABLED=yes + - VPN_PROV=protonvpn + - VPN_CLIENT=wireguard + - VPN_USER=mafyuh+pmp + - VPN_PASS= + - STRICT_PORT_FORWARD=yes + - LAN_NETWORK=10.0.0.0/24,10.69.69.0/24 + - ENABLE_PRIVOXY=yes + - PUID=1000 + - PGID=1000 + - WEBUI_PORT=49550 + - UMASK=1000 + - DEBUG=false + cap_add: + - NET_ADMIN + sysctls: + - net.ipv4.conf.all.src_valid_mark=1 + privileged: true + network_mode: bridge + restart: unless-stopped + + flaresolverr: + image: ghcr.io/flaresolverr/flaresolverr:v3.3.20 + container_name: flaresolverr + ports: + - '8191:8191' + environment: + - LOG_LEVEL=info + restart: unless-stopped + + cadvisor: + volumes: + - /:/rootfs:ro + - /var/run:/var/run:ro + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + - /dev/disk/:/dev/disk:ro + ports: + - 9999:8080 + container_name: cadvisor + privileged: true + devices: + - /dev/kmsg + image: gcr.io/cadvisor/cadvisor:v0.49.1 + + node-exporter: + image: docker.mafyuh.xyz/prom/node-exporter:v1.8.1 + container_name: monitoring_node_exporter + restart: unless-stopped + ports: + - 9100:9100 diff --git a/docker/jellyfin/README.md b/docker/jellyfin/README.md new file mode 100644 index 00000000..905dd435 --- /dev/null +++ b/docker/jellyfin/README.md @@ -0,0 +1,12 @@ +# Homelab Physical Machine +Bought an old Dell Optiplex 3050 as it supports NVMe storage, DDR4 RAM, Disk reader slot which I exchanged for a LibreDrive compatible drive, and has an extra PCIe slot with just enough room for a low profile GPU. + +## Specs +- Intel i5-6500 (4 core) +- 16GB DDR4 RAM +- Intel Arc A310 GPU (transcoding) +- 500GB NVMe SSD +- LG BU40N UHD Bluray drive + +## OS +[](https://releases.ubuntu.com/jammy/) \ No newline at end of file diff --git a/docker/jellyfin/docker-compose.yml b/docker/jellyfin/docker-compose.yml new file mode 100644 index 00000000..7ece0659 --- /dev/null +++ b/docker/jellyfin/docker-compose.yml @@ -0,0 +1,53 @@ +--- +services: + jellyfin: + image: ghcr.io/linuxserver/jellyfin@sha256:a363aa018edee61bcee46be5f8dbd0db2a317b2bc0f95121a46e522d798c2a63 + container_name: jellyfin + devices: + - /dev/dri/renderD129:/dev/dri/renderD129 + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + - DOCKER_MODS=linuxserver/mods:jellyfin-opencl-intel + volumes: + - /home/mafyuh/jellyfin/config:/config + - /mnt/thePoolShare/Media:/Media + - /home/mafyuh/jellyfin/transcodes:/transcodes + - /home/mafyuh/jellyfin/cache:/nvmecache + - /home/mafyuh/jellyfin/metadata:/nvmemetadata + ports: + - 8096:8096 + restart: unless-stopped + + makemkv: + image: docker.mafyuh.xyz/jlesage/makemkv@sha256:7af8a5d70006cbf0fc5ea54971779bc8b35f976dd844db173f5bc28ae97876b7 + container_name: makemkv + ports: + - 5800:5800 + volumes: + - /docker/appdata/makemkv:/config:rw + - /home/mafyuh/makemkv/storage:/storage:rw + - /mnt/thePoolShare/Media/BR:/output:rw + devices: + - /dev/sr0:/dev/sr0 + privileged: true + + syncthing: + image: ghcr.io/linuxserver/syncthing@sha256:6e70dd0cc0ddb038a8f58cf0945d6659b13c984f11d708407469bf16d520574c + container_name: syncthing + hostname: JF + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + volumes: + - /docker/appdata/syncthing/config:/config + - /docker/appdata/:/docker/appdata/ + - /home/mafyuh/jellyfin/:/home/mafyuh/jellyfin/ + ports: + - 8384:8384 + - 22000:22000/tcp + - 22000:22000/udp + - 21027:21027/udp + restart: unless-stopped diff --git a/docker/kasm/docker-compose.yml b/docker/kasm/docker-compose.yml new file mode 100644 index 00000000..b68d04e0 --- /dev/null +++ b/docker/kasm/docker-compose.yml @@ -0,0 +1,14 @@ +--- +services: + kasm: + image: ghcr.io/linuxserver/kasm@sha256:95c8d5d0f588cb3982da344c34b6acbebb5f428176947a923e5cc0cec4710f4d + container_name: kasm + privileged: true + environment: + - KASM_PORT=443 + volumes: + - /docker/appdata/kasm:/opt + ports: + - 3000:3000 + - 443:443 + restart: unless-stopped diff --git a/docker/netboot/docker-compose.yml b/docker/netboot/docker-compose.yml new file mode 100644 index 00000000..814738f2 --- /dev/null +++ b/docker/netboot/docker-compose.yml @@ -0,0 +1,17 @@ +--- +services: + netbootxyz: + image: ghcr.io/linuxserver/netbootxyz@sha256:dce6b2c729611f1090f2e6479b764d98aef24cc340d018d923fa6678fcbf330e + container_name: netboot + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + volumes: + - /home/mafyuh/netboot/config:/config + - /home/mafyuh/netboot/assets:/assets + ports: + - 3000:3000 + - 69:69/udp + - 8080:80 + restart: unless-stopped diff --git a/docker/nexus/docker-compose.yml b/docker/nexus/docker-compose.yml new file mode 100644 index 00000000..a09a1857 --- /dev/null +++ b/docker/nexus/docker-compose.yml @@ -0,0 +1,11 @@ +--- +services: + nexus: + image: docker.mafyuh.xyz/sonatype/nexus3:3.69.0 + container_name: nexus + restart: unless-stopped + ports: + - 8081:8081 + - 8082:8082 + volumes: + - /docker/appdata/nexus:/nexus-data ## To get to work run: sudo chown -R 200 /docker/appdata/nexus/ | cat /docker/appdata/nexus/admin.password diff --git a/docker/pages/docker-compose.yml b/docker/pages/docker-compose.yml new file mode 100644 index 00000000..7e7aec45 --- /dev/null +++ b/docker/pages/docker-compose.yml @@ -0,0 +1,21 @@ +--- +services: + pages: + image: codeberg.org/codeberg/pages-server:v5.1 + container_name: codeberg-pages + environment: + - GITEA_ROOT=https://git.mafyuh.dev + - GITEA_API_TOKEN=$GITEA_API_TOKEN + - ACME_ACCEPT_TERMS=true + - CLOUDFLARE_EMAIL=$CLOUDFLARE_EMAIL + - CLOUDFLARE_API_KEY=$CLOUDFLARE_API_KEY + - DNS_PROVIDER=cloudflare + - PAGES_DOMAIN=mafyuh.co + - CF_ZONE_API_TOKEN=$CF_ZONE_API_TOKEN + - CF_DNS_API_TOKEN=$CF_DNS_API_TOKEN + - ENABLE_HTTP_SERVER=false + ports: + - "80:80" + - "443:443" + volumes: + - /home/ubuntu/pages/datanew:/data diff --git a/docker/portainer/docker-compose.yml b/docker/portainer/docker-compose.yml new file mode 100644 index 00000000..6730359d --- /dev/null +++ b/docker/portainer/docker-compose.yml @@ -0,0 +1,15 @@ +services: + portainer: + image: docker.mafyuh.xyz/portainer/portainer-ee@sha256:0aa305da72738d9f90a209bf74bdc74172004690fa298f52d5f92dd065f26aea + container_name: portainer + command: -H unix:///var/run/docker.sock + ports: + - "9000:9000" + - "9443:9443" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + - "portainer_data:/data" + restart: always + +volumes: + portainer_data: diff --git a/docker/scripts/CD.json b/docker/scripts/CD.json new file mode 100644 index 00000000..8eb5b3ca --- /dev/null +++ b/docker/scripts/CD.json @@ -0,0 +1,4167 @@ +{ + "name": "CD", + "nodes": [ + { + "parameters": {}, + "id": "6cbda730-ad3e-49db-80c9-5cbf85c0e592", + "name": "No Operation, do nothing", + "type": "n8n-nodes-base.noOp", + "typeVersion": 1, + "position": [ + 1620, + 720 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "5d9661eb-85ea-4610-bfd8-1718394a35ec", + "leftValue": "={{ $json.body.action }}", + "rightValue": "closed", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "d2a850ce-717a-4b17-8c85-898470d2aa13", + "leftValue": "={{ $json.body.pull_request.merged }}", + "rightValue": "true", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "id": "6f81fe9d-8ceb-4909-b421-89d15731b0f0", + "name": "If Closed and Merged", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 1420, + 560 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/arrs" + }, + "id": "81a09800-2772-433e-aba9-b3c9dce518ab", + "name": "Compose Up -D", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 1640, + 140 + ], + "credentials": { + "sshPrivateKey": { + "id": "KB4TkUdkNDzLMJNV", + "name": "SSH arrs" + } + } + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/arrs" + }, + "id": "03392858-0d1e-4332-a526-d867e0cce99d", + "name": "Git Pull", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 1640, + 260 + ], + "credentials": { + "sshPrivateKey": { + "id": "KB4TkUdkNDzLMJNV", + "name": "SSH arrs" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "dec76b91-b6b4-4d8a-aa3c-d58f31016959", + "name": "If Error", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 1640, + 20 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "c66e7c80-1f16-44ab-93b4-2b7a0a803b45", + "name": "Gotify", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 1500, + 20 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "radarr", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "955462d6-85e9-4d8a-aaba-2d1f9df2c49f", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "sonarr", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "81b525fb-e899-4dcd-a6e8-84fd551e25d9", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "bazarr", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "bd4b3a81-272b-4a00-bec3-c5743dd4e506", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "lidarr", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "58766270-ca7b-429a-8b60-948e86ff3893", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "prowlarr", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "7000e55b-ac34-48e7-9db3-1489c68421db", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "homarr", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "7fd9e014-419e-4321-8503-15a47b538d1d", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "doplarr", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "d3038c2d-434b-462d-a0ed-1353cd3ae6ac", + "name": "If arrs", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 1640, + 400 + ] + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "6e62d930-1d0d-458a-8510-eeaea685bb57", + "name": "Comment On PR", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 1640, + -220 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "f17109a0-12d0-48ea-b0ae-eb76b0599be2", + "name": "Set # 4 http to work", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 1640, + -100 + ] + }, + { + "parameters": { + "content": "## Arrs", + "height": 80, + "width": 150 + }, + "id": "6fd9d2d1-513f-4d5a-9e08-1b07b9450b59", + "name": "Sticky Note", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 1620, + -320 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "sabnzbd", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "955462d6-85e9-4d8a-aaba-2d1f9df2c49f", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "qbittorrent", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "81b525fb-e899-4dcd-a6e8-84fd551e25d9", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "flaresolverr", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "be0fdc53-53b4-4d77-aa6e-07e36d5bb639", + "name": "If downloader", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 1940, + 420 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/downloaders" + }, + "id": "a8359ad3-4022-47e8-aa90-609bcfe07b00", + "name": "Git Pull1", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 1940, + 280 + ], + "credentials": { + "sshPrivateKey": { + "id": "SRUszsFwsf6Dk557", + "name": "SSH Downloader" + } + } + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/downloaders" + }, + "id": "86bd6473-4f5e-4fa0-ba1f-f5614557a35c", + "name": "Compose Up -D1", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 1940, + 140 + ], + "credentials": { + "sshPrivateKey": { + "id": "SRUszsFwsf6Dk557", + "name": "SSH Downloader" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "452589e9-ed4b-4d72-9851-6a028b26f0ea", + "name": "If Error1", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 1940, + 0 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D1').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "7f40ebe6-f153-453c-af11-fc5d1bd42a5d", + "name": "Gotify1", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 1800, + 0 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull1').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D1').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "29006b09-fbfc-49a8-a5c7-9ee5a36017d1", + "name": "Comment On PR1", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 1940, + -240 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "5356745c-18f2-40e1-a018-8dc431cda037", + "name": "Set # 4 http to work1", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 1940, + -120 + ] + }, + { + "parameters": { + "content": "## Downloaders", + "height": 83.99999999999999, + "width": 194.8000000000004 + }, + "id": "a678b296-8312-420e-93c6-ea8352c219ea", + "name": "Sticky Note1", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 1880, + -340 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/AI" + }, + "id": "b5bf4395-6e15-4284-86a1-f83aa488dd4a", + "name": "Compose Up -D2", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 2320, + 140 + ], + "credentials": { + "sshPrivateKey": { + "id": "uAJ2jWJ5wxU4N0lt", + "name": "SSH AI" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "6d18f8fb-7cd1-4d82-a567-a57d59cdf309", + "name": "If Error2", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 2320, + 0 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D2').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "99b44c53-a858-4424-9a26-30b1a2dfbae8", + "name": "Gotify2", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 2180, + 0 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull3').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D2').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "1a1248a6-7e1c-43e3-ac02-5939ad4c1464", + "name": "Comment On PR2", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 2320, + -240 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "557d7119-1715-4aac-8065-4ed02d3d0715", + "name": "Set # 4 http to work2", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 2320, + -120 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "ollama", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "955462d6-85e9-4d8a-aaba-2d1f9df2c49f", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "open-webui", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "81b525fb-e899-4dcd-a6e8-84fd551e25d9", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "mindsdb", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "1fd20c7b-9be1-4138-8d15-24918f9851b4", + "name": "If AI", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 2320, + 420 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/AI" + }, + "id": "f32bc155-6cb5-4ef3-8a16-303ced51ee5c", + "name": "Git Pull3", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 2320, + 280 + ], + "credentials": { + "sshPrivateKey": { + "id": "uAJ2jWJ5wxU4N0lt", + "name": "SSH AI" + } + } + }, + { + "parameters": { + "content": "## AI", + "height": 80, + "width": 150 + }, + "id": "3c9912a7-4f6e-4d8c-8db6-fd0593aba3df", + "name": "Sticky Note2", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 2300, + -360 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/authentik" + }, + "id": "e1bcb7be-e903-46f3-835c-e6c469e15660", + "name": "Compose Up -D3", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 2720, + 140 + ], + "credentials": { + "sshPrivateKey": { + "id": "uNC7chvx2NICWshB", + "name": "SSH authentik" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "7c63e389-80c5-463d-b39f-523f970fd1ae", + "name": "If Error3", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 2720, + 0 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D3').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "475541d6-474b-4a39-8d54-5dfbbb7e050a", + "name": "Gotify3", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 2580, + 0 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull4').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D3').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "b6a21655-89a8-4f51-8b01-fb2a57537b89", + "name": "Comment On PR3", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 2720, + -240 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "7fb60f61-2379-448e-9a58-38c111ccf4dd", + "name": "Set # 4 http to work3", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 2720, + -120 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/authentik" + }, + "id": "d0d281cd-2eb7-4521-b7ec-531dc2c89fff", + "name": "Git Pull4", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 2720, + 280 + ], + "credentials": { + "sshPrivateKey": { + "id": "uNC7chvx2NICWshB", + "name": "SSH authentik" + } + } + }, + { + "parameters": { + "content": "## authentik", + "height": 80, + "width": 150 + }, + "id": "da55b221-74d0-4db9-81a9-85fadb46b2ab", + "name": "Sticky Note3", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 2700, + -360 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "authentik", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "154f60cf-1f7e-4432-b545-5e23ce8f4795", + "name": "If authentik", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 2720, + 420 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/cf" + }, + "id": "03113279-00be-4d21-acf2-bf554d3127e9", + "name": "Compose Up -D4", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 3120, + 160 + ], + "credentials": { + "sshPrivateKey": { + "id": "7JtyYAB4EjNRmA7M", + "name": "SSH cf" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "8e223e93-60d2-4d8f-a1ab-a7805f35ff5f", + "name": "If Error4", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 3120, + 20 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D4').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "f60ac185-8215-4804-8e4f-9c2293851511", + "name": "Gotify4", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 2980, + 20 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull5').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D4').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "793c7814-813e-40a7-bcf1-96f86f44e5f6", + "name": "Comment On PR4", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 3120, + -220 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "42ae4710-66de-48cd-8d00-054a0c481edc", + "name": "Set # 4 http to work4", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 3120, + -100 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/cf" + }, + "id": "19408e51-2907-4833-a61a-2a55df8fdc4c", + "name": "Git Pull5", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 3120, + 300 + ], + "credentials": { + "sshPrivateKey": { + "id": "7JtyYAB4EjNRmA7M", + "name": "SSH cf" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "cloudflare", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "c4d24a9a-c22c-460d-bcc8-12aac0b5f107", + "name": "If cf", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 3120, + 440 + ] + }, + { + "parameters": { + "content": "## Cloudflare", + "height": 80, + "width": 150 + }, + "id": "36121726-20af-43a0-8795-5b7a41dcb6f1", + "name": "Sticky Note4", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 3080, + -340 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/drone" + }, + "id": "03890971-702e-4415-b38f-530f342102cf", + "name": "Compose Up -D5", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 3520, + 160 + ], + "credentials": { + "sshPrivateKey": { + "id": "AMcQKKPBATPi4NGr", + "name": "SSH drone" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "920cc150-b903-4370-98da-52762bcaa75e", + "name": "If Error5", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 3520, + 20 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D5').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "4dc7160a-fa0d-4ccf-96c0-f94ce318e337", + "name": "Gotify5", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 3380, + 20 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull6').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D5').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "e07d82c6-82d7-4d67-88e9-f838fe10543e", + "name": "Comment On PR5", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 3520, + -220 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "2d2c47ec-613a-4e6c-b974-36ca01fb7f52", + "name": "Set # 4 http to work5", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 3520, + -100 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/drone" + }, + "id": "5f6517d5-f481-4388-9551-4ff1fea86939", + "name": "Git Pull6", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 3520, + 300 + ], + "credentials": { + "sshPrivateKey": { + "id": "AMcQKKPBATPi4NGr", + "name": "SSH drone" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "drone", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "7b985ed2-518d-4250-a77f-738ff208ed8c", + "name": "If drone", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 3520, + 440 + ] + }, + { + "parameters": { + "content": "## Drone", + "height": 80, + "width": 150 + }, + "id": "e5dcf857-1227-4443-aaf2-60121fb30f65", + "name": "Sticky Note5", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 3500, + -320 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/jellyfin" + }, + "id": "5cb468ac-4a4e-44b0-bba1-3439941166c4", + "name": "Compose Up -D6", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 3900, + 180 + ], + "credentials": { + "sshPrivateKey": { + "id": "b6B08dgNKfFOMuYD", + "name": "SSH jellyfin" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "c5f4b9ff-4cba-4138-b911-8839291178f5", + "name": "If Error6", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 3900, + 40 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D6').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "71e3894d-64f6-436e-9111-be889edc16a0", + "name": "Gotify6", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 3760, + 40 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull7').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D6').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "8c02105c-d7de-4dee-a32c-f25309207044", + "name": "Comment On PR6", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 3900, + -200 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "7634b893-f44f-4d61-b915-eef1bd5883be", + "name": "Set # 4 http to work6", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 3900, + -80 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/jellyfin" + }, + "id": "5d20f0e4-7d76-4c73-a3e6-14fbfef8698a", + "name": "Git Pull7", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 3900, + 320 + ], + "credentials": { + "sshPrivateKey": { + "id": "b6B08dgNKfFOMuYD", + "name": "SSH jellyfin" + } + } + }, + { + "parameters": { + "content": "## Jellyfin", + "height": 80, + "width": 150 + }, + "id": "2dd215b5-18dc-4164-9f31-7e9be5d14106", + "name": "Sticky Note6", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 3880, + -300 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "jellyfin", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "d5cce51e-be9c-4b3d-be16-4e97bb14d075", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "makemkv", + "operator": { + "type": "string", + "operation": "equals", + "name": "filter.operator.equals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "6a4453d4-116d-4ba6-b078-3cb513ae5709", + "name": "If jellyfin", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 3900, + 460 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/kasm" + }, + "id": "c8711a86-f220-4ebf-94c9-1da15ca8d261", + "name": "Compose Up -D7", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 4300, + 180 + ], + "credentials": { + "sshPrivateKey": { + "id": "anuugVVvIkbvVdKY", + "name": "SSH kasm" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "e4774528-f2e2-45cc-b57c-1a7e127d5713", + "name": "If Error7", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 4300, + 40 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D7').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "8041c86d-2f7a-452e-9674-0b7d4569fb16", + "name": "Gotify7", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 4160, + 40 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull8').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D7').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "cf7099b9-05b6-421c-b2ef-f31eca791bf5", + "name": "Comment On PR7", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 4300, + -200 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "bdeb74c0-96ed-46c2-a8a6-16c785781ad0", + "name": "Set # 4 http to work7", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 4300, + -80 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/kasm" + }, + "id": "455250c1-4cce-4a2a-9d1d-0b954dad8a91", + "name": "Git Pull8", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 4300, + 320 + ], + "credentials": { + "sshPrivateKey": { + "id": "anuugVVvIkbvVdKY", + "name": "SSH kasm" + } + } + }, + { + "parameters": { + "content": "## Kasm", + "height": 80, + "width": 150 + }, + "id": "bfa867b2-8e9c-402a-8607-7fb31d2447a6", + "name": "Sticky Note7", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 4280, + -300 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "kasm", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "d97c82f9-d17c-4a9a-a6da-039cda0e35fa", + "name": "If kasm", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 4300, + 460 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/netboot" + }, + "id": "66e7a3db-c420-4805-a62a-d3876a799664", + "name": "Compose Up -D8", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 4740, + 200 + ], + "credentials": { + "sshPrivateKey": { + "id": "qE5UOq5xLxiHqyHY", + "name": "SSH netboot" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "725ef32a-0132-4aff-b069-4cd7fde83818", + "name": "If Error8", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 4740, + 60 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D8').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "4b393895-47dd-4a8e-b96b-94f4c86903b4", + "name": "Gotify8", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 4600, + 60 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull9').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D8').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "0e9dc672-1a15-4abc-97fb-4d44c462f240", + "name": "Comment On PR8", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 4740, + -180 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "b40e4641-837f-4e80-986b-6928d983427f", + "name": "Set # 4 http to work8", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 4740, + -60 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/netboot" + }, + "id": "bf0a001a-f278-4938-a636-375966e7860c", + "name": "Git Pull9", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 4740, + 340 + ], + "credentials": { + "sshPrivateKey": { + "id": "qE5UOq5xLxiHqyHY", + "name": "SSH netboot" + } + } + }, + { + "parameters": { + "content": "## Netboot", + "height": 80, + "width": 150 + }, + "id": "e4718651-e929-4a80-830d-17fda415e986", + "name": "Sticky Note8", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 4720, + -280 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "netboot", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "39e07fd5-1c07-4daf-88f2-d37bfd3952f2", + "name": "If netboot", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 4740, + 480 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/nexus" + }, + "id": "2a6ccef1-2221-4e63-8d7f-64a0075d0ed7", + "name": "Compose Up -D9", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 5120, + 200 + ], + "credentials": { + "sshPrivateKey": { + "id": "qKsmaEn7UzJ2fX1R", + "name": "SSH nexus" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "d8198e35-4e85-4749-a75d-8ef54fa136b7", + "name": "If Error9", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 5120, + 60 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D9').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "c902bf80-061f-4ec3-ace1-d69d5998c251", + "name": "Gotify9", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 4980, + 60 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull10').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D9').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "386ff64a-ad49-4696-85e6-8ad0627c2be7", + "name": "Comment On PR9", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 5120, + -180 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "8b35073a-aa84-454e-8126-a7390c119bc3", + "name": "Set # 4 http to work9", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 5120, + -60 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/nexus" + }, + "id": "b3e6c3c4-cc53-4bb9-924a-afbfad8f2102", + "name": "Git Pull10", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 5120, + 340 + ], + "credentials": { + "sshPrivateKey": { + "id": "qKsmaEn7UzJ2fX1R", + "name": "SSH nexus" + } + } + }, + { + "parameters": { + "content": "## Nexus", + "height": 80, + "width": 150 + }, + "id": "93265975-7de5-47ab-9a8f-ff7f147a65ed", + "name": "Sticky Note9", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 5100, + -280 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "nexus", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "e347d1ee-76f3-4160-a738-36c3a36f59d0", + "name": "If nexus", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 5120, + 480 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/portainer" + }, + "id": "b43fd75b-19b4-4faa-8c53-d7fddc6ecc7b", + "name": "Compose Up -D10", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 5520, + 220 + ], + "credentials": { + "sshPrivateKey": { + "id": "jdyIldpcL9WbzYbN", + "name": "SSH Portainer" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "402b29cb-68a0-4cde-ab33-25e5b2291061", + "name": "If Error10", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 5520, + 80 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D10').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "f7505872-10ba-4d13-bbe4-c0204ed7272b", + "name": "Gotify10", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 5380, + 80 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull11').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D10').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "eabb4d92-7ca4-4626-a2ed-030c3713589b", + "name": "Comment On PR10", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 5520, + -160 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "01e32843-42d2-4e6c-b82e-5558d145d1b1", + "name": "Set # 4 http to work10", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 5520, + -40 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/portainer" + }, + "id": "33d50a08-367a-4900-9cf7-9ffca1c8215d", + "name": "Git Pull11", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 5520, + 360 + ], + "credentials": { + "sshPrivateKey": { + "id": "jdyIldpcL9WbzYbN", + "name": "SSH Portainer" + } + } + }, + { + "parameters": { + "content": "## Portainer", + "height": 80, + "width": 150 + }, + "id": "447d939f-0ab2-4d23-b141-4dfa38e319c2", + "name": "Sticky Note10", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 5500, + -260 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/twingate" + }, + "id": "f6fbb45c-7dc9-4688-857f-2ccea1ad0f99", + "name": "Compose Up -D11", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 5900, + 220 + ], + "credentials": { + "sshPrivateKey": { + "id": "U0KmO7gbBp8HSrPK", + "name": "SSH twingate (OG VM)" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "ea7cb1fb-31fc-45db-b428-759250d1ffaa", + "name": "If Error11", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 5900, + 80 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D11').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "e679aaaf-e5ac-4f7b-a67d-695bd2fbb01f", + "name": "Gotify11", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 5760, + 80 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull12').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D11').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "d57f0df9-f839-4620-ac45-acb4ba28e239", + "name": "Comment On PR11", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 5900, + -160 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "993bdb81-54db-4574-99de-3ca34853ed79", + "name": "Set # 4 http to work11", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 5900, + -40 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/twingate" + }, + "id": "8d6e2037-cc5c-40e8-9002-09c6df8250cf", + "name": "Git Pull12", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 5900, + 360 + ], + "credentials": { + "sshPrivateKey": { + "id": "U0KmO7gbBp8HSrPK", + "name": "SSH twingate (OG VM)" + } + } + }, + { + "parameters": { + "content": "## Twingate", + "height": 80, + "width": 150 + }, + "id": "6b138cda-016c-4da8-a9ba-4e2ac9f39e1c", + "name": "Sticky Note11", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 5880, + -260 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "twingate", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "33c00efa-7626-4026-aa8c-ef7f8e949c51", + "name": "If twingate", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 5900, + 500 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "portainer", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "69411c52-254e-4681-adb9-a7cffd97666e", + "name": "If portainer", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 5520, + 500 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "forgejo", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "955462d6-85e9-4d8a-aaba-2d1f9df2c49f", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "gotify", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "81b525fb-e899-4dcd-a6e8-84fd551e25d9", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "nginx-proxy-manager", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "bd4b3a81-272b-4a00-bec3-c5743dd4e506", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "uptime-kuma", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "58766270-ca7b-429a-8b60-948e86ff3893", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "jellyseerr", + "operator": { + "type": "string", + "operation": "contains" + } + }, + { + "id": "7000e55b-ac34-48e7-9db3-1489c68421db", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "linkstackorg", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "d6ddc5f2-9508-4da5-bfef-4640397c81b9", + "name": "If arm", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 6520, + 520 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/ubuntu/Auto-Homelab/arm" + }, + "id": "4cdc19ac-2d2b-497a-8af6-ba5857351b76", + "name": "Git Pull2", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 6520, + 380 + ], + "credentials": { + "sshPrivateKey": { + "id": "jJC8YMOfifEQNRs3", + "name": "SSH ARM" + } + } + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/ubuntu/Auto-Homelab/arm" + }, + "id": "f0b6f361-a9b5-446c-8e72-815024086332", + "name": "Compose Up -D12", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 6520, + 220 + ], + "credentials": { + "sshPrivateKey": { + "id": "jJC8YMOfifEQNRs3", + "name": "SSH ARM" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "3661edf1-d849-4fdc-97a2-f19138875a1b", + "name": "If Error12", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 6520, + 100 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D12').item.json.stderr }}\n\nLink to PR: {{ $('If arm').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "afe79597-4881-4d21-b0ad-f6e78e9fd9f4", + "name": "Gotify12", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 6380, + 100 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull2').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D12').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "fc53af09-677e-4c8d-b28d-bc490a91d85a", + "name": "Comment On PR12", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 6520, + -140 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arm').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "75a06022-7501-43d7-afb4-0a1b3c234926", + "name": "Set # 4 http to work12", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 6520, + -20 + ] + }, + { + "parameters": { + "content": "## Arm", + "height": 80, + "width": 150 + }, + "id": "8c772dad-362b-4a06-ad22-dadb8b6b5ae3", + "name": "Sticky Note12", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 6500, + -240 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "docker compose up -d --quiet-pull", + "cwd": "/home/user/Auto-Homelab/adguard-main" + }, + "id": "eb167c7b-1619-413a-abdb-a931594cd885", + "name": "Compose Up -D13", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 6260, + 220 + ], + "credentials": { + "sshPrivateKey": { + "id": "8BDnNUtklkxfCqCj", + "name": "SSH adguard main" + } + } + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "51a1d695-817f-4c60-baf8-6457f425bbf8", + "leftValue": "={{ $json.code }}", + "rightValue": 0, + "operator": { + "type": "number", + "operation": "notEquals" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "e5e6ad51-0c75-4c7d-b839-fc0f14231f04", + "name": "If Error13", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 6260, + 80 + ] + }, + { + "parameters": { + "message": "=Failed to run docker compose up -d on a specific host.\n\nError Message: {{ $('Compose Up -D13').item.json.stderr }}\n\nLink to PR: {{ $('If arrs').item.json.body.pull_request.url }}", + "additionalFields": { + "priority": 9, + "title": "CI-CD Failure" + }, + "options": { + "contentType": "text/markdown" + } + }, + "id": "d10b73f3-f246-499a-a4de-3cc329066b5b", + "name": "Gotify13", + "type": "n8n-nodes-base.gotify", + "typeVersion": 1, + "position": [ + 6120, + 80 + ], + "credentials": { + "gotifyApi": { + "id": "Yncb8WJ8gs8jBk9m", + "name": "Gotify account" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "=https://git.example.com/api/v1/repos/user/Auto-Homelab/pulls/{{ $json.body.number }}/reviews", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Authorization", + "value": "Bearer your-api-key" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "body", + "value": "=## Continuous Deployment successfully ran.\n\n### Git Logs: \n{{ $('Git Pull13').item.json.stdout }}\n\n### Docker Compose Logs: \n{{ $('Compose Up -D13').item.json.stderr }}" + } + ] + }, + "options": {} + }, + "id": "184534f6-0769-4c73-96cf-23870881e651", + "name": "Comment On PR13", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + 6260, + -160 + ] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "5255c2b4-9347-4b22-a882-a9b45db282e3", + "name": "body.number", + "value": "={{ $('If arrs').item.json.body.number }}", + "type": "number" + } + ] + }, + "options": {} + }, + "id": "255fbe8b-a5dd-4fa0-8816-6fd98be238e8", + "name": "Set # 4 http to work13", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [ + 6260, + -40 + ] + }, + { + "parameters": { + "authentication": "privateKey", + "command": "git pull", + "cwd": "/home/user/Auto-Homelab/adguard-main" + }, + "id": "a884c608-8d82-4473-aba1-fcd00f308960", + "name": "Git Pull13", + "type": "n8n-nodes-base.ssh", + "typeVersion": 1, + "position": [ + 6260, + 360 + ], + "credentials": { + "sshPrivateKey": { + "id": "8BDnNUtklkxfCqCj", + "name": "SSH adguard main" + } + } + }, + { + "parameters": { + "content": "## Adguard", + "height": 80, + "width": 150 + }, + "id": "32293a35-1be3-435f-bd13-34341770fb33", + "name": "Sticky Note13", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 6240, + -260 + ] + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "f2a69d99-e73e-4772-a062-a096270cd861", + "leftValue": "={{ $json.body.pull_request.title }}", + "rightValue": "adguard", + "operator": { + "type": "string", + "operation": "contains" + } + } + ], + "combinator": "or" + }, + "options": {} + }, + "id": "5d37c4e3-66bf-4d72-874d-090d5c8075b8", + "name": "If adguard", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 6260, + 500 + ] + }, + { + "parameters": { + "content": "# n8n Continuous Deployment\n\n## Outline\n\n- Webhook is sent whenever a PR is merged\n- Filters out any new, edited or re-opened PR's\n- Checks the PR title for app name, which is filtered so each SSH session matches based on the IF conditions.\n- SSH in to the machine that hosts that docker compose stack running git pull and docker compose up -d \n- Optional, If there is any error message we sent Gotify a link to the PR and error message\n- Set number from JSON to number in n8n\n- Add that number to URL of API request to Forgejo which we add a review with the logs if no errors.\n\nThe only exception is n8n itself. Which for now I will manually update.", + "height": 351.7210668816243, + "width": 914.0473563800131 + }, + "id": "b8ebac22-8490-4cb0-aec6-b6f251832343", + "name": "Sticky Note14", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 520, + 780 + ] + }, + { + "parameters": {}, + "id": "90c58a53-7aa8-42ba-a2b3-f94cacd27fad", + "name": "No Operation, do nothing1", + "type": "n8n-nodes-base.noOp", + "typeVersion": 1, + "position": [ + 6800, + 540 + ] + }, + { + "parameters": { + "content": "# Things to Change\nThis is using Forgejo/ Gitea for API call, but API's change so make sure start data is correct\n\nEvery folder in my Git repo represents a different host, so alot of different ssh credentials or export same key\n\n## Webhook\n- POST\n- URL\n## IF\n- Just change the name of the apps that you want to run CD on, if it matches that host.\n## SSH\n- change the working directory on all of these!\n- make sure you are SSH'ing into the right host every module\n\nYou could stop here and the CD is done. but I like knowing stuff was done so we keep it on.\n\n## IF Error\n- git pull usually works without error, unless I delete a file from repo, so I dont track that for errors.\n- shouldn't have to change anything here\n- True sends to gotify the error with a link to suspect PR, false takes the logs from ssh modules and imports them.\n\n## Comment on PR\n- Change URL and make sure variable matches PR #\n\nIf any variable is red, it will fail. The only shared module between all is arrs as its first in line with all data.", + "height": 704.4741831606943, + "width": 914.0473563800131 + }, + "id": "da7c6615-5448-44b7-baec-38912bcc1030", + "name": "Sticky Note15", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 1940, + 686.1484651162787 + ] + }, + { + "parameters": { + "httpMethod": "POST", + "path": "65999988-3d1f-4594-a8ff-4643e39495b0", + "options": {} + }, + "id": "a99230e5-6684-4e52-a787-833693e4fc7d", + "name": "Webhook", + "type": "n8n-nodes-base.webhook", + "typeVersion": 2, + "position": [ + 1200, + 560 + ], + "webhookId": "65999988-3d1f-4594-a8ff-4643e39495b0" + } + ], + "pinData": {}, + "connections": { + "If Closed and Merged": { + "main": [ + [ + { + "node": "If arrs", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "No Operation, do nothing", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull": { + "main": [ + [ + { + "node": "Compose Up -D", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D": { + "main": [ + [ + { + "node": "If Error", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error": { + "main": [ + [ + { + "node": "Gotify", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work", + "type": "main", + "index": 0 + } + ] + ] + }, + "If arrs": { + "main": [ + [ + { + "node": "Git Pull", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If downloader", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work": { + "main": [ + [ + { + "node": "Comment On PR", + "type": "main", + "index": 0 + } + ] + ] + }, + "If downloader": { + "main": [ + [ + { + "node": "Git Pull1", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If AI", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull1": { + "main": [ + [ + { + "node": "Compose Up -D1", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error1": { + "main": [ + [ + { + "node": "Gotify1", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work1": { + "main": [ + [ + { + "node": "Comment On PR1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D1": { + "main": [ + [ + { + "node": "If Error1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D2": { + "main": [ + [ + { + "node": "If Error2", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error2": { + "main": [ + [ + { + "node": "Gotify2", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work2", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work2": { + "main": [ + [ + { + "node": "Comment On PR2", + "type": "main", + "index": 0 + } + ] + ] + }, + "If AI": { + "main": [ + [ + { + "node": "Git Pull3", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If authentik", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull3": { + "main": [ + [ + { + "node": "Compose Up -D2", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D3": { + "main": [ + [ + { + "node": "If Error3", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error3": { + "main": [ + [ + { + "node": "Gotify3", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work3", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work3": { + "main": [ + [ + { + "node": "Comment On PR3", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull4": { + "main": [ + [ + { + "node": "Compose Up -D3", + "type": "main", + "index": 0 + } + ] + ] + }, + "If authentik": { + "main": [ + [ + { + "node": "Git Pull4", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If cf", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D4": { + "main": [ + [ + { + "node": "If Error4", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error4": { + "main": [ + [ + { + "node": "Gotify4", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work4", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work4": { + "main": [ + [ + { + "node": "Comment On PR4", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull5": { + "main": [ + [ + { + "node": "Compose Up -D4", + "type": "main", + "index": 0 + } + ] + ] + }, + "If cf": { + "main": [ + [ + { + "node": "Git Pull5", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If drone", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D5": { + "main": [ + [ + { + "node": "If Error5", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error5": { + "main": [ + [ + { + "node": "Gotify5", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work5", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work5": { + "main": [ + [ + { + "node": "Comment On PR5", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull6": { + "main": [ + [ + { + "node": "Compose Up -D5", + "type": "main", + "index": 0 + } + ] + ] + }, + "If drone": { + "main": [ + [ + { + "node": "Git Pull6", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If jellyfin", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D6": { + "main": [ + [ + { + "node": "If Error6", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error6": { + "main": [ + [ + { + "node": "Gotify6", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work6", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work6": { + "main": [ + [ + { + "node": "Comment On PR6", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull7": { + "main": [ + [ + { + "node": "Compose Up -D6", + "type": "main", + "index": 0 + } + ] + ] + }, + "If jellyfin": { + "main": [ + [ + { + "node": "Git Pull7", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If kasm", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D7": { + "main": [ + [ + { + "node": "If Error7", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error7": { + "main": [ + [ + { + "node": "Gotify7", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work7", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work7": { + "main": [ + [ + { + "node": "Comment On PR7", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull8": { + "main": [ + [ + { + "node": "Compose Up -D7", + "type": "main", + "index": 0 + } + ] + ] + }, + "If kasm": { + "main": [ + [ + { + "node": "Git Pull8", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If netboot", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D8": { + "main": [ + [ + { + "node": "If Error8", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error8": { + "main": [ + [ + { + "node": "Gotify8", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work8", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work8": { + "main": [ + [ + { + "node": "Comment On PR8", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull9": { + "main": [ + [ + { + "node": "Compose Up -D8", + "type": "main", + "index": 0 + } + ] + ] + }, + "If netboot": { + "main": [ + [ + { + "node": "Git Pull9", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If nexus", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D9": { + "main": [ + [ + { + "node": "If Error9", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error9": { + "main": [ + [ + { + "node": "Gotify9", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work9", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work9": { + "main": [ + [ + { + "node": "Comment On PR9", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull10": { + "main": [ + [ + { + "node": "Compose Up -D9", + "type": "main", + "index": 0 + } + ] + ] + }, + "If nexus": { + "main": [ + [ + { + "node": "Git Pull10", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If portainer", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D10": { + "main": [ + [ + { + "node": "If Error10", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error10": { + "main": [ + [ + { + "node": "Gotify10", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work10", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work10": { + "main": [ + [ + { + "node": "Comment On PR10", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull11": { + "main": [ + [ + { + "node": "Compose Up -D10", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D11": { + "main": [ + [ + { + "node": "If Error11", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error11": { + "main": [ + [ + { + "node": "Gotify11", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work11", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work11": { + "main": [ + [ + { + "node": "Comment On PR11", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull12": { + "main": [ + [ + { + "node": "Compose Up -D11", + "type": "main", + "index": 0 + } + ] + ] + }, + "If twingate": { + "main": [ + [ + { + "node": "Git Pull12", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If adguard", + "type": "main", + "index": 0 + } + ] + ] + }, + "If portainer": { + "main": [ + [ + { + "node": "Git Pull11", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If twingate", + "type": "main", + "index": 0 + } + ] + ] + }, + "If arm": { + "main": [ + [ + { + "node": "Git Pull2", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "No Operation, do nothing1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D12": { + "main": [ + [ + { + "node": "If Error12", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error12": { + "main": [ + [ + { + "node": "Gotify12", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work12", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work12": { + "main": [ + [ + { + "node": "Comment On PR12", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull2": { + "main": [ + [ + { + "node": "Compose Up -D12", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compose Up -D13": { + "main": [ + [ + { + "node": "If Error13", + "type": "main", + "index": 0 + } + ] + ] + }, + "If Error13": { + "main": [ + [ + { + "node": "Gotify13", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Set # 4 http to work13", + "type": "main", + "index": 0 + } + ] + ] + }, + "Set # 4 http to work13": { + "main": [ + [ + { + "node": "Comment On PR13", + "type": "main", + "index": 0 + } + ] + ] + }, + "Git Pull13": { + "main": [ + [ + { + "node": "Compose Up -D13", + "type": "main", + "index": 0 + } + ] + ] + }, + "If adguard": { + "main": [ + [ + { + "node": "Git Pull13", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "If arm", + "type": "main", + "index": 0 + } + ] + ] + }, + "Webhook": { + "main": [ + [ + { + "node": "If Closed and Merged", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": true, + "settings": { + "executionOrder": "v1" + }, + "versionId": "8e977e9f-8cfb-4c27-b9ac-0a8bae2008b3", + "meta": { + "templateCredsSetupCompleted": true, + "instanceId": "2743a0d390bd542002362c342116ed832b98b73abedafaf0ff3d782245610b8e" + }, + "id": "y0MqGNMmNrZRUN7S", + "tags": [] +} \ No newline at end of file diff --git a/docker/scripts/README.md b/docker/scripts/README.md new file mode 100644 index 00000000..e4ef8bc7 --- /dev/null +++ b/docker/scripts/README.md @@ -0,0 +1,74 @@ +# n8n Continuous Deployment +Previously used this script for CD, it worked, but I wanted an instant deployment and not just ran on a schedule. So I created an n8n automation. Here's the visual breakdown: + +```mermaid + graph LR + A((Webhook Received)) --> B{PR Merged?} + B -- No --> C(End) + B -- Yes --> D{Extract App Name} + D --> E{SSH to Host Machine} + E --> F{Git Pull & Docker Compose Up} + F --> G{Error?} + G -- Yes --> H[Send Gotify Notification] + G -- No --> I[Extract PR Number] + I --> J[Add PR Number to Forgejo API URL] + J --> K[Send Review with Logs] + K --> L(End) + H --> L +``` + +## Outline + +- Webhook is sent whenever a PR is merged +- Filters out any new, edited or re-opened PR's +- Checks the PR title for app name, which is filtered so each SSH session matches based on the IF conditions. +- SSH in to the machine that hosts that docker compose stack running git pull and docker compose up -d +- Optional, If there is any error message we sent Gotify a link to the PR and error message +- Set number from JSON to number in n8n +- Add that number to URL of API request to Forgejo which we add a review with the logs if no errors. https://git.mafyuh.dev/mafyuh/Auto-Homelab/pulls/222#issuecomment-1799 + +The only exception is n8n itself. Which for now I will manually update. + +To import this into your n8n, create a new workflow, top right click 3 dots - Import from URL and paste https://git.mafyuh.dev/mafyuh/Auto-Homelab/raw/branch/main/scripts/CD.json + +## dccd instructions (no longer used besides ag-backup) + +Modified version of https://github.com/loganmarchione/dccd, with Gotify notification on error and allowing to choose which directory is cd'd into before running script. I run this on each docker host through crontab every 30 minutes, just adding the -f flag with the folder which that host represents. So each directory represents a host + +Clone this repo: +``` +git clone https://git.mafyuh.dev/mafyuh/Auto-Homelab.git +``` + +Make executable: +``` +sudo chmod +x /home/mafyuh/Auto-Homelab/scripts/dccd.sh +``` +Example: +``` +./dccd.sh -b main -d /home/mafyuh/Auto-Homelab -p -f 'arrs' +``` +Crontab every 30 mins: +``` +*/30 * * * * /home/mafyuh/Auto-Homelab/scripts/dccd.sh -b main -d /home/mafyuh/Auto-Homelab -l /tmp/dccd.txt -p -f 'arrs' +``` +View Logs: +``` +cat /tmp/dccd.txt +``` +Export Variables: +``` +export GOTIFY_BASE_URL="https:go.example.com" +export GOTIFY_TOKEN="token" +``` +Full Usage: +``` +Options: + -b <name> Specify the remote branch to track (default: main) + -d <path> Specify the base directory of the git repository (required) + -h Show this help message + -l <path> Specify the path to the log file (default: /tmp/dccd.log) + -p Specify if you want to prune docker images (default: don't prune) + -x <path> Exclude directories matching the specified pattern (relative to the base directory) + -f <pattern> Specify the pattern for folder names to match +``` \ No newline at end of file diff --git a/docker/twingate/docker-compose.yml b/docker/twingate/docker-compose.yml new file mode 100644 index 00000000..8defe46c --- /dev/null +++ b/docker/twingate/docker-compose.yml @@ -0,0 +1,38 @@ +services: + twingate-famous-alligator: + image: docker.mafyuh.xyz/twingate/connector@sha256:d916c024a0c568442fc4c5a3a081fc9543338a807591a3403b9bec941ed6deeb + container_name: twingate-famous-alligator + restart: always + environment: + - TWINGATE_NETWORK=$TWINGATE_NETWORK + - TWINGATE_ACCESS_TOKEN=$TWINGATE_ACCESS_TOKEN + - TWINGATE_REFRESH_TOKEN=$TWINGATE_REFRESH_TOKEN + - TWINGATE_LABEL_HOSTNAME=${HOSTNAME} + - TWINGATE_LABEL_DEPLOYED_BY=docker + sysctls: + - net.ipv4.ping_group_range=0 2147483647 + + docker-in-docker: + image: docker:dind + container_name: 'docker_dind' + privileged: 'true' + command: ['dockerd', '-H', 'tcp://0.0.0.0:2375', '--tls=false'] + restart: 'unless-stopped' + + gitea: + image: 'code.forgejo.org/forgejo/runner:3.5.0' + links: + - docker-in-docker + depends_on: + docker-in-docker: + condition: service_started + container_name: 'runner' + environment: + DOCKER_HOST: tcp://docker-in-docker:2375 + # User without root privileges, but with access to `/data`. + user: 1000:1000 + volumes: + - /home/mafyuh/data:/data + restart: 'unless-stopped' + + command: '/bin/sh -c "sleep 5; forgejo-runner daemon"' \ No newline at end of file diff --git a/docker/whisper/docker-compose.yml b/docker/whisper/docker-compose.yml new file mode 100644 index 00000000..85abecd7 --- /dev/null +++ b/docker/whisper/docker-compose.yml @@ -0,0 +1,19 @@ +--- +version: "2.1" +services: + whisperasr: + container_name: whisper + image: onerahmet/openai-whisper-asr-webservice:v1.4.1-gpu + environment: + - ASR_MODEL=base.en + - ASR_ENGINE=faster_whisper + ports: + - 9000:9000 + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] + restart: unless-stopped diff --git a/terraform/AI.tf b/terraform/AI.tf new file mode 100644 index 00000000..31204c37 --- /dev/null +++ b/terraform/AI.tf @@ -0,0 +1,71 @@ +resource "proxmox_virtual_environment_vm" "AI" { + + # VM General Settings + node_name = "pve2" + vm_id = 322 + name = "AI" + machine = "q35" + description = "Ollama, Open Webui, mindsdb" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo"] + started = true + + agent { + enabled = true + } + + clone { + vm_id = 8101 + } + + # VM CPU Settings + cpu { + cores = 10 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 16384 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "local-lvm" + size = 100 + interface = "scsi0" + } + + + hostpci { + device = "hostpci0" + pcie = true + mapping = "gpu2" + rombar = true + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_data_file_id = proxmox_virtual_environment_file.cloud_config2.id + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/README.md b/terraform/README.md new file mode 100644 index 00000000..9516ef2b --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,18 @@ +[](https://github.com/opentofu/opentofu) + + +<div align="center"> + +# IaC-Homelab + +Infrastructure as Code (IaC) for my homelab using OpenTofu. + +</div> + + +## Overview + +This repository manages the infrastructure for my homelab using OpenTofu and Proxmox. + + + diff --git a/terraform/adguard.tf b/terraform/adguard.tf new file mode 100644 index 00000000..c8375994 --- /dev/null +++ b/terraform/adguard.tf @@ -0,0 +1,64 @@ +resource "proxmox_virtual_environment_vm" "Adguard" { + + # VM General Settings + node_name = "prox" + vm_id = 206 + name = "Adguard" + description = "DNS Server" + tags = ["tofu", "ubuntu24", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = false # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8002 + } + + # VM CPU Settings + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 2048 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 60 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/arrbuntu.tf b/terraform/arrbuntu.tf new file mode 100644 index 00000000..cccb19e0 --- /dev/null +++ b/terraform/arrbuntu.tf @@ -0,0 +1,66 @@ +resource "proxmox_virtual_environment_vm" "Arrbuntu" { + + # VM General Settings + node_name = "prox" + vm_id = 200 + name = "arrbuntu" + description = "arrbuntu" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8000 + } + + # VM CPU Settings + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 6144 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 120 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = var.arrbuntu_ip_address + gateway = var.vlan_gateway + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/cloud-init.tf b/terraform/cloud-init.tf new file mode 100644 index 00000000..c3faf7e0 --- /dev/null +++ b/terraform/cloud-init.tf @@ -0,0 +1,73 @@ +data "local_file" "ssh_public_key" { + filename = "/home/mafyuh/.ssh/main_key.pub" +} + +resource "proxmox_virtual_environment_file" "cloud_config" { + content_type = "snippets" + datastore_id = "Slow4tb" + node_name = "prox" + + source_raw { + data = <<-EOF + #cloud-config + users: + - default + - name: mafyuh + groups: + - sudo + - docker + shell: /bin/bash + ssh_authorized_keys: + - ${trimspace(data.local_file.ssh_public_key.content)} + sudo: ALL=(ALL) NOPASSWD:ALL + runcmd: + - apt update + - apt install -y qemu-guest-agent net-tools nfs-common + - timedatectl set-timezone America/New_York + - systemctl enable qemu-guest-agent + - systemctl start qemu-guest-agent + - curl -fsSL https://get.docker.com | sudo sh + - su - mafyuh -c 'git clone https://git.mafyuh.dev/mafyuh/IaC-Homelab.git /home/mafyuh/IaC-Homelab' + - su - mafyuh -c 'git clone https://git.mafyuh.dev/mafyuh/Auto-Homelab.git /home/mafyuh/Auto-Homelab' + - echo "done" > /tmp/cloud-config.done + EOF + + file_name = "cloud-config.yaml" + } +} + +resource "proxmox_virtual_environment_file" "cloud_config2" { + content_type = "snippets" + datastore_id = "Fast500Gb" + node_name = "pve2" + + source_raw { + data = <<-EOF + #cloud-config + users: + - default + - name: mafyuh + groups: + - sudo + - docker + shell: /bin/bash + ssh_authorized_keys: + - ${trimspace(data.local_file.ssh_public_key.content)} + sudo: ALL=(ALL) NOPASSWD:ALL + runcmd: + - apt update + - apt install -y qemu-guest-agent net-tools nfs-common + - timedatectl set-timezone America/New_York + - systemctl enable qemu-guest-agent + - systemctl start qemu-guest-agent + - curl -fsSL https://get.docker.com | sudo sh + - su - mafyuh -c 'git clone https://git.mafyuh.dev/mafyuh/IaC-Homelab.git /home/mafyuh/IaC-Homelab' + - su - mafyuh -c 'git clone https://git.mafyuh.dev/mafyuh/Auto-Homelab.git /home/mafyuh/Auto-Homelab' + - su - mafyuh -c 'git config --global user.name "Mafyuh"' + - su - mafyuh -c 'git config --global user.email "matt@mafyuh.com"' + - echo "done" > /tmp/cloud-config.done + EOF + + file_name = "cloud-config.yaml" + } +} \ No newline at end of file diff --git a/terraform/docker-runner.tf b/terraform/docker-runner.tf new file mode 100644 index 00000000..437c5e41 --- /dev/null +++ b/terraform/docker-runner.tf @@ -0,0 +1,64 @@ +resource "proxmox_virtual_environment_vm" "Docker-Runner" { + + # VM General Settings + node_name = "prox" + vm_id = 209 + name = "docker-runner" + description = "docker-runner for forgejo" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8100 + } + + # VM CPU Settings + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 2048 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 50 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_data_file_id = proxmox_virtual_environment_file.cloud_config.id +} + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/docker-runner2.tf b/terraform/docker-runner2.tf new file mode 100644 index 00000000..47a00ee1 --- /dev/null +++ b/terraform/docker-runner2.tf @@ -0,0 +1,64 @@ +resource "proxmox_virtual_environment_vm" "Docker-Runner2" { + + # VM General Settings + node_name = "prox" + vm_id = 210 + name = "docker-runner2" + description = "docker-runner for forgejo" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8100 + } + + # VM CPU Settings + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 2048 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 50 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_data_file_id = proxmox_virtual_environment_file.cloud_config.id +} + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/downloaders.tf b/terraform/downloaders.tf new file mode 100644 index 00000000..8d6b0286 --- /dev/null +++ b/terraform/downloaders.tf @@ -0,0 +1,66 @@ +resource "proxmox_virtual_environment_vm" "Downloaders" { + + # VM General Settings + node_name = "prox" + vm_id = 201 + name = "Downloaders" + description = "Sab, Qbitty" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8000 + } + + # VM CPU Settings + cpu { + cores = 3 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 8192 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 260 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = var.downloaders_ip_address + gateway = var.vlan_gateway + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/k3s-master.tf b/terraform/k3s-master.tf new file mode 100644 index 00000000..64b1769c --- /dev/null +++ b/terraform/k3s-master.tf @@ -0,0 +1,65 @@ +resource "proxmox_virtual_environment_vm" "K3s-Master" { + + # VM General Settings + node_name = "prox" + vm_id = 300 + name = "K3s-Master" + description = "Kubernetes master" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8000 + } + + # VM CPU Settings + cpu { + cores = 4 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 8192 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 100 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/k3s-master2.tf b/terraform/k3s-master2.tf new file mode 100644 index 00000000..a7e54a81 --- /dev/null +++ b/terraform/k3s-master2.tf @@ -0,0 +1,65 @@ +resource "proxmox_virtual_environment_vm" "K3s-Master2" { + + # VM General Settings + node_name = "pve2" + vm_id = 321 + name = "K3s-Master2" + description = "Kubernetes Master" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8005 + } + + # VM CPU Settings + cpu { + cores = 4 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 8192 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "local-lvm" + size = 100 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/k3s-master3.tf b/terraform/k3s-master3.tf new file mode 100644 index 00000000..e857f92e --- /dev/null +++ b/terraform/k3s-master3.tf @@ -0,0 +1,65 @@ +resource "proxmox_virtual_environment_vm" "K3s-Master3" { + + # VM General Settings + node_name = "prox" + vm_id = 330 + name = "K3s-Master3" + description = "Kubernetes master" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8000 + } + + # VM CPU Settings + cpu { + cores = 4 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 8192 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 100 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/kasm.tf b/terraform/kasm.tf new file mode 100644 index 00000000..86500511 --- /dev/null +++ b/terraform/kasm.tf @@ -0,0 +1,62 @@ +resource "proxmox_virtual_environment_vm" "Kasm" { + + # VM General Settings + node_name = "pve2" + vm_id = 333 + name = "Kasm" + description = "kasm" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo"] + started = true + + agent { + enabled = true + } + + clone { + vm_id = 8101 + } + + # VM CPU Settings + cpu { + cores = 4 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 4096 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "local-lvm" + size = 100 + interface = "scsi0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_data_file_id = proxmox_virtual_environment_file.cloud_config2.id + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/nexus.tf b/terraform/nexus.tf new file mode 100644 index 00000000..79ccf758 --- /dev/null +++ b/terraform/nexus.tf @@ -0,0 +1,64 @@ +resource "proxmox_virtual_environment_vm" "Nexus" { + + # VM General Settings + node_name = "prox" + vm_id = 205 + name = "Nexus" + description = "Docker Registry to limit DockerHub pulls" + tags = ["tofu", "ubuntu24", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8002 + } + + # VM CPU Settings + cpu { + cores = 4 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 4096 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 120 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/npm.tf b/terraform/npm.tf new file mode 100644 index 00000000..bc1a381a --- /dev/null +++ b/terraform/npm.tf @@ -0,0 +1,66 @@ +resource "proxmox_virtual_environment_vm" "NPM" { + + # VM General Settings + node_name = "prox" + vm_id = 204 + name = "Nginx-Proxy-Manager" + description = "Nginx Proxy Manager" + tags = ["tofu", "ubuntu24", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8002 + } + + # VM CPU Settings + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 2048 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 40 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = var.npm_ip_address + gateway = var.vlan_gateway + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/provider.tf b/terraform/provider.tf new file mode 100644 index 00000000..a532e63f --- /dev/null +++ b/terraform/provider.tf @@ -0,0 +1,26 @@ +terraform { + + required_providers { + proxmox = { + source = "bpg/proxmox" + version = ">= 0.60.1" + } + } +} + +provider "proxmox" { + endpoint = var.virtual_environment_endpoint + password = var.ssh_password + username = "root@pam" + insecure = true + + ssh { + agent = true + username = "root" + password = var.ssh_password + node { + name = "prox" + address = var.prox_ip_address + } + } +} diff --git a/terraform/runner.tf b/terraform/runner.tf new file mode 100644 index 00000000..1bee9879 --- /dev/null +++ b/terraform/runner.tf @@ -0,0 +1,64 @@ +resource "proxmox_virtual_environment_vm" "Runner" { + + # VM General Settings + node_name = "prox" + vm_id = 207 + name = "Runner" + description = "Forgejo Runner" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo", "infrastructure"] + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8000 + } + + # VM CPU Settings + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 2048 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 60 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/ubuntu22-template.tf b/terraform/ubuntu22-template.tf new file mode 100644 index 00000000..a8b72037 --- /dev/null +++ b/terraform/ubuntu22-template.tf @@ -0,0 +1,48 @@ +resource "proxmox_virtual_environment_vm" "Ubuntu-22-Template" { + name = "ubuntu-22" + node_name = "prox" + vm_id = 8100 + tags = ["tofu", "ubuntu-22"] + template = true + started = false + + disk { + datastore_id = "Fast2Tb" + file_id = proxmox_virtual_environment_download_file.ubuntu_cloud_image_22.id + interface = "scsi0" + size = 4 + } + + agent { + enabled = true + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_data_file_id = proxmox_virtual_environment_file.cloud_config.id +} + +serial_device {} + +network_device { + bridge = "vmbr0" +} + +vga { + type = "serial0" + } + +} + + +resource "proxmox_virtual_environment_download_file" "ubuntu_cloud_image_22" { + content_type = "iso" + datastore_id = "local" + node_name = "prox" + url = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img" +} diff --git a/terraform/ubuntu22-template2.tf b/terraform/ubuntu22-template2.tf new file mode 100644 index 00000000..e7d6f75c --- /dev/null +++ b/terraform/ubuntu22-template2.tf @@ -0,0 +1,40 @@ +resource "proxmox_virtual_environment_vm" "Ubuntu-22-Template2" { + name = "ubuntu-22" + node_name = "pve2" + vm_id = 8101 + tags = ["tofu", "ubuntu-22"] + template = true + started = false + + disk { + datastore_id = "local-lvm" + file_id = "local:iso/jammy-server-cloudimg-amd64.img" + interface = "scsi0" + size = 4 + } + + agent { + enabled = true + } + + initialization { + ip_config { + ipv4 { + address = "dhcp" + } + } + + user_data_file_id = proxmox_virtual_environment_file.cloud_config2.id +} + +serial_device {} + +network_device { + bridge = "vmbr0" +} + +vga { + type = "serial0" + } + +} diff --git a/terraform/vars.tf b/terraform/vars.tf new file mode 100644 index 00000000..3462ab1e --- /dev/null +++ b/terraform/vars.tf @@ -0,0 +1,47 @@ +variable "virtual_environment_endpoint" { + type = string +} + +variable "virtual_environment_api" { + type = string +} + +variable "arrbuntu_ip_address" { + type = string +} + + variable "vlan_gateway" { + type = string +} + +variable "downloaders_ip_address" { + type = string +} + +variable "whisper_ip_address" { + type = string +} + +variable "ssh_password" { + type = string +} + +variable "ssh_username" { + type = string +} + +variable "prox_ip_address" { + type = string +} + +variable "npm_ip_address" { + type = string +} + +variable "init_username" { + type = string +} + +variable "init_password" { + type = string +} \ No newline at end of file diff --git a/terraform/whisper.tf b/terraform/whisper.tf new file mode 100644 index 00000000..ff5a4de8 --- /dev/null +++ b/terraform/whisper.tf @@ -0,0 +1,75 @@ +resource "proxmox_virtual_environment_vm" "Whisper" { + + # VM General Settings + node_name = "prox" + vm_id = 203 + name = "Whisper" + machine = "q35" + description = "Creates subtitles for Bazarr and stable-diffusion" + tags = ["tofu", "ubuntu-22", "auto-homelab-repo"] + started = false + + agent { + enabled = true # read 'Qemu guest agent' section, change to true only when ready + } + + clone { + vm_id = 8000 + } + + # VM CPU Settings + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + # VM Memory Settings + memory { + dedicated = 4096 + } + + # VM Network Settings + network_device { + bridge = "vmbr0" + vlan_id = 1 + } + + # VM Disk Settings + disk { + datastore_id = "Fast2Tb" + size = 40 + interface = "scsi0" + } + + vga { + type = "serial0" + } + + hostpci { + device = "hostpci0" + pcie = true + mapping = "gpu" + rombar = true + } + + initialization { + ip_config { + ipv4 { + address = var.whisper_ip_address + gateway = var.vlan_gateway + } + } + + user_account {} + } + + lifecycle { + ignore_changes = [ + initialization[0].user_account[0].keys, + initialization[0].user_account[0].password, + initialization[0].user_account[0].username, + ] + } + +} diff --git a/terraform/windows.tf b/terraform/windows.tf new file mode 100644 index 00000000..9d5e276c --- /dev/null +++ b/terraform/windows.tf @@ -0,0 +1,46 @@ +resource "proxmox_virtual_environment_vm" "Windows11" { + name = "windows" + node_name = "pve2" + vm_id = 250 + tags = ["tofu"] + started = true + bios = "ovmf" + machine = "q35" + + agent { + enabled = true + } + + disk { + datastore_id = "Fast500Gb" + interface = "scsi0" + size = 450 + } + + cpu { + cores = 2 + type = "host" + architecture = "x86_64" + } + + memory { + dedicated = 8192 + } + + efi_disk { + type = "4m" + } + + network_device { + bridge = "vmbr0" + } + + tpm_state { + datastore_id = "Fast500Gb" + version = "v2.0" +} + + operating_system { + type = "win11" +} +}