Initial Commit
All checks were successful
Deploy / Prepare Build (push) Successful in 13s

This commit is contained in:
2025-09-08 18:29:40 +10:00
commit 12444311a4
59 changed files with 2931 additions and 0 deletions

View File

@ -0,0 +1,74 @@
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: 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

View File

@ -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

View File

@ -0,0 +1,30 @@
name: Deploy
on:
push:
branches:
- master
jobs:
deploy:
name: Prepare Build
runs-on: homelab-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Deploy containers
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
eval $(ssh-agent -s)
ssh-add <(echo "${{ secrets.SSH_PRIVATE_KEY }}")
echo "HOST *" > ~/.ssh/config
echo "StrictHostKeyChecking no" >> ~/.ssh/config
echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > ~/.vault_password.txt
echo "nameserver 10.10.10.1" > /etc/resolv.conf
ansible-galaxy install oefenweb.fail2ban
./.gitea/workflows/deploy.sh "${{ github.event.before }}" "${{ github.sha }}"

13
.gitea/workflows/deploy.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
changed_tasks=($(git diff --name-only $1 $2 | grep '\.yml$'))
if [ ! -z "$changed_tasks" ]; then
for task in "${changed_tasks[@]}"; do
tag=$(echo "$task" | awk -F/ '{print $2}')
if [[ "$tag" != "deploy-homelab.yml" && "$tag" != "main.yml" && "$tag" != "all.yml" && "$tag" != "all.example.yml" && "$tag" != "ISSUE_TEMPLATE" && "$tag" != "workflows" ]] ; then
tag=${tag%.*}_install
ansible-playbook main.yml --tags "$tag" --vault-password-file ~/.vault_password.txt
fi
done
else
echo "No changes detected in task files. Skipping Ansible playbook execution."
fi

175
README.md Normal file
View File

