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/) |
+
+
+
+
+
+
+
+
+
+## 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"
+}
+}