mirror of
https://github.com/natelandau/ansible-homelab-config.git
synced 2025-11-18 09:53:41 -05:00
Compare commits
17 Commits
5e35cf4400
...
pre-commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0dca5c982 | ||
|
|
d9dfbb5152 | ||
|
|
6e8b39aef9 | ||
|
|
8734731355 | ||
|
|
9a47eb1f06 | ||
|
|
b40521919a | ||
|
|
855ff49ef1 | ||
|
|
12d1467369 | ||
|
|
55dea40077 | ||
|
|
feb1fbedf4 | ||
|
|
6b00bf557c | ||
|
|
ea9678eba6 | ||
|
|
1714dff877 | ||
|
|
7bde47d43a | ||
|
|
394b34a5d1 | ||
|
|
846fb2bc31 | ||
|
|
eff9059bac |
@@ -12,21 +12,21 @@ exclude_paths:
|
||||
- vault.yml
|
||||
- .venv/
|
||||
- ansible_collections/
|
||||
|
||||
skip_list:
|
||||
- name[template]
|
||||
- ignore-errors
|
||||
- meta-incorrect
|
||||
- meta-no-info
|
||||
- package-latest
|
||||
- role-name
|
||||
- unnamed-task
|
||||
- var-naming
|
||||
- latest[git]
|
||||
- yaml[indentation]
|
||||
# - name[template]
|
||||
# - ignore-errors
|
||||
# - meta-incorrect
|
||||
# - meta-no-info
|
||||
# - package-latest
|
||||
# - role-name
|
||||
# - unnamed-task
|
||||
# - var-naming
|
||||
# - latest[git]
|
||||
|
||||
warn_list:
|
||||
- experimental
|
||||
- risky-file-permissions
|
||||
- command-instead-of-module
|
||||
- no-changed-when
|
||||
- command-instead-of-shell
|
||||
# warn_list:
|
||||
# - experimental
|
||||
# - risky-file-permissions
|
||||
# - command-instead-of-module
|
||||
# - no-changed-when
|
||||
# - command-instead-of-shell
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
repos:
|
||||
- repo: "https://github.com/commitizen-tools/commitizen"
|
||||
rev: 3.12.0
|
||||
rev: v4.1.0
|
||||
hooks:
|
||||
- id: "commitizen"
|
||||
|
||||
- repo: "https://github.com/pre-commit/pre-commit-hooks"
|
||||
rev: v4.5.0
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-ast
|
||||
@@ -31,7 +31,7 @@ repos:
|
||||
args: [--markdown-linebreak-ext=md]
|
||||
|
||||
- repo: "https://github.com/adrienverge/yamllint.git"
|
||||
rev: v1.32.0
|
||||
rev: v1.35.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
files: \.(yaml|yml)$
|
||||
@@ -44,10 +44,20 @@ repos:
|
||||
entry: yamllint --strict --config-file .yamllint.yml
|
||||
|
||||
- repo: "https://github.com/crate-ci/typos"
|
||||
rev: v1.16.23
|
||||
rev: dictgen-v0.3.1
|
||||
hooks:
|
||||
- id: typos
|
||||
|
||||
- repo: "https://github.com/ansible/ansible-lint"
|
||||
rev: v24.12.2
|
||||
hooks:
|
||||
- id: ansible-lint
|
||||
additional_dependencies:
|
||||
- ansible
|
||||
args:
|
||||
- --config-file
|
||||
- .ansible-lint.yml
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: vault-pre-commit
|
||||
@@ -64,13 +74,6 @@ repos:
|
||||
pass_filenames: true
|
||||
types: [text]
|
||||
|
||||
- id: ansible-lint
|
||||
name: running ansible-lint
|
||||
language: system
|
||||
files: \.(yaml|yml)$
|
||||
pass_filenames: false
|
||||
entry: ansible-lint --force-color --config-file .ansible-lint.yml
|
||||
|
||||
- id: "lint-shellscript-templates"
|
||||
name: lint shellscript templates
|
||||
language: system
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
default.locale = "en_us"
|
||||
|
||||
[default.extend-words]
|
||||
Hashi = "Hashi" # Hashicorpt
|
||||
Hashi = "Hashi" # Hashicorpt
|
||||
hishtory = "hishtory" # Used for the hishtory package
|
||||
|
||||
[files]
|
||||
extend-exclude = ["galaxy-roles/"]
|
||||
|
||||
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"yaml.schemas": {
|
||||
"https://raw.githubusercontent.com/ansible-community/schemas/main/f/ansible.json#/$defs/playbook": "file:///Users/natelandau/repos/ansible-homelab-config/main.yml"
|
||||
}
|
||||
"files.associations": {
|
||||
"**/tasks/*.yml": "ansible",
|
||||
"**/handlers/*.yml": "ansible",
|
||||
"main.yml": "ansible",
|
||||
"inventory.yml": "ansible",
|
||||
"default_variables.yml": "ansible",
|
||||
"vault.yml": "ansible"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,14 +41,13 @@ This playbook adds storage, services, applications, and configurations to a prev
|
||||
- Custom shell scripts for backups and house keeping
|
||||
|
||||
* **Syncs Nomad and Docker Compose job files** to servers:
|
||||
- [ASN-to-IP](https://hub.docker.com/r/ddimick/asn-to-ip) - Used by Opnsense to build firewall aliases
|
||||
- [Authelia](https://www.authelia.com/) - Open-source full-featured authentication server
|
||||
- [Changedetection.io](https://github.com/dgtlmoon/changedetection.io) - Website change detection monitoring and notification service
|
||||
- [Diun](https://crazymax.dev/diun/) - Docker Image Update Notifier is a CLI application
|
||||
- [FreshRSS](https://freshrss.org/) - A containerized RSS reader
|
||||
- [Gitea](https://about.gitea.com/) - Slef-hodted Git service
|
||||
- [Grafana](https://grafana.com/) - Operational dashboards
|
||||
- [Grafana Loki](https://grafana.com/oss/loki/) - Log aggregation system
|
||||
- [Headless Trunk](https://github.com/alpeware/chrome-headless-trunk) - Headless Chromium
|
||||
- [iCloud Drive Docker](https://github.com/mandarons/icloud-drive-docker) - Backup files and photos from Apple iCloud
|
||||
- [InfluxDB](https://www.influxdata.com/) - Time series database
|
||||
- [Lidarr](https://lidarr.audio/) - Music collection manager
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[defaults]
|
||||
nocows = True
|
||||
roles_path = ./galaxy-roles:./roles
|
||||
collections_paths = ./
|
||||
collections_path = ./
|
||||
inventory = ./inventory.yml
|
||||
stdout_callback = yaml
|
||||
any_errors_fatal = True
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
# yamllint disable rule:indentation
|
||||
---
|
||||
# ---------------------------------- SOFTWARE VERSIONS
|
||||
authelia_version: 4.37.5
|
||||
backup_mongodb_version: 1.1.0
|
||||
consul_version: 1.16.1
|
||||
gitea_version: 1.21.6
|
||||
influxdb_version: 1.11.1
|
||||
nomad_version: 1.6.2
|
||||
nomad_version: 1.7.6
|
||||
prometheus_verssion: 2.46.0
|
||||
recyclarr_version: 5.3.1
|
||||
recyclarr_version: 6.0.2
|
||||
speedtest_cli_version: 1.2.0
|
||||
tdarr_installer_version: 2.00.13
|
||||
telegraf_version: 1.27.2
|
||||
traefik_version: "v2.10.4"
|
||||
valentina_version: 2.0.0
|
||||
backup_mongodb_version: "v1.0.0"
|
||||
telegraf_version: 1.29.5
|
||||
traefik_version: 2.10.7
|
||||
valentina_version: 2.2.1
|
||||
sabnzbd_version: 4.2.2
|
||||
|
||||
# ---------------------------------- SERVICE STATIC PORT MAPPINGS
|
||||
authelia_port: "9091"
|
||||
influxdb_port: "8086"
|
||||
tdarr_node_port: "8267"
|
||||
tdarr_server_port: "8266"
|
||||
@@ -23,6 +25,7 @@ tdarr_webui_port: "8265"
|
||||
# ---------------------------------- DIRECTORIES FOR SERVICE LOCAL STORAGE
|
||||
# These folders must be created, even if empty, to allow mounting nomad local storage end-points
|
||||
service_localfs_dirs:
|
||||
- gitea
|
||||
- influxdb
|
||||
- lidarr
|
||||
- prowlarr
|
||||
@@ -35,12 +38,27 @@ rpi_usb_drive_mount_point: /mnt/usbDrive
|
||||
rpi_localfs_service_storage: "{{ rpi_usb_drive_mount_point }}/docker"
|
||||
rpi_nfs_mount_point: /mnt
|
||||
rpi_nfs_mounts_list:
|
||||
- { local: "{{ rpi_nfs_mount_point }}/pi-cluster", src: "10.0.30.6:/volume1/pi-cluster" }
|
||||
- { local: "{{ rpi_nfs_mount_point }}/syncthing", src: "10.0.30.6:/volume1/syncthing" }
|
||||
- { local: "{{ rpi_nfs_mount_point }}/media", src: "10.0.30.6:/volume1/media" }
|
||||
- { local: "{{ rpi_nfs_mount_point }}/nate", src: "10.0.30.6:/volume1/nate" }
|
||||
- {
|
||||
local: "{{ rpi_nfs_mount_point }}/pi-cluster",
|
||||
src: "10.0.30.6:/volume1/pi-cluster",
|
||||
}
|
||||
- {
|
||||
local: "{{ rpi_nfs_mount_point }}/syncthing",
|
||||
src: "10.0.30.6:/volume1/syncthing",
|
||||
}
|
||||
- {
|
||||
local: "{{ rpi_nfs_mount_point }}/media",
|
||||
src: "10.0.30.6:/volume1/media",
|
||||
}
|
||||
- {
|
||||
local: "{{ rpi_nfs_mount_point }}/nate",
|
||||
src: "10.0.30.6:/volume1/nate",
|
||||
}
|
||||
rpi_nfs_mounts_remove:
|
||||
- { local: "{{ rpi_nfs_mount_point }}/downloads", src: "10.0.30.6:/volume1/downloads" }
|
||||
- {
|
||||
local: "{{ rpi_nfs_mount_point }}/downloads",
|
||||
src: "10.0.30.6:/volume1/downloads",
|
||||
}
|
||||
|
||||
# mac_autofs_type is one of 'smb,nfs,afp'
|
||||
mac_autofs_type: smb
|
||||
@@ -48,18 +66,36 @@ mac_localfs_service_storage: "/Users/{{ ansible_user }}/Library/docker"
|
||||
mac_storage_mount_point: /System/Volumes/Data/mnt
|
||||
mac_keep_alive_file: "{{ mac_storage_mount_point }}/pi-cluster/keepalive.txt"
|
||||
mac_nfs_mounts_list:
|
||||
- { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/volume1/pi-cluster" }
|
||||
- { local: "{{ mac_storage_mount_point }}/syncthing", src: "10.0.0.6:/volume1/syncthing" }
|
||||
- { local: "{{ mac_storage_mount_point }}/media", src: "10.0.0.6:/volume1/media" }
|
||||
- { local: "{{ mac_storage_mount_point }}/nate", src: "10.0.0.6:/volume1/nate" }
|
||||
- {
|
||||
local: "{{ mac_storage_mount_point }}/pi-cluster",
|
||||
src: "10.0.0.6:/volume1/pi-cluster",
|
||||
}
|
||||
- {
|
||||
local: "{{ mac_storage_mount_point }}/syncthing",
|
||||
src: "10.0.0.6:/volume1/syncthing",
|
||||
}
|
||||
- {
|
||||
local: "{{ mac_storage_mount_point }}/media",
|
||||
src: "10.0.0.6:/volume1/media",
|
||||
}
|
||||
- {
|
||||
local: "{{ mac_storage_mount_point }}/nate",
|
||||
src: "10.0.0.6:/volume1/nate",
|
||||
}
|
||||
|
||||
# Add mounts to remove from auto_nfs to the dict below if needed
|
||||
mac_nfs_mounts_remove:
|
||||
# - { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/volume1/pi-cluster" }
|
||||
|
||||
mac_afp_or_smb_mounts_list:
|
||||
- { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/pi-cluster" }
|
||||
- { local: "{{ mac_storage_mount_point }}/syncthing", src: "10.0.0.6:/syncthing" }
|
||||
- {
|
||||
local: "{{ mac_storage_mount_point }}/pi-cluster",
|
||||
src: "10.0.0.6:/pi-cluster",
|
||||
}
|
||||
- {
|
||||
local: "{{ mac_storage_mount_point }}/syncthing",
|
||||
src: "10.0.0.6:/syncthing",
|
||||
}
|
||||
- { local: "{{ mac_storage_mount_point }}/media", src: "10.0.0.6:/media" }
|
||||
- { local: "{{ mac_storage_mount_point }}/nate", src: "10.0.0.6:/nate" }
|
||||
|
||||
@@ -84,48 +120,26 @@ mac_tdarr_file_location: "/Users/{{ ansible_user }}/Library/tdarr"
|
||||
# ---------------------------------- PACKAGES
|
||||
|
||||
apt_packages_list:
|
||||
- bc
|
||||
- coreutils
|
||||
- curl
|
||||
- dnsutils
|
||||
- exa
|
||||
- fzf
|
||||
- git
|
||||
- git-extras
|
||||
- htop
|
||||
- iftop
|
||||
- iotop
|
||||
- iperf
|
||||
- jq
|
||||
- less
|
||||
- lnav
|
||||
- logrotate
|
||||
- lsof
|
||||
- nano
|
||||
- netcat
|
||||
- net-tools
|
||||
- nmap
|
||||
- openssh-server
|
||||
- p7zip-full
|
||||
- python3-pip
|
||||
- rsync
|
||||
- shellcheck
|
||||
- unzip
|
||||
- wget
|
||||
- yamllint
|
||||
- zsh
|
||||
- tailscale
|
||||
|
||||
homebrew_package_list:
|
||||
- ansible
|
||||
- ansible-lint
|
||||
- bash
|
||||
- bash-completion
|
||||
- bashdb
|
||||
- bat
|
||||
- bats-core
|
||||
- coreutils
|
||||
- diff-so-fancy
|
||||
- exa
|
||||
- ffmpeg
|
||||
- findutils
|
||||
- fping
|
||||
@@ -139,17 +153,12 @@ homebrew_package_list:
|
||||
- gnutls
|
||||
- gpg
|
||||
- grep
|
||||
- handbrake
|
||||
- htop
|
||||
- httpie
|
||||
- iperf
|
||||
- jq
|
||||
- nano
|
||||
- ncurses
|
||||
- nmap
|
||||
- openssl
|
||||
- pandoc
|
||||
- prettier
|
||||
- readline
|
||||
- shellcheck
|
||||
- shfmt
|
||||
@@ -157,11 +166,4 @@ homebrew_package_list:
|
||||
- sqlite
|
||||
- ssh-copy-id
|
||||
- tealdeer
|
||||
- tree
|
||||
- wget
|
||||
- yamllint
|
||||
- zsh
|
||||
|
||||
homebrew_cask_install_dir: /Applications
|
||||
homebrew_casks_list:
|
||||
- lingon-x
|
||||
|
||||
@@ -53,13 +53,13 @@
|
||||
|
||||
- name: Restart nomad (Debian)
|
||||
become: true
|
||||
ansible.builtin.systemd:
|
||||
ansible.builtin.systemd_service:
|
||||
name: nomad
|
||||
enabled: true
|
||||
state: restarted
|
||||
register: nomad_service
|
||||
failed_when: nomad_service.rc > 0
|
||||
changed_when: nomad_service.rc == 0
|
||||
# failed_when: nomad_service.Result != "success"
|
||||
# changed_when: nomad_service.Result == "success"
|
||||
when:
|
||||
- ansible_os_family == 'Debian'
|
||||
- "'nostart' not in ansible_run_tags"
|
||||
@@ -90,9 +90,11 @@
|
||||
- name: "Ensure nomad is really running"
|
||||
ansible.builtin.shell:
|
||||
cmd: "set -o pipefail && sleep 10 && /usr/local/bin/nomad node status -self -short | grep {{ inventory_hostname }}"
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: node_status_response
|
||||
failed_when: node_status_response.rc > 0
|
||||
changed_when: node_status_response.rc == 0
|
||||
changed_when: false
|
||||
when: "'nostart' not in ansible_run_tags"
|
||||
listen: "restart nomad"
|
||||
# - name: "Ensure sure Nomad service is really running"
|
||||
|
||||
@@ -106,7 +106,7 @@ all:
|
||||
ansible_user: "{{ my_username }}"
|
||||
ansible_become_pass: "{{ mac_become_pass }}"
|
||||
ansible_ssh_private_key_file: "{{ ssh_key_location }}/macMini"
|
||||
ansible_python_interpreter: "/usr/local/bin/python3"
|
||||
ansible_python_interpreter: "/Users/natelandau/.pyenv/shims/python"
|
||||
ansible_port: 22
|
||||
mac_intel: true
|
||||
is_nomad_client: true
|
||||
|
||||
3
main.yml
3
main.yml
@@ -76,4 +76,5 @@
|
||||
when: is_tdarr_server or is_tdarr_node
|
||||
|
||||
handlers:
|
||||
- ansible.builtin.import_tasks: handlers/main.yml
|
||||
- name: "Run handlers"
|
||||
ansible.builtin.import_tasks: handlers/main.yml
|
||||
|
||||
945
poetry.lock
generated
945
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -7,32 +7,26 @@
|
||||
version = "0.2.0"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
ansible = "^8.6.0"
|
||||
ansible-lint = { version = "^6.18.0", markers = "platform_system != 'Windows'" }
|
||||
commitizen = "^2.40.0"
|
||||
poethepoet = "^0.18.1"
|
||||
pre-commit = "^3.3.3"
|
||||
python = "^3.9"
|
||||
yamllint = "^1.32.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
black = "^23.11.0"
|
||||
sh = "^2.0.6"
|
||||
typos = "^1.16.23"
|
||||
ansible = "^9.3.0"
|
||||
ansible-lint = { version = "^24.2.1", markers = "platform_system != 'Windows'" }
|
||||
commitizen = "^3.18.3"
|
||||
jmespath = "^1.0.1"
|
||||
poethepoet = "^0.25.0"
|
||||
pre-commit = "^3.6.2"
|
||||
python = "^3.11"
|
||||
typos = "^1.19.0"
|
||||
yamllint = "^1.35.1"
|
||||
|
||||
[build-system]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
requires = ["poetry-core"]
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
|
||||
[tool.commitizen]
|
||||
bump_message = "bump(release): v$current_version → v$new_version"
|
||||
tag_format = "v$version"
|
||||
update_changelog_on_bump = true
|
||||
version = "0.2.0"
|
||||
version_files = ["pyproject.toml:version"]
|
||||
version_provider = "poetry"
|
||||
|
||||
[tool.poe.tasks]
|
||||
pb = """
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""Script to update the pyproject.toml file with the latest versions of the dependencies."""
|
||||
from pathlib import Path
|
||||
from textwrap import wrap
|
||||
|
||||
try:
|
||||
import tomllib
|
||||
except ModuleNotFoundError: # pragma: no cover
|
||||
import tomli as tomllib # type: ignore [no-redef]
|
||||
|
||||
import sh
|
||||
from rich.console import Console
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
def dryrun(msg: str) -> None:
|
||||
"""Print a message if the dry run flag is set.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"[cyan]DRYRUN | {msg}[/cyan]")
|
||||
|
||||
|
||||
def success(msg: str) -> None:
|
||||
"""Print a success message without using logging.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"[green]SUCCESS | {msg}[/green]")
|
||||
|
||||
|
||||
def warning(msg: str) -> None:
|
||||
"""Print a warning message without using logging.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"[yellow]WARNING | {msg}[/yellow]")
|
||||
|
||||
|
||||
def error(msg: str) -> None:
|
||||
"""Print an error message without using logging.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"[red]ERROR | {msg}[/red]")
|
||||
|
||||
|
||||
def notice(msg: str) -> None:
|
||||
"""Print a notice message without using logging.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"[bold]NOTICE | {msg}[/bold]")
|
||||
|
||||
|
||||
def info(msg: str) -> None:
|
||||
"""Print a notice message without using logging.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"INFO | {msg}")
|
||||
|
||||
|
||||
def usage(msg: str, width: int = 80) -> None:
|
||||
"""Print a usage message without using logging.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
width (optional): Width of the message
|
||||
"""
|
||||
for _n, line in enumerate(wrap(msg, width=width)):
|
||||
if _n == 0:
|
||||
console.print(f"[dim]USAGE | {line}")
|
||||
else:
|
||||
console.print(f"[dim] | {line}")
|
||||
|
||||
|
||||
def debug(msg: str) -> None:
|
||||
"""Print a debug message without using logging.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"[blue]DEBUG | {msg}[/blue]")
|
||||
|
||||
|
||||
def dim(msg: str) -> None:
|
||||
"""Print a message in dimmed color.
|
||||
|
||||
Args:
|
||||
msg: Message to print
|
||||
"""
|
||||
console.print(f"[dim]{msg}[/dim]")
|
||||
|
||||
|
||||
# Load the pyproject.toml file
|
||||
pyproject = Path(__file__).parents[1] / "pyproject.toml"
|
||||
|
||||
if not pyproject.exists():
|
||||
console.print("pyproject.toml file not found")
|
||||
raise SystemExit(1)
|
||||
|
||||
with pyproject.open("rb") as f:
|
||||
try:
|
||||
data = tomllib.load(f)
|
||||
except tomllib.TOMLDecodeError as e:
|
||||
raise SystemExit(1) from e
|
||||
|
||||
|
||||
# Get the latest versions of all dependencies
|
||||
info("Getting latest versions of dependencies...")
|
||||
packages: dict = {}
|
||||
for line in sh.poetry("--no-ansi", "show", "--outdated").splitlines():
|
||||
package, current, latest = line.split()[:3]
|
||||
packages[package] = {"current_version": current, "new_version": latest}
|
||||
|
||||
if not packages:
|
||||
success("All dependencies are up to date")
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
dependencies = data["tool"]["poetry"]["dependencies"]
|
||||
groups = data["tool"]["poetry"]["group"]
|
||||
|
||||
for p in dependencies:
|
||||
if p in packages:
|
||||
notice(
|
||||
f"Updating {p} from {packages[p]['current_version']} to {packages[p]['new_version']}"
|
||||
)
|
||||
sh.poetry("add", f"{p}@latest", _fg=True)
|
||||
|
||||
|
||||
for group in groups:
|
||||
for p in groups[group]["dependencies"]:
|
||||
if p in packages:
|
||||
notice(
|
||||
f"Updating {p} from {packages[p]['current_version']} to {packages[p]['new_version']}"
|
||||
)
|
||||
sh.poetry("add", f"{p}@latest", "--group", group, _fg=True)
|
||||
|
||||
sh.poetry("update", _fg=True)
|
||||
success("All dependencies are up to date")
|
||||
raise SystemExit(0)
|
||||
@@ -24,24 +24,18 @@
|
||||
when:
|
||||
- is_nomad_client or is_nomad_server
|
||||
|
||||
- name: Ensure nomad user can run sudo with the restore script
|
||||
- name: "SUDO: Confirm users can run service_backups"
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/sudoers
|
||||
path: "/etc/sudoers.d/010_{{ item }}-backups-nopasswd"
|
||||
line: "{{ item }} ALL=(ALL) NOPASSWD: /usr/local/bin/service_backups, /usr/local/bin/service_restore"
|
||||
state: present
|
||||
line: "nomad ALL=(ALL) NOPASSWD: /usr/local/bin/service_backups, /usr/local/bin/service_restore"
|
||||
validate: "/usr/sbin/visudo -cf %s"
|
||||
when:
|
||||
- is_nomad_client or is_nomad_server
|
||||
- "'pis' in group_names"
|
||||
|
||||
- name: Ensure my user can run sudo with the restore script
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/sudoers
|
||||
state: present
|
||||
line: "{{ ansible_user }} ALL=(ALL) NOPASSWD: /usr/local/bin/service_backups, /usr/local/bin/service_restore"
|
||||
create: true
|
||||
mode: "0440"
|
||||
validate: "/usr/sbin/visudo -cf %s"
|
||||
loop:
|
||||
- nomad
|
||||
- "{{ ansible_user }}"
|
||||
when:
|
||||
- is_nomad_client or is_nomad_server
|
||||
- "'pis' in group_names"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# yamllint disable rule:indentation
|
||||
---
|
||||
# TASK DESCRIPTION:
|
||||
# Downloads, installs, and configures Hashicorp Consul.
|
||||
@@ -117,7 +118,7 @@
|
||||
|
||||
- name: "Create Consul /opt storage and copy certificates"
|
||||
block:
|
||||
- name: "Create {{ consul_opt_dir }} directories"
|
||||
- name: "Create {{ consul_opt_dir }} directories" # noqa: name[template]
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
@@ -130,16 +131,25 @@
|
||||
- "{{ consul_opt_dir }}/plugins"
|
||||
- "{{ consul_opt_dir }}/certs"
|
||||
|
||||
- name: Copy certs to servers
|
||||
- name: Copy certs to servers # noqa
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: 0755
|
||||
loop:
|
||||
- { src: "certs/consul/consul-agent-ca.pem", dest: "{{ consul_opt_dir }}/certs/consul-agent-ca.pem" }
|
||||
- { src: "certs/consul/{{ datacenter_name }}-server-consul-0.pem", dest: "{{ consul_opt_dir }}/certs/{{ datacenter_name }}-server-consul-0.pem" }
|
||||
- { src: "certs/consul/{{ datacenter_name }}-server-consul-0-key.pem", dest: "{{ consul_opt_dir }}/certs/{{ datacenter_name }}-server-consul-0-key.pem" }
|
||||
- {
|
||||
src: "certs/consul/consul-agent-ca.pem",
|
||||
dest: "{{ consul_opt_dir }}/certs/consul-agent-ca.pem",
|
||||
}
|
||||
- {
|
||||
src: "certs/consul/{{ datacenter_name }}-server-consul-0.pem",
|
||||
dest: "{{ consul_opt_dir }}/certs/{{ datacenter_name }}-server-consul-0.pem",
|
||||
}
|
||||
- {
|
||||
src: "certs/consul/{{ datacenter_name }}-server-consul-0-key.pem",
|
||||
dest: "{{ consul_opt_dir }}/certs/{{ datacenter_name }}-server-consul-0-key.pem",
|
||||
}
|
||||
when:
|
||||
- is_consul_server
|
||||
|
||||
@@ -163,7 +173,7 @@
|
||||
when:
|
||||
- ansible_os_family == 'Debian'
|
||||
|
||||
- name: "Set owner of files to {{ ansible_user_uid }}:{{ ansible_user_gid }}"
|
||||
- name: "Set owner of files to {{ ansible_user_uid }}:{{ ansible_user_gid }}" # noqa: name[template]
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ consul_opt_dir }}"
|
||||
@@ -199,7 +209,7 @@
|
||||
when:
|
||||
- ansible_os_family == 'Debian'
|
||||
|
||||
- name: "Set owner of files to {{ ansible_user_uid }}:{{ ansible_user_gid }}"
|
||||
- name: "Set owner of files to {{ ansible_user_uid }}:{{ ansible_user_gid }}" # noqa: name[template]
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ interpolated_consul_configuration_dir }}"
|
||||
@@ -209,7 +219,7 @@
|
||||
when:
|
||||
- mac_intel or mac_arm or inventory_hostname == 'synology'
|
||||
|
||||
- name: "Set owner of root consul dir to {{ ansible_user_uid }}:{{ ansible_user_gid }} (synology)"
|
||||
- name: "Set owner of root consul dir to {{ ansible_user_uid }}:{{ ansible_user_gid }} (synology)" # noqa: name[template]
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: /volume1/docker/consul/
|
||||
@@ -328,7 +338,7 @@
|
||||
- ansible_os_family == 'Debian'
|
||||
- "'nostart' not in ansible_run_tags"
|
||||
|
||||
- name: Make sure Consul service is really running
|
||||
- name: Make sure Consul service is really running # noqa: command-instead-of-module
|
||||
ansible.builtin.command:
|
||||
cmd: systemctl is-active consul
|
||||
register: is_consul_really_running
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# NOTE: This task exists due to the arillso.logrotate failing completely on macOS
|
||||
|
||||
- name: Add service_backups.log to logrotate
|
||||
- name: Add service_backups.log to logrotate # noqa: ignore-errors
|
||||
become: true
|
||||
vars:
|
||||
logrotate_applications:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# yamllint disable rule:indentation
|
||||
---
|
||||
# TASK DESCRIPTION:
|
||||
# Downloads, installs, and configures Hashicorp Nomad.
|
||||
@@ -83,7 +84,7 @@
|
||||
|
||||
- name: "Create Nomad /opt storage"
|
||||
block:
|
||||
- name: "Create {{ nomad_opt_dir_location }} directories"
|
||||
- name: "Create {{ nomad_opt_dir_location }} directories" # noqa: name[template]
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
@@ -102,9 +103,18 @@
|
||||
dest: "{{ item.dest }}"
|
||||
mode: 0755
|
||||
loop:
|
||||
- { src: certs/nomad/nomad-ca.pem, dest: "{{ nomad_opt_dir_location }}/certs/nomad-ca.pem" }
|
||||
- { src: certs/nomad/server.pem, dest: "{{ nomad_opt_dir_location }}/certs/server.pem" }
|
||||
- { src: certs/nomad/server-key.pem, dest: "{{ nomad_opt_dir_location }}/certs/server-key.pem" }
|
||||
- {
|
||||
src: certs/nomad/nomad-ca.pem,
|
||||
dest: "{{ nomad_opt_dir_location }}/certs/nomad-ca.pem",
|
||||
}
|
||||
- {
|
||||
src: certs/nomad/server.pem,
|
||||
dest: "{{ nomad_opt_dir_location }}/certs/server.pem",
|
||||
}
|
||||
- {
|
||||
src: certs/nomad/server-key.pem,
|
||||
dest: "{{ nomad_opt_dir_location }}/certs/server-key.pem",
|
||||
}
|
||||
notify: "restart nomad"
|
||||
when: is_nomad_server
|
||||
|
||||
@@ -115,9 +125,18 @@
|
||||
dest: "{{ item.dest }}"
|
||||
mode: 0755
|
||||
loop:
|
||||
- { src: certs/nomad/nomad-ca.pem, dest: "{{ nomad_opt_dir_location }}/certs/nomad-ca.pem" }
|
||||
- { src: certs/nomad/client.pem, dest: "{{ nomad_opt_dir_location }}/certs/client.pem" }
|
||||
- { src: certs/nomad/client-key.pem, dest: "{{ nomad_opt_dir_location }}/certs/client-key.pem" }
|
||||
- {
|
||||
src: certs/nomad/nomad-ca.pem,
|
||||
dest: "{{ nomad_opt_dir_location }}/certs/nomad-ca.pem",
|
||||
}
|
||||
- {
|
||||
src: certs/nomad/client.pem,
|
||||
dest: "{{ nomad_opt_dir_location }}/certs/client.pem",
|
||||
}
|
||||
- {
|
||||
src: certs/nomad/client-key.pem,
|
||||
dest: "{{ nomad_opt_dir_location }}/certs/client-key.pem",
|
||||
}
|
||||
notify: "restart nomad"
|
||||
when: is_nomad_client
|
||||
|
||||
@@ -130,7 +149,7 @@
|
||||
recurse: true
|
||||
when: ansible_os_family == 'Debian'
|
||||
|
||||
- name: "Set owner of files to {{ ansible_user_uid }}:{{ ansible_user_gid }} (MacOSX)"
|
||||
- name: "Set owner of files to {{ ansible_user_uid }}:{{ ansible_user_gid }} (MacOSX)" # noqa: name[template]
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ nomad_opt_dir_location }}"
|
||||
|
||||
@@ -74,3 +74,15 @@
|
||||
dest: "{{ docker_compose_file_location }}/{{ item | basename | regex_replace('.j2$', '') }}"
|
||||
mode: 0644
|
||||
with_fileglob: "../templates/docker_compose_files/*.j2"
|
||||
|
||||
- name: "Prune docker caches"
|
||||
community.docker.docker_prune:
|
||||
containers: true
|
||||
images: true
|
||||
images_filters:
|
||||
dangling: false
|
||||
networks: true
|
||||
volumes: true
|
||||
builder_cache: true
|
||||
when:
|
||||
- is_docker_compose_client or is_nomad_client or is_nomad_server
|
||||
|
||||
@@ -54,14 +54,14 @@
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ homebrew_output.unchanged_pkgs }}"
|
||||
|
||||
- name: Install homebrew casks
|
||||
community.general.homebrew_cask:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
install_options: "appdir=/Applications"
|
||||
accept_external_apps: true
|
||||
upgrade_all: false
|
||||
update_homebrew: false
|
||||
greedy: false
|
||||
loop: "{{ homebrew_casks_list }}"
|
||||
ignore_errors: true
|
||||
# - name: Install homebrew casks # noqa: ignore-errors
|
||||
# community.general.homebrew_cask:
|
||||
# name: "{{ item }}"
|
||||
# state: present
|
||||
# install_options: "appdir=/Applications"
|
||||
# accept_external_apps: true
|
||||
# upgrade_all: false
|
||||
# update_homebrew: false
|
||||
# greedy: false
|
||||
# loop: "{{ homebrew_casks_list }}"
|
||||
# ignore_errors: true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# yamllint disable rule:indentation
|
||||
---
|
||||
# TASK DESCRIPTION:
|
||||
# Downloads, installs, and configures Telegraf
|
||||
@@ -206,7 +207,7 @@
|
||||
|
||||
- name: "Configure Telegraf"
|
||||
block:
|
||||
- name: "Ensure {{ telegraph_config_location }} exists"
|
||||
- name: "Ensure {{ telegraph_config_location }} exists" # noqa: name[template]
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
@@ -223,10 +224,22 @@
|
||||
dest: "{{ item.dest }}"
|
||||
mode: "644"
|
||||
loop:
|
||||
- { src: "telegraf/base_config.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.conf" }
|
||||
- { src: "telegraf/custom_metrics.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/custom_metrics.conf" }
|
||||
- { src: "telegraf/nomad.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/nomad.conf" }
|
||||
- { src: "telegraf/docker.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/docker.conf" }
|
||||
- {
|
||||
src: "telegraf/base_config.conf.j2",
|
||||
dest: "{{ telegraph_config_location }}/telegraf.conf",
|
||||
}
|
||||
- {
|
||||
src: "telegraf/custom_metrics.conf.j2",
|
||||
dest: "{{ telegraph_config_location }}/telegraf.d/custom_metrics.conf",
|
||||
}
|
||||
- {
|
||||
src: "telegraf/nomad.conf.j2",
|
||||
dest: "{{ telegraph_config_location }}/telegraf.d/nomad.conf",
|
||||
}
|
||||
- {
|
||||
src: "telegraf/docker.conf.j2",
|
||||
dest: "{{ telegraph_config_location }}/telegraf.d/docker.conf",
|
||||
}
|
||||
notify: restart_telegraf
|
||||
|
||||
- name: Template leader configs (ie, configs that should be placed on a single server)
|
||||
@@ -236,9 +249,18 @@
|
||||
dest: "{{ item.dest }}"
|
||||
mode: "644"
|
||||
loop:
|
||||
- { src: "telegraf/leader.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/leader.conf" }
|
||||
- { src: "telegraf/speedtest.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/speedtest.conf" }
|
||||
- { src: "telegraf/pingHosts.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/pingHosts.conf" }
|
||||
- {
|
||||
src: "telegraf/leader.conf.j2",
|
||||
dest: "{{ telegraph_config_location }}/telegraf.d/leader.conf",
|
||||
}
|
||||
- {
|
||||
src: "telegraf/speedtest.conf.j2",
|
||||
dest: "{{ telegraph_config_location }}/telegraf.d/speedtest.conf",
|
||||
}
|
||||
- {
|
||||
src: "telegraf/pingHosts.conf.j2",
|
||||
dest: "{{ telegraph_config_location }}/telegraf.d/pingHosts.conf",
|
||||
}
|
||||
when:
|
||||
- is_cluster_leader
|
||||
notify: restart_telegraf
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
{% if is_consul_server %}
|
||||
"server" = true
|
||||
"ui_config" = {
|
||||
"enabled" = true
|
||||
"enabled" = true
|
||||
}
|
||||
{% else %}
|
||||
"ui_config" = {
|
||||
"enabled" = false
|
||||
"enabled" = false
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
@@ -28,15 +28,15 @@
|
||||
|
||||
# ----------------------------------------- Networking
|
||||
"addresses" = {
|
||||
"dns" = "0.0.0.0"
|
||||
"grpc" = "0.0.0.0"
|
||||
"http" = "0.0.0.0"
|
||||
"https" = "0.0.0.0"
|
||||
"dns" = "0.0.0.0"
|
||||
"grpc" = "0.0.0.0"
|
||||
"http" = "0.0.0.0"
|
||||
"https" = "0.0.0.0"
|
||||
}
|
||||
"ports" = {
|
||||
"dns" = 8600
|
||||
"http" = 8500
|
||||
"server" = 8300
|
||||
"dns" = 8600
|
||||
"http" = 8500
|
||||
"server" = 8300
|
||||
}
|
||||
|
||||
{% if 'linode' in group_names %}
|
||||
@@ -57,7 +57,7 @@
|
||||
{% if 'linode' in group_names %}
|
||||
"retry_join" = [{% for h in groups['linode-cluster'] if hostvars[h].is_consul_server == true %}"{{ hostvars[h].linode_private_ip }}"{% if not loop.last %}, {% endif %}{% endfor %}]
|
||||
{% else %}
|
||||
"retry_join" = [{% for h in groups['lan'] if hostvars[h].is_consul_server == true %}"{{ hostvars[h].ansible_host }}"{% if not loop.last %}, {% endif %}{% endfor %}]
|
||||
"retry_join" = ["{{ rpi1_ip_address }}", "{{ rpi2_ip_address }}", "{{ rpi3_ip_address }}"]
|
||||
{% if is_consul_server %}
|
||||
{% if 'linode' in group_names %}
|
||||
"join_wan" = [{% for h in groups['linode-cluster'] if hostvars[h].is_consul_server == true %}"{{ hostvars[h].ansible_host }}"{% if not loop.last %}, {% endif %}{% endfor %}]
|
||||
@@ -81,7 +81,7 @@
|
||||
"key_file" = "{{ consul_opt_dir }}/certs/{{ datacenter_name }}-server-consul-0-key.pem"
|
||||
{% endif %}
|
||||
"auto_encrypt" = {
|
||||
"allow_tls" = true
|
||||
"allow_tls" = true
|
||||
}
|
||||
{% else %} {# Consul Clients #}
|
||||
"verify_incoming" = false
|
||||
@@ -93,14 +93,14 @@
|
||||
"ca_file" = "{{ consul_opt_dir }}/certs/consul-agent-ca.pem"
|
||||
{% endif %}
|
||||
"auto_encrypt" = {
|
||||
"tls" = true
|
||||
"tls" = true
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
"acl" = {
|
||||
enabled = false
|
||||
default_policy = "allow"
|
||||
enable_token_persistence = true
|
||||
default_policy = "allow"
|
||||
enable_token_persistence = true
|
||||
enabled = false
|
||||
}
|
||||
|
||||
# ----------------------------------------- Cluster Operations
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
"traefik.http.routers.sabnzbd.entryPoints=web,websecure",
|
||||
"traefik.http.routers.sabnzbd.service=sabnzbd",
|
||||
"traefik.http.routers.sabnzbd.tls=true",
|
||||
"traefik.http.routers.sabnzbd.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.sabnzbd.middlewares=authelia@file"
|
||||
"traefik.http.routers.sabnzbd.tls.certresolver=cloudflare"
|
||||
],
|
||||
"checks": [{
|
||||
"id": "sabnzbd-http-check",
|
||||
@@ -21,6 +20,27 @@
|
||||
"failures_before_critical": 3
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "jellyfin",
|
||||
"id": "jellyfin",
|
||||
"tags": [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.services.jellyfin.loadbalancer.server.port=8096",
|
||||
"traefik.http.routers.jellyfin.rule=Host(`jellyfin.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.jellyfin.entryPoints=web,websecure",
|
||||
"traefik.http.routers.jellyfin.service=jellyfin",
|
||||
"traefik.http.routers.jellyfin.tls=true",
|
||||
"traefik.http.routers.jellyfin.tls.certresolver=cloudflare"
|
||||
],
|
||||
"checks": [{
|
||||
"id": "jellyfin-http-check",
|
||||
"http": "http://{{ synology_second_ip }}:8096",
|
||||
"interval": "30s",
|
||||
"timeout": "5s",
|
||||
"success_before_passing": 3,
|
||||
"failures_before_critical": 3
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "synology",
|
||||
"id": "synology",
|
||||
|
||||
17
templates/docker_compose_files/synology_jellyfin.yml.j2
Normal file
17
templates/docker_compose_files/synology_jellyfin.yml.j2
Normal file
@@ -0,0 +1,17 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
jellyfin:
|
||||
image: lscr.io/linuxserver/jellyfin:latest
|
||||
hostname: jellyfin
|
||||
container_name: jellyfin
|
||||
network_mode: "host"
|
||||
environment:
|
||||
- "TZ=America/New_York"
|
||||
- "PGID=101"
|
||||
- "PUID={{ ansible_user_uid }}"
|
||||
volumes:
|
||||
- /volume1/pi-cluster/jellyfin:/config
|
||||
- /volume1/media/media/movies:/data/movies
|
||||
- /volume1/media/media/tv:/data/tv
|
||||
restart: unless-stopped
|
||||
@@ -2,7 +2,7 @@ version: '3.9'
|
||||
|
||||
services:
|
||||
sabnzbd:
|
||||
image: ghcr.io/linuxserver/sabnzbd
|
||||
image: ghcr.io/linuxserver/sabnzbd:{{ sabnzbd_version }}
|
||||
hostname: sabnzbd
|
||||
container_name: sabnzbd
|
||||
network_mode: "bridge"
|
||||
@@ -10,13 +10,15 @@ services:
|
||||
- "TZ=America/New_York"
|
||||
- "PGID=101"
|
||||
- "PUID={{ ansible_user_uid }}"
|
||||
#- "DOCKER_MODS=linuxserver/mods:universal-cron"
|
||||
volumes:
|
||||
- /var/services/homes/{{ my_username }}:/{{ my_username }}
|
||||
- /volume1/nate:/nate
|
||||
- /volume1/media/downloads/nzb:/nzbd
|
||||
- /volume1/media/downloads/temp:/incomplete-downloads
|
||||
- /volume1/media/downloads/complete:/downloads
|
||||
- /volume1/docker/sabnzbd:/config
|
||||
- /volume1/pi-cluster/sabnzbd:/config
|
||||
- /volume1/pi-cluster/sabnzbd/startup-scripts:/custom-cont-init.d
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 9090:9090
|
||||
|
||||
@@ -5,28 +5,28 @@ datacenter = "{{ datacenter_name }}"
|
||||
|
||||
# ----------------------------------------- Files and Logs
|
||||
data_dir = "{{ nomad_opt_dir_location }}"
|
||||
plugin_dir = "{{ nomad_opt_dir_location }}/plugins"
|
||||
log_level = "warn"
|
||||
log_file = "{{ nomad_opt_dir_location }}/logs/nomad.log"
|
||||
log_rotate_max_files = 5
|
||||
enable_syslog = false
|
||||
log_file = "{{ nomad_opt_dir_location }}/logs/nomad.log"
|
||||
log_level = "warn"
|
||||
log_rotate_max_files = 5
|
||||
plugin_dir = "{{ nomad_opt_dir_location }}/plugins"
|
||||
|
||||
# ----------------------------------------- Networking
|
||||
bind_addr = "0.0.0.0" # the default
|
||||
|
||||
advertise {
|
||||
{% if 'linode' in group_names %}
|
||||
http = "{{ linode_private_ip }}:4646"
|
||||
rpc = "{{ linode_private_ip }}:4647"
|
||||
serf = "{{ linode_private_ip }}:4648" # non-default ports may be specified
|
||||
http = "{{ linode_private_ip }}:4646"
|
||||
rpc = "{{ linode_private_ip }}:4647"
|
||||
serf = "{{ linode_private_ip }}:4648" # non-default ports may be specified
|
||||
{% elif 'synology' in group_names %}
|
||||
http = "{{ synology_second_ip }}:4646"
|
||||
rpc = "{{ synology_second_ip }}:4647"
|
||||
serf = "{{ synology_second_ip }}:4648" # non-default ports may be specified
|
||||
http = "{{ synology_second_ip }}:4646"
|
||||
rpc = "{{ synology_second_ip }}:4647"
|
||||
serf = "{{ synology_second_ip }}:4648" # non-default ports may be specified
|
||||
{% else %}
|
||||
http = "{{ ansible_host }}:4646"
|
||||
rpc = "{{ ansible_host }}:4647"
|
||||
serf = "{{ ansible_host }}:4648" # non-default ports may be specified
|
||||
http = "{{ ansible_host }}:4646"
|
||||
rpc = "{{ ansible_host }}:4647"
|
||||
serf = "{{ ansible_host }}:4648" # non-default ports may be specified
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
@@ -48,170 +48,171 @@ consul {
|
||||
|
||||
{% if is_nomad_server %}
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.nomad-server.entryPoints=web,websecure",
|
||||
"traefik.http.routers.nomad-server.service=nomad-server",
|
||||
"traefik.http.routers.nomad-server.rule=Host(`nomad.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.nomad-server.tls=true",
|
||||
"traefik.http.routers.nomad-server.middlewares=authelia@file,redirectScheme@file",
|
||||
"traefik.http.services.nomad-server.loadbalancer.server.port=4646"
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.nomad-server.entryPoints=web,websecure",
|
||||
"traefik.http.routers.nomad-server.service=nomad-server",
|
||||
"traefik.http.routers.nomad-server.rule=Host(`nomad.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.nomad-server.tls=true",
|
||||
"traefik.http.routers.nomad-server.middlewares=redirectScheme@file",
|
||||
"traefik.http.services.nomad-server.loadbalancer.server.port=4646"
|
||||
]
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
# ----------------------------------------- Client Config
|
||||
client {
|
||||
enabled = true
|
||||
enabled = true
|
||||
{% if 'pis' in group_names %}
|
||||
node_class = "rpi"
|
||||
node_class = "rpi"
|
||||
{% elif 'macs' in group_names %}
|
||||
node_class = "mac"
|
||||
node_class = "mac"
|
||||
{% elif 'synology' in group_names %}
|
||||
node_class = "synology"
|
||||
node_class = "synology"
|
||||
{% endif %}
|
||||
reserved {
|
||||
cpu = 250
|
||||
memory = 100
|
||||
reserved_ports = "22"
|
||||
}
|
||||
reserved {
|
||||
cpu = 250
|
||||
memory = 100
|
||||
reserved_ports = "22"
|
||||
}
|
||||
{% if not is_nomad_server %}
|
||||
{% if 'linode' in group_names %}
|
||||
server_join {
|
||||
retry_join = [{% for h in groups['linode'] if hostvars[h].is_nomad_server == true %}"{{ hostvars[h].ansible_host }}"{% if not loop.last %}, {% endif %}{% endfor %}]
|
||||
retry_max = 3
|
||||
retry_interval = "15s"
|
||||
}
|
||||
server_join {
|
||||
retry_join = [{% for h in groups['linode'] if hostvars[h].is_nomad_server == true %}"{{ hostvars[h].ansible_host }}"{% if not loop.last %}, {% endif %}{% endfor %}]
|
||||
retry_max = 3
|
||||
retry_interval = "15s"
|
||||
}
|
||||
{% else %}
|
||||
server_join {
|
||||
retry_join = [{% for h in groups['lan'] if hostvars[h].is_nomad_server == true %}"{{ hostvars[h].ansible_host }}"{% if not loop.last %}, {% endif %}{% endfor %}]
|
||||
retry_max = 3
|
||||
retry_interval = "15s"
|
||||
}
|
||||
servers = ["{{ rpi1_ip_address }}", "{{ rpi2_ip_address }}", "{{ rpi3_ip_address }}"]
|
||||
server_join {
|
||||
retry_join = ["{{ rpi1_ip_address }}", "{{ rpi2_ip_address }}", "{{ rpi3_ip_address }}"]
|
||||
retry_max = 3
|
||||
retry_interval = "15s"
|
||||
}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
meta {
|
||||
# These are variables that can be used in Nomad job files
|
||||
PUID = "{{ ansible_user_uid }}"
|
||||
PGID = "{{ ansible_user_gid }}"
|
||||
nfsStorageRoot = "{{ interpolated_nfs_service_storage }}"
|
||||
localStorageRoot = "{{ interpolated_localfs_service_storage }}"
|
||||
{% if 'macs' in group_names %}
|
||||
restoreCommand = "/usr/local/bin/service_restore"
|
||||
restoreCommand1 = "--verbose"
|
||||
restoreCommand2 = "--job"
|
||||
restoreCommand3 = ""
|
||||
backupCommand = "/usr/local/bin/service_backups"
|
||||
backupCommandArg1 = "--verbose"
|
||||
backupCommandArg2 = "--loglevel=INFO"
|
||||
backupCommandArg3 = ""
|
||||
backupAllocArg1 = "--verbose"
|
||||
backupAllocArg2 = "--loglevel=INFO"
|
||||
backupAllocArg3 = "--allocation"
|
||||
backupAllocArg4 = "--delete"
|
||||
backupAllocArg5 = "--job"
|
||||
backupAllocArg6 = ""
|
||||
{% else %}
|
||||
restoreCommand = "sudo"
|
||||
restoreCommand1 = "/usr/local/bin/service_restore"
|
||||
restoreCommand2 = "--job"
|
||||
restoreCommand3 = "--verbose"
|
||||
backupCommand = "sudo"
|
||||
backupCommandArg1 = "/usr/local/bin/service_backups"
|
||||
backupCommandArg2 = "--verbose"
|
||||
backupCommandArg3 = "--loglevel=INFO"
|
||||
backupAllocArg1 = "/usr/local/bin/service_backups"
|
||||
backupAllocArg2 = "--verbose"
|
||||
backupAllocArg3 = "--loglevel=INFO"
|
||||
backupAllocArg4 = "--allocation"
|
||||
backupAllocArg5 = "--job"
|
||||
backupAllocArg6 = "--delete"
|
||||
{% endif %}
|
||||
}
|
||||
meta {
|
||||
# These are variables that can be used in Nomad job files
|
||||
PUID = "{{ ansible_user_uid }}"
|
||||
PGID = "{{ ansible_user_gid }}"
|
||||
nfsStorageRoot = "{{ interpolated_nfs_service_storage }}"
|
||||
localStorageRoot = "{{ interpolated_localfs_service_storage }}"
|
||||
{% if 'macs' in group_names %}
|
||||
restoreCommand = "/usr/local/bin/service_restore"
|
||||
restoreCommand1 = "--verbose"
|
||||
restoreCommand2 = "--job"
|
||||
restoreCommand3 = ""
|
||||
backupCommand = "/usr/local/bin/service_backups"
|
||||
backupCommandArg1 = "--verbose"
|
||||
backupCommandArg2 = "--loglevel=INFO"
|
||||
backupCommandArg3 = ""
|
||||
backupAllocArg1 = "--verbose"
|
||||
backupAllocArg2 = "--loglevel=INFO"
|
||||
backupAllocArg3 = "--allocation"
|
||||
backupAllocArg4 = "--delete"
|
||||
backupAllocArg5 = "--job"
|
||||
backupAllocArg6 = ""
|
||||
{% else %}
|
||||
restoreCommand = "sudo"
|
||||
restoreCommand1 = "/usr/local/bin/service_restore"
|
||||
restoreCommand2 = "--job"
|
||||
restoreCommand3 = "--verbose"
|
||||
backupCommand = "sudo"
|
||||
backupCommandArg1 = "/usr/local/bin/service_backups"
|
||||
backupCommandArg2 = "--verbose"
|
||||
backupCommandArg3 = "--loglevel=INFO"
|
||||
backupAllocArg1 = "/usr/local/bin/service_backups"
|
||||
backupAllocArg2 = "--verbose"
|
||||
backupAllocArg3 = "--loglevel=INFO"
|
||||
backupAllocArg4 = "--allocation"
|
||||
backupAllocArg5 = "--job"
|
||||
backupAllocArg6 = "--delete"
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
} # /client
|
||||
|
||||
{% if is_nomad_server %}
|
||||
# ----------------------------------------- Server Config
|
||||
server {
|
||||
enabled = true
|
||||
encrypt = "{{ nomad_encryption_key }}"
|
||||
enabled = true
|
||||
encrypt = "{{ nomad_encryption_key }}"
|
||||
{% if 'linode' in group_names %}
|
||||
bootstrap_expect = 1
|
||||
bootstrap_expect = 1
|
||||
{% else %}
|
||||
bootstrap_expect = 3
|
||||
bootstrap_expect = 3
|
||||
{% endif %}
|
||||
node_gc_threshold = "15m"
|
||||
job_gc_interval = "15m"
|
||||
job_gc_threshold = "6h"
|
||||
heartbeat_grace = "60s"
|
||||
min_heartbeat_ttl = "20s"
|
||||
raft_protocol = "3"
|
||||
node_gc_threshold = "15m"
|
||||
job_gc_interval = "15m"
|
||||
job_gc_threshold = "6h"
|
||||
heartbeat_grace = "60s"
|
||||
min_heartbeat_ttl = "20s"
|
||||
raft_protocol = "3"
|
||||
|
||||
server_join {
|
||||
retry_join = [{% for h in groups['lan'] if hostvars[h].is_nomad_server == true %}"{{ hostvars[h].ansible_host }}"{% if not loop.last %}, {% endif %}{% endfor %}]
|
||||
retry_max = 3
|
||||
retry_interval = "15s"
|
||||
}
|
||||
server_join {
|
||||
retry_join = ["{{ rpi1_ip_address }}", "{{ rpi2_ip_address }}", "{{ rpi3_ip_address }}"]
|
||||
retry_max = 3
|
||||
retry_interval = "15s"
|
||||
}
|
||||
}
|
||||
|
||||
autopilot {
|
||||
cleanup_dead_servers = true
|
||||
last_contact_threshold = "200ms"
|
||||
max_trailing_logs = 250
|
||||
server_stabilization_time = "10s"
|
||||
enable_redundancy_zones = false
|
||||
disable_upgrade_migration = false
|
||||
enable_custom_upgrades = false
|
||||
cleanup_dead_servers = true
|
||||
disable_upgrade_migration = false
|
||||
enable_custom_upgrades = false
|
||||
enable_redundancy_zones = false
|
||||
last_contact_threshold = "200ms"
|
||||
max_trailing_logs = 250
|
||||
server_stabilization_time = "10s"
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if is_nomad_server and is_nomad_client %}
|
||||
client {
|
||||
enabled = true
|
||||
enabled = true
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
# ----------------------------------------- Telemety
|
||||
telemetry = {
|
||||
publish_allocation_metrics = true
|
||||
publish_node_metrics = true
|
||||
collection_interval = "10s"
|
||||
filter_default = false
|
||||
datadog_address = "localhost:8125"
|
||||
prefix_filter = [
|
||||
"+nomad.client.allocations.running",
|
||||
"+nomad.client.allocations.terminal",
|
||||
"+nomad.client.allocs.cpu.allocated",
|
||||
"+nomad.client.allocs.cpu.total_percent",
|
||||
"+nomad.client.allocs.memory.allocated",
|
||||
"+nomad.client.allocs.memory.swap",
|
||||
"+nomad.client.allocs.memory.usage",
|
||||
"+nomad.nomad.job_status.dead",
|
||||
"+nomad.nomad.job_status.running",
|
||||
"+nomad.nomad.job_status.pending",
|
||||
"+nomad.nomad.job_summary.running",
|
||||
"+nomad.nomad.job_summary.complete",
|
||||
"+nomad.nomad.job_summary.lost",
|
||||
"+nomad.nomad.job_summary.failed"]
|
||||
collection_interval = "10s"
|
||||
datadog_address = "localhost:8125"
|
||||
filter_default = false
|
||||
publish_allocation_metrics = true
|
||||
publish_node_metrics = true
|
||||
prefix_filter = [
|
||||
"+nomad.client.allocations.running",
|
||||
"+nomad.client.allocations.terminal",
|
||||
"+nomad.client.allocs.cpu.allocated",
|
||||
"+nomad.client.allocs.cpu.total_percent",
|
||||
"+nomad.client.allocs.memory.allocated",
|
||||
"+nomad.client.allocs.memory.swap",
|
||||
"+nomad.client.allocs.memory.usage",
|
||||
"+nomad.nomad.job_status.dead",
|
||||
"+nomad.nomad.job_status.running",
|
||||
"+nomad.nomad.job_status.pending",
|
||||
"+nomad.nomad.job_summary.running",
|
||||
"+nomad.nomad.job_summary.complete",
|
||||
"+nomad.nomad.job_summary.lost",
|
||||
"+nomad.nomad.job_summary.failed"
|
||||
]
|
||||
}
|
||||
|
||||
# ----------------------------------------- Plugins
|
||||
plugin "raw_exec" {
|
||||
config {
|
||||
enabled = true
|
||||
}
|
||||
config {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
plugin "docker" {
|
||||
config {
|
||||
allow_caps = ["all"]
|
||||
allow_privileged = true
|
||||
extra_labels = ["job_name"]
|
||||
volumes {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
allow_caps = ["all"]
|
||||
allow_privileged = true
|
||||
extra_labels = ["job_name", "job_id", "task_group_name", "task_name", "namespace", "node_name", "node_id"]
|
||||
volumes {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
job "backup_local_filesystems" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "sysbatch"
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "sysbatch"
|
||||
|
||||
periodic {
|
||||
cron = "0 */8 * * * *"
|
||||
prohibit_overlap = true
|
||||
time_zone = "America/New_York"
|
||||
}
|
||||
|
||||
task "do_backups" {
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.backupCommand}"
|
||||
args = ["${meta.backupCommandArg1}", "${meta.backupCommandArg2}", "${meta.backupCommandArg3}"]
|
||||
periodic {
|
||||
cron = "0 */8 * * * *"
|
||||
prohibit_overlap = true
|
||||
time_zone = "America/New_York"
|
||||
}
|
||||
} // /task do_backups
|
||||
|
||||
task "do_backups" {
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.backupCommand}"
|
||||
args = ["${meta.backupCommandArg1}", "${meta.backupCommandArg2}", "${meta.backupCommandArg3}"]
|
||||
}
|
||||
} // /task do_backups
|
||||
|
||||
} //job
|
||||
|
||||
@@ -1,109 +1,110 @@
|
||||
job "diagnostics" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
operator = "regexp"
|
||||
value = "rpi1"
|
||||
}
|
||||
|
||||
group "diagnostics" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
operator = "regexp"
|
||||
value = "macmini"
|
||||
}
|
||||
|
||||
network {
|
||||
port "whoami" {
|
||||
to = 80
|
||||
}
|
||||
}
|
||||
group "diagnostics" {
|
||||
|
||||
task "diagnostics" {
|
||||
count = 1
|
||||
|
||||
// env {
|
||||
// KEY = "VALUE"
|
||||
// }
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "alpine:latest"
|
||||
hostname = "${NOMAD_JOB_NAME}"
|
||||
args = [
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"chmod 755 /local/bootstrap.sh && /local/bootstrap.sh"
|
||||
]
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/pi-cluster/backups/config_backups:/backups",
|
||||
"${meta.localStorageRoot}:/docker"
|
||||
]
|
||||
} // docker config
|
||||
|
||||
template {
|
||||
destination = "local/bootstrap.sh"
|
||||
data = <<EOH
|
||||
#!/bin/sh
|
||||
|
||||
apk update
|
||||
apk add --no-cache bash
|
||||
apk add --no-cache bind-tools
|
||||
apk add --no-cache curl
|
||||
apk add --no-cache git
|
||||
apk add --no-cache jq
|
||||
apk add --no-cache openssl
|
||||
apk add --no-cache iperf3
|
||||
apk add --no-cache nano
|
||||
apk add --no-cache wget
|
||||
|
||||
tail -f /dev/null # Keep container running
|
||||
EOH
|
||||
}
|
||||
|
||||
} // task diagnostics
|
||||
task "whoami" {
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "containous/whoami:latest"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
ports = ["whoami"]
|
||||
|
||||
} // /docker config
|
||||
|
||||
service {
|
||||
port = "whoami"
|
||||
name = "${NOMAD_JOB_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.service=${NOMAD_JOB_NAME}",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
check {
|
||||
type = "http"
|
||||
path = "/"
|
||||
interval = "90s"
|
||||
timeout = "15s"
|
||||
}
|
||||
check_restart {
|
||||
limit = 2
|
||||
grace = "1m"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
cpu = 25 # MHz
|
||||
memory = 10 # MB
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
} // /task whoami
|
||||
network {
|
||||
port "whoami" {
|
||||
to = 80
|
||||
}
|
||||
}
|
||||
|
||||
} // group
|
||||
task "diagnostics" {
|
||||
|
||||
// env {
|
||||
// KEY = "VALUE"
|
||||
// }
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "alpine:latest"
|
||||
hostname = "${NOMAD_JOB_NAME}"
|
||||
args = [
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"chmod 755 /local/bootstrap.sh && /local/bootstrap.sh"
|
||||
]
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/pi-cluster/tmp:/diagnostics",
|
||||
"${meta.localStorageRoot}:/docker"
|
||||
]
|
||||
} // docker config
|
||||
|
||||
template {
|
||||
destination = "local/bootstrap.sh"
|
||||
data = <<EOH
|
||||
#!/bin/sh
|
||||
|
||||
apk update
|
||||
apk add --no-cache bash
|
||||
apk add --no-cache bind-tools
|
||||
apk add --no-cache curl
|
||||
apk add --no-cache git
|
||||
apk add --no-cache jq
|
||||
apk add --no-cache openssl
|
||||
apk add --no-cache iperf3
|
||||
apk add --no-cache nano
|
||||
apk add --no-cache wget
|
||||
|
||||
tail -f /dev/null # Keep container running
|
||||
EOH
|
||||
}
|
||||
|
||||
} // task diagnostics
|
||||
|
||||
// task "whoami" {
|
||||
// driver = "docker"
|
||||
// config {
|
||||
// image = "containous/whoami:latest"
|
||||
// hostname = "${NOMAD_TASK_NAME}"
|
||||
// ports = ["whoami"]
|
||||
|
||||
// } // /docker config
|
||||
|
||||
// service {
|
||||
// port = "whoami"
|
||||
// name = "${NOMAD_JOB_NAME}"
|
||||
// provider = "nomad"
|
||||
// tags = [
|
||||
// "traefik.enable=true",
|
||||
// "traefik.http.routers.${NOMAD_JOB_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
// "traefik.http.routers.${NOMAD_JOB_NAME}.entryPoints=web,websecure",
|
||||
// "traefik.http.routers.${NOMAD_JOB_NAME}.service=${NOMAD_JOB_NAME}",
|
||||
// "traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
// "traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare"
|
||||
// ]
|
||||
// check {
|
||||
// type = "http"
|
||||
// path = "/"
|
||||
// interval = "90s"
|
||||
// timeout = "15s"
|
||||
// }
|
||||
// check_restart {
|
||||
// limit = 2
|
||||
// grace = "1m"
|
||||
// }
|
||||
// }
|
||||
// resources {
|
||||
// cpu = 25 # MHz
|
||||
// memory = 10 # MB
|
||||
// }
|
||||
|
||||
// } // /task whoami
|
||||
|
||||
} // group
|
||||
} // job
|
||||
|
||||
404
templates/nomad_jobs/gitea.hcl
Normal file
404
templates/nomad_jobs/gitea.hcl
Normal file
@@ -0,0 +1,404 @@
|
||||
job "gitea" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
constraint {
|
||||
distinct_hosts = true
|
||||
}
|
||||
|
||||
group "gitea" {
|
||||
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "rpi"
|
||||
// }
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "webui" {
|
||||
to = "3000"
|
||||
}
|
||||
port "ssh" {
|
||||
to = "22"
|
||||
}
|
||||
}
|
||||
|
||||
task "create_filesystem" {
|
||||
// Copy the most recent backup into place on the local computer. sonarr will not work with
|
||||
// its database in an NFS share
|
||||
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.restoreCommand}"
|
||||
args = [
|
||||
"${meta.restoreCommand1}",
|
||||
"${meta.restoreCommand2}",
|
||||
"${NOMAD_JOB_NAME}",
|
||||
"${meta.restoreCommand3}"
|
||||
]
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
hook = "prestart"
|
||||
sidecar = false
|
||||
}
|
||||
|
||||
} // /task create_filesystem
|
||||
|
||||
|
||||
task "gitea" {
|
||||
|
||||
env {
|
||||
GITEA__mailer__ENABLED = true
|
||||
GITEA__mailer__FROM = "gitea@{{ homelab_domain_name }}"
|
||||
GITEA__mailer__PASSWD = "{{ gitea_smtp_password }}"
|
||||
GITEA__mailer__PROTOCOL = "smtp+starttls"
|
||||
GITEA__mailer__SMTP_ADDR = "{{ email_smtp_host }}"
|
||||
GITEA__mailer__SMTP_PORT = "{{ email_smtp_port_starttls }}"
|
||||
GITEA__mailer__SUBJECT_PREFIX = "[Gitea]"
|
||||
GITEA__mailer__USER = "{{ email_smtp_account }}"
|
||||
GITEA__repository__DEFAULT_REPO_UNITS = "repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages" # add `repo.actions` to the list if enabling actions
|
||||
GITEA__server__DOMAIN = "{{ homelab_domain_name }}"
|
||||
GITEA__server__ROOT_URL = "https://${NOMAD_JOB_NAME}.{{ homelab_domain_name }}"
|
||||
GITEA__server__SSH_DOMAIN = "${NOMAD_JOB_NAME}.{{ homelab_domain_name }}"
|
||||
GITEA__server__SSH_PORT = "2222" # Traefik gitea-ssh entrypoint
|
||||
GITEA__server__START_SSH_SERVER = false
|
||||
GITEA__service__ENABLE_NOTIFY_MAIL = true
|
||||
GITEA__time__DEFAULT_UI_LOCATION = "America/New_York"
|
||||
TZ = "America/New_York"
|
||||
USER_GID = "${meta.PGID}"
|
||||
USER_UID = "${meta.PUID}"
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "gitea/gitea:{{ gitea_version }}"
|
||||
image_pull_timeout = "10m"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.localStorageRoot}/${NOMAD_JOB_NAME}:/data",
|
||||
"/etc/timezone:/etc/timezone:ro",
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
]
|
||||
ports = ["webui", "ssh"]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "webui"
|
||||
name = "${NOMAD_JOB_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.service=${NOMAD_JOB_NAME}",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "webui"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
|
||||
} // service
|
||||
|
||||
service {
|
||||
port = "ssh"
|
||||
name = "gitea-ssh-svc"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)",
|
||||
"traefik.tcp.routers.gitea-ssh.entrypoints=gitea-ssh",
|
||||
"traefik.tcp.routers.gitea-ssh.service=gitea-ssh-svc"
|
||||
]
|
||||
} // service
|
||||
|
||||
// resources {
|
||||
// cpu = 100 # MHz
|
||||
// memory = 300 # MB
|
||||
// } // resources
|
||||
|
||||
} // task gitea
|
||||
|
||||
task "save_configuration" {
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.backupCommand}"
|
||||
args = [
|
||||
"${meta.backupAllocArg1}",
|
||||
"${meta.backupAllocArg2}",
|
||||
"${meta.backupAllocArg3}",
|
||||
"${meta.backupAllocArg4}",
|
||||
"${meta.backupAllocArg5}",
|
||||
"${NOMAD_JOB_NAME}",
|
||||
"${meta.backupAllocArg6}"
|
||||
]
|
||||
}
|
||||
lifecycle {
|
||||
hook = "poststop"
|
||||
sidecar = false
|
||||
}
|
||||
} // /task save_configuration
|
||||
|
||||
} // group
|
||||
|
||||
|
||||
// group "action-runners" {
|
||||
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "macmini"
|
||||
// }
|
||||
|
||||
// constraint {
|
||||
// distinct_hosts = true
|
||||
// }
|
||||
|
||||
// count = 1
|
||||
|
||||
// restart {
|
||||
// attempts = 0
|
||||
// delay = "30s"
|
||||
// }
|
||||
|
||||
// network {
|
||||
// port "cache" {
|
||||
// to = "8088"
|
||||
// }
|
||||
// }
|
||||
|
||||
// task "await-gitea" {
|
||||
|
||||
// lifecycle {
|
||||
// hook = "prestart"
|
||||
// sidecar = false
|
||||
// }
|
||||
|
||||
// driver = "docker"
|
||||
|
||||
// config {
|
||||
// image = "busybox:latest"
|
||||
// command = "/bin/sh"
|
||||
// args = [
|
||||
// "-c",
|
||||
// "chmod 755 /local/ping.sh && /local/ping.sh"
|
||||
// ]
|
||||
// network_mode = "host"
|
||||
// }
|
||||
|
||||
// template {
|
||||
// destination = "local/ping.sh"
|
||||
// change_mode = "restart"
|
||||
// data = <<-EOH
|
||||
// #!/bin/sh
|
||||
// {% raw -%}
|
||||
// {{ range nomadService "gitea" }}
|
||||
// IP="{{ .Address }}"
|
||||
// PORT="{{ .Port }}"
|
||||
// {{ end }}
|
||||
// {% endraw -%}
|
||||
|
||||
// until [ -n "${IP}" ] && [ -n "${PORT}" ]; do
|
||||
// echo "Waiting for Nomad to populate the service information..."
|
||||
// sleep 1
|
||||
// done
|
||||
|
||||
// echo "Waiting for Gitea to start..."
|
||||
|
||||
// until nc -z "${IP}" "${PORT}"; do
|
||||
// echo "'nc -z ${IP} ${PORT}' is unavailable..."
|
||||
// sleep 1
|
||||
// done
|
||||
|
||||
// echo "Gitea is up! Found at ${IP}:${PORT}"
|
||||
|
||||
// EOH
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// task "gitea-action-runner" {
|
||||
|
||||
// env {
|
||||
// CONFIG_FILE = "/local/config.yml"
|
||||
// GITEA_INSTANCE_URL = "https://${NOMAD_JOB_NAME}.{{ homelab_domain_name }}"
|
||||
// GITEA_RUNNER_NAME = "${node.unique.name}-action-runner"
|
||||
// GITEA_RUNNER_REGISTRATION_TOKEN = "{{ gitea_runner_registration_token }}"
|
||||
// PGID = "${meta.PGID}"
|
||||
// PUID = "${meta.PUID}"
|
||||
// TZ = "America/New_York"
|
||||
// }
|
||||
|
||||
// driver = "docker"
|
||||
// config {
|
||||
// image = "gitea/act_runner:latest"
|
||||
// image_pull_timeout = "10m"
|
||||
// hostname = "${NOMAD_TASK_NAME}"
|
||||
// volumes = [
|
||||
// "${meta.nfsStorageRoot}/pi-cluster/gitea-action-runners:/data",
|
||||
// "/var/run/docker.sock:/var/run/docker.sock"
|
||||
// ]
|
||||
// ports = ["cache"]
|
||||
// } // docker config
|
||||
|
||||
// template {
|
||||
// destination = "local/config.yml"
|
||||
// env = false
|
||||
// change_mode = "noop"
|
||||
// data = <<-EOH
|
||||
// log:
|
||||
// # The level of logging, can be trace, debug, info, warn, error, fatal
|
||||
// level: info
|
||||
|
||||
// runner:
|
||||
// # Where to store the registration result.
|
||||
// {% raw %}file: .runner-{{ env "node.unique.name" }}{% endraw +%}
|
||||
// # Execute how many tasks concurrently at the same time.
|
||||
// capacity: 1
|
||||
// # Extra environment variables to run jobs.
|
||||
// envs:
|
||||
// A_TEST_ENV_NAME_1: a_test_env_value_1
|
||||
// A_TEST_ENV_NAME_2: a_test_env_value_2
|
||||
// # Extra environment variables to run jobs from a file.
|
||||
// # It will be ignored if it's empty or the file doesn't exist.
|
||||
// env_file: .env
|
||||
// # The timeout for a job to be finished.
|
||||
// # Please note that the Gitea instance also has a timeout (3h by default) for the job.
|
||||
// # So the job could be stopped by the Gitea instance if it's timeout is shorter than this.
|
||||
// timeout: 3h
|
||||
// # Whether skip verifying the TLS certificate of the Gitea instance.
|
||||
// insecure: false
|
||||
// # The timeout for fetching the job from the Gitea instance.
|
||||
// fetch_timeout: 5s
|
||||
// # The interval for fetching the job from the Gitea instance.
|
||||
// fetch_interval: 2s
|
||||
// # The labels of a runner are used to determine which jobs the runner can run, and how to run them.
|
||||
// # Like: ["macos-arm64:host", "ubuntu-latest:docker://node:16-bullseye", "ubuntu-22.04:docker://node:16-bullseye"]
|
||||
// # If it's empty when registering, it will ask for inputting labels.
|
||||
// # If it's empty when execute `daemon`, will use labels in `.runner` file.
|
||||
// labels: []
|
||||
|
||||
// cache:
|
||||
// # Enable cache server to use actions/cache.
|
||||
// enabled: false
|
||||
// # The directory to store the cache data.
|
||||
// # If it's empty, the cache data will be stored in $HOME/.cache/actcache.
|
||||
// dir: ""
|
||||
// # The host of the cache server.
|
||||
// # It's not for the address to listen, but the address to connect from job containers.
|
||||
// # So 0.0.0.0 is a bad choice, leave it empty to detect automatically.
|
||||
// {% raw %}host: "{{ env "NOMAD_IP_cache" }}"{% endraw +%}
|
||||
// # The port of the cache server.
|
||||
// {% raw %}port: {{ env "NOMAD_HOST_PORT_cache" }}{% endraw +%}
|
||||
// # The external cache server URL. Valid only when enable is true.
|
||||
// # If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself.
|
||||
// # The URL should generally end with "/".
|
||||
// external_server: ""
|
||||
|
||||
// container:
|
||||
// # Specifies the network to which the container will connect.
|
||||
// # Could be host, bridge or the name of a custom network.
|
||||
// # If it's empty, act_runner will create a network automatically.
|
||||
// network: ""
|
||||
// # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
|
||||
// privileged: false
|
||||
// # And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway).
|
||||
// options:
|
||||
// # The parent directory of a job's working directory.
|
||||
// # If it's empty, /workspace will be used.
|
||||
// workdir_parent:
|
||||
// # Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob
|
||||
// # You can specify multiple volumes. If the sequence is empty, no volumes can be mounted.
|
||||
// # For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to:
|
||||
// # valid_volumes:
|
||||
// # - data
|
||||
// # - /src/*.json
|
||||
// # If you want to allow any volume, please use the following configuration:
|
||||
// # valid_volumes:
|
||||
// # - '**'
|
||||
// valid_volumes:
|
||||
// - '**'
|
||||
// # overrides the docker client host with the specified one.
|
||||
// # If it's empty, act_runner will find an available docker host automatically.
|
||||
// # If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers.
|
||||
// # If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work.
|
||||
// docker_host: ""
|
||||
// # Pull docker image(s) even if already present
|
||||
// force_pull: false
|
||||
|
||||
// host:
|
||||
// # The parent directory of a job's working directory.
|
||||
// # If it's empty, $HOME/.cache/act/ will be used.
|
||||
// workdir_parent:
|
||||
// EOH
|
||||
// }
|
||||
|
||||
// // service {
|
||||
// // port = "cache"
|
||||
// // name = "${NOMAD_TASK_NAME}"
|
||||
// // provider = "nomad"
|
||||
// // tags = [
|
||||
// // "traefik.enable=true",
|
||||
// // "traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
// // "traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
// // "traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
// // "traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
// // "traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
// // "traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file"
|
||||
// // ]
|
||||
|
||||
// // check {
|
||||
// // type = "tcp"
|
||||
// // port = "cache"
|
||||
// // interval = "30s"
|
||||
// // timeout = "4s"
|
||||
// // }
|
||||
|
||||
// // check_restart {
|
||||
// // limit = 0
|
||||
// // grace = "1m"
|
||||
// // }
|
||||
|
||||
// // } // service
|
||||
|
||||
// resources {
|
||||
// cpu = 400 # MHz
|
||||
// memory = 600 # MB
|
||||
// } // resources
|
||||
|
||||
// } // task gitea-action-runner
|
||||
|
||||
// } // group action-runners
|
||||
|
||||
} // job
|
||||
101
templates/nomad_jobs/hishtory-server.hcl
Normal file
101
templates/nomad_jobs/hishtory-server.hcl
Normal file
@@ -0,0 +1,101 @@
|
||||
job "hishtory" {
|
||||
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
# README
|
||||
# https://github.com/linuxserver/docker-hishtory-server
|
||||
# https://github.com/ddworken/hishtory/blob/master/README.md
|
||||
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "rpi(1|2|3)"
|
||||
// }
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
group "hishtory" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "port1" {
|
||||
to = "8080"
|
||||
}
|
||||
}
|
||||
|
||||
task "hishtory" {
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
HISHTORY_SQLITE_DB = "/config/hishtory.db"
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "lscr.io/linuxserver/hishtory-server:latest"
|
||||
image_pull_timeout = "10m"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/pi-cluster/${NOMAD_TASK_NAME}:/config"
|
||||
]
|
||||
ports = ["port1"]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "port1"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "port1"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 1800 # MHz
|
||||
memory = 800 # MB
|
||||
} // resources
|
||||
|
||||
} // task
|
||||
|
||||
|
||||
} // group
|
||||
|
||||
|
||||
} // job
|
||||
@@ -3,143 +3,149 @@ job "icloud_backup" {
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
// Need to authenticate within the container by running
|
||||
// icloud --username=<icloud-username> --session-directory=/app/session_data
|
||||
// and then entering the 2FA code that is sent to the user associated with the iCloud account.
|
||||
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "rpi(1|2|3)"
|
||||
// }
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
group "icloud_backup" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
task "icloud_backup" {
|
||||
group "icloud_backup" {
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
// ENV_ICLOUD_PASSWORD = "[icloud password]" # 2FA renders this env var useless at the moment.
|
||||
}
|
||||
count = 1
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "mandarons/icloud-drive"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/nate/icloud_backup:/app/icloud",
|
||||
"${meta.nfsStorageRoot}/pi-cluster/icloud_backup/session_data:/app/session_data",
|
||||
"local/icloud_backup.yaml:/app/config.yaml",
|
||||
"/etc/timezone:/etc/timezone:ro",
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
]
|
||||
} // docker config
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
template {
|
||||
destination = "local/icloud_backup.yaml"
|
||||
env = false
|
||||
change_mode = "restart"
|
||||
perms = "644"
|
||||
data = <<-EOH
|
||||
app:
|
||||
logger:
|
||||
# level - debug, info (default), warning, or error
|
||||
level: "info"
|
||||
# log filename icloud.log (default)
|
||||
filename: "icloud.log"
|
||||
credentials:
|
||||
# iCloud drive username
|
||||
username: "{{ icloud_backup_username }}"
|
||||
# Retry login interval
|
||||
retry_login_interval: 3600 # 1 hour
|
||||
# Drive destination
|
||||
root: "icloud"
|
||||
smtp:
|
||||
# If you want to receive email notifications about expired/missing 2FA credentials then uncomment
|
||||
email: "{{ email_smtp_account }}"
|
||||
# optional, to email address. Default is sender email.
|
||||
#to: "receiver@test.com"
|
||||
password: "{{ icloud_backup_smtp_password }}"
|
||||
host: "{{ email_smtp_host }}"
|
||||
port: {{ email_smtp_port_starttls }}
|
||||
# If your email provider doesn't handle TLS
|
||||
no_tls: false
|
||||
drive:
|
||||
destination: "drive"
|
||||
remove_obsolete: true
|
||||
sync_interval: 172800 # 2 days
|
||||
filters:
|
||||
# File filters to be included in syncing iCloud drive content
|
||||
folders:
|
||||
- "Scanner By Readdle"
|
||||
- "Documents by Readdle"
|
||||
# - "folder3"
|
||||
file_extensions:
|
||||
# File extensions to be included
|
||||
- "pdf"
|
||||
- "png"
|
||||
- "jpg"
|
||||
- "jpeg"
|
||||
- "xls"
|
||||
- "xlsx"
|
||||
- "docx"
|
||||
- "pptx"
|
||||
- "txt"
|
||||
- "md"
|
||||
- "html"
|
||||
- "htm"
|
||||
- "css"
|
||||
- "js"
|
||||
- "json"
|
||||
- "xml"
|
||||
- "yaml"
|
||||
- "yml"
|
||||
- "csv"
|
||||
- "mp3"
|
||||
- "mp4"
|
||||
- "mov"
|
||||
- "wav"
|
||||
- "mkv"
|
||||
- "m4a"
|
||||
photos:
|
||||
destination: "photos"
|
||||
remove_obsolete: true
|
||||
sync_interval: 172800 # 2 days
|
||||
filters:
|
||||
albums:
|
||||
# - "album1"
|
||||
file_sizes: # valid values are original, medium and/or thumb
|
||||
- "original"
|
||||
# - "medium"
|
||||
# - "thumb"
|
||||
EOH
|
||||
} // template data
|
||||
task "icloud_backup" {
|
||||
|
||||
resources {
|
||||
cpu = 900 # MHz
|
||||
memory = 100 # MB
|
||||
} // resources
|
||||
env {
|
||||
ENV_CONFIG_FILE_PATH = "/local/icloud_backup.yaml"
|
||||
PGID = "${meta.PGID}"
|
||||
PUID = "${meta.PUID}"
|
||||
TZ = "America/New_York"
|
||||
// ENV_ICLOUD_PASSWORD = "[icloud password]" # 2FA renders this env var useless at the moment.
|
||||
}
|
||||
|
||||
} // task
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "mandarons/icloud-drive"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/nate/icloud_backup:/app/icloud",
|
||||
"${meta.nfsStorageRoot}/pi-cluster/icloud_backup/session_data:/app/session_data",
|
||||
"/etc/timezone:/etc/timezone:ro",
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
]
|
||||
} // docker config
|
||||
|
||||
template {
|
||||
destination = "local/icloud_backup.yaml"
|
||||
env = false
|
||||
change_mode = "restart"
|
||||
perms = "644"
|
||||
data = <<-EOH
|
||||
---
|
||||
app:
|
||||
logger:
|
||||
# level - debug, info (default), warning, or error
|
||||
level: "info"
|
||||
# log filename icloud.log (default)
|
||||
filename: "icloud.log"
|
||||
credentials:
|
||||
# iCloud drive username
|
||||
username: "{{ icloud_backup_username }}"
|
||||
# Retry login interval
|
||||
retry_login_interval: 3600 # 1 hour
|
||||
root: "icloud"
|
||||
smtp:
|
||||
# If you want to receive email notifications about expired/missing 2FA credentials then uncomment
|
||||
email: "{{ email_smtp_account }}"
|
||||
# optional, to email address. Default is sender email.
|
||||
#to: "receiver@test.com"
|
||||
password: "{{ icloud_backup_smtp_password }}"
|
||||
host: "{{ email_smtp_host }}"
|
||||
port: {{ email_smtp_port_starttls }}
|
||||
# If your email provider doesn't handle TLS
|
||||
no_tls: false
|
||||
drive:
|
||||
destination: "drive"
|
||||
remove_obsolete: true
|
||||
sync_interval: 172800 # 2 days
|
||||
filters:
|
||||
# File filters to be included in syncing iCloud drive content
|
||||
folders:
|
||||
- "Scanner By Readdle"
|
||||
- "Documents by Readdle"
|
||||
# - "folder3"
|
||||
file_extensions:
|
||||
# File extensions to be included
|
||||
- "pdf"
|
||||
- "png"
|
||||
- "jpg"
|
||||
- "jpeg"
|
||||
- "xls"
|
||||
- "xlsx"
|
||||
- "docx"
|
||||
- "pptx"
|
||||
- "txt"
|
||||
- "md"
|
||||
- "html"
|
||||
- "htm"
|
||||
- "css"
|
||||
- "js"
|
||||
- "json"
|
||||
- "xml"
|
||||
- "yaml"
|
||||
- "yml"
|
||||
- "csv"
|
||||
- "mp3"
|
||||
- "mp4"
|
||||
- "mov"
|
||||
- "wav"
|
||||
- "mkv"
|
||||
- "m4a"
|
||||
photos:
|
||||
destination: "photos"
|
||||
remove_obsolete: true
|
||||
sync_interval: 172800 # 2 days
|
||||
all_albums: false # Optional, default false. If true preserve album structure. If same photo is in multiple albums creates duplicates on filesystem
|
||||
folder_format: "%Y-%m" # optional, if set put photos in subfolders according to format. Cheatsheet - https://strftime.org
|
||||
filters:
|
||||
albums:
|
||||
# - "album1"
|
||||
file_sizes: # valid values are original, medium and/or thumb
|
||||
- "original"
|
||||
# - "medium"
|
||||
# - "thumb"
|
||||
EOH
|
||||
} // template data
|
||||
|
||||
resources {
|
||||
cpu = 900 # MHz
|
||||
memory = 100 # MB
|
||||
} // resources
|
||||
|
||||
} // task
|
||||
|
||||
|
||||
} // group
|
||||
} // group
|
||||
|
||||
|
||||
} // job
|
||||
|
||||
98
templates/nomad_jobs/jellyfin.hcl
Normal file
98
templates/nomad_jobs/jellyfin.hcl
Normal file
@@ -0,0 +1,98 @@
|
||||
job "jellyfin" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
operator = "regexp"
|
||||
value = "macmini"
|
||||
}
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
group "jellyfin" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "webui" {
|
||||
static = "8096"
|
||||
to = "8096"
|
||||
}
|
||||
port "udp1" {
|
||||
static = "7359"
|
||||
to = "7359"
|
||||
}
|
||||
}
|
||||
|
||||
task "jellyfin" {
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "lscr.io/linuxserver/jellyfin:latest"
|
||||
image_pull_timeout = "10m"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/pi-cluster/${NOMAD_TASK_NAME}:/config",
|
||||
"${meta.nfsStorageRoot}/media/media/movies:/data/movies",
|
||||
"${meta.nfsStorageRoot}/media/media/tv:/data/tv"
|
||||
]
|
||||
ports = ["webui", "udp1"]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "webui"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "webui"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 2500 # MHz
|
||||
memory = 750 # MB
|
||||
} // resources
|
||||
|
||||
} // task
|
||||
} // group
|
||||
} // job
|
||||
@@ -1,92 +1,92 @@
|
||||
job "overseerr" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "rpi"
|
||||
// }
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "rpi"
|
||||
// }
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
group "overseerr" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "overseerr" {
|
||||
to = "5055"
|
||||
}
|
||||
}
|
||||
group "overseerr" {
|
||||
|
||||
task "overseerr" {
|
||||
count = 1
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "ghcr.io/linuxserver/overseerr"
|
||||
hostname = "${NOMAD_JOB_NAME}"
|
||||
ports = ["overseerr"]
|
||||
volumes = [ "${meta.nfsStorageRoot}/pi-cluster/overseerr:/config" ]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "overseerr"
|
||||
name = "${NOMAD_JOB_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.service=overseerr",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.middlewares=authelia@file"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "overseerr"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
network {
|
||||
port "overseerr" {
|
||||
to = "5055"
|
||||
}
|
||||
}
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 1600 # MHz
|
||||
memory = 300 # MB
|
||||
} // resources
|
||||
task "overseerr" {
|
||||
|
||||
} // task
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "lscr.io/linuxserver/overseerr:latest"
|
||||
hostname = "${NOMAD_JOB_NAME}"
|
||||
ports = ["overseerr"]
|
||||
image_pull_timeout = "10m"
|
||||
volumes = [ "${meta.nfsStorageRoot}/pi-cluster/overseerr:/config" ]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "overseerr"
|
||||
name = "${NOMAD_JOB_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.service=overseerr",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "overseerr"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 1600 # MHz
|
||||
memory = 300 # MB
|
||||
} // resources
|
||||
|
||||
} // task
|
||||
|
||||
|
||||
} // group
|
||||
} // group
|
||||
|
||||
|
||||
} // job
|
||||
|
||||
@@ -137,6 +137,7 @@ job "pihole" {
|
||||
service {
|
||||
name = "piholeDNStcp"
|
||||
port = "dns"
|
||||
provider = "nomad"
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "dns"
|
||||
|
||||
@@ -51,7 +51,7 @@ job "promtail-syslogs" {
|
||||
|
||||
{% raw -%}
|
||||
clients:
|
||||
- url: http://{{ range service "loki" }}{{ .Address }}:{{ .Port }}{{ end }}/loki/api/v1/push
|
||||
- url: http://{{ range nomadService "loki" }}{{ .Address }}:{{ .Port }}{{ end }}/loki/api/v1/push
|
||||
{% endraw %}
|
||||
|
||||
scrape_configs:
|
||||
|
||||
@@ -1,136 +1,136 @@
|
||||
job "radarr" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "rpi3"
|
||||
// }
|
||||
// constraint {
|
||||
// attribute = "${node.unique.name}"
|
||||
// operator = "regexp"
|
||||
// value = "rpi3"
|
||||
// }
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
group "radarrGroup" {
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "10m"
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "radarr" {
|
||||
to = "7878"
|
||||
}
|
||||
}
|
||||
group "radarrGroup" {
|
||||
|
||||
task "create_filesystem" {
|
||||
// Copy the most recent backup into place on the local computer. sonarr will not work with
|
||||
// its database in an NFS share
|
||||
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.restoreCommand}"
|
||||
args = [
|
||||
"${meta.restoreCommand1}",
|
||||
"${meta.restoreCommand2}",
|
||||
"${NOMAD_JOB_NAME}",
|
||||
"${meta.restoreCommand3}"
|
||||
]
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
hook = "prestart"
|
||||
sidecar = false
|
||||
}
|
||||
|
||||
} // /task create_filesystem
|
||||
|
||||
task "radarr" {
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
//DOCKER_MODS = "linuxserver/mods:universal-cron|linuxserver/mods:universal-mod2"
|
||||
//UMASK_SET = 022 #optional
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "ghcr.io/linuxserver/radarr:develop"
|
||||
hostname = "${NOMAD_JOB_NAME}"
|
||||
force_pull = true
|
||||
ports = ["radarr"]
|
||||
volumes = [
|
||||
"${meta.localStorageRoot}/${NOMAD_JOB_NAME}:/config",
|
||||
"${meta.nfsStorageRoot}/media:/media"
|
||||
]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "radarr"
|
||||
name = "${NOMAD_JOB_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.service=${NOMAD_JOB_NAME}",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "radarr"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "10m"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
network {
|
||||
port "radarr" {
|
||||
to = "7878"
|
||||
}
|
||||
}
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 2000 # MHz
|
||||
memory = 400 # MB
|
||||
} // resources
|
||||
task "create_filesystem" {
|
||||
// Copy the most recent backup into place on the local computer. sonarr will not work with
|
||||
// its database in an NFS share
|
||||
|
||||
} // /task radarr
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.restoreCommand}"
|
||||
args = [
|
||||
"${meta.restoreCommand1}",
|
||||
"${meta.restoreCommand2}",
|
||||
"${NOMAD_JOB_NAME}",
|
||||
"${meta.restoreCommand3}"
|
||||
]
|
||||
}
|
||||
|
||||
task "save_configuration" {
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.backupCommand}"
|
||||
args = [
|
||||
"${meta.backupAllocArg1}",
|
||||
"${meta.backupAllocArg2}",
|
||||
"${meta.backupAllocArg3}",
|
||||
"${meta.backupAllocArg4}",
|
||||
"${meta.backupAllocArg5}",
|
||||
"${NOMAD_JOB_NAME}",
|
||||
"${meta.backupAllocArg6}"
|
||||
]
|
||||
}
|
||||
lifecycle {
|
||||
hook = "poststop"
|
||||
sidecar = false
|
||||
}
|
||||
} // /task save_configuration
|
||||
lifecycle {
|
||||
hook = "prestart"
|
||||
sidecar = false
|
||||
}
|
||||
|
||||
} // group
|
||||
} // /task create_filesystem
|
||||
|
||||
task "radarr" {
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
//DOCKER_MODS = "linuxserver/mods:universal-cron|linuxserver/mods:universal-mod2"
|
||||
//UMASK_SET = 022 #optional
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "ghcr.io/linuxserver/radarr:develop"
|
||||
hostname = "${NOMAD_JOB_NAME}"
|
||||
force_pull = true
|
||||
ports = ["radarr"]
|
||||
volumes = [
|
||||
"${meta.localStorageRoot}/${NOMAD_JOB_NAME}:/config",
|
||||
"${meta.nfsStorageRoot}/media:/media"
|
||||
]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "radarr"
|
||||
name = "${NOMAD_JOB_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.service=${NOMAD_JOB_NAME}",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "radarr"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 2000 # MHz
|
||||
memory = 400 # MB
|
||||
} // resources
|
||||
|
||||
} // /task radarr
|
||||
|
||||
task "save_configuration" {
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
# When running a binary that exists on the host, the path must be absolute
|
||||
command = "${meta.backupCommand}"
|
||||
args = [
|
||||
"${meta.backupAllocArg1}",
|
||||
"${meta.backupAllocArg2}",
|
||||
"${meta.backupAllocArg3}",
|
||||
"${meta.backupAllocArg4}",
|
||||
"${meta.backupAllocArg5}",
|
||||
"${NOMAD_JOB_NAME}",
|
||||
"${meta.backupAllocArg6}"
|
||||
]
|
||||
}
|
||||
lifecycle {
|
||||
hook = "poststop"
|
||||
sidecar = false
|
||||
}
|
||||
} // /task save_configuration
|
||||
|
||||
} // group
|
||||
} // job
|
||||
|
||||
@@ -70,46 +70,136 @@ job "recyclarr" {
|
||||
sonarr:
|
||||
series:
|
||||
base_url: https://sonarr.{{ homelab_domain_name }}/
|
||||
api_key: {{ sonarr_api_key }}
|
||||
api_key: "{{ sonarr_api_key }}"
|
||||
delete_old_custom_formats: true
|
||||
replace_existing_custom_formats: true
|
||||
|
||||
# Quality definitions from the guide to sync to Sonarr. Choices: series, anime
|
||||
quality_definition:
|
||||
type: series
|
||||
|
||||
# Release profiles from the guide to sync to Sonarr v3 (Sonarr v4 does not use this!)
|
||||
# Use `recyclarr list release-profiles` for values you can put here.
|
||||
# https://trash-guides.info/Sonarr/Sonarr-Release-Profile-RegEx/
|
||||
release_profiles:
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
reset_unmatched_scores:
|
||||
enabled: true
|
||||
upgrade:
|
||||
allowed: true
|
||||
until_quality: WEB-1080p
|
||||
qualities:
|
||||
- name: Bluray-2160p Remux
|
||||
enabled: false
|
||||
- name: Bluray-2160p
|
||||
enabled: false
|
||||
- name: WEB-2160p
|
||||
enabled: false
|
||||
qualities:
|
||||
- WEBRip-2160p
|
||||
- WEBDL-2160p
|
||||
- name: HDTV-2160p
|
||||
enabled: false
|
||||
- name: Bluray-1080p Remux
|
||||
enabled: false
|
||||
- name: Bluray-1080p
|
||||
- name: WEB-1080p
|
||||
qualities:
|
||||
- WEBRip-1080p
|
||||
- WEBDL-1080p
|
||||
- name: HDTV-1080p
|
||||
- name: Bluray-720p
|
||||
enabled: false
|
||||
- name: WEB-720
|
||||
qualities:
|
||||
- WEBRip-720p
|
||||
- WEBDL-720p
|
||||
- name: HDTV-720p
|
||||
custom_formats:
|
||||
- trash_ids:
|
||||
- EBC725268D687D588A20CBC5F97E538B # Low Quality Groups
|
||||
- 1B018E0C53EC825085DD911102E2CA36 # Release Sources (Streaming Service)
|
||||
- 71899E6C303A07AF0E4746EFF9873532 # P2P Groups + Repack/Proper
|
||||
strict_negative_scores: false
|
||||
|
||||
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
|
||||
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
|
||||
- e2315f990da2e2cbfc9fa5b7a6fcfe48 # LQ Release Title
|
||||
# - 47435ece6b99a0b477caf360e79ba0bb # X265
|
||||
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
|
||||
- 32b367365729d530ca1c124a0b180c64 # Bad dual lingual groups
|
||||
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: -1000
|
||||
- trash_ids:
|
||||
- 76e060895c5b8a765c310933da0a5357 # Optionals
|
||||
filter:
|
||||
include:
|
||||
- cec8880b847dd5d31d29167ee0112b57 # Golden rule
|
||||
- 436f5a7d08fbf02ba25cb5e5dfe98e55 # Ignore Dolby Vision without HDR10 fallback.
|
||||
# - f3f0f3691c6a1988d4a02963e69d11f2 # Ignore The Group -SCENE
|
||||
# - 5bc23c3a055a1a5d8bbe4fb49d80e0cb # Ignore so called scene releases
|
||||
- 538bad00ee6f8aced8e0db5218b8484c # Ignore Bad Dual Audio Groups
|
||||
- 4861d8238f9234606df6721df6e27deb # Ignore AV1
|
||||
- bc7a6383cbe88c3ee2d6396e1aacc0b3 # Prefer HDR
|
||||
- 6f2aefa61342a63387f2a90489e90790 # Dislike retags: rartv, rarbg, eztv, TGx
|
||||
- 19cd5ecc0a24bf493a75e80a51974cdd # Dislike retagged groups
|
||||
- 6a7b462c6caee4a991a9d8aa38ce2405 # Dislike release ending: en
|
||||
- 236a3626a07cacf5692c73cc947bc280 # Dislike release containing: 1-
|
||||
# - fa47da3377076d82d07c4e95b3f13d07 # Prefer Dolby Vision
|
||||
- ec8fa7296b64e8cd390a1600981f3923 # Repack
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 5
|
||||
- trash_ids:
|
||||
- eb3d5cc0a2be0db205fb823640db6a3c # Repack2
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 6
|
||||
- trash_ids:
|
||||
- 44e7c4de10ae50265753082e5dc76047 # Repack3
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 7
|
||||
- trash_ids: # Streaming services, Low Tier
|
||||
- bbcaf03147de0f73be2be4a9078dfa03 # 40D
|
||||
- fcc09418f67ccaddcf3b641a22c5cfd7 # ALL4
|
||||
- 77a7b25585c18af08f60b1547bb9b4fb # CC
|
||||
- f27d46a831e6b16fa3fee2c4e5d10984 # CANALPlus
|
||||
- 4e9a630db98d5391aec1368a0256e2fe # CRAV
|
||||
- 36b72f59f4ea20aad9316f475f2d9fbb # DCU
|
||||
- 7be9c0572d8cd4f81785dacf7e85985e # FOD
|
||||
- 7a235133c87f7da4c8cccceca7e3c7a6 # HBO
|
||||
- f6cce30f1733d5c8194222a7507909bb # HULU
|
||||
- dc503e2425126fa1d0a9ad6168c83b3f # IP
|
||||
- 0ac24a2a68a9700bcb7eeca8e5cd644c # iT
|
||||
- b2b980877494b560443631eb1f473867 # NLZ
|
||||
- fb1a91cdc0f26f7ca0696e0e95274645 # OViD
|
||||
- c30d2958827d1867c73318a5a2957eb1 # Red
|
||||
- ae58039e1319178e6be73caab5c42166 # Sho
|
||||
- d100ea972d1af2150b65b1cffb80f6b5 # TVer
|
||||
- 0e99e7cc719a8a73b2668c3a0c3fe10c # U-next
|
||||
- 5d2317d99af813b6529c7ebf01c83533 # VDL
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 50
|
||||
- trash_ids: # Streaming services, second tier
|
||||
- d660701077794679fd59e8bdf4ce3a29 # AMZN
|
||||
- a880d6abc21e7c16884f3ae393f84179 # HMAX
|
||||
- d34870697c9db575f17700212167be23 # NF
|
||||
- 1656adc6d7bb2c8cca6acfb6592db421 # PCOK
|
||||
- c67a75ae4a1715f2bb4d492755ba4195 # PMTP
|
||||
- 3ac5d84fce98bab1b531393e9c82f467 # QIBI
|
||||
- 1efe8da11bfd74fbbcd4d8117ddb9213 # STAN
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 80
|
||||
- trash_ids: # Streaming services, Top tier
|
||||
- f67c9ca88f463a48346062e8ad07713f # ATVP
|
||||
- 89358767a60cc28783cdc3d0be9388a4 # DSNP
|
||||
- 81d1fbf600e2540cee87f3a23f9d3c1c # MAX
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 100
|
||||
- trash_ids: # HQ Source Groups: Tier 1
|
||||
- e6258996055b9fbab7e9cb2f75819294
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 1700
|
||||
- trash_ids: # HQ Source Groups: Tier 2
|
||||
- 58790d4e2fdcd9733aa7ae68ba2bb503
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 1650
|
||||
- trash_ids: # HQ Source Groups: Tier 3
|
||||
- d84935abd3f8556dcd51d4f27e22d0a6
|
||||
quality_profiles:
|
||||
- name: "HD - 720p/1080p"
|
||||
score: 1600
|
||||
|
||||
# Configuration specific to Radarr.
|
||||
radarr:
|
||||
movies:
|
||||
# Set the URL/API Key to your actual instance
|
||||
base_url: https://radarr.{{ homelab_domain_name }}/
|
||||
api_key: {{ radarr_api_key }}
|
||||
api_key: "{{ radarr_api_key }}"
|
||||
delete_old_custom_formats: true
|
||||
replace_existing_custom_formats: true
|
||||
|
||||
@@ -120,9 +210,11 @@ radarr:
|
||||
|
||||
quality_profiles:
|
||||
- name: "720p/1080p"
|
||||
reset_unmatched_scores: true
|
||||
reset_unmatched_scores:
|
||||
enabled: true
|
||||
- name: "720p/1080p Remux"
|
||||
reset_unmatched_scores: true
|
||||
reset_unmatched_scores:
|
||||
enabled: true
|
||||
|
||||
custom_formats:
|
||||
# Use `recyclarr list custom-formats radarr` for values you can put here.
|
||||
@@ -183,9 +275,9 @@ radarr:
|
||||
- f2aacebe2c932337fe352fa6e42c1611 # 9.1 Surround
|
||||
quality_profiles:
|
||||
- name: "720p/1080p"
|
||||
score: -50
|
||||
score: -100
|
||||
- name: "720p/1080p Remux"
|
||||
score: -50
|
||||
score: -100
|
||||
|
||||
- trash_ids:
|
||||
- 89dac1be53d5268a7e10a19d3c896826 # 2.0 Stereo
|
||||
@@ -200,6 +292,7 @@ radarr:
|
||||
score: 80
|
||||
- name: "720p/1080p Remux"
|
||||
score: 80
|
||||
|
||||
EOH
|
||||
}
|
||||
|
||||
|
||||
27
templates/nomad_jobs/remove_nzbs.hcl
Normal file
27
templates/nomad_jobs/remove_nzbs.hcl
Normal file
@@ -0,0 +1,27 @@
|
||||
job "remove_nzbs" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "batch"
|
||||
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
operator = "regexp"
|
||||
value = "rpi"
|
||||
}
|
||||
|
||||
periodic {
|
||||
cron = "*/15 * * * * *"
|
||||
prohibit_overlap = true
|
||||
time_zone = "America/New_York"
|
||||
}
|
||||
|
||||
task "remove_nzbs" {
|
||||
driver = "raw_exec"
|
||||
config {
|
||||
command = "/home/pi/.pyenv/shims/python"
|
||||
args = ["/home/pi/repos/bin/bin-sabnzbd/removeNZBs.py"]
|
||||
}
|
||||
|
||||
} // /task do_backups
|
||||
|
||||
} //job
|
||||
@@ -1,500 +1,529 @@
|
||||
job "reverse-proxy" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
value = "rpi1"
|
||||
}
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
group "authelia-group" {
|
||||
|
||||
group "reverse-proxy-group" {
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
operator = "regexp"
|
||||
value = "rpi"
|
||||
}
|
||||
|
||||
network {
|
||||
port "authelia-port" {
|
||||
static = {{ authelia_port }}
|
||||
to = 9091
|
||||
}
|
||||
port "whoami" {
|
||||
to = 80
|
||||
}
|
||||
port "dashboard" {
|
||||
static = 8080
|
||||
to = 8080
|
||||
}
|
||||
port "web" {
|
||||
static = 80
|
||||
to = 80
|
||||
}
|
||||
port "websecure" {
|
||||
static = 443
|
||||
to = 443
|
||||
}
|
||||
port "externalwebsecure" {
|
||||
static = 4430
|
||||
to = 4430
|
||||
}
|
||||
}
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
task "authelia" {
|
||||
network {
|
||||
port "authelia-port" {
|
||||
to = 9091
|
||||
}
|
||||
}
|
||||
|
||||
env {
|
||||
TZ = "America/New_York"
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
}
|
||||
task "authelia" {
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "authelia/authelia:{{ authelia_version }}"
|
||||
hostname = "authelia"
|
||||
ports = ["authelia-port"]
|
||||
volumes = [ "${meta.nfsStorageRoot}/pi-cluster/authelia:/config" ]
|
||||
args = [
|
||||
"--config",
|
||||
"/local/authelia/config.yml"
|
||||
]
|
||||
} // docker config
|
||||
env {
|
||||
TZ = "America/New_York"
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
}
|
||||
|
||||
template {
|
||||
destination = "local/authelia/users.yml"
|
||||
env = false
|
||||
change_mode = "restart"
|
||||
perms = "644"
|
||||
data = <<-EOH
|
||||
---
|
||||
###############################################################
|
||||
# Users Database #
|
||||
###############################################################
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "authelia/authelia:{{ authelia_version }}"
|
||||
hostname = "authelia"
|
||||
ports = ["authelia-port"]
|
||||
image_pull_timeout = "10m"
|
||||
volumes = [ "${meta.nfsStorageRoot}/pi-cluster/authelia:/config" ]
|
||||
args = [
|
||||
"--config",
|
||||
"/local/authelia/config.yml"
|
||||
]
|
||||
} // docker config
|
||||
|
||||
# This file can be used if you do not have an LDAP set up.
|
||||
users:
|
||||
{{ authelia_user1_name }}:
|
||||
displayname: "{{ authelia_user1_name }}"
|
||||
password: "$argon2id$v=19$m=65536,t=1,p={{ authelia_user1_password }}"
|
||||
email: {{ authelia_user1_email }}
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
EOH
|
||||
}
|
||||
template {
|
||||
destination = "local/authelia/users.yml"
|
||||
env = false
|
||||
change_mode = "restart"
|
||||
perms = "644"
|
||||
data = <<-EOH
|
||||
---
|
||||
###############################################################
|
||||
# Users Database #
|
||||
###############################################################
|
||||
|
||||
template {
|
||||
destination = "local/authelia/config.yml"
|
||||
env = false
|
||||
change_mode = "restart"
|
||||
perms = "644"
|
||||
data = <<-EOH
|
||||
---
|
||||
## The theme to display: light, dark, grey, auto.
|
||||
theme: auto
|
||||
# This file can be used if you do not have an LDAP set up.
|
||||
users:
|
||||
{{ authelia_user1_name }}:
|
||||
displayname: "{{ authelia_user1_name }}"
|
||||
password: "$argon2id$v=19$m=65536,t=1,p={{ authelia_user1_password }}"
|
||||
email: {{ authelia_user1_email }}
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
EOH
|
||||
}
|
||||
|
||||
jwt_secret: {{ authelia_jwt_secret}}
|
||||
default_redirection_url: https://authelia.{{ homelab_domain_name}}
|
||||
template {
|
||||
destination = "local/authelia/config.yml"
|
||||
env = false
|
||||
change_mode = "restart"
|
||||
perms = "644"
|
||||
data = <<-EOH
|
||||
---
|
||||
## The theme to display: light, dark, grey, auto.
|
||||
theme: auto
|
||||
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
path: ""
|
||||
read_buffer_size: 4096
|
||||
write_buffer_size: 4096
|
||||
enable_pprof: false
|
||||
enable_expvars: false
|
||||
disable_healthcheck: false
|
||||
jwt_secret: {{ authelia_jwt_secret}}
|
||||
default_redirection_url: https://authelia.{{ homelab_domain_name}}
|
||||
|
||||
log:
|
||||
level: info
|
||||
format: text
|
||||
# file_path: "/config/log.txt"
|
||||
keep_stdout: false
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
path: ""
|
||||
buffers:
|
||||
read: 4096
|
||||
write: 4096
|
||||
timeouts:
|
||||
read: 15s
|
||||
write: 15s
|
||||
idle: 30s
|
||||
enable_pprof: false
|
||||
enable_expvars: false
|
||||
disable_healthcheck: false
|
||||
|
||||
totp:
|
||||
issuer: authelia.com
|
||||
log:
|
||||
level: info
|
||||
format: text
|
||||
# file_path: "/config/log.txt"
|
||||
keep_stdout: false
|
||||
|
||||
authentication_backend:
|
||||
disable_reset_password: false
|
||||
file:
|
||||
path: /local/authelia/users.yml
|
||||
password:
|
||||
algorithm: argon2id
|
||||
iterations: 1
|
||||
salt_length: 16
|
||||
parallelism: 8
|
||||
memory: 64
|
||||
totp:
|
||||
issuer: authelia.com
|
||||
|
||||
access_control:
|
||||
default_policy: deny
|
||||
networks:
|
||||
- name: internal
|
||||
networks:
|
||||
- 10.0.0.0/8
|
||||
#- 172.16.0.0/12
|
||||
#- 192.168.0.0/18
|
||||
rules:
|
||||
# Rules applied to everyone
|
||||
- domain: "*.{{ homelab_domain_name }}"
|
||||
policy: two_factor
|
||||
authentication_backend:
|
||||
password_reset:
|
||||
disable: false
|
||||
file:
|
||||
path: /local/authelia/users.yml
|
||||
password:
|
||||
algorithm: argon2id
|
||||
iterations: 1
|
||||
salt_length: 16
|
||||
parallelism: 8
|
||||
memory: 64
|
||||
|
||||
access_control:
|
||||
default_policy: deny
|
||||
networks:
|
||||
- internal
|
||||
- name: internal
|
||||
networks:
|
||||
- 10.0.0.0/8
|
||||
#- 172.16.0.0/12
|
||||
#- 192.168.0.0/18
|
||||
rules:
|
||||
# Rules applied to everyone
|
||||
- domain: "*.{{ homelab_domain_name }}"
|
||||
policy: two_factor
|
||||
networks:
|
||||
- internal
|
||||
|
||||
session:
|
||||
name: authelia_session
|
||||
domain: {{ homelab_domain_name }}
|
||||
same_site: lax
|
||||
secret: {{ authelia_session_secret }}
|
||||
expiration: 1h
|
||||
inactivity: 15m
|
||||
remember_me_duration: 1w
|
||||
session:
|
||||
name: authelia_session
|
||||
domain: {{ homelab_domain_name }}
|
||||
same_site: lax
|
||||
secret: {{ authelia_session_secret }}
|
||||
expiration: 1h
|
||||
inactivity: 15m
|
||||
remember_me_duration: 1w
|
||||
|
||||
regulation:
|
||||
max_retries: 5
|
||||
find_time: 10m
|
||||
ban_time: 15m
|
||||
regulation:
|
||||
max_retries: 5
|
||||
find_time: 10m
|
||||
ban_time: 15m
|
||||
|
||||
storage:
|
||||
encryption_key: {{ authelia_sqlite_encryption_key}}
|
||||
local:
|
||||
path: /config/db.sqlite3
|
||||
storage:
|
||||
encryption_key: {{ authelia_sqlite_encryption_key}}
|
||||
local:
|
||||
path: /config/db.sqlite3
|
||||
|
||||
notifier:
|
||||
smtp:
|
||||
username: {{ email_smtp_account }}
|
||||
password: {{ authelia_smtp_password }}
|
||||
host: {{ email_smtp_host }}
|
||||
port: {{ email_smtp_port }}
|
||||
sender: "Authelia <{{ my_email_address }}>"
|
||||
subject: "[Authelia] {title}"
|
||||
startup_check_address: {{ my_email_address }}
|
||||
notifier:
|
||||
smtp:
|
||||
username: {{ email_smtp_account }}
|
||||
password: {{ authelia_smtp_password }}
|
||||
host: {{ email_smtp_host }}
|
||||
port: {{ email_smtp_port }}
|
||||
sender: "Authelia <{{ my_email_address }}>"
|
||||
subject: "[Authelia] {title}"
|
||||
startup_check_address: {{ my_email_address }}
|
||||
|
||||
ntp:
|
||||
address: "time.cloudflare.com:123"
|
||||
version: 3
|
||||
max_desync: 3s
|
||||
disable_startup_check: true
|
||||
disable_failure: true
|
||||
EOH
|
||||
}
|
||||
ntp:
|
||||
address: "time.cloudflare.com:123"
|
||||
version: 3
|
||||
max_desync: 3s
|
||||
disable_startup_check: true
|
||||
disable_failure: true
|
||||
EOH
|
||||
}
|
||||
|
||||
service {
|
||||
port = "authelia-port"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`authelia.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.middlewares.authelia-headers.headers.customResponseHeaders.Cache-Control=no-store",
|
||||
"traefik.http.middlewares.authelia-headers.headers.customResponseHeaders.Pragma=no-cache",
|
||||
"traefik.http.routers.authelia.middlewares=authelia-headers"
|
||||
service {
|
||||
port = "authelia-port"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`authelia.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.middlewares.authelia-headers.headers.customResponseHeaders.Cache-Control=no-store",
|
||||
"traefik.http.middlewares.authelia-headers.headers.customResponseHeaders.Pragma=no-cache",
|
||||
"traefik.http.routers.authelia.middlewares=authelia-headers"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "authelia-port"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 200 # MHz
|
||||
memory = 1000 # MB
|
||||
}
|
||||
|
||||
} // task authelia
|
||||
|
||||
} // authelia-group
|
||||
|
||||
group "reverse-proxy-group" {
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
value = "rpi1"
|
||||
}
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "whoami" {
|
||||
to = 80
|
||||
}
|
||||
port "dashboard" {
|
||||
static = 8080
|
||||
to = 8080
|
||||
}
|
||||
port "web" {
|
||||
static = 80
|
||||
to = 80
|
||||
}
|
||||
port "websecure" {
|
||||
static = 443
|
||||
to = 443
|
||||
}
|
||||
port "externalwebsecure" {
|
||||
static = 4430
|
||||
to = 4430
|
||||
}
|
||||
port "ssh" { # Used for gitea
|
||||
static = 2222
|
||||
to = 2222
|
||||
}
|
||||
}
|
||||
|
||||
task "whoami" {
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "containous/whoami:latest"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
image_pull_timeout = "10m"
|
||||
ports = ["whoami"]
|
||||
|
||||
} // /docker config
|
||||
|
||||
service {
|
||||
port = "whoami"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_TASK_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file"
|
||||
]
|
||||
check {
|
||||
type = "http"
|
||||
path = "/"
|
||||
interval = "90s"
|
||||
timeout = "15s"
|
||||
}
|
||||
check_restart {
|
||||
limit = 2
|
||||
grace = "1m"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
cpu = 25 # MHz
|
||||
memory = 10 # MB
|
||||
}
|
||||
|
||||
} // /task whoami
|
||||
|
||||
task "traefik" {
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
CF_API_EMAIL = "{{ my_email_address }}"
|
||||
CF_DNS_API_TOKEN = "{{ traefik_cf_api_token }}"
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "traefik:v{{ traefik_version }}"
|
||||
hostname = "traefik"
|
||||
ports = ["dashboard", "web", "websecure","externalwebsecure", "ssh"]
|
||||
volumes = [ "${meta.nfsStorageRoot}/pi-cluster/traefik/acme:/acme" ]
|
||||
image_pull_timeout = "10m"
|
||||
args = [
|
||||
"--global.sendAnonymousUsage=false",
|
||||
"--global.checkNewVersion=false",
|
||||
"--entryPoints.gitea-ssh.address=:2222",
|
||||
"--entryPoints.web.address=:80",
|
||||
"--entryPoints.websecure.address=:443",
|
||||
"--entryPoints.externalwebsecure.address=:4430",
|
||||
"--entrypoints.web.http.redirections.entryPoint.to=websecure",
|
||||
"--entrypoints.web.http.redirections.entryPoint.scheme=https",
|
||||
"--entrypoints.web.http.redirections.entryPoint.permanent=true",
|
||||
"--providers.file.filename=/local/traefik/siteconfigs.toml",
|
||||
"--providers.file.watch=true",
|
||||
"--providers.consulcatalog=true",
|
||||
"--providers.consulcatalog.endpoint.address=http://${NOMAD_IP_web}:8500",
|
||||
"--providers.consulcatalog.prefix=traefik",
|
||||
"--providers.consulcatalog.exposedbydefault=false",
|
||||
"--providers.nomad=true",
|
||||
"--providers.nomad.endpoint.address=http://${NOMAD_IP_web}:4646",
|
||||
// "--metrics=true",
|
||||
// "--metrics.influxdb=true",
|
||||
// "--metrics.influxdb.address=influxdb.service.consul:{{ influxdb_port }}",
|
||||
// "--metrics.influxdb.protocol=http",
|
||||
// "--metrics.influxdb.pushinterval=10s",
|
||||
// "--metrics.influxdb.database=homelab",
|
||||
// "--metrics.influxdb.retentionpolicy=2day",
|
||||
// "--metrics.influxdb.addentrypointslabels=true",
|
||||
// "--metrics.influxdb.addserviceslabels=true",
|
||||
"--accesslog=true",
|
||||
"--log=true",
|
||||
"--log.level=ERROR",
|
||||
"--api=true",
|
||||
"--api.dashboard=true",
|
||||
"--api.insecure=true",
|
||||
"--certificatesresolvers.cloudflare.acme.email={{ my_email_address }}",
|
||||
"--certificatesresolvers.cloudflare.acme.storage=/acme/acme-${node.unique.name}.json",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge=true",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge.delaybeforecheck=10",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
|
||||
]
|
||||
} // docker config
|
||||
|
||||
template {
|
||||
destination = "local/traefik/httpasswd"
|
||||
env = false
|
||||
change_mode = "noop"
|
||||
data = <<-EOH
|
||||
{{ my_username }}:{{ traefik_http_pass_me }}
|
||||
family:{{ traefik_http_pass_family }}
|
||||
EOH
|
||||
}
|
||||
|
||||
template {
|
||||
destination = "local/traefik/httpasswdFamily"
|
||||
env = false
|
||||
change_mode = "noop"
|
||||
data = <<-EOH
|
||||
{{ my_username }}:{{ traefik_http_pass_me }}
|
||||
family:{{ traefik_http_pass_family }}
|
||||
EOH
|
||||
}
|
||||
|
||||
template {
|
||||
destination = "local/traefik/siteconfigs.toml"
|
||||
env = false
|
||||
change_mode = "noop"
|
||||
data = <<-EOH
|
||||
[http]
|
||||
[http.middlewares]
|
||||
[http.middlewares.compress.compress]
|
||||
|
||||
[http.middlewares.localIPOnly.ipWhiteList]
|
||||
sourceRange = ["10.0.0.0/8"]
|
||||
|
||||
[http.middlewares.redirectScheme.redirectScheme]
|
||||
scheme = "https"
|
||||
permanent = true
|
||||
|
||||
[http.middlewares.authelia.forwardAuth]
|
||||
address = {% raw %}"http://{{ range nomadService "authelia" }}{{ .Address }}:{{ .Port }}{{ end }}{% endraw %}/api/verify?rd=https://authelia.{{ homelab_domain_name }}"
|
||||
trustForwardHeader = true
|
||||
authResponseHeaders = ["Remote-User", "Remote-Groups", "Remote-Name", "Remote-Email"]
|
||||
|
||||
[http.middlewares.basicauth.basicauth]
|
||||
usersfile = "/local/traefik/httpasswd"
|
||||
removeHeader = true
|
||||
|
||||
[http.middlewares.basicauth-family.basicauth]
|
||||
usersfile = "/local/traefik/httpasswdFamily"
|
||||
removeHeader = true
|
||||
|
||||
[http.middlewares.allowFrame.headers]
|
||||
customFrameOptionsValue = "allow-from https://home.{{ homelab_domain_name }}"
|
||||
|
||||
[http.routers]
|
||||
|
||||
[http.routers.consul]
|
||||
rule = "Host(`consul.{{ homelab_domain_name }}`)"
|
||||
service = "consul"
|
||||
entrypoints = ["web","websecure"]
|
||||
[http.routers.consul.tls]
|
||||
certResolver = "cloudflare" # From static configuration
|
||||
|
||||
[http.services]
|
||||
|
||||
[http.services.consul]
|
||||
[http.services.consul.loadBalancer]
|
||||
passHostHeader = true
|
||||
[[http.services.consul.loadBalancer.servers]]
|
||||
url = "http://consul.service.consul:8500"
|
||||
|
||||
EOH
|
||||
}
|
||||
|
||||
service {
|
||||
port = "dashboard"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_TASK_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file,redirectScheme@file"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "authelia-port"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "dashboard"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
} // service
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 200 # MHz
|
||||
memory = 1000 # MB
|
||||
}
|
||||
resources {
|
||||
cpu = 140 # MHz
|
||||
memory = 100 # MB
|
||||
} // resources
|
||||
|
||||
} // task authelia
|
||||
} // task traefik
|
||||
|
||||
task "whoami" {
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "containous/whoami:latest"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
ports = ["whoami"]
|
||||
// task "promtail-traefik" {
|
||||
|
||||
} // /docker config
|
||||
// driver = "docker"
|
||||
// config {
|
||||
// image = "grafana/promtail"
|
||||
// hostname = "promtail-traefik"
|
||||
// volumes = [
|
||||
// "/mnt/pi-cluster/logs:/traefik"
|
||||
// ]
|
||||
// args = [
|
||||
// "-config.file",
|
||||
// "/local/promtail-config.yaml",
|
||||
// "-print-config-stderr",
|
||||
// ]
|
||||
// } // docker config
|
||||
|
||||
service {
|
||||
port = "whoami"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_TASK_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
// "traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file"
|
||||
]
|
||||
check {
|
||||
type = "http"
|
||||
path = "/"
|
||||
interval = "90s"
|
||||
timeout = "15s"
|
||||
}
|
||||
check_restart {
|
||||
limit = 2
|
||||
grace = "1m"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
cpu = 25 # MHz
|
||||
memory = 10 # MB
|
||||
}
|
||||
// template {
|
||||
// destination = "local/promtail-config.yaml"
|
||||
// env = false
|
||||
// data = <<-EOH
|
||||
// server:
|
||||
// http_listen_port: 9080
|
||||
// grpc_listen_port: 0
|
||||
|
||||
} // /task whoami
|
||||
// positions:
|
||||
// filename: /alloc/positions.yaml
|
||||
|
||||
task "traefik" {
|
||||
// {% raw -%}
|
||||
// clients:
|
||||
// - url: http://{{ range nomadService "loki" }}{{ .Address }}:{{ .Port }}{{ end }}/loki/api/v1/push
|
||||
// {% endraw %}
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
CF_API_EMAIL = "{{ my_email_address }}"
|
||||
CF_DNS_API_TOKEN = "{{ traefik_cf_api_token }}"
|
||||
}
|
||||
// scrape_configs:
|
||||
// - job_name: traefik
|
||||
// static_configs:
|
||||
// - targets:
|
||||
// - localhost
|
||||
// labels:
|
||||
// job: traefik_access
|
||||
// {% raw %}host: {{ env "node.unique.name" }}{% endraw +%}
|
||||
// __path__: "/alloc/logs/traefik.std*.0"
|
||||
// pipeline_stages:
|
||||
// - regex:
|
||||
// expression: '^(?P<remote_addr>[\w\.]+) - (?P<remote_user>[^ ]*) \[(?P<time_local>.*)\] "(?P<method>[^ ]*) (?P<request>[^ ]*) (?P<protocol>[^ ]*)" (?P<status>[\d]+) (?P<body_bytes_sent>[\d]+) "(?P<http_referer>[^"]*)" "(?P<http_user_agent>[^"]*)" (?P<request_number>[^ ]+) "(?P<router>[^ ]+)" "(?P<server_URL>[^ ]+)" (?P<response_time_ms>[^ ]+)ms$'
|
||||
// - labels:
|
||||
// method:
|
||||
// status:
|
||||
// router:
|
||||
// response_time_ms:
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "traefik:{{ traefik_version }}"
|
||||
hostname = "traefik"
|
||||
ports = ["dashboard", "web", "websecure","externalwebsecure"]
|
||||
volumes = [ "${meta.nfsStorageRoot}/pi-cluster/traefik/acme:/acme" ]
|
||||
args = [
|
||||
"--global.sendAnonymousUsage=false",
|
||||
"--global.checkNewVersion=false",
|
||||
"--entryPoints.web.address=:80",
|
||||
"--entryPoints.websecure.address=:443",
|
||||
"--entryPoints.externalwebsecure.address=:4430",
|
||||
"--entrypoints.web.http.redirections.entryPoint.to=websecure",
|
||||
"--entrypoints.web.http.redirections.entryPoint.scheme=https",
|
||||
"--entrypoints.web.http.redirections.entryPoint.permanent=true",
|
||||
"--providers.file.filename=/local/traefik/siteconfigs.toml",
|
||||
"--providers.file.watch=true",
|
||||
"--providers.consulcatalog=true",
|
||||
"--providers.consulcatalog.endpoint.address=http://${NOMAD_IP_web}:8500",
|
||||
"--providers.consulcatalog.prefix=traefik",
|
||||
"--providers.consulcatalog.exposedbydefault=false",
|
||||
"--providers.nomad=true",
|
||||
"--providers.nomad.endpoint.address=http://${NOMAD_IP_web}:4646",
|
||||
// "--metrics=true",
|
||||
// "--metrics.influxdb=true",
|
||||
// "--metrics.influxdb.address=influxdb.service.consul:{{ influxdb_port }}",
|
||||
// "--metrics.influxdb.protocol=http",
|
||||
// "--metrics.influxdb.pushinterval=10s",
|
||||
// "--metrics.influxdb.database=homelab",
|
||||
// "--metrics.influxdb.retentionpolicy=2day",
|
||||
// "--metrics.influxdb.addentrypointslabels=true",
|
||||
// "--metrics.influxdb.addserviceslabels=true",
|
||||
"--accesslog=true",
|
||||
"--log=true",
|
||||
"--log.level=ERROR",
|
||||
"--api=true",
|
||||
"--api.dashboard=true",
|
||||
"--api.insecure=true",
|
||||
"--certificatesresolvers.cloudflare.acme.email={{ my_email_address }}",
|
||||
"--certificatesresolvers.cloudflare.acme.storage=/acme/acme-${node.unique.name}.json",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge=true",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge.delaybeforecheck=10",
|
||||
"--certificatesresolvers.cloudflare.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
|
||||
]
|
||||
} // docker config
|
||||
// EOH
|
||||
// } // template
|
||||
|
||||
template {
|
||||
destination = "local/traefik/httpasswd"
|
||||
env = false
|
||||
change_mode = "noop"
|
||||
data = <<-EOH
|
||||
{{ my_username }}:{{ traefik_http_pass_me }}
|
||||
family:{{ traefik_http_pass_family }}
|
||||
EOH
|
||||
}
|
||||
// lifecycle {
|
||||
// hook = "poststart"
|
||||
// sidecar = true
|
||||
// }
|
||||
|
||||
template {
|
||||
destination = "local/traefik/httpasswdFamily"
|
||||
env = false
|
||||
change_mode = "noop"
|
||||
data = <<-EOH
|
||||
{{ my_username }}:{{ traefik_http_pass_me }}
|
||||
family:{{ traefik_http_pass_family }}
|
||||
EOH
|
||||
}
|
||||
// resources {
|
||||
// cpu = 30 # MHz
|
||||
// memory = 30 # MB
|
||||
// } // resources
|
||||
|
||||
template {
|
||||
destination = "local/traefik/siteconfigs.toml"
|
||||
env = false
|
||||
change_mode = "noop"
|
||||
data = <<-EOH
|
||||
[http]
|
||||
[http.middlewares]
|
||||
[http.middlewares.compress.compress]
|
||||
// } // promtail sidecar task
|
||||
|
||||
[http.middlewares.localIPOnly.ipWhiteList]
|
||||
sourceRange = ["10.0.0.0/8"]
|
||||
|
||||
[http.middlewares.redirectScheme.redirectScheme]
|
||||
scheme = "https"
|
||||
permanent = true
|
||||
|
||||
|
||||
[http.middlewares.authelia.forwardAuth]
|
||||
address = {% raw %}"http://{{ env "NOMAD_IP_authelia_port" }}:{{ env "NOMAD_PORT_authelia_port" }}{% endraw %}/api/verify?rd=https://authelia.{{ homelab_domain_name }}"
|
||||
trustForwardHeader = true
|
||||
authResponseHeaders = ["Remote-User", "Remote-Groups", "Remote-Name", "Remote-Email"]
|
||||
|
||||
|
||||
[http.middlewares.basicauth.basicauth]
|
||||
usersfile = "/local/traefik/httpasswd"
|
||||
removeHeader = true
|
||||
|
||||
[http.middlewares.basicauth-family.basicauth]
|
||||
usersfile = "/local/traefik/httpasswdFamily"
|
||||
removeHeader = true
|
||||
|
||||
[http.middlewares.allowFrame.headers]
|
||||
customFrameOptionsValue = "allow-from https://home.{{ homelab_domain_name }}"
|
||||
|
||||
[http.routers]
|
||||
|
||||
[http.routers.consul]
|
||||
rule = "Host(`consul.{{ homelab_domain_name }}`)"
|
||||
service = "consul"
|
||||
entrypoints = ["web","websecure"]
|
||||
[http.routers.consul.tls]
|
||||
certResolver = "cloudflare" # From static configuration
|
||||
|
||||
[http.services]
|
||||
|
||||
[http.services.consul]
|
||||
[http.services.consul.loadBalancer]
|
||||
passHostHeader = true
|
||||
[[http.services.consul.loadBalancer.servers]]
|
||||
url = "http://consul.service.consul:8500"
|
||||
|
||||
EOH
|
||||
}
|
||||
|
||||
service {
|
||||
port = "dashboard"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_TASK_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file,redirectScheme@file"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "dashboard"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
} // service
|
||||
|
||||
resources {
|
||||
//cpu = 40 # MHz
|
||||
memory = 64 # MB
|
||||
} // resources
|
||||
|
||||
} // task traefik
|
||||
|
||||
// task "promtail-traefik" {
|
||||
|
||||
// driver = "docker"
|
||||
// config {
|
||||
// image = "grafana/promtail"
|
||||
// hostname = "promtail-traefik"
|
||||
// volumes = [
|
||||
// "/mnt/pi-cluster/logs:/traefik"
|
||||
// ]
|
||||
// args = [
|
||||
// "-config.file",
|
||||
// "/local/promtail-config.yaml",
|
||||
// "-print-config-stderr",
|
||||
// ]
|
||||
// } // docker config
|
||||
|
||||
// template {
|
||||
// destination = "local/promtail-config.yaml"
|
||||
// env = false
|
||||
// data = <<-EOH
|
||||
// server:
|
||||
// http_listen_port: 9080
|
||||
// grpc_listen_port: 0
|
||||
|
||||
// positions:
|
||||
// filename: /alloc/positions.yaml
|
||||
|
||||
// {% raw -%}
|
||||
// clients:
|
||||
// - url: http://{{ range service "loki" }}{{ .Address }}:{{ .Port }}{{ end }}/loki/api/v1/push
|
||||
// {% endraw %}
|
||||
|
||||
// scrape_configs:
|
||||
// - job_name: traefik
|
||||
// static_configs:
|
||||
// - targets:
|
||||
// - localhost
|
||||
// labels:
|
||||
// job: traefik_access
|
||||
// {% raw %}host: {{ env "node.unique.name" }}{% endraw +%}
|
||||
// __path__: "/alloc/logs/traefik.std*.0"
|
||||
// pipeline_stages:
|
||||
// - regex:
|
||||
// expression: '^(?P<remote_addr>[\w\.]+) - (?P<remote_user>[^ ]*) \[(?P<time_local>.*)\] "(?P<method>[^ ]*) (?P<request>[^ ]*) (?P<protocol>[^ ]*)" (?P<status>[\d]+) (?P<body_bytes_sent>[\d]+) "(?P<http_referer>[^"]*)" "(?P<http_user_agent>[^"]*)" (?P<request_number>[^ ]+) "(?P<router>[^ ]+)" "(?P<server_URL>[^ ]+)" (?P<response_time_ms>[^ ]+)ms$'
|
||||
// - labels:
|
||||
// method:
|
||||
// status:
|
||||
// router:
|
||||
// response_time_ms:
|
||||
|
||||
// EOH
|
||||
// } // template
|
||||
|
||||
// lifecycle {
|
||||
// hook = "poststart"
|
||||
// sidecar = true
|
||||
// }
|
||||
|
||||
// resources {
|
||||
// cpu = 30 # MHz
|
||||
// memory = 30 # MB
|
||||
// } // resources
|
||||
|
||||
// } // promtail sidecar task
|
||||
|
||||
} // reverse-proxy-group
|
||||
} // reverse-proxy-group
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ job "sabnzbd" {
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare"
|
||||
// "traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file"
|
||||
]
|
||||
|
||||
|
||||
97
templates/nomad_jobs/speedtest.hcl
Normal file
97
templates/nomad_jobs/speedtest.hcl
Normal file
@@ -0,0 +1,97 @@
|
||||
job "speedtest" {
|
||||
region = "global"
|
||||
datacenters = ["{{ datacenter_name }}"]
|
||||
type = "service"
|
||||
|
||||
constraint {
|
||||
attribute = "${node.unique.name}"
|
||||
operator = "regexp"
|
||||
value = "macmini"
|
||||
}
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
group "speedtest" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "port1" {
|
||||
to = "80"
|
||||
}
|
||||
}
|
||||
|
||||
task "speedtest" {
|
||||
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
DB_CONNECTION = "sqlite"
|
||||
APP_KEY = "{{ speedtest_app_key }}"
|
||||
}
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "lscr.io/linuxserver/speedtest-tracker:latest"
|
||||
image_pull_timeout = "10m"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/pi-cluster/${NOMAD_TASK_NAME}:/config"
|
||||
]
|
||||
ports = ["port1"]
|
||||
} // docker config
|
||||
|
||||
service {
|
||||
port = "port1"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare"
|
||||
]
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "port1"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 1000 # MHz
|
||||
memory = 200 # MB
|
||||
} // resources
|
||||
|
||||
} // task
|
||||
|
||||
|
||||
} // group
|
||||
|
||||
|
||||
} // job
|
||||
@@ -40,6 +40,7 @@ job "stash" {
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
STASH_STASH = "/data/"
|
||||
STASH_GENERATED = "/generated/"
|
||||
STASH_METADATA = "/metadata/"
|
||||
@@ -58,6 +59,7 @@ job "stash" {
|
||||
"${meta.nfsStorageRoot}/nate/.stash/generated:/generated",
|
||||
"${meta.nfsStorageRoot}/nate/.stash/media:/data",
|
||||
"${meta.nfsStorageRoot}/nate/.stash/metadata:/metadata",
|
||||
"${meta.nfsStorageRoot}/nate/.stash/blobs:/blobs",
|
||||
"/etc/timezone:/etc/timezone:ro"
|
||||
]
|
||||
ports = ["port1"]
|
||||
@@ -74,7 +76,6 @@ job "stash" {
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.service=${NOMAD_JOB_NAME}",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_JOB_NAME}.tls.certresolver=cloudflare",
|
||||
// "traefik.http.routers.${NOMAD_JOB_NAME}.middlewares=authelia@file"
|
||||
]
|
||||
|
||||
check {
|
||||
@@ -90,7 +91,7 @@ job "stash" {
|
||||
} // service
|
||||
|
||||
resources {
|
||||
cpu = 4500 # MHz
|
||||
cpu = 3000 # MHz
|
||||
memory = 400 # MB
|
||||
} // resources
|
||||
|
||||
|
||||
@@ -9,88 +9,89 @@ job "TEMPLATE" {
|
||||
// value = "rpi(1|2|3)"
|
||||
// }
|
||||
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
group "TEMPLATE" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
update {
|
||||
max_parallel = 1
|
||||
health_check = "checks"
|
||||
min_healthy_time = "10s"
|
||||
healthy_deadline = "5m"
|
||||
progress_deadline = "10m"
|
||||
auto_revert = true
|
||||
canary = 0
|
||||
stagger = "30s"
|
||||
}
|
||||
|
||||
network {
|
||||
port "port1" {
|
||||
static = "80"
|
||||
to = "80"
|
||||
group "TEMPLATE" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
}
|
||||
}
|
||||
|
||||
task "TEMPLATE" {
|
||||
network {
|
||||
port "port1" {
|
||||
static = "80"
|
||||
to = "80"
|
||||
}
|
||||
}
|
||||
|
||||
// env {
|
||||
// PUID = "${meta.PUID}"
|
||||
// PGID = "${meta.PGID}"
|
||||
// }
|
||||
task "TEMPLATE" {
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = ""
|
||||
image_pull_timeout = "10m"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/pi-cluster/${NOMAD_TASK_NAME}:/etc/TEMPLATE/",
|
||||
"/etc/timezone:/etc/timezone:ro",
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
]
|
||||
ports = ["port1"]
|
||||
} // docker config
|
||||
env {
|
||||
PUID = "${meta.PUID}"
|
||||
PGID = "${meta.PGID}"
|
||||
TZ = "America/New_York"
|
||||
}
|
||||
|
||||
service {
|
||||
port = "port1"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file"
|
||||
]
|
||||
driver = "docker"
|
||||
config {
|
||||
image = ""
|
||||
image_pull_timeout = "10m"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
volumes = [
|
||||
"${meta.nfsStorageRoot}/pi-cluster/${NOMAD_TASK_NAME}:/etc/TEMPLATE/"
|
||||
]
|
||||
ports = ["port1"]
|
||||
} // docker config
|
||||
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "port1"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
} // service
|
||||
service {
|
||||
port = "port1"
|
||||
name = "${NOMAD_TASK_NAME}"
|
||||
provider = "nomad"
|
||||
tags = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls=true",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare",
|
||||
"traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file"
|
||||
]
|
||||
|
||||
// resources {
|
||||
// cpu = 100 # MHz
|
||||
// memory = 300 # MB
|
||||
// } // resources
|
||||
check {
|
||||
type = "tcp"
|
||||
port = "port1"
|
||||
interval = "30s"
|
||||
timeout = "4s"
|
||||
}
|
||||
|
||||
} // task
|
||||
check_restart {
|
||||
limit = 0
|
||||
grace = "1m"
|
||||
}
|
||||
|
||||
} // service
|
||||
|
||||
// resources {
|
||||
// cpu = 100 # MHz
|
||||
// memory = 300 # MB
|
||||
// } // resources
|
||||
|
||||
} // task
|
||||
|
||||
|
||||
} // group
|
||||
} // group
|
||||
|
||||
|
||||
} // job
|
||||
|
||||
@@ -23,7 +23,6 @@ job "valentina" {
|
||||
group "valentina" {
|
||||
|
||||
count = 1
|
||||
|
||||
restart {
|
||||
attempts = 0
|
||||
delay = "30s"
|
||||
@@ -41,12 +40,14 @@ job "valentina" {
|
||||
VALENTINA_GUILDS = "{{ valentina_guids }}"
|
||||
VALENTINA_LOG_LEVEL = "INFO"
|
||||
VALENTINA_LOG_LEVEL_AWS = "INFO"
|
||||
VALENTINA_LOG_LEVEL_HTTP = "ERROR"
|
||||
VALENTINA_MONGO_DATABASE_NAME = "{{ valentina_mongo_database_name }}"
|
||||
VALENTINA_MONGO_URI = "{{ valentina_mongo_uri }}"
|
||||
VALENTINA_OWNER_CHANNELS = "{{ valentina_owner_channels }}"
|
||||
VALENTINA_OWNER_IDS = "{{ valentina_owner_ids }}"
|
||||
VALENTINA_S3_BUCKET_NAME = "{{ valentina_s3_bucket_name}}"
|
||||
VALENTINA_DB_PATH = "/valentina/valentina.sqlite" # Depreciated
|
||||
VALENTINA_GITHUB_TOKEN = "{{ valentina_github_token }}"
|
||||
VALENTINA_GITHUB_REPO = "{{ valentina_github_repo }}"
|
||||
}
|
||||
driver = "docker"
|
||||
config {
|
||||
@@ -115,7 +116,7 @@ job "valentina" {
|
||||
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "ghcr.io/natelandau/backup-mongodb:{{ backup_mongodb_version }}"
|
||||
image = "ghcr.io/natelandau/backup-mongodb:v{{ backup_mongodb_version }}"
|
||||
image_pull_timeout = "10m"
|
||||
hostname = "${NOMAD_TASK_NAME}"
|
||||
ports = ["port1"]
|
||||
@@ -148,11 +149,6 @@ job "valentina" {
|
||||
}
|
||||
} // service
|
||||
|
||||
|
||||
} // task
|
||||
|
||||
|
||||
} // group
|
||||
|
||||
|
||||
} // job
|
||||
|
||||
@@ -20,6 +20,7 @@ _mainScript_() {
|
||||
readarr
|
||||
sonarr
|
||||
uptimekuma
|
||||
gitea
|
||||
)
|
||||
fi
|
||||
|
||||
@@ -131,7 +132,7 @@ _mainScript_() {
|
||||
BACKUP_RETENTION_HOURLY=2
|
||||
BACKUP_RETENTION_DAILY=6
|
||||
BACKUP_RETENTION_WEEKLY=3
|
||||
BACKUP_RETENTION_MONTHLY=2
|
||||
BACKUP_RETENTION_MONTHLY=4
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
420
vault.yml
420
vault.yml
@@ -1,200 +1,222 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
64346463626630316432653930363164323930653865363031616265663934393233373135656238
|
||||
3562616139656435613231396137623462383137646639650a653662303766333437393238386230
|
||||
62356230636233633235346339313661383761303333316230343363646665336630386536616532
|
||||
6234623037653031350a333266626462616434623164633464383931666163386535313962346361
|
||||
62393162356461626461393866663666323561383934623339313763393061383734623936303266
|
||||
62386537653339653764656133323131633663643563356561643164633035363635336230393161
|
||||
36623966376538346332376338346432323939353866626533633837316338633165336236666632
|
||||
38653433646630623831646232373365373661636362393366653837616433373439646236386234
|
||||
33376339643664663133323431653937343163613165333165656536336663666232383331613737
|
||||
37333830303066333839616565326538623237633465343238636337346530323438666264306336
|
||||
65366530623030306263306536323861393734623939666239313436393836353366333534663830
|
||||
36303665396537393832613265383734363363383631373630313666353138663461396530633439
|
||||
34663630346366306539313036663365356433616133303237393161663835393734383463336637
|
||||
64356164323863336235663966613164643836313462663330346339666631633462636237386638
|
||||
35316133373032303763363632353365663737336139366430613566653635336637366130386134
|
||||
30343036623038613265646338306639663565396535663531646366353739663335633262613935
|
||||
38396366323266393064333764623465323334353532383438373833363035643833393535656233
|
||||
33396538343331653164666338383862663063343231346434393031356439363031333832383734
|
||||
65613337383564613935303639353935353333633831303835323433386165396336396331396432
|
||||
36386236373136643862326566303830353533316232316534353436363766373533386462396164
|
||||
39643863316366636439653461333238623336306636633664343465633731363634663031383464
|
||||
38303735366333623339363839333533393061623639643065366336316439323131633764633332
|
||||
38313734326532643061633632333538373764333663363238643036656337333035643632623765
|
||||
38613736336364316264326237353536653364353638653866353062636563613035663433653936
|
||||
63306139346537633738383061303466393632366436323964626565333537366136366336373364
|
||||
38616237303363316130323265666438616161666263633463613837666561393363656233333466
|
||||
61306438626234663665666438343364373330306231383731626535656131323065653730303562
|
||||
62333365656564613662346339306132626135646664373035643032343366333230616234366532
|
||||
61386265646537323861306434353235323463613033346662333037643337616266633463656533
|
||||
32366262666539306463346136613261383730623033343731633337656561653731383835306461
|
||||
32333336333134306332633039333566626133656331313334633033343164306133636331623666
|
||||
32393462303834656139343766613837393162396234343534383139323965353633633162303539
|
||||
32303137396433333131306437623330373633626438393633356439613264373366613630386630
|
||||
33306433613464356236653266386661396638373361663465313835633362333635346439663834
|
||||
35316230396231323231323966663462343234376531306336373164643663616262343966316265
|
||||
31663639316337303436366533336537336632333734373830626130366133326135643264653033
|
||||
37333836363536616361613763323266653663366662666137363637376666346331373936343639
|
||||
63666363366236356531353564356331316632336263356663613438373535303665633363306234
|
||||
37643237306338626562386363616630336337396538636563393933383963653130356531306435
|
||||
66626535393839386338323633353362313337396634653765303737636331633064363239666462
|
||||
62366261353739643333363634376437646265303534663038656338643266303635356533656437
|
||||
32373165613439356335633861643433353062366638323035346437663964343635633265363265
|
||||
35613534613463653165383634303231653631366633663966373837376561643038313639363662
|
||||
37316135346332623433363164306261343061393565353435373335656237363365323466373833
|
||||
34653835313034623161306434616633663261656636653333353561633333343134616432376361
|
||||
35353532623231366363373465616261383530373530616166353830643437626334326135613438
|
||||
32643532343933336435336361616338376264386165306363346663343335343161653066353162
|
||||
36346437623661343763623135393066626532373337616636373366336236356236633865383461
|
||||
30396437393166303066333037373134616565303462313239373463333137323331343237653334
|
||||
30306233393166333638313866313964336634386436386264323931626661306564626439383061
|
||||
61623364366432636465353162666638326635653661323233646639303030623233313763626235
|
||||
31306337386330636430623439363936346166633033336630653034376466316535666364623036
|
||||
63303639333264313736386337333938623234383536646130313964623935356139653762663662
|
||||
64323235366166653936616130626262306430353933303436666236623233356463366466616265
|
||||
38653064343538353436363764613832303236366338336431666239663236623131653635396337
|
||||
30313739326330396638356131313263316237643166666335363161656537366532343866313161
|
||||
39613164306265303061316562356338643564663230663962666237316132303062326435633439
|
||||
36393730663133666564623833323739646565366136363635313564623030336465663533396161
|
||||
66366466396230653736326333646166373735323166346331346164666663336463643866656463
|
||||
30636465646336386234393539633238326631356266663238336133323163613261623963376134
|
||||
36376538666263353036383533343862336130663132383964376263623430383035623962623135
|
||||
64376563653636396663663336666566376165303261353565313534356462303931376238313664
|
||||
36316633313835376266613734303263303866623462616235313266386435613562636530336330
|
||||
38616530626262383930333334623431623662666561383966383438373930386461376461663066
|
||||
65323731343662393361363134643831303931613930643262333934613861353563366361316465
|
||||
64393931373032306363323334373266663266363437666135313335393766366433663730323536
|
||||
32313632633163616563326234623965363230663433326462353637663862663039306637333464
|
||||
61313839633039356365643336313039643739353764326664353035376533623034633433326530
|
||||
33303731316434643232636637623463326231343065346462373637316436623237303335376437
|
||||
35353334383535656264316564653638663036323464333564303236656430313862313533303165
|
||||
66613964336462626632313936623332363266623662313438663831326637313839313830633434
|
||||
61646430666333383630636139353865323365623462306332616439373261636565653534306661
|
||||
64663863353537373834356564386338336535653866373330343138363030656534643165353533
|
||||
30373131363764663132313637343331666139313561313464326436653338386231333662643937
|
||||
31623235393736393962336664623832636266393035343431376632643231343831383161613335
|
||||
35666231383237333330613361653931646237663364336334306135323039636336633561333864
|
||||
63356438346633326532336663373337643637626232653139353964633238336366663331363761
|
||||
34656236373566326536626631336331363238623235333936633830336263313165353434663862
|
||||
32616631313639346564376563383635643333663532323461336231613332363532643730313536
|
||||
32363431393863336337613563303865316664316562333462613232646661613231616139666538
|
||||
61633337623935313233313136343465626264373032366330303430326362353963613730373535
|
||||
62626434313831613836316263623135663331343035643563383837656238626237356438396431
|
||||
65313165323233363162373235626237356462353666646563633735363164333234313838646538
|
||||
35366666393636666432613334383134336335373536316630316330326661303731326632303862
|
||||
36653665666539393964333831313230356438613263343532353866356132396634343266616130
|
||||
35383734313132353662613635643861383435306562396262643564646461383261613362373065
|
||||
31386437626162623637323138333965663034343936626263303539623162353461616333636363
|
||||
61346439613562623138643539306137363231396661306162663330356661326566396630653038
|
||||
65623164336632613633326534316562656638636135623466306331393761626339386233356534
|
||||
39656531373438373763393033353632613761623334316539626236363837653434313437363736
|
||||
31313738613737386562356638643133366532363138373231653662303538313131303333316130
|
||||
66303238363638373538383233336361626461376661666565323631326635353335636436333164
|
||||
36313735316466383938626566623733633464303734303032343936313431306233646234386466
|
||||
63633835663339616262323131356234366635313337386338336435396438333765373431323436
|
||||
38613166656639323632393766313835353364313836386238393361623132373537633735613965
|
||||
36356639303862336263646235303231646539323235383063643162323937323535626564653937
|
||||
33663262303964663461613334663865353164303936356332326466326265626438633264363839
|
||||
38373163303834363562356133643834346166613934616537366633323664316231303936616531
|
||||
37323635323735393836336430343438613533663535343135313838643365613139653765633732
|
||||
66633432616662363135653535646539356265626236666161633336316562376637366538336339
|
||||
30306364303036643865386336626337623134313535323432666235373964363035396366646338
|
||||
39653137316363343138666161333762383762316634653232356233363465303633303832376634
|
||||
34333431616238303035363534613766323836643361313535656539623538653333666461376334
|
||||
32633433313134646664646239643962326562623435626432336361343939303335313331616365
|
||||
34383765373833633333396461366464643463616430646437386339306463346462336331316361
|
||||
65393330333438373662363635653330323263323331336435626135323138316430653531303939
|
||||
63623936303365343266326632336237373061613731636538623733303132616330313637666138
|
||||
35383533643537383239636662396231313536353533393262333230366430613437623264373733
|
||||
36623036383465663439346135313038643731336562336531636461323236626132626261636461
|
||||
33306265303435393032623066333136353030373664376563646233356331373234333663313934
|
||||
65316462326431383037626432353137386336313035383232363063336535373338346364623466
|
||||
31656164383461646535366232356563353466313962643638303230363061363637326337343562
|
||||
33666139366464306635353961346362333537336332363930326337633461323864663039316236
|
||||
62323534666161316534346663653266313739656537663332303637666339386538613136313237
|
||||
34353664376135333736373264303332366539643436626236663762326466303037643863626237
|
||||
61336161626139366462343132633937333139626262663630666537326362376635326365316238
|
||||
64623339666536666431343261323463313466323838313635316639383663373737353466663765
|
||||
39376263633362383135653636633461356631626361623635663439373661663865613337303430
|
||||
64323462343939323930373635666635366535656530363137663833643864633861303535613163
|
||||
30383539393737356132313637376430396430306434333263636162323633656364323931616234
|
||||
39366565323430333862313736366535356561376465636334666639343331643239633431613764
|
||||
63353738323933396365653037363832653531326661646163613737363733383132376664393931
|
||||
33363032613736363361636531313739386339313131346139663130623530656664333039656562
|
||||
31366137346538633166656362626664353936653339653837336662626332663066393139363665
|
||||
34396532633030343134666662363538363534616232633035343063623537316434613837376235
|
||||
61316438646438313564336230356333373738346563313631386633313136633531656364376263
|
||||
37393861333830623238326335623830383566633066303238626633613338653865316231333138
|
||||
64656136366230633138303838383037626134656237336664643736333037376233666539626363
|
||||
36303661623261323161346136663339643035636239393966316461623238356664396233306238
|
||||
39616538636638383133373238636661343233313865643537626264326534383235376466356166
|
||||
32353234383439353461356635626261626433383564626234376465333066346333653965303265
|
||||
63316464343533326263626632616339383737323533313466633466336135316339666563633834
|
||||
62636666626363323963356334653862643532623939376630373338646636303834653562346532
|
||||
64616463313032303136353961626362383138613035306165376535633566333831633835376134
|
||||
37643836346131626335646562656536356662363765383862303162353931336135353565633739
|
||||
34633736363433343132656431666266393731363130313137633934383263653837306630306539
|
||||
61373438346234656335613236363666313831656364656230333864383265303262633665346365
|
||||
37326264393230373964356539643166363562303332633430316639646463383662316364326463
|
||||
30616365623437373366353265656661626432333463353237613233393462386361353964613363
|
||||
62336566386535326463343366326561346332333962343430383464633664616663616364343730
|
||||
38636437393037623635636637313863653164623837313363383264613635333732363437663135
|
||||
33343433623963653561303638363237643536383232313837343030353933343432313935623837
|
||||
37363338666232336564373863653835323936633137663162636331386137323333633632373161
|
||||
31336266656561663539313636313961636264613133653234633066376437616139383236323139
|
||||
39353030303232633864383630643934333632613862623964343331356666346536393937666163
|
||||
65343765626166626535666231633164303366393635366631303266633361616137666639313435
|
||||
64643038663732643063633032623031653732393539373065343135393630393461396235363933
|
||||
32306664663364656434353736613863326565346366386531343561373134366661336663306638
|
||||
37616138396663386533323766356531666636653033313830653266303835616333343835386130
|
||||
34646563333664363765373434623038663163333563623763383563383438343436653465386338
|
||||
65396139323139666236643631636363363932373464303934656331653263636664386666396662
|
||||
62323034343239616665343434303164323432313166633637623832623261303938613164623161
|
||||
65366261353765353233323133356231653936623239333962303463346538366166316639643232
|
||||
31333463313633396134623435636432346261366136356434373630626234633665386634623038
|
||||
33623662623238646162656634663666633639303833653634633330366366313266373435336564
|
||||
30373161316632336136373765356538336630383139666434613462303734623338643134626264
|
||||
38393032363162306434626666323138363739386662633234623963313566313438613231643738
|
||||
66663961323635333231363237333435313231326139643462643834323734626464363466306235
|
||||
36386166356661663030666265633735356636363532366364343139323337393937303936663236
|
||||
64383132353036313261376438643335633765316232396230626365623337616636363863643865
|
||||
34373038376466633835646261363461336338376137356236653262326132356639363863656163
|
||||
38666366616664646639626564393264643333383233383534393433363334663633313838633666
|
||||
65656463643864623766333035316232656263363934303764663761643164353965623361636338
|
||||
66633961373236333138336331386536646331663239613430643165636336376232633265346532
|
||||
31333636323832363966633037346262393139646166353938613836316135633461373337396630
|
||||
64636361303063626366653431623366663438626539353264353334303663316439623235346636
|
||||
33376631613931326431316465346466343636663930356366383434326532376132326663306636
|
||||
65316265343633633433323361636338373233616239313463333365363030393239396362346139
|
||||
66383739393866396161323363306632313264363364393466383961316365313832346661383334
|
||||
61646338633561656437343730343439383765366432323533666633653839323962326662346430
|
||||
32386638323262326334653736323338356434656639613730626131646138643130613935356632
|
||||
33316636373233353932383234663035623935313734383638306334376134623330336461326632
|
||||
30633134386533633732383938393831303839633333326538666536663733353938356136653562
|
||||
37653635373232316338303739343865636263363030353938613865393761346431646638333065
|
||||
33623334616639636537353531643734366339393339653536383363616536323839396434363933
|
||||
35393636333233346466386437646237316333613532336135393638396163346463393761613437
|
||||
36626161626664343332363564353339373736383466663737343038313335663438316536613465
|
||||
64306265613164353630363732346162363366363338343264306335306338323761373161313364
|
||||
63333534316133346163323632643231353033636164363037363733376362316334366261353464
|
||||
31636431323766653431333165653366363366303130336636363366646464643231303138376438
|
||||
66666137363764376563313538373161373664366132316533663032353661363666356566663962
|
||||
32346536336631646265343334366262316262333634373162336631613934386663363061313337
|
||||
61353364383664623163663936613437393934636566373834636461383336653733396635343636
|
||||
33373363646364643437356539333665653165383639396164363262623235623562303065303633
|
||||
61376664613137376333613166326364616138613764666161303364643631393861663232356533
|
||||
32346630373437623139333563386635383532343733356538373831336330633739333462313439
|
||||
35313461623331396135393361386463366266366164313332346232653662393433663361653265
|
||||
31316631623537616630343736653336356662343938363438363266383739393837623335303835
|
||||
36613163373731393964356537616337333365653238393862653036353538393362663561653563
|
||||
64323437353638376366326661336238333439383030626438343530633034656363396439373562
|
||||
66666136383837656464323732393331316263653735383837386264323632623031653333363932
|
||||
62346461646236383666613532623564396638346333356133313537643537356237326266366132
|
||||
65653934616435303766646339396266363439653464643839663335663535326639363936666431
|
||||
32376461323530343532343731326438396639636233326334666639313637396564326634616330
|
||||
64643235323331373539636239356439376266393934383031663766616162633430303564383865
|
||||
34333337346164623238623462323333666139326339393333666535303738626231383935363264
|
||||
63653435653962326561363232626463616162663330313631393939376232393131323562363561
|
||||
34666366303931396339303465653038353137313732326237633561643265323431366264366131
|
||||
633731376131636639313335633339633934
|
||||
39376437663661656434636637396539303863633934376535353938656434386533323063626439
|
||||
3665306133383637383739626233663565383562393534640a396436386366303730653366363530
|
||||
39383533663836613934303665613031636535646233316364313766303964666266646134343833
|
||||
3365623733383236630a616635383739636635663964323361663439336235336536626433333438
|
||||
63356539353363663930363639396666386236653337313366313362326132346563663663633165
|
||||
36396635616138313539653966373462363666316462313765623665303439383233353733656237
|
||||
38643466393336333031326438316662386137613936626563393461613236613738306537666166
|
||||
34313964346132623131623561363331323764373336613238313764653739623437656136333133
|
||||
37663238653665313430653031393239636562376533346335363263373836613331333131623164
|
||||
36323535633831656136633661326362646366623037386233656238616163623564653137303834
|
||||
39643965363039643537303031643032333836316534336439346665316436306465663062323338
|
||||
35393132346334653539343430373934323233623432386665633532366335333031356263376266
|
||||
36386231613533383265346130383238316666663230643532383938663562386639326330646462
|
||||
38633930343332353664363463303438643232633862646535626131633633396266353337396231
|
||||
65353132653034653661316630663462633565363966326137373835316366313734646230376365
|
||||
33666536333134323532363935326234393031393261393935656131366364616165643662333137
|
||||
33316562663566353338346538313933313562613532383733326433653262366135353830336361
|
||||
65343437346234343032323763353030663731336236623635633437393332323164666539313965
|
||||
37366563383463613032333437366133343361643131353963346531313037643862363762383735
|
||||
65383765386462653263343335633065623836613736663532313433396433376139633333653663
|
||||
37336565656463356166636330306333636561366335366638383861316633623661396565633462
|
||||
32623530326334383065346466643766383531353962666135313466633532643664356430386133
|
||||
64653737326430623666313666643334313866616630313162666436373031363630613065393938
|
||||
34626562346333346362643461346163396565393064356663356132663731353364363565316466
|
||||
64343938613864646438326630323463323435393730643631626237303466346538376566333235
|
||||
35393939626463376633306566336564663765313333616539376237323735656335646635366662
|
||||
65363761616439656162363834623035346230383434653662366235343334636630383331623637
|
||||
63633666646262646134303930363431343964373963393035343932393739633664373362343563
|
||||
30643766643935643731613737646134303133646632313630353530376635616439666566636634
|
||||
64336161336535323362616637306231376534336437633364393962666662336564643030373030
|
||||
37356136336235313737316232613036366632663266306131366634386462336535303636353663
|
||||
34313538373965636366356435613664313934663264666533316231623331336533396634333761
|
||||
66363562623235626235346232306664636239386131353966366134393932653465636137646333
|
||||
37376534313361666534383433613331663131626461373931343338643433616561336566626361
|
||||
62623661323338353265356361366537653164316465316631653263636165636166366466326230
|
||||
37363632653031616563323737616438666166363936386531313537653239656163353731366662
|
||||
66616438303538366338326533653630636338323435636263616263306636616632616533623130
|
||||
32316139356430656262343133653932356231386364393734393964343537306561383138316536
|
||||
64663132393239306665353636643561336334393938643239336637303766393533323436386665
|
||||
61373036623566613931366365663961396432346535633837323531323934373939383832636637
|
||||
64653131333432666366393431303036353165643362383934623730323965306163303333323236
|
||||
63626130373234366531386465636336663065633339386337366361316235333563653534313064
|
||||
38393437383438323762616330393535326333366364666330646135636339363232333336326162
|
||||
39633964373439346237363734316633376234383933666137616533313034333932353330623333
|
||||
37373963363234326634663634333766616232626262663764326164333464663066636339646463
|
||||
37633937666532613762313330323365323033613039316463363633316164363663653865653363
|
||||
64343536333634663864333035623238316536386131613762616161636361326632353234313236
|
||||
61353831666664316361613065323038326439636262363762653066396434353137373439303662
|
||||
35333437616432326334333536666633616334313530316262623634386531313066666662633633
|
||||
33343635666433316437386661633361336466306161653262323734623961363736643532623132
|
||||
39323364656339386561333463323866356438663965393661353638333530663934346563393565
|
||||
33383862633632613366313738383337636366666565353464623131316630316237653335376239
|
||||
66623436663366653530323864366264666362306461613939393463353437636535656539653131
|
||||
63623433346431393165346235396565373038633430366138316163613238386231363736626630
|
||||
65336533663233386331663534636236393531643139386434373032666234343736336264396630
|
||||
32353131356461343938633164306338366338303736353665613137316664653337313135363031
|
||||
61306636613833336538663764616138633532396164666461636362336533383330343434326237
|
||||
32663833313066396263636634316566383966326334396465396633363961616365383434653137
|
||||
33373163363362643765313033646537386533396230333232343163333432323631386662363765
|
||||
66643232323239303766643033326362373162333237383863336365336530386563663264626365
|
||||
38383337646138643762623937643333383834633735356434613561626433633035386236376135
|
||||
36656234666363356433356565666161303664623236303961623332353431646565613733393031
|
||||
38643661376636393335643839326133653464343637393661623464336230343761353738616438
|
||||
31306335396538643366643734633164393037616363623435623330396432323231313665393864
|
||||
64336662386639326637373866386234343638366630366434356537666437643364613466613331
|
||||
63363338333962356261346664643635373964633339373935356339666661343532386534366264
|
||||
30323538656539353433613765356232386366633065366235316434626438396630363862653433
|
||||
63323537616630666339653732623838666132613333386231333934393065663930653436336133
|
||||
35633432363738623366376537303065306330613664626535333361383431663331623836353361
|
||||
64393937316639383934383963313738313539316334356232316265623830346337343933336465
|
||||
66316338343762646165643030633865343561323434636239306131373238303931633261396332
|
||||
30306139343634613130646434303766356639353334663165643435666635373638623130353734
|
||||
63336432653134653462633032383232343839333734653966653038343935303932386535623863
|
||||
61383638383835353836626138393534353239356462396235656662613138356530316532633137
|
||||
36383832623364363435363535343131373238613534393462636638663130373265326362303435
|
||||
38666261633263363262333338333765343164316566363366666563643030353338656535613437
|
||||
30616436656239343438313133386564383566623930353866323336643131306166393632353830
|
||||
61646534356433376534376436383366323836663766376661343961626238316338633039623539
|
||||
35346637633963346464616361613862333662663239376635346437346436393736346130343534
|
||||
32313736613936383339323738316335633039626563303136373363316365336565633062373065
|
||||
62313632336138626665373365303463623264623034623538336461333962343432353435396162
|
||||
66396264326661323865393638343166373336653561373437313266636536623534333165323537
|
||||
32396331353964316231306466653237393430313736393932323365363239353264616565326466
|
||||
34643866323736303730356433326463306536383662316566653738613636363061623261313239
|
||||
62663961343636366631613732343363366165383335613635616433316539383035623762336363
|
||||
37373764343038393136373139613565363838343435333730346430396535333533643534363532
|
||||
63376332303162633533666439303065366162653838393333313738643662303135353665373338
|
||||
35326436393233623961383263636134393038373435666131616332323462653337303162346363
|
||||
37633735376432663236633234383166306132633037303731373735356663626539333362613132
|
||||
64313838626136356663323936356337623561633364303438353038666539363738616537653364
|
||||
34646535306462666164626566323739623333306132396534343938313766663836643534396335
|
||||
33306330356337653663666337313039376464633132383933323732313235393338346239303664
|
||||
66666561396331653636646530616534616132363834386436623634366339623538383065363836
|
||||
33313131303533616335366339333239313031346365353461326430643666666534613637616564
|
||||
66623264303263663261653034383661306261366263303233336231386265393164393231363263
|
||||
63396334303431623833313864353263663538623165656230316232646464383335363732333833
|
||||
35383030396138313635613966336639623330626662383835333336646632313338353239313262
|
||||
36663431373464363734376136393362653536636436386139643438643362386631663161356636
|
||||
37653337306435633365333039663832353331653030393161353338656532323130353230383862
|
||||
37636633666361373430663139646466643530313336616139663539313838346233326634366138
|
||||
61656161383838356662393366643537633438623066306134636332373735363536653031643064
|
||||
66363033336533393739366235346264656432383065633364333838303766643938396362393935
|
||||
30353363343839333536393866366561393261623863383964373366626666323363323664333962
|
||||
32663064366133386263306262656564613563653066313732366134383166313362383832393561
|
||||
66316563643733633062326530366263323339353039326664643935346235316632386337396266
|
||||
66363836666639313066333736653535393435653631316132323637316234303032366664366537
|
||||
30373739363136393037613039623761343261346633343066633462616535313037316535376639
|
||||
33653232373237613933616531393130356466363761316531353234663334343630363736383465
|
||||
37623063323065363130303661633939663436646435313834636437653938396264646137343561
|
||||
31373937346337396338393666666264636632343961343461646134653338373164313238313030
|
||||
38326231343838623730633334356162303934393538333035356139613939353833326637633933
|
||||
34626363616239363661346665333232646230316534666436333335363038303033356232326231
|
||||
33333034373833353530376435303135313230313361326137363737643733363961616265343764
|
||||
30303730623536303731633561333162373036316263376461666265363133363836613666353732
|
||||
39343637333538303830633064313432646239336539346136323537356663373464303862653232
|
||||
61653235303638376161326531626339616164353636306162353739316666333537633836636562
|
||||
64626432656438376238633763356565356365623739616663303639646431393465376439643538
|
||||
38326436313563396536383162316365383065653866663138663265373131333437626664366638
|
||||
32633033366138663263653639376534633933323633326332636335303262373931656539356230
|
||||
31643061636139373362343735396337313534316230646435333036636238393131353635393061
|
||||
37313031633566396336353664626431376238336363323164393562613335613361623932393635
|
||||
39613633626437383932323063353238366466663365396134663431303334333866323134646137
|
||||
61336233356437323362346661373566633363353431323138316262343865636239376165353031
|
||||
33613432633239626336323964646461643233313633636239333430346463323334373863303736
|
||||
61343566383135653736663761643461343866373930616165613166336230616639316332663764
|
||||
35323438633339383736383539383836613436313036393262316362663038336134366263376365
|
||||
30616231633536643138383235393362306435333536363538353936626532366439366534646535
|
||||
37653563623839633133396430376464326336663233396234386264386331366366356632313366
|
||||
65363332363661623739623563303064626230363966643137616337383366343236663638326130
|
||||
61316637336430643539656266396435623362633465366132653036353435386635653034376266
|
||||
30313466366538373832393363313661653936303035363136343739336239356461356433393964
|
||||
32393239343238366262616662373235633763383532613961653164303234663231313038393237
|
||||
66353836623437653164373165393834366162623138653363316231306131383438653265663866
|
||||
35643433636230363232303837323939366131613933366137373861303538633830303631313765
|
||||
38313838313538643437613965353430386231376263643938343365333433313864313039336466
|
||||
65323531616439333363373433663464373366653834643861373566373631316339643330393232
|
||||
63373962353737303232653562303834323766353932323130303565383934306366636666626666
|
||||
36376136333962643663333730336161613466306261636531353935336631373635663662356139
|
||||
64383635333864333638316433303463616534376661333433313664623536303532613532363733
|
||||
63356535336239333262323432643932636164623833656237623831373062663261363330393664
|
||||
62646337343536356434336463386337373963363832306338316139636430363530346636353765
|
||||
35303963636132313264666133633837356563386537646464636563303734653062393331333561
|
||||
65346134386136353433326234616635393632383934363862636130346532303561336632636437
|
||||
65616230373063323063326663613131663162326530326466306331353237303462396639663934
|
||||
35333035353831383664336133636363363930353866383237363666393365323837306562393838
|
||||
32343431643062393532396339383539353863643466653235363963336136313836393663623132
|
||||
62376634333630353532653436643333636330303334366565316538313138396566663834353334
|
||||
35613830326430393433333539373938323435623061323833653736663938306366636335333964
|
||||
35303862326561613038643765643066636665663734336434616430356666393861666661303430
|
||||
30636437663738633463303561353566393035613134313664633037373261646337663736613562
|
||||
37393934653437343736386438633234653764653736636265623563666362333431633765326331
|
||||
62396135613637666237303164323661303461613739316538663633626639353932366363626331
|
||||
38383033643965616232333138613761613933323934356530623763363162613464653736333639
|
||||
35666339393866373431623663383130356532656263643332373064363864346639326635353132
|
||||
38666534346133623232636635383335376438343434633633303531636163303736333738656364
|
||||
38373864313066376361626163333162323138663936386232383034366437393737353833386664
|
||||
33303935666264633465366363333932396139643964323066336565623334393239393132343236
|
||||
33366536653864656233663461396432386437363239323064333234313937373033323962336231
|
||||
61313331636334313365306133646339643731303732356136633130386261656263616435623866
|
||||
30353031373939303236313235643963623338643531386265656230336434373365303432386262
|
||||
37356631376661326266343266613862333737303630316637363333623632633832653534346232
|
||||
30623535393934303332653537316133396639366331323865366333663638653730366431666463
|
||||
34366632626665353731616637393132353531613232356538613764376361616536313430633965
|
||||
37643836363366656666653366383233623231333364333661656632336137383732363435353933
|
||||
36353038653835643632316563383930376462363238386361303939343730316537313662626164
|
||||
34613065306332333433653766396365396332353839383562326361373939356662396361613362
|
||||
63623030353463396131336361653730646537303066653636633239333634386663366637346465
|
||||
61626633633436316233646432323534666333396238363366313433656134646566333862623833
|
||||
61393263376638353634333338653763363639383136306165393736663865616337643864333432
|
||||
35366563643637363465303930333062396165643366366464373636373463326663333162613361
|
||||
33323032626433333664333161623031316430383939613533313534393833303935343865333262
|
||||
66396366383233356436663762316231656535626237633739613765356238386339333331363031
|
||||
32616238313137376635623631303232616330303037373433376333313763626262643636636638
|
||||
36353738373036343535616337663634393764633062306435396263343032323032353130326137
|
||||
38613134306438626331636633346361336161633831353761623236326638663462653039643961
|
||||
64653938613361336463663532366431316138356236633637313133333961316266326132653730
|
||||
65333266666566373962363962356132383531656130356465383363356166303764643863303531
|
||||
33363137356237616361316565336536376236353637633435633433356161316361313330643834
|
||||
34626664323065666166613530373664623635643566613333353565616439383365383962633230
|
||||
65316437373430623561346333363463613531356333356234663338633338316161633039323964
|
||||
62376534373636376166383166393139613331323937306138396232653762653765386231616637
|
||||
33376338346532363366383438353266326366626434336430616566653438313334383337613939
|
||||
64366136323631653766616232386438656635333964343439633666613834613361393262653462
|
||||
39383336356233343436313036643435303639343435356365333765653464656238336338323034
|
||||
30363039623866346539323739393664623564373230353533383631663137313533366538373537
|
||||
32346134663533353063323639383735323365336133373334343233303961663631333864373134
|
||||
62306432643663646663353065643565626538343538333431616364376535616261656431626263
|
||||
39643136623964336630353231346637613437333437616265353630616533383761356430343633
|
||||
37303737336335633661363663326561323433613431653264653635653766353030373437653333
|
||||
32393935613831636333313735613066306166643734303731363038343532363638386130343837
|
||||
39376537336437393263363662313831353633343130626365616431383663633235306238396439
|
||||
35396461303136323733346638306430643030646262623661643764336264666161373263356535
|
||||
38336234326631303838313538343061653037366366316236383333623563323264643462326531
|
||||
35373061653734663766663063613466333836333566343562616666646566313163636266663961
|
||||
37623035383632353735306661313530353334656563323866616462626565313035663739343663
|
||||
66646332653939666163636432396332316563356534336463326466316133333731636534383734
|
||||
36613936393064376361343437303365643534653961616634656261323335336335373932343535
|
||||
36373263666665393164393563316166363938333462643736626235303231316562393334373736
|
||||
65353961313065636332353432333539636431353833333337346636356661633565646339393865
|
||||
33666230383462363136336665396463393862363637316634616262386363303062356663343265
|
||||
39666466303337643637343665356330373938653066346139653365346263623437363539313334
|
||||
65313834366239326161323535336339303764353736623365663336353763383061396630656631
|
||||
36623961633166353261393536663234623335323063343764363864656139623633393932616665
|
||||
32356138613135616163613532316231366137326131346366313638386335393664383061326631
|
||||
30653933323434303931653465376132313831326235343563663932333233633033613962633532
|
||||
39343065653934383565376262663262633637313864346363643631353564306337626335306135
|
||||
38356430626566366634313538336563393262396434303463363561646165313330646561333366
|
||||
37333931316432346561623535313735313331373664393931383166663133373263383766343539
|
||||
66323338366637343133633735373465313266626465323237656563343137363763643634333536
|
||||
37353635643835656461316438653961346131643535643461383632613436653634666439643739
|
||||
62323234633230326433383164386532326339623838336130393264666561323063396137653534
|
||||
65643036316131313330353265633564383164363365303838376535623639383239323433656165
|
||||
61363933333737306331393166316666316561663262613261646533666365623531663130326564
|
||||
64656134316438363431366434303836383666316435373762343739663136643337343531393166
|
||||
35356663346564316436663031636262323764376231663238613233353231666564313333666331
|
||||
34616565636261343963646435313536326364303130336137323234393432343437386137363630
|
||||
33386632353730333563626163656366646133376465383430616637653065373962306532616330
|
||||
36323466373339386139316466373163383363376262643264323332343064656464363134656563
|
||||
61316462333462303139653361303765613062633265616335313032306165633033666432616138
|
||||
38356635646431306462393061643363323335386666616666353063646164623338363265623166
|
||||
35663532613666613765313861353832336233653564653734656339383935623538
|
||||
|
||||
Reference in New Issue
Block a user