@ -0,0 +1,175 @@
![Header Image](https://miro.medium.com/v2/resize:fit:4000/1*16DgdobhWUUXKzF4fwjOdw.png)
<div align = "center">
# Homelab
Homelab deployed as Infrastructure as Code (IaC) using ansible.
</div>
<!-- [![deploy-containers](https://gitea.comprofix.com/mmckinnon/homelab/actions/workflows/deploy-containers.yml/badge.svg)](https://gitea.comprofix.com/mmckinnon/homelab/actions) -->
<div align="center">
| Hypervisor | OS | Tools | Firewall |
|---|---|---|---|
| [![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](https://www.proxmox.com) | [![Debian](https://img.shields.io/badge/Debian-%23c9d1d9?&logo=Debian&logoColor=red)](https://www.debian.org/releases/stable/) | [![Gitea](https://img.shields.io/badge/gitea-%23c9d1d9?logo=gitea&logoColor=green)](https://about.gitea.com/) [![Docker](https://img.shields.io/badge/-Docker-%23c9d1d9?logo=docker)](https://www.docker.com/) | [![pfSense](https://img.shields.io/badge/-pfSense-%23c9d1d9?logo=pfsense&logoColor=blue)](https://www.pfsense.org/)
</div>
This is a complete rewrite of previous IaC code to allow for better functionalilty and rebuild. Also using a VPS for containers that need to be always up incase lab server goes offline.
<!-- <div align="center">
## Apps in Repo:
<table>
<tr>
<th>Logo</th>
<th>Name</th>
<th>Description</th>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://www.vectorlogo.zone/logos/letsencrypt/letsencrypt-icon.svg"></td>
<td><a href="https://certbot.eff.org/">Certbot</a></td>
<td>Used to generate Let's Encrypt Certificates</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://code.visualstudio.com/assets/images/code-stable.png"></td>
<td><a href="https://github.com/coder/code-server">codeserver</a></td>
<td>Run VS Code on any machine anywhere and access it in the browser</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/amir20/dozzle/master/assets/favicon.svg"></td>
<td><a href="https://dozzle.dev">dozzle</a></td>
<td>Real-time logging and monitoring for Docker in the browser</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/go-gitea/gitea/main/assets/logo.svg"></td>
<td><a href="https://docs.gitea.com/category/installation">Gitea</a></td>
<td>Self-Hosted Git Service</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/go-gitea/gitea/main/assets/logo.svg"></td>
<td><a href="https://docs.gitea.com/usage/actions/act-runner">Act Runner (Gitea Runner)</a></td>
<td>Self-Hosted Runner Service</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/thomiceli/opengist/a9dd531f676d01b93bb6bd70751a69382ca563b0/public/opengist.svg"></td>
<td><a href="https://github.com/thomiceli/opengist">Opengist</a></td>
<td>Opengist is a self-hosted pastebin powered by Git</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/homepage.png"></td>
<td><a href="https://gethomepage.dev/latest/">Homepage</a></td>
<td>A modern, fully static, fast, secure fully proxied, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/invoiceninja.svg"></td>
<td><a href="https://invoiceninja.com/">Invoice Ninja</a></td>
<td>Free Invoicing Software for Small Businesses</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/jellyfin.svg"></td>
<td><a href="https://jellyfin.org/">Jellyfin</a></td>
<td>Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/jellyseerr.svg"></td>
<td><a href="https://github.com/Fallenbagel/jellyseerr">Jellyseerr</a></td>
<td>Jellyseerr is a free and open source software application for managing requests for your media library.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/lidarr.svg"></td>
<td><a href="https://lidarr.audio/">Lidarr</a></td>
<td>Lidarr is a music collection manager for Usenet and BitTorrent users. </td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/mariadb.svg"></td>
<td><a href="https://mariadb.org/">MariaDB</a></td>
<td>MariaDB Server is one of the most popular open source relational databases. Its made by the original developers of MySQL and guaranteed to stay open source.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/mealie.svg"></td>
<td><a href="https://mealie.io">Mealie</a></td>
<td>Mealie is an intuitive and easy to use recipe management app.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/osticket.svg"></td>
<td><a href="https://osticket.com/">osTicket</a></td>
<td>osTicket is a widely used and trusted open source support ticketing system.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/planka.svg"></td>
<td><a href="https://planka.app/">Planka</a></td>
<td>Elegant open source project tracking</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/portainer.svg"></td>
<td><a href="https://portainer.io/">Portainer</a></td>
<td>Portainer is your container management software</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/postgres.svg"></td>
<td><a href="https://portainer.io/">PostgreSQL</a></td>
<td>PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/privatebin.svg"></td>
<td><a href="https://privatebin.info/">Privatebin</a></td>
<td>PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/prowlarr.svg"></td>
<td><a href="https://github.com/Prowlarr/Prowlarr">Prowlarr</a></td>
<td>Prowlarr supports management of both Torrent Trackers and Usenet Indexers.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://icons.veryicon.com/png/o/miscellaneous/cookd-pc/kms-management.png"></td>
<td><a href="https://github.com/Py-KMS-Organization/py-kms">py-kms</a></td>
<td>KMS activates Microsoft products on a local network, eliminating the need for individual computers to connect to Microsoft.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/qbittorrent.svg"></td>
<td><a href="https://qbittorrent.org">qBittorrent</a></td>
<td>qBittorrent is a cross-platform free and open-source BitTorrent client </td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/radarr.svg"></td>
<td><a href="https://radarr.video">Radarr</a></td>
<td>Radarr is a movie collection manager for Usenet and BitTorrent users.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/readarr.svg"></td>
<td><a href="https://readarr.com">Readarr</a></td>
<td>Readarr is a ebook collection manager for Usenet and BitTorrent users. </td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/sabnzbd.svg"></td>
<td><a href="https://sabnzbd.com">Sabnzbd</a></td>
<td>Free and easy binary newsreader</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/sonarr.svg"></td>
<td><a href="https://sonarr.tv">Sonarr</a></td>
<td>Sonarr is a PVR for Usenet and BitTorrent users.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/speedtest-tracker-logo.png"></td>
<td><a href="https://sonarr.tv">Speedtest-Tracker</a></td>
<td>Speedtest-tracker is a self-hosted internet performance tracking application that runs speedtest checks against Ookla's Speedtest service.</td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/stirling-pdf.svg"></td>
<td><a href="https://github.com/Stirling-Tools/Stirling-PDF">Stirling-PDF</a></td>
<td>This is a robust, locally hosted web-based PDF manipulation tool using Docker. </td>
</tr>
<tr>
<td><img vertical-align=baseline width="32" src="https://raw.githubusercontent.com/walkxcode/dashboard-icons/dd34fba44b97d3d5753dda032487890cb6fa5879/svg/vaultwarden.svg"></td>
<td><a href="https://github.com/dani-garcia/vaultwarden">Vaultwarden</a></td>
<td>Self-Hosted implementation of the Bitwarden server API written in Rust and compatible with upstream Bitwarden clients</td>
</tr>
</div> -->

6
ansible.cfg Normal file
View File

@ -0,0 +1,6 @@
[defaults]
inventory=hosts
deprecation_warnings=False
host_key_checking=False
interpreter_python=auto_silent

View File

@ -0,0 +1,78 @@
---
- hosts: proxmox
become: yes
tasks:
- name: Write notify script
ansible.builtin.template:
src: scripts/notify.sh.j2
dest: /tmp/notify.sh
- name: Delete existing template
community.general.proxmox_kvm:
api_host: "{{ api_host }}"
api_user: "{{ api_user }}"
api_password: "{{ api_password }}"
node: "{{ node_target }}"
name: "debian-12-generic-amd64"
state: absent
- name: Download cloud-init image
register: image
ansible.builtin.get_url:
url: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
dest: /tmp
mode: '0644'
force: true
- name: Install Tools
ansible.builtin.apt:
name:
- libguestfs-tools
- python3
- python3-pip
- python3-proxmoxer
update_cache: true
install_recommends: false
state: present
- name: Install Tools to cloud-init image
ansible.builtin.shell: |
virt-copy-in -a {{ image.dest }} /tmp/notify.sh /usr/local/bin
virt-customize -a {{ image.dest }} --run-command 'chmod +x /usr/local/bin/notify.sh'
virt-customize -a {{ image.dest }} --run-command 'sed -i "s|primary.*|primary: https://deb.debian.org/debian|g" /etc/cloud/cloud.cfg'
virt-customize -a {{ image.dest }} --run-command 'apt update'
virt-customize -a {{ image.dest }} --install qemu-guest-agent
- name: Create new VM template from cloud-init image
community.general.proxmox_kvm:
api_host: "{{ api_host }}"
api_user: "{{ api_user }}"
# api_password: "{{ api_password }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
api_port: "8006"
node: "{{ node_target }}"
name: "debian-12-generic-amd64"
agent: "enabled=1"
bios: ovmf
boot: 'order=scsi0'
cores: 4
sockets: 1
machine: q35
memory: 4096
ostype: "l26"
vga: std
scsihw: 'virtio-scsi-single'
net:
net0: 'virtio,bridge=vmbr0,firewall=1,tag=10'
ipconfig:
ipconfig0: 'ip=dhcp'
template: true
timeout: 600
vmid: 10000
- name: Import HDD to Template
command:
cmd: "qm set 10000 --scsi0 {{ storage_target }}:0,iothread=1,discard=on,import-from=/tmp/debian-12-generic-amd64.qcow2,format=raw"

10
frigate.yml Normal file
View File

@ -0,0 +1,10 @@
---
- hosts: frigate
become: yes
pre_tasks:
- name: Base Install
include_tasks: tasks/base.yml
roles:
- role: docker
tags: docker_install
tags: frigate_install

124
group_vars/all.yml Normal file
View File

@ -0,0 +1,124 @@
$ANSIBLE_VAULT;1.1;AES256
38386463636233373264323131333862626466386564393661613466323530633631613133656138
3135346230633433346361376665316331666231386339610a393037323931653836626262626263
32386638393261393037663262626266306565626363663263666231313939643964316264316233
3531653138643236660a656165383736373438646235633566373839393038303263343265306231
37393930643634656665336531616337353063343537396266646530613162356264343730366161
65643264343462396634363739656264643330393832383233313031363937653565663831323134
32356565646433386263643866633261383864626231316134376331646339396134616136623934
66363739303661316338323237656463616331333233303331636662663439333533313063663738
66666162343131313631373765303732323461643539356135386466613164393463623230633938
62643134393033653634376333666230613636666239386439343562383034663561326438356434
31303762643863353531363937343237663964363830316539613739396163393163326538303332
62383436303537363765633465383661663433643466646131303464306130393237353665666466
65613530383233353561656235303531343065613364363931633962373233666135646433396338
38313738376431616161653961646265386166643965343364393263353837373536366461633766
65306463626435613431363565303966396362393366373361653138646266346433356363333035
64393664366232623231386237626131333165303132313935613564333038323662373238633364
30383030323236313333616266643433616232383636633664363064383833633165656136306464
34313461626531333530396536393937613363323061393436353161393034613762326264613331
63626462643337353430623766333232393162346632343462303734623461623033616636313333
66346135366530343134656361653035373832323835336637663535303337393662626134373762
62656561343366313763366335646266323164366665633631376230386634336362316362336462
65303536313234636661626437633265666562656330623766353731393062303236376530613263
36383434623030363537356430373636623365333230656637373536323866343833353831653163
30666530333935396261373630396331303736626433663739373437353036346561333238386665
32383531633331376230366632336663376438353231366639643765383337646630306531313064
66663566303362353264306337303638623335366339303365336234383464396264646563636536
33383832353739393564613236353030396533666338363231623132303436663365373865326136
63663631656665343632396465306234383234303732623166633031633239326131363737306361
36323066623839643339313863363534313231386563393364313835633635636233663536326333
35346461626266376637313334633039383662626161623462656535393136386363326663373463
66353834613939643862386565366136356237313231656437363266303231376336353532333438
63346165363031383136636238376635613939636165303366303266616165393863323430396362
38303833616462643339316439366539373066643937313134663838363131383533356466656232
61316264316564316330326265383766643037666138393565633133373437653934653032386136
39643134636431613533633139396338623631623536333930646634366636656662383133383236
31653266336462623565343266663134323939323637663630653164326531303934646131313932
35643330353033613731366164323534386633623565633564376436343532396530636165616438
31383130653230383730623939656437316161306235643132313633633162626561343339303761
32343637366362346235383765366633333337366232386661363662643633613830366661393832
38313565616433633039636665383539333633383734313661313766353062626430363034333862
34336332306335646362333766346135383738333065633934396134373463333162666362653630
30633365346165383361646633353231343532343532353536383464636566643665346236363632
62333766343138393763333539633532623330623136613738626136633162366534613932643463
62613131376263333063376638323737666564653664306632366331366332663566666133613534
61393435333332333961376534363131633461373331323634333833306436663938386166393635
38373136393737333736373062363837363533323031356665353766383164383036346530313831
36393033323331353836623362386630643737343536376662643931393863653865613139353138
38633064343837313564343834613132306239666630636336626234363964653939303366363566
39666465396465356261346234346435356162366564643436313033316338376431303330313539
61613538326336386230616339363462353138666362306565653766323639333638343863326636
32363534333131356535643063316233376336636633643630363761396464646438613239386563
37356333303133666439653632653533636336306266376535356330353337343332313637616336
62396131633162356135356439363534353032373765373635366533393061646331386633633239
37346566353736653830633238623530393537373164323861343961366263303764643937316234
38326361343163313135396461643037323962386262636566313761353033323263666631393830
62326362333264323666616638313135636233646466366433306533393031353831366266393130
30653630626239343330633736303831353336356636643938306239363533393066353034316338
37336332386565646364336331316632393864623066646231346135303163623833636632376338
30363234313863396663633237613165373137343536623831366261393264326133356461643239
35633937363761356564373230646365666666346630663935636262313932343534343963623635
34326365646565616634386137323933653931373061303465663939373831366336653830653566
36656631366434633065613430366236373165366365346664303266326136393438306563353265
33323732653330373764363664363363363662626434626537386337383531303566663836356464
34363635636161376530383930323361653063313338666162643234316363373835643633353738
37663762326665336339373665626534303436626639313636636333383666613966343563613861
36343961353339363137363539653435373132663263303533343935336435353161313036633364
38326265313163623864666563373632303461393430613639616634613632303935393438333663
61666166613738633163646130386364393137356436376666646162653937663137333764353032
37353238613732623361613965316231623631623536623261643839323431396130363063316165
38656635623762336465393764306261303666366538633565306637376664643963343239356466
35656337643361326262643262326136306666303138663533373966363739663131653463363935
33326438393464643436326263663066623233386132636136636636646133303565326231306237
34383235356238326561396130306362303263376466393462663938643362353165386435666430
62656234323537323534356561646662306630383330386631323334373934393864666664306566
39303661656231373032643239303866633434626131366164316439656466613830626262663538
36373437646464323265643365393165396230316636343466623962663038356163373433313335
31663566626136313436643237316631636133353635613862333632613537313531623036623961
66313131653731386333383962346634346138663666393138323661306239643736383533376432
65653663303539326566646637333235653030356364623565633964303866313364663539303935
34373536663935623638613930366533316334303566366265386266333466623331326635346330
62323537666361626166323630303961363763386164613866613262336366633235323231626638
30663038356535666638303134656634613134373837323736363430316137613335656531643062
36356562383361393061663466323732383965313733633034346162653966313735393563656536
32666361366430323239613437313833373330333336373636613463613566363337393161376535
39336538323635656663613133356535373562383933616666666338373532346238353163616535
33393461393365313764623332343332326535333533343934346138303132656234643731373238
66633034643965633834333966323462323433613165303930343834663532626531343431396430
33383732623165393032363437646430303062393032353632306439333261633963653638666232
36613433303432623164646637316131333364323830323334633538333166306537343936393961
61353831396338383436646636616363336564396336653634393666316566326165643562386534
30383462323863336630643261613561663066343665313161643161333339623739323966383663
65366562643363653534666666666234323964613732656334353534613966386233643335313736
32303632336635656239326562386234383136346163396261653363316136343034386262333838
62663966643530393964306437313534336666363765333431303239666164616665633332306466
35356432393430663638376334663235663337393637343437376261653438663365653730343366
38636538613731383833336231336432353561366265323933313239613836656437653935373663
39303535613365343834373934343066383233326565623438373161626433323264353664316464
61353265333636653039643934386361643931383033373636303138303635303361383538353965
61613639616136376633303634643135613134373763323635386230393339633133373332636161
66616338343737613333656234363663636132326665333734303036643966383239303563636563
64366437656265656466376465613233653838343038663862643330653430613237656435383835
37663866626663303032656163663635373037323839623439323264303333386338653930343666
61306630653461346632313265313964393932376539663233333336313232363838343839643239
61383062306333376330393337356364343131383530653461383737366431646236366538376632
61636638323166303666633766623836626431333636626462653633343538303135323532343636
62646333623164343665363039373139643466363366653935643365386131333632653031306165
62663864383739303161356134643664396363303964663161383033393333303733626366316662
39646466313534386637636562313163393865366631613838353637653533313232313666313838
31613166653262386633393663366639336232383166633033303435643262656131343338643832
66626533306430623733386233633561306536386262623030306630363362646338616634396339
62363736646234383935383930343464643864393162656663386437323636613033643439613333
34633266363264636466353135356537653931383131653863386137643032646664643133656536
34343864643366376663616437373363636233343439353264656638326338333262386534346136
35656130643533343736623564386537363737343761303739646361633165643963393166336265
38336530333933653462393263316164383162373065663937363736623430373863303330323261
34656534363235353032366237646336373039613836626130633738313664663162393031386561
39373564343533373263306261653537663439326462393735343964323565343031646163333939
62623834623939313438353939653138626165353434386638613439363739363465613037616636
37333732333634333934633037613038323934636434303731363535663732663361613261663734
35373061356665663936333438336132643930323463373635633137663132333362306136303830
34613962356439303664323734643265313131643135366531643235633037646337313537323033
31313837376134363664343766316436346162363264383165383561656362316633383136316533
653961363033343965336230373962656537

View File

@ -0,0 +1,82 @@
---
ansible_user: administrator
data_folder: "/data"
install_packages: # Add addition packages here
- rsyslog
- htop
- vim-nox
- git
- zsh
- curl
- wget
- apt-transport-https
- ca-certificates
- gnupg2
- python3
- python3-pip
- nfs-common
- cron
- jq
- sudo
- logwatch
- sendemail
- libio-socket-ssl-perl
- libnet-ssleay-perl
- iptables-persistent
- rclone
- parted
- open-iscsi
MYSQL_ROOT_PASSWORD: MYSQLPASSWORD
MYSQL_HOST: MYSQLHOSTNAME
MAIL_HOST: SMTPHOST
MAIL_PORT: 25
MAIL_FROM: emailfrom@email.com
MAIL_FROM_NAME: EMAIL NAME
MAIL_ADMIN: emailadmin@email.com
#Postgres
POSTGRES_PASSWORD: POSTGRESADMIN
# Proxmox API variables
api_host: "{{ ansible_host }}"
api_user: root@pam
api_password: APIPASSWORD
api_token_id: APIID
api_token_secret: xxxxxxx
# Proxmox node target
node_target: pve
# VM storage target
storage_target: local-zfs
#Gitea
gitea_db_root_password: "GITEA_ROOT_PASSWORD"
gitea_db_user: "GITEA_DBUSER
gitea_db_password: "GITEA_DBPASS"
OG_GITEA_KEY: xxxxxxx
OG_GITEA_SECRET: xxxxxxx
# Invoice Ninja Variables
IN_APP_KEY: base64:xxxxxx
IN_APP_URL: https://invoice.ninja.com
IN_DB_DATABASE: invoiceninja
IN_DB_USERNAME: invoiceninja
IN_DB_PASSWORD: invoiceninja
#Speedtest-Tracker
ST_DATABASE: speedtest_tracker
ST_DB_USERNAME: speedtest_dbuser
ST_DB_PASSWORD: speedtest_dbpass
GITEA_RUNNER_TOKEN: gitea_runner_token
VAULTWARDEN_BACKUP_ZIP_PASSWORD: vaultwarden_password
TEAMS: webhook_teams_url

18
hosts Normal file
View File

@ -0,0 +1,18 @@
[proxmox]
pve2.comprofix.xyz ansible_user=root
[cloud]
vps02.comprofix.com
[docker]
docker.comprofix.xyz
[omada]
omada-lxc.comprofix.xyz ansible_user=root
[vps]
vps01.comprofix.com
[jellyfin]
jellyfin.comprofix.xyz

191
main.yml Normal file
View File

@ -0,0 +1,191 @@
---
- hosts: all
name: Configure all servers
tasks:
- name: Gather facts if run with tags
ansible.builtin.setup:
when: (ansible_run_tags | length) > 0
tags: always
- hosts: jellyfin
become: yes
tasks:
- include_tasks: tasks/base.yml
tags: base_install
- hosts: cloud
become: yes
roles:
- role: oefenweb.fail2ban
vars:
fail2ban_services:
- name: sshd
port: 22
maxretry: 3
bantime: -1
tags: fail2ban
- role: docker
tags: docker_install
- name: traefik
vars:
traefik_host: traefik01.comprofix.com
tags: traefik_install
tasks:
- name: Deploy Vaultwarden
import_tasks: tasks/vaultwarden.yml
tags: vaultwarden_install
- name: Deploy gitea
import_tasks: tasks/gitea.yml
tags: gitea_install
- name: Gotify
import_tasks: tasks/gotify.yml
tags: gotify_install
tags: cloud_install
- hosts: docker
become: yes
pre_tasks:
- name: Connect iscsi
import_tasks: tasks/iscsi.yml
tags: iscsi_connect
roles:
- role: oefenweb.fail2ban
vars:
fail2ban_services:
- name: sshd
port: 22
maxretry: 3
bantime: -1
tags: fail2ban
- role: docker
tags: docker_install
- role: nfs
mounts:
- name: Data share
path: /mnt/nfs/data
src: truenas.comprofix.xyz:/mnt/datapool/data
tags: nfs_install
- role: traefik
vars:
traefik_host: traefik02.comprofix.xyz
tags: traefik_install
tasks:
- name: Deploy comprofix.com website
import_tasks: tasks/comprofix.com.yml
tags: comprofix_install
- name: Deploy iDrac Fan Controller
import_tasks: tasks/idrac.yml
tags: idrac_install
- name: Deploy MariaDB
import_tasks: tasks/mariadb.yml
tags: mariadb_install
- name: Deploy InvoiceNinja
import_tasks: tasks/invoiceninja.yml
tags: invoiceninja_install
- name: Deploy Homepage
import_tasks: tasks/homepage.yml
tags: homepage_install
# - name: Deploy osTicket
# import_tasks: tasks/osticket.yml
# tags: osticket_install
- name: Deploy speedtest-tracker
import_tasks: tasks/speedtest.yml
tags: speedtest_install
- name: Deploy dozzle
import_tasks: tasks/dozzle.yml
tags: dozzle_install
- name: Deploy jellyseerr
import_tasks: tasks/jellyseerr.yml
tags: jellyseerr_install
- name: Deploy lidarr
import_tasks: tasks/lidarr.yml
tags: lidarr_install
- name: Deploy prowlarr
import_tasks: tasks/prowlarr.yml
tags: prowlarr_install
- name: Deploy radarr
import_tasks: tasks/radarr.yml
tags: radarr_install
# - name: Deploy readarr
# import_tasks: tasks/readarr.yml
# tags: readarr_install
- name: Deploy sonarr
import_tasks: tasks/sonarr.yml
tags: sonarr_install
- name: Deploy sabnzbd
import_tasks: tasks/sabnzbd.yml
tags: sabnzbd_install
- name: Deploy mealie
import_tasks: tasks/mealie.yml
tags: mealie_install
- name: Deploy pyKMS
import_tasks: tasks/pykms.yml
tags: pykms_install
- name: Deploy mediawiki
import_tasks: tasks/mediawiki.yml
tags: mediawiki_install
- name: Deploy traggo
import_tasks: tasks/traggo.yml
tags: traggo_install
- name: Deploy gitea-runner-homelab
import_tasks: tasks/gitea-runner-homelab.yml
tags: gitea-runner-homelab_install
tags: dockerserver_install
- hosts: omada
become: yes
pre_tasks:
- name: Update packages
import_tasks: tasks/base.yml
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "/data"
roles:
- role: docker
tags: docker_install
- role: nfs
mounts:
- name: Data share
path: /data
src: truenas.comprofix.xyz:/mnt/datapool/docker
tags: nfs_install
tasks:
- name: Deploy Dozzle Agent
import_tasks: tasks/dozzle-agent.yml
tags: dozzle-agent_install
- name: Deploy Omada
import_tasks: tasks/omada.yml
tags: omada_install
tags: omada_lxc_install

18
renovate.json Normal file
View File

@ -0,0 +1,18 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>RenovateBot/renovate-config",
":semanticCommitTypeAll(chore)"
],
"ignoreDeps": ["postgres"],
"automerge": true,
"automergeType": "branch",
"automergeStrategy": "rebase",
"commitBodyTable": true,
"ignoreTests": true,
"major": {
"automerge": false,
"commitMessagePrefix": "chore(deps-major): ",
"labels": ["dependencies", "breaking"]
}
}

View File

@ -0,0 +1,2 @@
---
# defaults file for docker

View File

@ -0,0 +1,52 @@
galaxy_info:
author: Matthew McKinnon
description: Mounting NFS filesystem
company: support@comprofix.com
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -0,0 +1,49 @@
---
- name: Add Docker apt key.
ansible.builtin.get_url:
url: "{{ docker_apt_gpg_key }}"
dest: /etc/apt/trusted.gpg.d/docker.asc
mode: "0644"
force: false
checksum: "{{ docker_apt_gpg_key_checksum | default(omit) }}"
ignore_errors: true
- name: Add Docker repository.
apt_repository:
repo: "{{ docker_apt_repository }}"
state: present
filename: "{{ docker_apt_filename }}"
update_cache: true
- name: Install Docker packages.
package:
name: "{{ docker_packages }}"
state: "present"
- name: Install Docker Module for Python
pip:
name:
- PyYAML==5.3.1
- docker
- docker-compose
- pymysql
- passlib
state: "present"
- name: Ensure docker users are added to the docker group.
user:
name: "{{ item }}"
groups: docker
append: true
with_items: "{{ docker_users }}"
- name: Reset ssh connection to apply user changes.
meta: reset_connection
- name: Setup cron job for backup
cron:
name: Docker Prune
weekday: 0
minute: 0
hour: 5
job: "docker system prune -af && docker image prune -af && docker system prune -af --volumes"

View File

@ -0,0 +1,51 @@
$ANSIBLE_VAULT;1.1;AES256
32396236613762346266373632613335306233666563346466653731653034613637656335636463
3864336133316534333262373835643732303963353538320a343235363461613837383962303762
62373739653137326664306563646632663661323339626636333461303132366133393266313833
6137313537666138320a376334396531643233626265643538613133313866623236383338353035
62623166316366393837313166646539376362383363353862303439303230376163366335353237
66626130373762333536396265663262376335323162633961656139313435333765363163633161
65393532663339363738623232316135326338656330303764633530663661626163343533643430
63646337363636386337373435373939363434646161616638326665316636383362346232303763
39656636643261383137306339633433613534313362636537393433656230613333333463396437
32623630636464313665656562393766376330633038366534623634656535303237666332363638
36373566303432653664383230626436663362323336336233396363353430353535336464376137
33393762363330633963656161383535306365383062616466626266373637396338643930333931
66373739303232393233303131663031333639346236633030346337313938383739386561386263
36643831323930666665376237656163393532333438346332653562306532636530386365636331
38643637613261373030323963656266613661656663643330383333336336383433393633383335
65326130646536323861346437336362333630613034366639656536353430326366316530396436
34636235336433666261386163316330363337393963643761646261633932666134316331386463
63643463343162313162323537623764303564343438636133643162646530643435306262653838
30376539303130303536316136383761333836646231316563633564643635376230313333653739
38663032343736626461303835656662323064666139323935323534346362383636636237333937
34616663666364323734643530343936383030326539623065356561633563653764386134633562
37616463633931336233623335336331313463656132653331303530616332306332613936623130
63616264333531303762663665323636663466313933393064623534653561343561633632636565
39633435313963393034366336316665323339333962343666666533646632343666393332323635
65653062643332663362343666643433336562353639656366623961306132313734613838336237
36653962353839636662363335373238393433613037623364356637336562303765313466313166
34326365393433646166653461333138386166663537343566633565316163323866333932366432
34666532346164316232663964666132653232393264633066333734333238636135376263643937
66353665353564353938343934363337396165616462336439363338343065306533653334636566
35356231346431646237636662633030313135633663336163383965656136393238636334396137
65613833666662353339616434623735386638656331643831383134626163386636313633323333
34383862373634373732613333656437323436383962306163633833343430303336383433366336
63313138383237373330623536383438306330373164336637646165313562343935656566653531
30356365333863383165633634343230653735343164393030313339653563376435313832396266
65623237393066666163363530356163313861323366373233383531386533623965306237623137
33363239396634306466663535323736373333643266336164336230303836643939343335626339
35373166616136633666323034313364613334303462616564383861343738653964663332616536
32353135633331336239353834666237313939386334383261663532333139636363353436363864
33396336623566346532613738353332643965623335653162323534613330663964353833333937
30373761393834323964633039393339376538353261396331316336323333383064356363633264
62613432313436353163383837363935373164366236343936313366623936336439613364336639
63336536333732326236323761323033613965333763366237316431303363346263373131663338
65376535386239353362326630396232623533626266376233326330316466383564313935663134
65363839323134663537356663346437616662366463393036353736353664356538656163353562
65323162663934653462353136353065333666353564313066613466663734623066623439613964
36353035653163306661393335636430623233633962303033656539363265663135666663643164
37613334653964366433646366613861336335373137393065373739363863626334316631323332
66623465373730373231316265653330383061326231373931636132663233643735343564313636
36313330336461616134663336306566646639383435396236383162366266366662383635333832
3266363963363362343563653131373339666163663536653032

View File

@ -0,0 +1,21 @@
---
# vars file for docker
docker_edition: 'ce'
docker_packages:
- "docker-{{ docker_edition }}"
- "docker-{{ docker_edition }}-cli"
- "docker-{{ docker_edition }}-rootless-extras"
- "containerd.io"
- "docker"
- "docker-compose-plugin"
# Docker repo URL.
docker_url: https://download.docker.com/linux
docker_apt_repository: "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.asc] {{docker_url}}/{{ ansible_distribution | lower}} {{ansible_distribution_release}} stable"
docker_apt_ignore_key_error: true
docker_apt_gpg_key: "{{ docker_url }}/{{ ansible_distribution | lower }}/gpg"
docker_apt_gpg_key_checksum: "sha256:1500c1f56fa9e26b9b8f42452a553675796ade0807cdce11975eb98170b3a570"
docker_apt_filename: "docker"
# A list of users who will be added to the docker group.
docker_users: [administrator] # CHANGE_ME!!! - Add addition users.
# Docker daemon options as a dict
docker_daemon_options: {}

View File

@ -0,0 +1,8 @@
---
# defaults file for roles/nfs-mount
# List of NFS shares
nfs_share_mounts: []
# Default NFS4 mount options
nfs_mount_opts: "rw,sync,hard"

52
roles/nfs/meta/main.yml Normal file
View File

@ -0,0 +1,52 @@
galaxy_info:
author: Matthew McKinnon
description: Mounting NFS filesystem
company: support@comprofix.com
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

20
roles/nfs/tasks/main.yml Normal file
View File

@ -0,0 +1,20 @@
---
- name: Install NFS mount utility
ansible.builtin.apt:
update_cache: true
pkg: nfs-common
state: present
when: ansible_os_family == "Debian"
- name: Mount an NFS volume
ansible.posix.mount:
src: "{{ item.src }}"
path: "{{ item.path }}"
opts: "{{ item.opts | default(nfs_mount_opts) }}"
state: "{{ item.state | default( 'mounted' ) }}"
fstype: nfs
with_items: "{{ mounts }}"

View File

@ -0,0 +1,2 @@
---
# defaults file for common

View File

@ -0,0 +1,52 @@
galaxy_info:
author: Matthew McKinnon
description: Traefik Proxy
company: support@comprofix.com
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -0,0 +1,95 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/traefik"
- "{{ data_folder }}/traefik/data"
- "{{ data_folder }}/traefik/data/log"
- name: Create a network
docker_network:
name: proxy
register: network
- name: Copy Traefik config
template:
src: templates/traefik.yml.j2
dest: "{{ data_folder }}/traefik/data/traefik.yml"
mode: "0600"
- name: Copy Traefik config
template:
src: templates/config.yml.j2
dest: "{{ data_folder }}/traefik/data/config.yml"
mode: "0600"
when: traefik_host == "traefik02.comprofix.xyz"
- name: Check if {{ data_folder }}/traefik/data/acme.json exists
ansible.builtin.stat:
path: "{{ data_folder }}/traefik/data/acme.json"
register: file_status
- name: Creates {{ data_folder }}/traefik/data/acme.json if it doesn't exists
ansible.builtin.file:
path: "{{ data_folder }}/traefik/data/acme.json"
state: touch
owner: root
group: root
mode: "0600"
when: not file_status.stat.exists
- name: Check if traefik.json.log exists
ansible.builtin.stat:
path: "{{ data_folder }}/traefik/data/log/traefik.json.log"
register: file_status
- name: Creates traefik.json.log if it doesn't exists
ansible.builtin.file:
path: "{{ data_folder }}/traefik/data/log/traefik.json.log"
state: touch
owner: root
group: root
mode: "0600"
when: not file_status.stat.exists
- name: Create traefik Container
docker_container:
name: traefik
image: traefik:v3.5
restart_policy: unless-stopped
networks:
- name: "proxy"
ports:
- 80:80
- 443:443
env:
CF_API_EMAIL: "{{ CF_API_EMAIL }}"
CF_DNS_API_TOKEN: "{{CF_DNS_API_TOKEN}}"
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- "{{ data_folder }}/traefik/data/traefik.yml:/traefik.yml:ro"
- "{{ data_folder }}/traefik/data/acme.json:/acme.json"
- "{{ data_folder }}/traefik/data/log:/var/log/traefik"
- "{{ data_folder }}/traefik/data/config.yml:/config.yml:ro"
labels:
traefik.enable: "true"
traefik.http.routers.traefik.entrypoints: "http"
traefik.http.routers.traefik.rule: "Host(`{{traefik_host}}`)"
traefik.http.middlewares.traefik-auth.basicauth.users: "{{ traefik_api_user }}:{{ traefik_api_password | password_hash('blowfish','1234567890123456789012') }}"
traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme: "https"
traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto: "https"
traefik.http.routers.traefik.middlewares: "traefik-https-redirect"
traefik.http.routers.traefik-secure.entrypoints: "https"
traefik.http.routers.traefik-secure.rule: "Host(`{{traefik_host}}`)"
traefik.http.routers.traefik-secure.middlewares: "traefik-auth"
traefik.http.routers.traefik-secure.tls: "true"
traefik.http.routers.traefik-secure.tls.certresolver: "cloudflare"
traefik.http.routers.traefik-secure.tls.domains[0].main: "comprofix.com"
traefik.http.routers.traefik-secure.tls.domains[0].sans: "*.comprofix.com"
traefik.http.routers.traefik-secure.tls.domains[1].main: "comprofix.xyz"
traefik.http.routers.traefik-secure.tls.domains[1].sans: "*.comprofix.xyz"
traefik.http.routers.traefik-secure.service: "api@internal"

View File

@ -0,0 +1,51 @@
---
http:
routers:
oc-router:
entryPoints:
- "https"
service: oc-service
rule: "Host(`omada.comprofix.xyz`)" # change it to actual address
tls: {}
middlewares:
- default-headers
- https-redirect
services:
oc-service:
loadBalancer:
servers:
- url: https://omada-lxc.comprofix.xyz:8043 # change it to actual ip of the controller
middlewares:
https-redirect:
redirectScheme:
scheme: https
permanent: true
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https
default-whitelist:
IPAllowList:
sourceRange:
- "10.0.0.0/8"
- "192.168.0.0/16"
- "172.16.0.0/12"
- "100.64.0.0/10"
secured:
chain:
middlewares:
- default-headers

View File

@ -0,0 +1,42 @@
api:
dashboard: true
debug: true
entryPoints:
http:
address: ":80"
http:
redirections:
entryPoint:
to: https
scheme: https
https:
address: ":443"
serversTransport:
insecureSkipVerify: true
log:
level: DEBUG
filePath: /var/log/traefik/traefik.json.log
format: json
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /config.yml
certificatesResolvers:
cloudflare:
acme:
email: {{ CF_API_EMAIL }}
storage: acme.json
dnsChallenge:
provider: cloudflare
#disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers.
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"

View File

@ -0,0 +1,14 @@
$ANSIBLE_VAULT;1.1;AES256
61386364396339353533653064303734346336653531366139333738353461613037396365663265
3731366362343630646162353636316565356563323135350a636335653931376137666139653739
36306631376639336561643064386430633636343362646233623263356635636134303931356364
6466383864366236320a376134623032383566643166626231323432373562373864333864653032
63316630303362616337383833623733316131323764626532366338333566643834326236383232
31646330363965386233383739336238336538666165383166393834643134663937393535333361
34373236386339366436643733393030313331303537636233383864623435386166366537386633
37653030313066393136616661356564373932643033663735656238313132396664623438343833
65356539386435656433393933653939313635376639366163353336373661396230336533626238
39643438313763343635393165376263666633363963623962643263323531616466656532646432
62383430346666343465613436346637333336663562316165303864376464363566343165633665
66353134313866393439323564353834346436326132643439383134623864333765616162353436
6338

View File

@ -0,0 +1,5 @@
---
CF_API_EMAIL: CF_EMAIL
CF_DNS_API_TOKEN: "CF_API_TOKEN"
traefik_api_user: "admin"
traefik_api_password: "password"

2
scripts/notify.sh.j2 Normal file
View File

@ -0,0 +1,2 @@
#!/bin/bash
curl -H "Content-Type: application/json" -d '{"text": "Cloud-init provisioning has been completed on '"$(hostname)"'!"}' "{{ TEAMS }}"

196
scripts/rclone.conf Normal file
View File

@ -0,0 +1,196 @@
$ANSIBLE_VAULT;1.1;AES256
63623637376239613064343634336463616165333831353331633738356662303534303133363338
6334613838656263393764666534333434646232616662300a306638646461363133613365323635
36383130373964333937643532356538303936666434653566616232363934336531353732653766
6166333932323764350a643331313162376239643364633337376366363663306539363962613431
64336561626166613061353962323461646664343637386664363530626666333930353365383334
36313939626436663436623235656435666136653834336131303434663739626135643430613836
63386138363963646433643966613331633563633834366364353337323762663232663865363666
32336432323962366237323833656535386338646265336562396437663539346430636635623037
38613330666362396562346137316132363764376265636337646430303437663233663464353465
34663530323561626237333030376466636436396331643136343235316161343934646366353335
63333762343033353066646236633437396365363464366231333462653239666237343564313934
38373162616635633730316334613239383938626364633732353031616261363066653266346339
39383537396635626639636433396263613231303030306136653262326538636232663131633531
36336432666461356537353438386464396661613664303331313466663836353939383630396663
63316363623235333934616635303461376138646530393936353934316431386234383364353166
38346162633133623066343532316331313661336365323664353066663864353263653532623238
66326535306537363831613538363761623366626436386261343365643239323863303263363334
63626164656239643038663765613339633064323137303834333035343935383737646430316631
35386534343563393636326164653062343139353265663032393830333663323831616562393665
61313665633731313737626362353032316432656665623832333461353464313735623738386564
38343464333264626161363839333534353131366130366361656363383465656233626334323830
63306431353365356438393037666132366637383530653636363065323161623831346434343964
34303730646531386265326430313733333233636337386639613466626335326465396536653337
32613035646639666635366662653938326632373264343731396633383134636534343064646335
39326263393131323665306636633435356234393864393835323662643636346262353961393162
37663962613430626135653666306133613166393736633530313139613161333438383662353136
32303033636634306562633739393831336333383931376536326137353935383537323464613362
61326338643435633530333163613235386434343637346636366262336539333762643232643362
64643032336264613664643433356238323836393236306136633038323436656335313733356166
37393965643638626236626566363463633837343561353433373036636430643436613862346462
38386432316631623432386661353765343338323164303535613864643264343363303365316465
31626334646562323139623630363439613436373537626362643530613036306435383039363836
30353932306332613034666439356232366430626230336566666162393437323864656663346639
31633331386432323830343062383237356463363637336436306432396539306166613138333162
61346634373336383732636638376330383131333961656534636663626335366264393733373234
32623430336233653236633536626563356239636161373733633337643239613938336566336463
34343236323664363561306337646133616431303764346437313938613430386131323335346331
62383839633162366366613236303639643163303134383662313730666365376338376436656462
36643161363738303531353364393764633139336239336632346164373766666336353339633737
33393364306466656164616531663662613632323865623966393564613737643765343530346131
63653233313335333335636161326265323263306636323761396131666339323534343133333966
63343761343135616363363638366430313430666539303135623065313131666533386364623861
36356233343566303161616337343536663236643634626139643563663231353131316561633232
62666238653130633536626432313935353438613666353735613262336134346630343839306166
65653732613666656636343737336331666434363065343930656463613837323765303737643764
64616230373964363565306136623135663730323164623439393437366233643038303363663731
63333666663831653763613632666437393438386534363533356138383231303439306235636537
37636561613463333930323565303935313839653364653533636562653364666331326663333362
33393839376262346431326236633839323234363861663963616531366538333338356339323330
32643633656339333635363964313564343432383364323833646632343133623063383339626131
38633638656232306161383961383665316638666166663038353266303233396234303263333162
37306338363434613738643361663861613963643537353831316639323831346231633736356662
66623637393165623566636437636438626634323862316662386465653437666336376632373735
30343634393133653536616366383762323933316531343864363439616139663539663736336631
66376430383436313838656337653465353736396430643334356339343533373634313136336337
37633938353336336231383531376333653838613233363265646337353936363135313030303164
31376632663165383863373332313561633836363464626633626661363936643432333365666131
31643033636434356335363439633263343831326434316435616530666563613638326231323639
37333466613934636332303738313362623364353133383037383366356333663935396566633431
30373532326236626238396666643235303739383961663466643765373932653462356636653863
65396130343236653334323031626536663965313065336338643166623434336130623434383665
36613533316438366330393364373235326266616236363662396137666338613764633361656566
38633235616139363765666632363934303234633062363130663462316462666439383736353232
30383932396462306430663839326433303834373965663466643264663436633433656663613434
66356563373662626634333265333033303930653737303434303363346331303333373933336435
39633730613738373361383732373337666262363965656232323866316661313134396266666530
31346162373463383666656535386430373465646266623431653161616533393133613131313533
39383739613939393639616435653261323230663532363234613638303831313833326233366131
39363165643531666337393661366563363131623235376665613633656162343131333637333663
30376331666661316130616163393435343535356465326133326335373333643738306331323430
33646462613065393334613833346565613964616665303933326139306230613465326433396439
64643031626663383166326630303038656530633064376339373864303438366335393064316537
63666532343164363166353036663336613433366636373437643830643732396462633635633764
63343433313062353666383135633330353431376532393430316561633334653966306439613663
31333934366161343361393438383164353965333565386262333737363535633663646665343032
30396434636435353766343065613635613364396638343966393831646236313131633131363839
38376539333131333763376161346634666137326464396432636562333538373962386239303761
37633662376633303366613962333830393430623563303734363965663865303532376134383130
34373335363664313536306465346534393834666264623261616465623962626262636332306636
39616161656334303438666432386366646336633832626237333231333833613738346631643961
39616137353738363461396635636336363335353838613938303465386131633038306130643533
38633839653937353663636630653966653432656462346237313063613338353631666439613861
30633030323165376435393965336139333133653939366533316636323032323764333834623964
37343561396131343763313334626137386534353639383935353934333738653762383736313235
33353233373133353631303238363934366339393838636266396432653361616162373963343065
36373862616164383037343538663532313363613164383264643763376564396264323134346337
37366261393436616566396431323265626334376662663964323963363262353332613662393737
65313066386237353764363435613866613435323236643436333561346536333964666562643732
39333739633232353630643333623238383461313530623435333263373562333564323464373430
66653031333763633662646631633561656262353462386538343462633533353662633065346461
37643437333265333337646631653765343036313638393638373035323534383036323039376338
31613361306332376639636562343261343865653765633130313464666230306238353135623062
31383638393064333763343139666663353531623533633033373039626564346436373439666331
38663961663032653238633036383438393465353563363439353437366266353139383766656631
65363032346433393166306131333131356339633561666134653432306661313663346566653238
38316231363933613561313936613163356337646337653033396562613564666133613336623533
63616235346262663666373239373832613835323238353039633737363030323166386230303734
36313637383430656433613236363462343466666361303933646665346366663235306333656366
34316663343962363561636166313265396363636233303830646633626663353933663266366363
30393131313361353637663864636466323436663330343534353535643430303162633730383139
37343633323965333463613434326232346639383035326234383234623238333635633036353462
38303765643539336262656338633033366534373961373835643835633461646165656663613936
32373532663861646537323638613832333631323239343865396434636132656332366335323337
31663962366162363433353832386164333337386631653538656639383936383337623764636563
30383738346236623565333466323566306138373565376334396464343265383034326436323836
39323237396339653261626638373538383464313536343365333934306262633238383939626265
66626661336462366236346632316662386336353436623562356639376230386530353438616430
63316361626265356436343031383365323839626538393735393030666338343132663565376231
39623634623833333432383739346339306434383764633635613461383262316135663461393737
38346261323831643862383139333662666339663039386534386365656632366562633139613366
33326230353161313064633539333131646436376139623966326236343937616630626335656663
66303537633965376366303463333765613131663636373137613361363066326230643837636236
37316435393538353166313933313665363936303066363933336436386139303465613665386165
39366637313436366432623863306136363633303233313165646431656136613835623236623361
32333131666630336330393737396135666163346131326232306362316166343633326664623030
62313435623162356365623664643962343334313836333537663031343736636164383836343731
62316636643361666136363364643038353330373334353663646139623362636163366666343434
66383366643261333539333862336466376639303139666134393834336639386637376461653331
35343932343835323035623034323633383663616530386139616566666635343236363739613237
38653062383837653630323563343230303862623064306361633532356532343866373662343138
33636365613331396433663364616331313663333132373934663130336335613639313762373564
63363131346365613333633736323432386339373965623964626336626637316137346535326232
36363431313166626164363663303932366134313933303135613231366330663330623831633539
39623034343134303135643538396464316163393264353533623365613130393662626530636261
35656663373030663331316133646561363565356438666533316563393433623661616630336465
61383464366165343963623734346563616539356635356161376165356235306634636138633236
66643535373931363732653764383939663762373063663839363166333761353633316232393338
33343135623365393230303266633031343065346334363534383135343865346130653236333432
64383466323365313731326563386131616338663061316330323964643166636464626537643736
35656561353961613931613036653065363861353836386231646136643639373738643539353330
32373737323332636563356131346233303037336130336137383264343438373264363161643037
30353765393661343333366432353964383636373739346439333532336364316135343233336362
36383637313733653263386330663363376135633437356566343035356239306666613035666662
64613139303566363864303036613662636266333338386430366639356338313236633531623865
63636233666338373630333733396365643337373662656131313830616435333562643139313333
31316439663633363238316231633961613137643337306135326437643534376166666364333961
38353562663062373461393736623634616663373365643630366462656639633637363436643163
64306631653835616664303031383365643632316566383832323030643831303563336163636264
30653237376534323339613030366439373930316466326261356136383131323335306334613365
66623339643234656337643837623137326537306566383537366430333139313761663361393134
61313663313139356537396439316337386132343930626161366464373162306162343863313261
32656630636461633436306162396534313131626361363266393437353535306162326434653733
35623561616132343338363534383335393939333065633462643561366333333034636363386533
39333936663939383031356534363636383332613162323133396166303665653935376630636236
31633361363236353663303338363033633133613334616264663431633335353936373963383838
32343965396438663739646166366262323133333664386563643637373761323930383633333039
64616635633937346165613962643965633033663134306261383737313466313065323666366138
32633731363662306161353636333131623662336434366432303232306164323866646639616534
31613061656137643137343261366462386533636166313965656531633237386537636166316138
33353164313366343132636263626134656265343733646465383664653266623166616333666635
38343165396233343633393963616138333138303938643732393530343032663765663036643762
35373961303537613331323538323431343934386134663466336438323462343766653936353037
62303537373038323836636464643361346337393330316532353737333732366261303761373531
32323736336536356234643266383962623832656265303035376532663762306435323262363238
31353661663563653932336532646632623832343832373263376434313066303039646234373237
32626664343334613337386539343433336335303836616162616130613635306234343536396634
61633836373937656435383639373130376637393239333137396535306263303030343565306463
36653838323631356166363234353963353234363538353763326631366438343833626564616439
32386534653133383634623330653936363364366633646566623038386562626365386163363630
62366137633739373436633963623138366361343333666564663162346562383463666237353862
37383033636563393039396535383535343364353338353731303539393638633462353230643034
62656134346566366565646666666364646633626163623938653538353165396134636534353864
31643633653463313461613935663964326135376166633166313762363831636532363333353437
30333238323066316535303233646666613034333035383830383636633165333766663364383632
62303030643239383931333533636534356635363538303236396666373731336335313762626337
66393636353038333735326366613265653539613436303864353037316366613938356132356366
36376666343532353161323965653336313161373764623339626330656139623764633836343639
61366531353433646262303662303937306562353836626163353465393835633762353039326631
62393063343865616165393039323533653165376132303564316330363434643139393337353133
33353764333338656264643233316164613038346161383364383939626536353030346534356433
65366535343565393366626531623665353130323563646166366433633030653035356334353966
33346137633237363839383233313037663438663535623561653064356538623634336135313263
33623739333339616261646664646634306534323534386665303166386431336164666663646236
36396438653535393665666664653534353562303538656462346262316338343035303930633837
38656335663365636237356632623631623161653839373933366539353733323464386330386134
32343862623133633865313136663765366364646535326339633766333930323564386339383739
66353037343837303164303430316235303131306166366136313433363137346563306133616461
36653239323333356164636665353236353835636532623562326131323439323534316366616337
35366335323164356439646336663938343366316538383838323764663163663935613364663631
32653134613636393131623165353431376265313634396239306530393665303033393439636663
37386363643737386661643638303038363662623266353963613130663735356631366530643663
38613734373864353231363363396561303238353433373065356532303732353734613335616264
66613565633535323564616261353363363839326331623365383262663263366664336361643561
37393836323062313363386562633237353266336261383865333335356434336634303231306134
33373165663638623464633464623531383664333237323164633231373163336633613232323937
65616636393663623039623536663736636664333164363036356230653963623937356238613134
39393536613834386438343163316161613739303730633765643938313662356333613031613365
63613239303065633030666430396463383032333665383434646562306139356135616432666136
38613561363662303735323031626433636632616635613664386230303537396132633337366364
39303461373636623465383863396132393565636566313730393238306130333630343365656632
66316532643762663563376331666437666538343363356562343634333861353530613733313035
64366437393036363165316438383565633864383132343035333837663235356232646130363137
33386436393533626133626636393665666233366663313163323563653131363637323739323664
35653634616562376132363761373464323466393230616232343936666437316535303436323633
333637333634306336326535393964323138

224
tasks/base.yml Normal file
View File

@ -0,0 +1,224 @@
---
- name: Ensure facts are gathered
setup:
- name: Ensure debian-archive-keyring is installed
apt:
name: debian-archive-keyring
state: present
update_cache: yes
become: yes
- name: Update cache
apt:
force_apt_get: yes
update_cache: yes
when: ansible_distribution in ['Debian', 'Ubuntu']
- name: Update all packages to their latest version
apt:
name: "*"
force_apt_get: yes
state: latest
when: ansible_distribution in ['Debian', 'Ubuntu']
register: upgrade_result
- name: Upgrade all packages on servers
apt:
upgrade: dist
force_apt_get: yes
when: ansible_distribution in ['Debian', 'Ubuntu']
register: dist_upgrade_result
- name: Install required packages
package:
name: "{{ install_packages }}"
state: present
become: yes
register: install_result
when: ansible_distribution in ['Debian', 'Ubuntu']
- name: Reboot if required after updates
reboot:
reboot_timeout: 600
test_command: whoami
when:
- upgrade_result.changed or dist_upgrade_result.changed or install_result.changed
- ansible_virtualization_type != "lxc"
become: yes
- name: Gather facts after reboot
setup:
# --- Upgrade Bookworm to Trixie ---
- name: Upgrade Bookworm -> Trixie
block:
- name: Replace sources.list entries for Trixie
lineinfile:
path: /etc/apt/sources.list
regexp: "^deb "
line: "deb https://deb.debian.org/debian trixie main"
become: yes
- name: Update cache for Trixie
apt:
update_cache: yes
force_apt_get: yes
- name: Dist-upgrade to Trixie
apt:
upgrade: dist
force_apt_get: yes
register: trixie_upgrade
- name: Reboot to apply Trixie
reboot:
reboot_timeout: 600
test_command: whoami
when:
- trixie_upgrade.changed
- ansible_virtualization_type != "lxc"
when: ansible_distribution_release == "bookworm"
become: yes
# --- Move to Trixie sources.list.d layout ---
- name: Remove old sources.list.d
file:
path: /etc/apt/sources.list.d
state: absent
become: yes
- name: Remove old sources.list
file:
path: /etc/apt/sources.list
state: absent
become: yes
- name: Ensure sources.list.d directory exists
file:
path: /etc/apt/sources.list.d
state: directory
mode: 0755
become: yes
- name: Create Trixie sources.list.d
copy:
dest: /etc/apt/sources.list.d/debian.sources
content: |
Types: deb deb-src
URIs: https://deb.debian.org/debian
Suites: trixie trixie-updates trixie-backports
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb deb-src
URIs: https://deb.debian.org/debian-security
Suites: trixie-security
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
owner: root
group: root
mode: 0644
become: yes
- name: Update APT cache after moving to sources.list.d layout
apt:
update_cache: yes
force_apt_get: yes
become: yes
- name: Find all EXTERNALLY-MANAGED files under /usr/lib/python*
find:
paths: /usr/lib
patterns: "EXTERNALLY-MANAGED"
file_type: file
recurse: yes
register: externally_managed_files
become: yes
- name: Delete EXTERNALLY-MANAGED files
file:
path: "{{ item.path }}"
state: absent
loop: "{{ externally_managed_files.files }}"
when: externally_managed_files.matched > 0
become: yes
# - name: Download Oh My Zsh installation script
# get_url:
# url: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
# dest: /tmp/install_ohmyzsh.sh
# - name: Run Oh My Zsh installation script
# become: no
# command: sh /tmp/install_ohmyzsh.sh --unattended
# register: ohmyzsh_result
# failed_when: "'FAILED' in ohmyzsh_result.stderr"
# - name: Download zsh Dracula Theme
# become: no
# unarchive:
# src: https://github.com/dracula/zsh/archive/refs/heads/master.zip
# dest: "/tmp"
# remote_src: yes
# - name: Download moe theme for zsh
# become: no
# get_url:
# url: https://git.comprofix.com/mmckinnon/dotfiles/raw/branch/master/oh-my-zsh/moe.zsh-theme
# dest: "/home/{{ ansible_user }}/.oh-my-zsh/themes"
# force: true
# - name: Move zsh theme to correct folder
# become: no
# copy:
# src: /tmp/zsh-master/
# dest: /home/{{ ansible_user }}/.oh-my-zsh/themes
# remote_src: yes
# - name: Create vim config paths
# become: no
# file:
# path: "/home/{{ ansible_user }}/.vim/pack/themes/start/dracula"
# state: directory
# - name: Download vim Dracula Theme
# become: no
# unarchive:
# src: https://github.com/dracula/vim/archive/refs/heads/master.zip
# dest: "/tmp"
# remote_src: yes
# - name: Move vim theme to correct folder
# become: no
# copy:
# src: /tmp/vim-master/
# dest: /home/{{ ansible_user }}/.vim/pack/themes/start/dracula
# remote_src: yes
# - name: Get zsh config
# become: no
# get_url:
# url: https://git.comprofix.com/mmckinnon/dotfiles/raw/branch/master/zsh/zshrc
# dest: "/home/{{ ansible_user }}/.zshrc"
# force: true
# - name: Get vim config
# become: no
# get_url:
# url: https://git.comprofix.com/mmckinnon/dotfiles/raw/branch/master/vim/vimrc
# dest: "/home/{{ ansible_user }}/.vimrc"
# force: true
# - name: Set shell zsh
# user:
# name: "{{ ansible_user }}"
# shell: /bin/zsh
# - name: Set moe theme for zsh
# become: no
# ansible.builtin.lineinfile:
# path: "/home/{{ansible_user}}/.zshrc"
# regexp: '^ZSH_THEME="dracula"'
# line: 'ZSH_THEME="moe"'

14
tasks/comprofix.com.yml Normal file
View File

@ -0,0 +1,14 @@
- name: Create the comprofix.com container
docker_container:
name: comprofix.com
image: git.comprofix.com/mmckinnon/comprofix.com:latest
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
labels:
traefik.enable: "true"
traefik.http.routers.comprofix.rule: "Host(`comprofix.com`)"
traefik.http.routers.comprofix.entrypoints: "https"
traefik.http.routers.comprofix.tls: "true"
traefik.http.services.comprofix.loadbalancer.server.port: "80"

12
tasks/dozzle-agent.yml Normal file
View File

@ -0,0 +1,12 @@
---
- name: Create the dozzle container
docker_container:
name: dozzle_agent
image: amir20/dozzle:v8.13.12
restart_policy: unless-stopped
command: agent
recreate: true
ports:
- 7007:7007
volumes:
- /var/run/docker.sock:/var/run/docker.sock

29
tasks/dozzle.yml Normal file
View File

@ -0,0 +1,29 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/dozzle"
- "{{ data_folder }}/dozzle/config"
- name: Create the dozzle container
docker_container:
name: dozzle
image: amir20/dozzle:v8.13.12
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
env:
DOZZLE_LEVEL: "trace"
DOZZLE_REMOTE_AGENT: "omada-lxc.comprofix.xyz:7007"
labels:
traefik.enable: "true"
traefik.http.routers.dozzle.rule: "Host(`dozzle.comprofix.xyz`)"
traefik.http.routers.dozzle.entrypoints: "https"
traefik.http.routers.dozzle.tls: "true"
traefik.http.services.dozzle.loadbalancer.server.port: "8080"
traefik.http.services.dozzle.loadbalancer.server.scheme: "http"

View File

@ -0,0 +1,42 @@
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/gitea-runner"
- "{{ data_folder }}/gitea-runner/config"
- name: Check that config.yaml exists
stat:
path: "{{ data_folder }}/gitea-runner/config/config.yaml"
register: configyaml
- name: Create config.yaml file
file:
path: "{{ data_folder }}/gitea-runner/config/config.yaml"
state: touch
mode: "0600"
access_time: preserve
modification_time: preserve
when: configyaml.stat.exists == False
- name: Create the gitea-runner container
docker_container:
name: gitea-runner
image: gitea/act_runner:0.2.13
restart_policy: unless-stopped
recreate: true
# dns_servers:a
# - 10.10.10.1
# - 127.0.0.11
volumes:
- "/etc/resolv.conf:/etc/resolv.conf:ro"
- /var/run/docker.sock:/var/run/docker.sock
- "{{ data_folder }}/gitea-runner/config/config.yaml:/config.yaml"
- "/etc/hosts:/etc/hosts:ro"
env:
CONFIG_FILE: "/config.yaml"
GITEA_INSTANCE_URL: "https://git.comprofix.com"
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ GITEA_RUNNER_TOKEN }}"
GITEA_RUNNER_NAME: "homelab-runner"
GITEA_RUNNER_LABELS: "alpine-latest:docker://alpine:latest,ubuntu-latest:docker://node:22-trixie,homelab-latest:docker://git.comprofix.com/mmckinnon/debian-latest:2025.08.31-093853"

134
tasks/gitea.yml Normal file
View File

@ -0,0 +1,134 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/gitea"
- "{{ data_folder }}/gitea/data"
- "{{ data_folder }}/gitea/db"
- name: Create MySQL DB for Gitea
docker_container:
name: gitea_db
image: mysql:9
restart_policy: unless-stopped
networks:
- name: proxy
env:
MYSQL_ROOT_PASSWORD: "{{ gitea_db_root_password }}"
MYSQL_USER: "{{ gitea_db_user }}"
MYSQL_PASSWORD: "{{ gitea_db_password }}"
MYSQL_DATABASE: gitea
volumes:
- "{{ data_folder }}/gitea/db:/var/lib/mysql"
- name: Create the Gitea container
docker_container:
name: gitea
image: gitea/gitea:1.24
restart_policy: unless-stopped
recreate: true
# dns_servers:
# - 10.10.10.1
# - 127.0.0.11
networks:
- name: proxy
ports:
- "2222:22"
env:
PUID: "1001"
PGID: "1001"
TZ: "Australia/Brisbane"
volumes:
- "{{ data_folder }}/gitea/data:/data"
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
labels:
traefik.enable: "true"
traefik.http.routers.gitea.rule: "Host(`git.comprofix.com`)"
traefik.http.routers.gitea.entrypoints: "https"
traefik.http.routers.gitea.tls: "true"
traefik.http.routers.gitea.service: "gitea"
traefik.http.services.gitea.loadbalancer.server.port: "3000"
register: container_gitea
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/gitea-runner"
- "{{ data_folder }}/gitea-runner/config"
- name: Check that config.yaml exists
stat:
path: "{{ data_folder }}/gitea-runner/config/config.yaml"
register: configyaml
- name: Create config.yaml file
file:
path: "{{ data_folder }}/gitea-runner/config/config.yaml"
state: touch
mode: "0600"
access_time: preserve
modification_time: preserve
when: configyaml.stat.exists == False
- name: Create the gitea-runner container
docker_container:
name: gitea-runner
image: gitea/act_runner:0.2.13
restart_policy: unless-stopped
recreate: true
# dns_servers:
# - 10.10.10.1
# - 127.0.0.11
volumes:
- "/etc/resolv.conf:/etc/resolv.conf:ro"
- /var/run/docker.sock:/var/run/docker.sock
- "{{ data_folder }}/gitea-runner/config/config.yaml:/config.yaml"
- "/etc/hosts:/etc/hosts:ro"
env:
CONFIG_FILE: "/config.yaml"
GITEA_INSTANCE_URL: "https://git.comprofix.com"
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ GITEA_RUNNER_TOKEN }}"
GITEA_RUNNER_NAME: "gitea-runner"
GITEA_RUNNER_LABELS: "alpine-latest:docker://alpine:latest,ubuntu-latest:docker://node:22-trixie,vps-latest:docker://git.comprofix.com/mmckinnon/debian-latest:2025.08.31-093853"
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/opengist"
- name: Create the opengist container
docker_container:
name: opengist
image: ghcr.io/thomiceli/opengist:1.10
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
# dns_servers:
# - 10.10.10.1
# - 127.0.0.11
volumes:
- "{{ data_folder }}/opengist:/opengist"
env:
OG_GITEA_CLIENT_KEY: "{{ OG_GITEA_KEY }}"
OG_GITEA_SECRET: "{{ OG_GITEA_SECRET }}"
# URL of the Gitea instance. Default: https://gitea.com/
OG_GITEA_URL: "https://git.comprofix.com"
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
labels:
traefik.enable: "true"
traefik.http.routers.opengist.rule: "Host(`gist.comprofix.com`)"
traefik.http.routers.opengist.entrypoints: "https"
traefik.http.routers.opengist.tls: "true"
traefik.http.routers.opengist.service: "opengist"
traefik.http.services.opengist.loadbalancer.server.port: "6157"
register: container

