mirror of
https://github.com/RWejlgaard/pez-infra.git
synced 2026-07-04 15:46:16 +00:00
Compare commits
4 commits
352bfbe3bc
...
ef31162b2d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef31162b2d | ||
| d9c0d3abde | |||
| 4cdb2d3fe4 | |||
| 38540963af |
17 changed files with 75 additions and 14 deletions
6
.github/workflows/_deploy-core.yml
vendored
6
.github/workflows/_deploy-core.yml
vendored
|
|
@ -31,16 +31,16 @@ jobs:
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Cache pip packages
|
- name: Cache pip packages
|
||||||
uses: actions/cache@v5
|
uses: actions/cache@v6
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: pip-ansible
|
key: pip-ansible
|
||||||
|
|
||||||
- name: Cache Ansible collections
|
- name: Cache Ansible collections
|
||||||
uses: actions/cache@v5
|
uses: actions/cache@v6
|
||||||
with:
|
with:
|
||||||
path: ~/.ansible
|
path: ~/.ansible
|
||||||
key: ansible-galaxy-${{ hashFiles('ansible/requirements.yml') }}
|
key: ansible-galaxy-${{ hashFiles('ansible/requirements.yml') }}
|
||||||
|
|
|
||||||
2
.github/workflows/deploy-on-merge.yml
vendored
2
.github/workflows/deploy-on-merge.yml
vendored
|
|
@ -23,7 +23,7 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
hosts: ${{ steps.discover.outputs.hosts }}
|
hosts: ${{ steps.discover.outputs.hosts }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Read hosts from inventory
|
- name: Read hosts from inventory
|
||||||
id: discover
|
id: discover
|
||||||
|
|
|
||||||
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
|
|
@ -24,7 +24,7 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
hosts: ${{ steps.prepare.outputs.hosts }}
|
hosts: ${{ steps.prepare.outputs.hosts }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Build host matrix
|
- name: Build host matrix
|
||||||
id: prepare
|
id: prepare
|
||||||
|
|
|
||||||
2
.github/workflows/lint-ansible.yml
vendored
2
.github/workflows/lint-ansible.yml
vendored
|
|
@ -8,7 +8,7 @@ jobs:
|
||||||
name: ansible-lint
|
name: ansible-lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Check for Ansible files
|
- name: Check for Ansible files
|
||||||
id: check
|
id: check
|
||||||
|
|
|
||||||
2
.github/workflows/lint-docker-compose.yml
vendored
2
.github/workflows/lint-docker-compose.yml
vendored
|
|
@ -8,7 +8,7 @@ jobs:
|
||||||
name: docker compose config
|
name: docker compose config
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Stub missing env files referenced by Compose
|
- name: Stub missing env files referenced by Compose
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
4
.github/workflows/terraform.yml
vendored
4
.github/workflows/terraform.yml
vendored
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
name: Plan
|
name: Plan
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- uses: ./.github/actions/setup-tofu
|
- uses: ./.github/actions/setup-tofu
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: production
|
environment: production
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- uses: ./.github/actions/setup-tofu
|
- uses: ./.github/actions/setup-tofu
|
||||||
|
|
||||||
|
|
|
||||||
3
.github/workflows/validate-caddyfile.yml
vendored
3
.github/workflows/validate-caddyfile.yml
vendored
|
|
@ -8,7 +8,7 @@ jobs:
|
||||||
name: caddy validate
|
name: caddy validate
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Check for Caddyfile
|
- name: Check for Caddyfile
|
||||||
id: check
|
id: check
|
||||||
|
|
@ -29,4 +29,5 @@ jobs:
|
||||||
# fail loudly on an HTTP error instead of saving an error page.
|
# fail loudly on an HTTP error instead of saving an error page.
|
||||||
curl -fsSL "https://caddyserver.com/api/download?os=linux&arch=amd64" -o caddy
|
curl -fsSL "https://caddyserver.com/api/download?os=linux&arch=amd64" -o caddy
|
||||||
chmod +x caddy
|
chmod +x caddy
|
||||||
|
./caddy add-package github.com/caddy-dns/hetzner@v2.0.0
|
||||||
./caddy validate --config ansible/services/caddy/Caddyfile --adapter caddyfile
|
./caddy validate --config ansible/services/caddy/Caddyfile --adapter caddyfile
|
||||||
|
|
|
||||||
2
.github/workflows/validate-terraform.yml
vendored
2
.github/workflows/validate-terraform.yml
vendored
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
name: tofu plan
|
name: tofu plan
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
- uses: ./.github/actions/setup-tofu
|
- uses: ./.github/actions/setup-tofu
|
||||||
|
|
||||||
|
|
|
||||||
1
Makefile
1
Makefile
|
|
@ -4,6 +4,5 @@
|
||||||
decrypt:
|
decrypt:
|
||||||
@find . -name "*.enc.*" ! -name "*.example" -not -path "./.git/*" | while read f; do \
|
@find . -name "*.enc.*" ! -name "*.example" -not -path "./.git/*" | while read f; do \
|
||||||
out=$$(echo "$$f" | sed 's/\.enc\././'); \
|
out=$$(echo "$$f" | sed 's/\.enc\././'); \
|
||||||
echo "Decrypting $$f -> $$out"; \
|
|
||||||
sops -d "$$f" > "$$out"; \
|
sops -d "$$f" > "$$out"; \
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ ansible_python_interpreter: /usr/bin/python3
|
||||||
|
|
||||||
docker_services:
|
docker_services:
|
||||||
- poste-io
|
- poste-io
|
||||||
|
- n8n
|
||||||
|
|
||||||
# Mail ports (25,80,110,143,443,465,587,993,995) exposed via Docker
|
# Mail ports (25,80,110,143,443,465,587,993,995) exposed via Docker
|
||||||
# port mappings in ansible/services/poste-io/docker-compose.yml.
|
# port mappings in ansible/services/poste-io/docker-compose.yml.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ There is **no** per-host subdirectory — services are named by what they are, a
|
||||||
| bitwarden | Docker | helsinki-a | Vaultwarden + MariaDB |
|
| bitwarden | Docker | helsinki-a | Vaultwarden + MariaDB |
|
||||||
| forgejo | Docker | helsinki-a | Git forge |
|
| forgejo | Docker | helsinki-a | Git forge |
|
||||||
| poste-io | Docker | nuremberg-a | Mail |
|
| poste-io | Docker | nuremberg-a | Mail |
|
||||||
|
| n8n | Docker | nuremberg-a | Workflow automation |
|
||||||
| jellyseerr | Docker | london-b | Plex request manager |
|
| jellyseerr | Docker | london-b | Plex request manager |
|
||||||
| navidrome | Docker | london-b | Music streaming |
|
| navidrome | Docker | london-b | Music streaming |
|
||||||
| bookshelf | Docker | london-b | Ebook/audiobook manager (Readarr revival) |
|
| bookshelf | Docker | london-b | Ebook/audiobook manager (Readarr revival) |
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,16 @@ london-a.pez.sh {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*.k8s.pez.sh {
|
||||||
|
tls {
|
||||||
|
dns hetzner {env.HETZNER_DNS_API_TOKEN}
|
||||||
|
}
|
||||||
|
tracing {
|
||||||
|
span k8s
|
||||||
|
}
|
||||||
|
reverse_proxy 100.123.97.26:80
|
||||||
|
}
|
||||||
|
|
||||||
## LONDON-B SERVICES ##
|
## LONDON-B SERVICES ##
|
||||||
|
|
||||||
# Jellyfin
|
# Jellyfin
|
||||||
|
|
@ -155,6 +165,14 @@ music.pez.sh {
|
||||||
|
|
||||||
## NUREMBERG-A SERVICES ##
|
## NUREMBERG-A SERVICES ##
|
||||||
|
|
||||||
|
# n8n (own auth)
|
||||||
|
n8n.pez.sh {
|
||||||
|
tracing {
|
||||||
|
span n8n
|
||||||
|
}
|
||||||
|
reverse_proxy 100.70.180.24:5678
|
||||||
|
}
|
||||||
|
|
||||||
## HELSINKI-A SERVICES ##
|
## HELSINKI-A SERVICES ##
|
||||||
|
|
||||||
# Bitwarden (requires HTTPS tweaking)
|
# Bitwarden (requires HTTPS tweaking)
|
||||||
|
|
|
||||||
10
ansible/services/n8n/README.md
Normal file
10
ansible/services/n8n/README.md
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# n8n
|
||||||
|
|
||||||
|
Workflow automation / orchestration.
|
||||||
|
|
||||||
|
- **Host:** nuremberg-a
|
||||||
|
- **URL:** https://n8n.pez.sh
|
||||||
|
- **Port:** 5678 (bound to the Tailscale IP `100.70.180.24` only; exposed publicly via Caddy on helsinki-a)
|
||||||
|
- **Auth:** n8n's own user management (login on first run)
|
||||||
|
- **Data:** `n8n_data` named volume (`/home/node/.n8n`)
|
||||||
|
- **Files:** `./local-files` mounted at `/files` inside the container
|
||||||
28
ansible/services/n8n/docker-compose.yml
Normal file
28
ansible/services/n8n/docker-compose.yml
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
# n8n - Workflow automation
|
||||||
|
# Host: nuremberg-a (100.70.180.24)
|
||||||
|
# Port bound to the Tailscale IP only; public access is via Caddy on helsinki-a.
|
||||||
|
# n8n manages its own auth (user management / login).
|
||||||
|
|
||||||
|
services:
|
||||||
|
n8n:
|
||||||
|
image: docker.n8n.io/n8nio/n8n
|
||||||
|
container_name: n8n
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "100.70.180.24:5678:5678"
|
||||||
|
environment:
|
||||||
|
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
|
||||||
|
- N8N_HOST=n8n.pez.sh
|
||||||
|
- N8N_PORT=5678
|
||||||
|
- N8N_PROTOCOL=http
|
||||||
|
- NODE_ENV=production
|
||||||
|
- WEBHOOK_URL=https://n8n.pez.sh/
|
||||||
|
- GENERIC_TIMEZONE=Europe/London
|
||||||
|
- TZ=Europe/London
|
||||||
|
volumes:
|
||||||
|
- n8n_data:/home/node/.n8n
|
||||||
|
- ./local-files:/files
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
n8n_data:
|
||||||
0
ansible/services/n8n/local-files/.gitkeep
Normal file
0
ansible/services/n8n/local-files/.gitkeep
Normal file
|
|
@ -89,9 +89,12 @@ Dedicated mail server on Hetzner Cloud. Isolated to protect IP reputation.
|
||||||
| Service | Port | Deployment | Auth | URL |
|
| Service | Port | Deployment | Auth | URL |
|
||||||
|---------|------|-----------|------|-----|
|
|---------|------|-----------|------|-----|
|
||||||
| poste.io | 25, 80, 110, 143, 443, 465, 587, 993, 995 | Docker | Own auth | (webmail via direct host access) |
|
| poste.io | 25, 80, 110, 143, 443, 465, 587, 993, 995 | Docker | Own auth | (webmail via direct host access) |
|
||||||
|
| n8n | 5678 | Docker | Own auth | https://n8n.pez.sh |
|
||||||
|
|
||||||
poste.io bundles everything — postfix, dovecot, rspamd, webmail — into a single container. Makes updates straightforward.
|
poste.io bundles everything — postfix, dovecot, rspamd, webmail — into a single container. Makes updates straightforward.
|
||||||
|
|
||||||
|
n8n (workflow automation) binds 5678 to the Tailscale IP only; public access is proxied by Caddy on helsinki-a. It manages its own user auth.
|
||||||
|
|
||||||
## copenhagen-a — Gaming
|
## copenhagen-a — Gaming
|
||||||
|
|
||||||
Game servers. Not publicly exposed via Caddy — accessed directly over the public IP/Tailscale.
|
Game servers. Not publicly exposed via Caddy — accessed directly over the public IP/Tailscale.
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ locals {
|
||||||
resource "hcloud_zone_rrset" "A_helsinki_a" {
|
resource "hcloud_zone_rrset" "A_helsinki_a" {
|
||||||
for_each = toset([
|
for_each = toset([
|
||||||
"@", "apps", "auth", "bitwarden", "download", "git", "helsinki-a",
|
"@", "apps", "auth", "bitwarden", "download", "git", "helsinki-a",
|
||||||
"jellyfin", "jellyfin-requests", "ldap", "lidarr", "london-a", "music", "naveen",
|
"jellyfin", "jellyfin-requests", "*.k8s", "ldap", "lidarr", "london-a", "music", "naveen",
|
||||||
"plex", "prowlarr", "radarr", "readarr", "request",
|
"n8n", "plex", "prowlarr", "radarr", "readarr", "request",
|
||||||
"sonarr", "soulseek", "status",
|
"sonarr", "soulseek", "status",
|
||||||
])
|
])
|
||||||
zone = hcloud_zone.pezsh.name
|
zone = hcloud_zone.pezsh.name
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue