From 623e70f62d58a1584b8491654004d97323b11491 Mon Sep 17 00:00:00 2001 From: Matt Reeves 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 0000000..8bb3a22 --- /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 0000000..ce53c2d --- /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 0000000..934f570 --- /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 0000000..e2d6832 --- /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 0000000..aa185d2 --- /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 0000000..a19104d --- /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 a9e8a0c..98806c6 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 0000000..05311be --- /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 0000000..d9282ab --- /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 0000000..5f6257f --- /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 0000000..75e2cf4 --- /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 0000000..567dd67 --- /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 0000000..2c40330 --- /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 +[![Ubuntu](https://img.shields.io/badge/Ubuntu_22.04-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/jammy/) +### Hypervisor +[![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](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 0000000..cc0f340 --- /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 0000000..4a6f829 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,312 @@ +[![Yamllint](https://git.mafyuh.dev/mafyuh/Auto-Homelab/badges/workflows/yamllint.yml/badge.svg)](https://git.mafyuh.dev/mafyuh/Auto-Homelab/actions) +[![Yamllint](https://git.mafyuh.dev/mafyuh/Auto-Homelab/badges/workflows/CD.yml/badge.svg)](https://git.mafyuh.dev/mafyuh/Auto-Homelab/actions) +[![Renovate](https://git.mafyuh.dev/renovatebot/renovate/badges/workflows/renovate.yml/badge.svg)](https://git.mafyuh.dev/renovatebot/renovate/actions) +[![Pulls](https://git.mafyuh.dev/mafyuh/Auto-Homelab/badges/pulls.svg)](https://git.mafyuh.dev/mafyuh/Auto-Homelab/pulls) +![Header Image](https://raw.githubusercontent.com/Mafyuh/homelab-svg-assets/main/assets/header_.png) +
+ +# 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. + +
+

+ Wiki | + How to Setup | + Blog | + Inspiration | + Infrastructure +

+ +
+ +| Hypervisor | OS | Tools | VPS (arm) | Firewall | +|---|---|---|---|---| +| [![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](https://www.proxmox.com) | [![Ubuntu](https://img.shields.io/badge/Ubuntu_22.04-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/jammy/) [![Ubuntu](https://img.shields.io/badge/Ubuntu_24-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/noble/) | [![Forgejo](https://img.shields.io/badge/-Forgejo-%23c9d1d9?logo=forgejo&logoColor=orange)](https://forgejo.org/) [![Docker](https://img.shields.io/badge/-Docker-%23c9d1d9?logo=docker)](https://www.docker.com/) | [![Oracle](https://img.shields.io/badge/-Oracle_Cloud-%23c9d1d9?logo=oracle&logoColor=red)](https://www.oracle.com/cloud/) | [![pfSense](https://img.shields.io/badge/-pfSense-%23c9d1d9?logo=pfsense&logoColor=blue)](https://www.pfsense.org/) | + +
+ +
+ +## Apps in Repo: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LogoNameDescription
AdGuard HomeNetwork Wide DNS adblock as well as my DNS server (2/2)
AdGuard Home SyncSyncs my instances of Adguard
authentikOpen Source Identity Provider
BazarrDownloads subtitles for Radarr/Sonarr
Cloudflare TunnelsHow I expose some of these services
Codeberg PagesGithub Pages for Gitea installs. hosts https://mafyuh.co
DoplarrAllows my users to request content through Discord if they choose
FlareSolverrProxy server to bypass Cloudflare and DDoS-GUARD protection
ForgejoThis site
Forgejo RunnerRuns CI/CD tasks Yamllint and Renovatebot and CD through AWX
GotfiySelf hosted notification service
HomarrHomelab dashboard that integrates with the arr's so I see data in 1 place
JellyfinOpen Source Streaming Service for home media like Plex
JellyseerrRequest platform for my Jellyfin user's to request content
jfa-goUsed for some PPV/Live TV automations to create users for certain periods of time
KasmDocker container streaming platform for browser-based access to desktops, applications, and web services
LidarrMusic Collection Manager
LinkStackCreating a static links page for my Jellyfin users
MakeMKVUsed to rip Bluray's with my LG BU40N drive
mindsdbConnects Ollama models to 100+ different databases, easy to use.
Netboot.xyzNetwork boot instead of using my ventoy USB
Nginx Proxy ManagerReverse Proxy used for its simplicity (1/3)
n8nSelf hosted automation platform, Zapier alternative, switched from ActivePieces
OllamaEasiest way to run LLM's on your own hardware
open-webuiCreates a ChatGPT like web interface for talking to Ollama models
PortainerWeb-based management for learning Kubernetes, I learned Docker this way and will Kub as well
ProwlarrSearches indexers for Radarr/Sonarr
qBittorrent VPNModified qBittorrent with VPN killswitch enabled
RadarrMovie Collection Manager
SabnzbdUsenet downloader to download content
SonarrRadarr, but for TV Shows
Sonatype NexusSelf-hosted Docker registry to help lower Docker pulls
SyncthingHow I backup all config files, following 3-2-1 backup procedure
Twingate ConnectorsMain VPN between homelab and cloud VPS's
Uptime KumaSelf hosted service uptime tracker
WhisperAI Model that I use to generate subtitles for Bazarr when they can't be found
+ +
+ +
+ +## Apps not yet in repo: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LogoNameDescription
AWX (Ansible Tower)Used to easily run Ansible playbooks on all my VM's, and now CD for this repo, installed on K3s
GrafanaMonitoring for various services
WordpressWooCommerce store setup for JF PPV access
GuacamoleRemote access in browser via SSH, RDP, VNC, etc
Home AssistantSlowly migrating over to Home Assistant from Google Home
PlausibleAnalytics tracker for certain websites (Blog)
wazuhSecurity platform monitoring everything with agents installed on all VM's
+ +
+ +
+ +## Full Workflow Chart + +
+ +```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 0000000..f01af6a --- /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 0000000..a1b3c2a --- /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 0000000..4d5eafe --- /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 + +[![Oracle](https://img.shields.io/badge/-Oracle_Cloud-%23c9d1d9?logo=oracle&logoColor=red)](https://www.oracle.com/cloud/) + +## Specs +- 4 core ARM +- 24GB RAM +- Currently 150GB Storage (will expand) + +## OS +[![Ubuntu](https://img.shields.io/badge/Ubuntu_22.04-%23c9d1d9?&logo=ubuntu&logoColor=red)](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 0000000..2c96a42 --- /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 0000000..3e11076 --- /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 +[![Ubuntu](https://img.shields.io/badge/Ubuntu_22.04-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/jammy/) +### Hypervisor +[![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](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 0000000..f0e296c --- /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 0000000..45590e2 --- /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 0000000..411ecce --- /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 0000000..6a7db96 --- /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 0000000..dd736b2 --- /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 +[![Ubuntu](https://img.shields.io/badge/Ubuntu_22.04-%23c9d1d9?&logo=ubuntu&logoColor=red)](https://releases.ubuntu.com/jammy/) +### Hypervisor +[![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](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 0000000..479bc9f --- /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 0000000..905dd43 --- /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 +[![Ubuntu](https://img.shields.io/badge/Ubuntu_22.04-%23c9d1d9?&logo=ubuntu&logoColor=red)](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 0000000..7ece065 --- /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 0000000..b68d04e --- /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 0000000..814738f --- /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 0000000..a09a185 --- /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 0000000..7e7aec4 --- /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 0000000..6730359 --- /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 0000000..8eb5b3c --- /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 0000000..e4ef8bc --- /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 Specify the remote branch to track (default: main) + -d Specify the base directory of the git repository (required) + -h Show this help message + -l 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 Exclude directories matching the specified pattern (relative to the base directory) + -f 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 0000000..8defe46 --- /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 0000000..85abecd --- /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 0000000..31204c3 --- /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 0000000..9516ef2 --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,18 @@ +[![OpenTofu](https://img.shields.io/badge/OpenTofu-v1.7.1-blue)](https://github.com/opentofu/opentofu) + + +
+ +# IaC-Homelab + +Infrastructure as Code (IaC) for my homelab using OpenTofu. + +
+ + +## 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 0000000..c837599 --- /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 0000000..cccb19e --- /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 0000000..c3faf7e --- /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 0000000..437c5e4 --- /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 0000000..47a00ee --- /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 0000000..8d6b028 --- /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 0000000..64b1769 --- /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 0000000..a7e54a8 --- /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 0000000..e857f92 --- /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 0000000..8650051 --- /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 0000000..79ccf75 --- /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 0000000..bc1a381 --- /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 0000000..a532e63 --- /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 0000000..1bee987 --- /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 0000000..a8b7203 --- /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 0000000..e7d6f75 --- /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 0000000..3462ab1 --- /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 0000000..ff5a4de --- /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 0000000..9d5e276 --- /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" +} +}