26
tasks/gotify.yml Normal file
View File

@ -0,0 +1,26 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/gotify"
- "{{ data_folder }}/gotify/data"
- name: Create the gotify container
docker_container:
name: gotify
image: gotify/server:2.6.3
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
volumes:
- /data/gotify/data:/app/data
labels:
traefik.enable: "true"
traefik.http.routers.gotify.rule: "Host(`gotify.comprofix.com`)"
traefik.http.routers.gotify.entrypoints: "https"
traefik.http.routers.gotify.tls: "true"
traefik.http.routers.gotify.service: "gotify"
traefik.http.services.gotify.loadbalancer.server.port: "80"

40
tasks/homepage.yml Normal file
View File

@ -0,0 +1,40 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/homepage"
- "{{ data_folder }}/homepage/config"
- name: Get dashboard-icons
git:
repo: https://github.com/walkxcode/dashboard-icons.git
dest: /data/dashboard-icons
update: yes
- name: Create the homepage container
docker_container:
name: homepage
image: ghcr.io/gethomepage/homepage:v1.4.6
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
dns_servers:
- 10.10.10.1
env:
LOG_LEVEL: debug
HOMEPAGE_ALLOWED_HOSTS: homepage.comprofix.xyz
volumes:
- "{{ data_folder }}/homepage/config:/app/config"
- "{{ data_folder }}/dashboard-icons:/app/public/icons"
- /var/run/docker.sock:/var/run/docker.sock
labels:
traefik.enable: "true"
traefik.http.routers.homepage.rule: "Host(`homepage.comprofix.xyz`)"
traefik.http.routers.homepage.entrypoints: "https"
traefik.http.routers.homepage.tls: "true"
traefik.http.routers.homepage.service: "homepage"
traefik.http.services.homepage.loadbalancer.server.port: "3000"
register: container_homepage

15
tasks/idrac.yml Normal file
View File

@ -0,0 +1,15 @@
---
- name: Create the Dell_R730xd Fan Contoller container
docker_container:
name: Dell_R730xd
image: ghcr.io/tigerblue77/dell_idrac_fan_controller:latest@sha256:eda09016a4acbee8883996f3b8cd4832a723200999bd037934675e75e2f00908
restart_policy: unless-stopped
recreate: true
env:
IDRAC_HOST: "10.10.10.105"
IDRAC_USERNAME: "root"
IDRAC_PASSWORD: "calvin"
FAN_SPEED: "40"
CPU_TEMPERATURE_THRESHOLD: "80"
CHECK_INTERVAL: "60"
DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE: "true"

95
tasks/invoiceninja.yml Normal file
View File

@ -0,0 +1,95 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/invoiceninja/"
- "{{ data_folder }}/invoiceninja/config"
- "{{ data_folder }}/invoiceninja/db"
- name: "create stack.env"
copy:
dest: "{{ data_folder }}/invoiceninja/stack.env"
content: |
APP_NAME="Invoice Ninja"
APP_ENV=production
APP_KEY="{{ IN_APP_KEY }}"
APP_DEBUG=false
APP_URL="{{ IN_APP_URL }}"
REQUIRE_HTTPS=true
TRUSTED_PROXIES='*'
SESSION_ENCRYPT=false
SESSION_SECURE=false
DB_CONNECTION="mysql"
MULTI_DB_ENABLED=false
DB_HOST="{{MYSQL_HOST}}"
DB_DATABASE="{{IN_DB_DATABASE}}"
DB_USERNAME="{{IN_DB_USERNAME}}"
DB_PASSWORD="{{IN_DB_PASSWORD}}"
DB_PORT="3306"
DEMO_MODE=false
BROADCAST_DRIVER=log
LOG_CHANNEL=stack
CACHE_DRIVER=file
#QUEUE_CONNECTION=sync
QUEUE_CONNECTION=database
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER="smtp"
MAIL_HOST="{{MAIL_HOST}}"
MAIL_PORT="{{MAIL_PORT}}"
MAIL_ENCRYPTION="tls"
MAIL_FROM_ADDRESS="{{MAIL_FROM}}"
MAIL_FROM_NAME="{{MAIL_FROM_NAME}}"
POSTMARK_API_TOKEN=
GOOGLE_MAPS_API_KEY=
ERROR_EMAIL=
NINJA_ENVIRONMENT="selfhost"
#options - snappdf / phantom / hosted_ninja
PDF_GENERATOR=hosted_ninja
PHANTOMJS_KEY='a-demo-key-with-low-quota-per-ip-address'
PHANTOMJS_SECRET=secret
UPDATE_SECRET=secret
SENTRY_LARAVEL_DSN=https://32f01ea994744fa08a0f688769cef78a@sentry.invoicing.co/
- name: Create the invoiceninja-app container
docker_container:
name: invoiceninja-app
image: invoiceninja/invoiceninja:5
env_file: "{{ data_folder }}/invoiceninja/stack.env"
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
volumes:
- "{{ data_folder }}/invoiceninja/config/hosts:/etc/hosts"
- "{{ data_folder }}/invoiceninja/docker/app/public:/var/www/app/public"
- "{{ data_folder }}/invoiceninja/docker/app/storage:/var/www/app/storage"
- name: Create the invoiceninja-nginx container
docker_container:
name: invoiceninja-nginx
image: nginx:1.29.1
env_file: "{{ data_folder }}/invoiceninja/stack.env"
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
volumes:
- "{{ data_folder }}/invoiceninja/config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf"
- "{{ data_folder }}/invoiceninja/docker/app/public:/var/www/app/public"
- "{{ data_folder }}/invoiceninja/docker/app/storage:/var/www/app/storage"
labels:
traefik.enable: "true"
traefik.http.routers.invoiceninja.rule: "Host(`invoice.comprofix.com`)"
traefik.http.routers.invoiceninja.entrypoints: "https"
traefik.http.routers.invoiceninja.tls: "true"
traefik.http.services.invoiceninja.loadbalancer.server.port: "80"
traefik.http.services.invoiceninja.loadbalancer.server.scheme: "http"

88
tasks/iscsi.yml Normal file
View File

@ -0,0 +1,88 @@
---
- name: Ensure open-iscsi is installed
package:
name: open-iscsi
state: present
- name: Ensure parted is installed
package:
name: parted
state: present
- name: Discover iSCSI targets
command: sudo iscsiadm -m discovery -t sendtargets -p "10.10.10.2"
register: iscsi_discovery
- name: Set target_iqn variable based on discovery
set_fact:
target_iqn: "{{ item.split(' ')[1] }}"
loop: "{{ iscsi_discovery.stdout_lines }}"
when: item.startswith("10.10.10.2")
- name: Check if iSCSI target is already connected
command: iscsiadm -m session
register: iscsi_sessions
changed_when: false
failed_when: iscsi_sessions.rc not in [0, 21] # Allow success if the return code is 0 or 21
- name: Connect to iSCSI target
command: sudo iscsiadm -m node -T "{{ target_iqn }}" -p "10.10.10.2" --login
when: target_iqn is defined and target_iqn not in iscsi_sessions.stdout
- name: Set iSCSI target for automatic login
command: sudo iscsiadm -m node -T "{{ target_iqn }}" -p "10.10.10.2" --op update --name node.startup --value automatic
when: target_iqn is defined
- name: Fail if no target_iqn found
fail:
msg: "No target IQN found for iSCSI server IP 10.10.10.2"
when: target_iqn is not defined
- name: List all block devices
command: lsblk -o NAME,SIZE,TYPE,MODEL
register: lsblk_output
- name: Set iSCSI device variable
set_fact:
iscsi_device: "/dev/{{ item.split()[0] }}"
loop: "{{ lsblk_output.stdout_lines }}"
when: item.split()[2] == 'disk' and 'iSCSI' in item # Adjust based on the MODEL you observe
- name: Fail if no iSCSI device found
fail:
msg: "No iSCSI device found!"
when: iscsi_device is not defined
- name: Create a partition on iSCSI device using parted
parted:
device: "{{ iscsi_device }}"
number: 1
state: present
part_type: primary
fs_type: ext4
part_start: 0% # Start at the beginning of the device
part_end: 100% # Use the entire available space
- name: Create filesystem on new partition
filesystem:
fstype: ext4
dev: "{{ iscsi_device }}1" # Format the partition
- name: Create mount point
file:
path: /data
state: directory
- name: Mount iSCSI target
mount:
path: /data
src: "{{ iscsi_device }}1" # Mount the new partition
fstype: ext4
opts: defaults,_netdev
state: mounted
# - name: Ensure iSCSI target is mounted at boot
# lineinfile:
# path: /etc/fstab
# line: "{{ iscsi_device }}1 /data ext4 _netdev 0 0"
# state: present

29
tasks/jellyseerr.yml Normal file
View File

@ -0,0 +1,29 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/jellyseerr"
- "{{ data_folder }}/jellyseerr/config"
- name: Create the jellyseerr container
docker_container:
name: jellyseerr
image: fallenbagel/jellyseerr:2.7.3
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
volumes:
- "{{ data_folder }}/jellyseerr/config:/app/config"
labels:
traefik.enable: "true"
traefik.http.routers.jellyseerr.rule: "Host(`jellyseerr.comprofix.xyz`)"
traefik.http.routers.jellyseerr.entrypoints: "https"
traefik.http.routers.jellyseerr.tls: "true"
traefik.http.services.jellyseerr.loadbalancer.server.port: "5055"

36
tasks/lidarr.yml Normal file
View File

@ -0,0 +1,36 @@
---
- name: Set Facts
set_fact:
container_name: 'lidarr'
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/lidarr"
- "{{ data_folder }}/lidarr/config"
- name: Create the lidarr container
docker_container:
name: lidarr
image: ghcr.io/linuxserver/lidarr:latest@sha256:186bc4d3f22bd6a71c235c1c7f57f90a8473f766278d9c929398fb5ce90eae7e
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
AUTO_UPDATE: "true" #optional
DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:lidarr"
volumes:
- "{{ data_folder }}/lidarr/config:/config"
- /mnt/nfs/data:/data
labels:
traefik.enable: "true"
traefik.http.routers.lidarr.rule: "Host(`lidarr.comprofix.xyz`)"
traefik.http.routers.lidarr.entrypoints: "https"
traefik.http.routers.lidarr.tls: "true"
traefik.http.services.lidarr.loadbalancer.server.port: "8686"

29
tasks/mariadb.yml Normal file
View File

@ -0,0 +1,29 @@
---
- name: Set Facts
set_fact:
container_name: 'mariadb'
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/mariadb"
- "{{ data_folder }}/mariadb/config"
- name: Create the mariadb container
docker_container:
name: "mariadb"
image: ghcr.io/linuxserver/mariadb:11.4.8
restart_policy: unless-stopped
recreate: true
ports:
- 3306:3306
env:
PUID: "0"
PGID: "0"
MYSQL_ROOT_PASSWORD: "{{MYSQL_ROOT_PASSWORD}}"
TZ: "Australia/Brisbane"
volumes:
- "{{ data_folder }}/mariadb/config:/config"

36
tasks/mealie.yml Normal file
View File

@ -0,0 +1,36 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/mealie"
- "{{ data_folder }}/mealie/config"
- name: Create the mealie container
docker_container:
name: mealie
image: ghcr.io/mealie-recipes/mealie:v3.1.2
restart_policy: unless-stopped
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
RECIPE_PUBLIC: "true"
RECIPE_SHOW_NUTRITION: "false"
RECIPE_SHOW_ASSETS: "true"
RECIPE_LANDSCAPE_VIEW: "true"
RECIPE_DISABLE_COMMENTS: "true"
RECIPE_DISABLE_AMOUNT: "true"
BASE_URL: "mealie.comprofix.xyz"
SMTP_HOST: "{{MAIL_HOST}}"
volumes:
- "{{ data_folder }}/mealie/data/:/app/data"
labels:
traefik.enable: "true"
traefik.http.routers.mealie.rule: "Host(`mealie.comprofix.xyz`)"
traefik.http.routers.mealie.entrypoints: "https"
traefik.http.routers.mealie.tls: "true"
traefik.http.services.mealie.loadbalancer.server.port: "9000"

29
tasks/mediawiki.yml Normal file
View File

@ -0,0 +1,29 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/mediawiki"
- name: Create the wiki container
docker_container:
name: mediawiki
image: mediawiki:1.44.0
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
volumes:
- "{{ data_folder }}/mediawiki/images:/var/www/html/images"
- "{{ data_folder }}/mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php"
labels:
traefik.enable: "true"
traefik.http.routers.wiki.rule: "Host(`wiki.comprofix.xyz`)"
traefik.http.routers.wiki.entrypoints: "https"
traefik.http.routers.wiki.tls: "true"
traefik.http.services.wiki.loadbalancer.server.port: "80"

24
tasks/omada.yml Normal file
View File

@ -0,0 +1,24 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/omada"
- "{{ data_folder }}/omada/data"
- "{{ data_folder }}/omada/logs"
- name: Create the omada container
docker_container:
name: omada
image: mbentley/omada-controller:5.15
restart_policy: unless-stopped
recreate: true
network_mode: host
volumes:
- "{{ data_folder }}/omada/data:/opt/tplink/EAPController/data"
- "{{ data_folder }}/omada/logs:/opt/tplink/EAPController/logs"
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"

61
tasks/osticket.yml Normal file
View File

@ -0,0 +1,61 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/osticket"
- "{{ data_folder }}/osticket/config"
- name: Create the osticket container
docker_container:
name: osticket
image: devinsolutions/osticket:1.17.5
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
SMTP_HOST: "{{MAIL_HOST}}"
MYSQL_HOST: "{{MYSQL_HOST}}"
MYSQL_DATABASE: "{{OST_DATABASE}}"
MYSQL_USER: "{{OST_DB_USER}}"
MYSQL_PASSWORD: "{{OST_DB_PASSWORD}}"
INSTALL_SECRET: "{{OST_SIRI}}"
labels:
traefik.enable: "true"
traefik.http.routers.osticket.rule: "Host(`helpdesk.comprofix.com`)"
traefik.http.routers.osticket.entrypoints: "https"
traefik.http.routers.osticket.tls: "true"
traefik.http.services.osticket.loadbalancer.server.port: "80"
traefik.http.services.osticket.loadbalancer.server.scheme: "http"
- name: Add tzdata to osTicket container
community.docker.docker_container_exec:
container: osticket
command: apk add tzdata
- name: Set container Timezone
community.docker.docker_container_exec:
container: osticket
command: "ln -s /usr/share/zoneinfo/Australia/Brisbane /etc/localtime"
- name: Set PHP Timezone
community.docker.docker_container_exec:
container: osticket
command: "sed -i 's|UTC|Australia/Brisbane|g' /usr/local/etc/php/conf.d/php-osticket.ini"
- name: Patch mysqli.php for timezone
community.docker.docker_container_exec:
container: osticket
command: "sed -i 's|system_time_zone|time_zone|g' /var/www/html/include/mysqli.php"
- name: Clear ost_sessions table
mysql_query:
login_host: "{{MYSQL_HOST}}"
login_user: "{{OST_DB_USER}}"
login_password: "{{OST_DB_PASSWORD}}"
login_db: "{{OST_DATABASE}}"
query:
- USE comprofix_ost;
- TRUNCATE TABLE ost_session;

22
tasks/postgres.yml Normal file
View File

@ -0,0 +1,22 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "/mnt/nfs/docker/postgres"
- "/mnt/nfs/docker/postgres/config"
- name: Create the postgres container
docker_container:
name: postgres
image: postgres:16-alpine
restart_policy: unless-stopped
recreate: true
ports:
- 5432:5432
env:
POSTGRES_PASSWORD: "{{POSTGRES_PASSWORD}}"
volumes:
- /mnt/nfs/docker/postgres/db-data:/var/lib/postgresql/data

31
tasks/prowlarr.yml Normal file
View File

@ -0,0 +1,31 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/prowlarr"
- "{{ data_folder }}/prowlarr/config"
- name: Create the prowlarr container
docker_container:
name: prowlarr
image: linuxserver/prowlarr:2.0.5
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
AUTO_UPDATE: "true" #optional
DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:prowlarr"
volumes:
- "{{ data_folder }}/prowlarr/config:/config"
labels:
traefik.enable: "true"
traefik.http.routers.prowlarr.rule: "Host(`prowlarr.comprofix.xyz`)"
traefik.http.routers.prowlarr.entrypoints: "https"
traefik.http.routers.prowlarr.tls: "true"
traefik.http.services.prowlarr.loadbalancer.server.port: "9696"

26
tasks/pykms.yml Normal file
View File

@ -0,0 +1,26 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/pykms"
- "{{ data_folder }}/pykms/db"
- name: Create the pykms container
docker_container:
name: pykms
image: ghcr.io/py-kms-organization/py-kms:latest
restart_policy: unless-stopped
recreate: true
ports:
- "1688:1688"
env:
IP: "0.0.0.0"
SQLITE: "true"
HWID: "RANDOM"
LOGLEVEL: "INFO"
volumes:
- "{{ data_folder }}/pykms/db:/home/py-kms/db"
- /etc/localtime:/etc/localtime:ro

31
tasks/radarr.yml Normal file
View File

@ -0,0 +1,31 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/radarr"
- "{{ data_folder }}/radarr/config"
- name: Create the radarr container
docker_container:
name: radarr
image: linuxserver/radarr:5.27.5
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:radarr"
volumes:
- "{{ data_folder }}/radarr/config:/config"
- /mnt/nfs/data:/data
labels:
traefik.enable: "true"
traefik.http.routers.radarr.rule: "Host(`radarr.comprofix.xyz`)"
traefik.http.routers.radarr.entrypoints: "https"
traefik.http.routers.radarr.tls: "true"
traefik.http.services.radarr.loadbalancer.server.port: "7878"

33
tasks/readarr.yml Normal file
View File

@ -0,0 +1,33 @@
# Readarr has been archived/retired.
# Keeping this for history
# ---
# - name: Create directories
# file:
# path: "{{ item }}"
# state: directory
# with_items:
# - "{{ data_folder }}/readarr"
# - "{{ data_folder }}/readarr/config"
# - name: Create the readarr container
# docker_container:
# name: readarr
# image: linuxserver/readarr:develop@sha256:eb37f58646a901dc7727cf448cae36daaefaba79de33b5058dab79aa4c04aefb
# restart_policy: unless-stopped
# recreate: true
# networks:
# - name: proxy
# env:
# PUID: "1000"
# PGID: "1000"
# TZ: "Australia/Brisbane"
# DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:readarr"
# volumes:
# - "{{ data_folder }}/readarr/config/:/config"
# - /mnt/nfs/data/:/data
# labels:
# traefik.enable: "true"
# traefik.http.routers.readarr.rule: "Host(`readarr.comprofix.xyz`)"
# traefik.http.routers.readarr.entrypoints: "https"
# traefik.http.routers.readarr.tls: "true"
# traefik.http.services.readarr.loadbalancer.server.port: "8787"

32
tasks/sabnzbd.yml Normal file
View File

@ -0,0 +1,32 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/sabnzbd"
- "{{ data_folder }}/sabnzbd/config"
- name: Create the sabnzbd container
docker_container:
name: sabnzbd
image: linuxserver/sabnzbd:4.5.3
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
HOSTNAME: "sabnzbd.comprofix.xyz"
DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:sabnzbd"
volumes:
- "{{ data_folder }}/sabnzbd/config:/config"
- /mnt/nfs/data:/data
labels:
traefik.enable: "true"
traefik.http.routers.sabnzbd.rule: "Host(`sabnzbd.comprofix.xyz`)"
traefik.http.routers.sabnzbd.entrypoints: "https"
traefik.http.routers.sabnzbd.tls: "true"
traefik.http.services.sabnzbd.loadbalancer.server.port: "8080"

31
tasks/sonarr.yml Normal file
View File

@ -0,0 +1,31 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/sonarr"
- "{{ data_folder }}/sonarr/config"
- name: Create the sonarr container
docker_container:
name: sonarr
image: linuxserver/sonarr:4.0.15
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:sonarr"
volumes:
- "{{ data_folder }}/sonarr/config/:/config"
- /mnt/nfs/data:/data
labels:
traefik.enable: "true"
traefik.http.routers.sonarr.rule: "Host(`sonarr.comprofix.xyz`)"
traefik.http.routers.sonarr.entrypoints: "https"
traefik.http.routers.sonarr.tls: "true"
traefik.http.services.sonarr.loadbalancer.server.port: "8989"

41
tasks/speedtest.yml Normal file
View File

@ -0,0 +1,41 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/speedtest"
- "{{ data_folder }}/speedtest/config"
- "{{ data_folder }}/speedtest/web"
- name: Create the speedtest container
docker_container:
name: speedtest
image: lscr.io/linuxserver/speedtest-tracker:1.6.6
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
APP_KEY: "base64:ViJcK7rSIwGC+TAW7pRWnczB43zPPVHH2Hx80t7eVm0="
PUID: "1000"
PGID: "1000"
DB_CONNECTION: "mysql"
DB_HOST: "{{ MYSQL_HOST }}"
DB_PORT: "3306"
DB_DATABASE: "{{ST_DATABASE}}"
DB_USERNAME: "{{ST_DB_USERNAME}}"
DB_PASSWORD: "{{ST_DB_PASSWORD}}"
TZ: "Australia/Brisbane"
SPEEDTEST_SCHEDULE: "0 * * * *"
DISPLAY_TIMEZONE: "Australia/Brisbane"
volumes:
- "{{ data_folder }}/speedtest/config:/config"
- "{{ data_folder }}/speedtest/web:/etc/ssl/web"
labels:
traefik.enable: "true"
traefik.http.routers.speedtest.rule: "Host(`speedtest.comprofix.xyz`)"
traefik.http.routers.speedtest.entrypoints: "https"
traefik.http.routers.speedtest.tls: "true"
traefik.http.services.speedtest.loadbalancer.server.port: "80"
traefik.http.services.speedtest.loadbalancer.server.scheme: "http"

26
tasks/traggo.yml Normal file
View File

@ -0,0 +1,26 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/traggo"
- "{{ data_folder }}/traggo/data"
- name: Create the traggo container
docker_container:
name: traggo
image: traggo/server:0.7.1
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
volumes:
- /data/traggo/data:/opt/traggo/data
labels:
traefik.enable: "true"
traefik.http.routers.traggo.rule: "Host(`traggo.comprofix.xyz`)"
traefik.http.routers.traggo.entrypoints: "https"
traefik.http.routers.traggo.tls: "true"
traefik.http.services.traggo.loadbalancer.server.port: "3030"
traefik.http.services.traggo.loadbalancer.server.scheme: "http"

64
tasks/vaultwarden.yml Normal file
View File

@ -0,0 +1,64 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
with_items:
- "{{ data_folder }}/vaultwarden"
- "{{ data_folder }}/vaultwarden/config"
- "{{ data_folder }}/vaultwardenbackup"
- "{{ data_folder }}/vaultwardenbackup/config"
- "{{ data_folder }}/vaultwardenbackup/config/rclone"
- name: Create the vaultwarden container
docker_container:
name: vaultwarden
image: vaultwarden/server:1.34.3
restart_policy: unless-stopped
recreate: true
networks:
- name: proxy
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
volumes:
- "{{ data_folder }}/vaultwarden/data:/data"
labels:
traefik.enable: "true"
traefik.http.routers.vaultwarden.rule: "Host(`vault.comprofix.com`)"
traefik.http.routers.vaultwarden.entrypoints: "https"
traefik.http.routers.vaultwarden.tls: "true"
traefik.http.routers.vaultwarden.service: "vaultwarden"
traefik.http.services.vaultwarden.loadbalancer.server.port: "80"
register: container
- name: Copy rclone config
copy:
src: scripts/rclone.conf
dest: "{{ data_folder }}/vaultwardenbackup/config/rclone/rclone.conf"
decrypt: yes
mode: "0600"
- name: Create the vaultwarden container
docker_container:
name: vaultwardenbackup
image: ttionya/vaultwarden-backup:1.25.1
restart_policy: unless-stopped
recreate: true
env:
PUID: "1000"
PGID: "1000"
TZ: "Australia/Brisbane"
CRON: "0 4 * * *"
BACKUP_KEEP_DAYS: "14"
ZIP_PASSWORD: "{{ VAULTWARDEN_BACKUP_ZIP_PASSWORD }}"
volumes:
- "{{ data_folder }}/vaultwarden/data:/bitwarden/data"
- "{{ data_folder }}/vaultwardenbackup/config:/config"
register: container

48
vault.sh Executable file
View File

@ -0,0 +1,48 @@
#!/bin/bash
# If number of arguments is 0
if [ $# -eq 0 ]
then
echo "This script will encrypt of decrypt all files containing secrets."
echo "There are all files in vars as well as all secrets.yaml files under each service."
echo "Specify 'decrypt' or 'encrypt' as argument"
echo "If you put the vault password in a password file named .vault_password, the script will not ask for a password."
exit 1
fi
#files=`find . \( -type d -name 'group_vars' -o -name 'vars' \) -exec find {} -type f \;`
files=(
"./group_vars/all.yml"
"./roles/docker/vars/main.yml"
"./roles/traefik/vars/main.yml"
"./scripts/rclone.conf"
)
# password_type=--ask-vault-password
# if [ -f "~/.vault_password.txt" ]
# then
# if [ `stat -c %a ~/.vault_password.txt` != "600" ]
# then
# echo "~/.vault_password.txt file has bad permissions; fixing this to 600"
# chmod 600 ~/.vault_password.txt
# fi
# password_type="--vault-password-file=~/.vault_password.txt"
# fi
if [ $1 == "encrypt" ]
then
for file in "${files[@]}"; do
echo "$file encrypted"
ansible-vault encrypt --vault-password-file=~/.vault_password "$file"
echo $value;
done
elif [ $1 == "decrypt" ]
then
for file in "${files[@]}"; do
echo "$file decrypted"
ansible-vault decrypt --vault-password-file=~/.vault_password "$file"
done
else
echo "Wrong argument supplied. Run without arguments to see allowed ones."
fi