Compare commits

...

3 commits

Author SHA1 Message Date
af2f462c1c
fix: prometheus retention and authelia fix (#73)
Some checks are pending
Deploy (on merge) / Deploy (push) Waiting to run
Terraform / Plan (push) Waiting to run
Terraform / Apply (push) Blocked by required conditions
* fix: prometheus retention time

* also fix bug with authelia

* linting issues

* more linting
2026-04-25 21:35:39 +01:00
b82013c2f0
fix: actually decomission nextcloud and TWDNE (#72)
* fix: actually decomission nextcloud and TWDNE

* ignore spaces in lint and remove dns for the services

* linting on the linting config wasn't linting the lints
2026-04-25 18:19:16 +01:00
35c5079d8f
fix: remove cloud and TWDNE and add energy dashboard for grafana (#71) 2026-04-25 17:46:17 +01:00
18 changed files with 825 additions and 343 deletions

3
ansible/.ansible-lint Normal file
View file

@ -0,0 +1,3 @@
---
skip_list:
- yaml[braces]

View file

@ -40,7 +40,7 @@ The deploy playbook runs in stages, each independently taggable:
3. **node-exporter** — Prometheus monitoring agent on all hosts
4. **services** — Per-host service deployment:
- `helsinki-a`: Caddy reverse proxy
- `london-b`: Docker Compose services (Nextcloud, Jellyseer, etc.)
- `london-b`: Docker Compose services (Jellyseer, etc.)
- `nuremberg-a`: poste.io mail
- `copenhagen-a`: Minecraft + MaNGOS systemd services
- `london-a`: Prometheus + Grafana (FreeBSD)

View file

@ -11,9 +11,6 @@ docker_services:
- forgejo
- bitwarden
systemd_services:
- thiswebsitedoesnotexist
node_exporter_bind_tailscale: true
common_ufw_allowed_ports:

View file

@ -5,7 +5,6 @@ host_location: "London"
prometheus_location: london
docker_services:
- nextcloud-aio
- jellyseerr
- navidrome
- slskd

View file

@ -10,6 +10,8 @@
ansible.builtin.include_vars:
file: "{{ playbook_dir }}/../group_vars/all/secrets.yaml"
no_log: true
roles:
- prometheus
tasks:
- name: Deploy Prometheus config
ansible.builtin.template:
@ -77,11 +79,6 @@
notify: Restart grafana
handlers:
- name: Restart prometheus
ansible.builtin.service:
name: prometheus
state: restarted
- name: Restart grafana
ansible.builtin.service:
name: grafana

View file

@ -0,0 +1,2 @@
---
prometheus_retention_time: "1y"

View file

@ -0,0 +1,5 @@
---
- name: Restart prometheus
ansible.builtin.service:
name: prometheus
state: restarted

View file

@ -0,0 +1,7 @@
---
- name: Set Prometheus args in rc.conf (FreeBSD)
community.general.sysrc:
name: prometheus_args
value: "--storage.tsdb.retention.time={{ prometheus_retention_time }}"
when: ansible_facts["os_family"] == "FreeBSD"
notify: Restart prometheus

View file

@ -6,22 +6,20 @@
services:
authelia:
container_name: authelia
image: docker.io/authelia/authelia:latest
restart: unless-stopped
container_name: "authelia"
image: "docker.io/authelia/authelia:latest"
restart: "unless-stopped"
ports:
- '127.0.0.1:9091:9091'
- "127.0.0.1:9091:9091"
environment:
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE: /secrets/JWT_SECRET
AUTHELIA_SESSION_SECRET_FILE: /secrets/SESSION_SECRET
AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE: /secrets/STORAGE_ENCRYPTION_KEY
AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE: /secrets/MYSQL_PASSWORD
AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE: /secrets/LLDAP_ADMIN_PASSWORD
AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE: /secrets/SMTP_PASSWORD
TZ: UTC
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE: "/secrets/JWT_SECRET"
AUTHELIA_SESSION_SECRET_FILE: "/secrets/SESSION_SECRET"
AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE: "/secrets/STORAGE_ENCRYPTION_KEY"
AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE: "/secrets/MYSQL_PASSWORD"
TZ: "UTC"
volumes:
- /root/authelia/config:/config
- /root/authelia/secrets:/secrets
- "/root/authelia/config:/config"
- "/root/authelia/secrets:/secrets"
depends_on:
mariadb:
condition: service_healthy
@ -31,19 +29,19 @@ services:
- authelia
mariadb:
container_name: authelia-mariadb
image: docker.io/library/mariadb:11
restart: unless-stopped
container_name: "authelia-mariadb"
image: "docker.io/library/mariadb:11"
restart: "unless-stopped"
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/MYSQL_ROOT_PASSWORD
MYSQL_DATABASE: authelia
MYSQL_USER: authelia
MYSQL_PASSWORD_FILE: /run/secrets/MYSQL_PASSWORD
TZ: UTC
MYSQL_ROOT_PASSWORD_FILE: "/run/secrets/MYSQL_ROOT_PASSWORD"
MYSQL_DATABASE: "authelia"
MYSQL_USER: "authelia"
MYSQL_PASSWORD_FILE: "/run/secrets/MYSQL_PASSWORD"
TZ: "UTC"
volumes:
- /root/authelia/mariadb:/var/lib/mysql
- /root/authelia/secrets/MYSQL_ROOT_PASSWORD:/run/secrets/MYSQL_ROOT_PASSWORD:ro
- /root/authelia/secrets/MYSQL_PASSWORD:/run/secrets/MYSQL_PASSWORD:ro
- "/root/authelia/mariadb:/var/lib/mysql"
- "/root/authelia/secrets/MYSQL_ROOT_PASSWORD:/run/secrets/MYSQL_ROOT_PASSWORD:ro"
- "/root/authelia/secrets/MYSQL_PASSWORD:/run/secrets/MYSQL_PASSWORD:ro"
networks:
- authelia
healthcheck:
@ -54,24 +52,24 @@ services:
start_period: 30s
lldap:
container_name: authelia-lldap
image: docker.io/lldap/lldap:latest
restart: unless-stopped
container_name: "authelia-lldap"
image: "docker.io/lldap/lldap:latest"
restart: "unless-stopped"
ports:
- '17170:17170' # Web UI
- '3890:3890' # LDAP
- "17170:17170"
- "3890:3890"
environment:
UID: '1000'
GID: '1000'
TZ: UTC
LLDAP_LDAP_BASE_DN: dc=pez,dc=sh
LLDAP_LDAP_USER_DN: admin
LLDAP_LDAP_USER_PASS_FILE: /secrets/LLDAP_ADMIN_PASSWORD
LLDAP_JWT_SECRET_FILE: /secrets/LLDAP_JWT_SECRET
UID: "1000"
GID: "1000"
TZ: "UTC"
LLDAP_LDAP_BASE_DN: "dc=pez,dc=sh"
LLDAP_LDAP_USER_DN: "admin"
LLDAP_LDAP_USER_PASS_FILE: "/secrets/LLDAP_ADMIN_PASSWORD"
LLDAP_JWT_SECRET_FILE: "/secrets/LLDAP_JWT_SECRET"
volumes:
- /root/authelia/lldap:/data
- /root/authelia/secrets/LLDAP_ADMIN_PASSWORD:/secrets/LLDAP_ADMIN_PASSWORD:ro
- /root/authelia/secrets/LLDAP_JWT_SECRET:/secrets/LLDAP_JWT_SECRET:ro
- "/root/authelia/lldap:/data"
- "/root/authelia/secrets/LLDAP_ADMIN_PASSWORD:/secrets/LLDAP_ADMIN_PASSWORD:ro"
- "/root/authelia/secrets/LLDAP_JWT_SECRET:/secrets/LLDAP_JWT_SECRET:ro"
networks:
- authelia

View file

@ -117,10 +117,6 @@ jellyfin-requests.pez.solutions, jellyfin-requests.pez.sh {
reverse_proxy 100.84.65.101:5056
}
https://cloud.pez.sh:443 {
reverse_proxy 100.84.65.101:11000 # Adjust to match APACHE_PORT and APACHE_IP_BINDING. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md#adapting-the-sample-web-server-configurations-below
}
music.pez.sh {
reverse_proxy 100.84.65.101:4533
}
@ -172,12 +168,6 @@ pez.solutions {
file_server
}
# Pez.solutions
cloud.pez.solutions {
root * /srv/cloud.pez.solutions
file_server
}
# Pez.sh
pez.sh {
root * /srv/pez.sh
@ -219,8 +209,3 @@ git.pez.sh {
reverse_proxy localhost:3000
}
# This Website Does Not Exist
thiswebsitedoesnotexist.pez.sh {
reverse_proxy localhost:3721
}

View file

@ -1,192 +0,0 @@
# Caddyfile template for helsinki-a reverse proxy
#
# Variables (replace before deploying):
# {{HELSINKI_A_IP}} - helsinki-a Tailscale IP (currently 100.67.6.27)
# {{LONDON_A_IP}} - london-a Tailscale IP (currently 100.122.219.41)
# {{LONDON_B_IP}} - london-b Tailscale IP (currently 100.84.65.101)
# {{AUTHELIA_PORT}} - Authelia port (currently 9091)
# {{DOMAIN_PRIMARY}} - Primary domain (currently pez.sh)
# {{DOMAIN_ALT}} - Alternate domain (currently pez.solutions)
#
# Authelia forward_auth pattern: see README.md for details.
{
admin {{HELSINKI_A_IP}}:2019
metrics {
per_host
}
}
# ============================================================
# Snippet: Authelia forward_auth
# Include with `import authelia` inside any site block.
# ============================================================
(authelia) {
forward_auth localhost:{{AUTHELIA_PORT}} {
uri /api/authz/forward-auth
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
}
## LONDON-A SERVICES ##
# Grafana
grafana.{{DOMAIN_ALT}}, grafana.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_A_IP}}:3000
}
# Prometheus
prometheus.{{DOMAIN_ALT}}, prometheus.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_A_IP}}:9090
}
## LONDON-B SERVICES ##
# Jellyfin (no auth — has its own login)
jellyfin.{{DOMAIN_ALT}}, jellyfin.{{DOMAIN_PRIMARY}} {
reverse_proxy {{LONDON_B_IP}}:8096
}
# Plex (no auth — has its own login)
plex.{{DOMAIN_ALT}}, plex.{{DOMAIN_PRIMARY}} {
reverse_proxy {{LONDON_B_IP}}:32400
}
# Radarr
radarr.{{DOMAIN_ALT}}, radarr.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:7878
}
# Sonarr
sonarr.{{DOMAIN_ALT}}, sonarr.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:8989
}
# Lidarr
lidarr.{{DOMAIN_ALT}}, lidarr.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:8686
}
# Readarr
readarr.{{DOMAIN_ALT}}, readarr.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:8787
}
# slskd (Soulseek)
soulseek.{{DOMAIN_ALT}}, soulseek.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:5030
}
# Prowlarr
prowlarr.{{DOMAIN_ALT}}, prowlarr.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:9696
}
# Transmission
download.{{DOMAIN_ALT}}, download.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:9091
}
# Overseerr (no auth — has its own login)
request.{{DOMAIN_ALT}}, request.{{DOMAIN_PRIMARY}} {
reverse_proxy {{LONDON_B_IP}}:5055
}
# Jellyseerr (no auth — has its own login)
jellyfin-requests.{{DOMAIN_ALT}}, jellyfin-requests.{{DOMAIN_PRIMARY}} {
reverse_proxy {{LONDON_B_IP}}:5056
}
# Nextcloud AIO
https://cloud.{{DOMAIN_PRIMARY}}:443 {
reverse_proxy {{LONDON_B_IP}}:11000
}
# Navidrome
music.{{DOMAIN_PRIMARY}} {
reverse_proxy {{LONDON_B_IP}}:4533
}
# Miniflux RSS
rss.{{DOMAIN_PRIMARY}} {
import authelia
reverse_proxy {{LONDON_B_IP}}:8181
}
## HELSINKI-A SERVICES (localhost) ##
# Bitwarden
https://bitwarden.{{DOMAIN_PRIMARY}} {
reverse_proxy localhost:8443 {
transport http {
tls_insecure_skip_verify
}
}
}
# Authelia portal
auth.{{DOMAIN_ALT}}, auth.{{DOMAIN_PRIMARY}} {
reverse_proxy localhost:{{AUTHELIA_PORT}}
}
# LLDAP web UI
ldap.{{DOMAIN_PRIMARY}} {
reverse_proxy 127.0.0.1:17170
}
# Apps dashboard
apps.{{DOMAIN_ALT}}, apps.{{DOMAIN_PRIMARY}} {
root * /srv/apps
import authelia
file_server
}
# Static sites
{{DOMAIN_ALT}} {
root * /srv/pez.solutions
file_server
}
cloud.{{DOMAIN_ALT}} {
root * /srv/cloud.pez.solutions
file_server
}
{{DOMAIN_PRIMARY}} {
root * /srv/pez.sh
file_server
}
signup.{{DOMAIN_ALT}} {
root * /srv/pez-signup
file_server
}
naveen.{{DOMAIN_PRIMARY}} {
root * /srv/naveen
file_server
}
status.{{DOMAIN_PRIMARY}} {
root * /srv/status
file_server
}
# Forgejo (auth handled by Forgejo itself)
git.{{DOMAIN_PRIMARY}} {
reverse_proxy localhost:3000
}
# This Website Does Not Exist
thiswebsitedoesnotexist.{{DOMAIN_PRIMARY}} {
reverse_proxy localhost:3721
}

View file

@ -85,7 +85,6 @@ forward_auth localhost:9091 {
| Apps dashboard | Authelia | Internal apps page |
| Jellyfin, Plex | Own auth | Have built-in user management |
| Overseerr, Jellyseerr | Own auth | Have built-in user management |
| Nextcloud | Own auth | Has built-in user management |
| Navidrome (music) | No auth* | Accessible directly |
| Bitwarden | Own auth | Has built-in vault auth |
| Forgejo (git) | Own auth | Has built-in user management |
@ -124,5 +123,4 @@ The `Caddyfile.template` replaces hardcoded values with placeholders:
- The live Caddyfile on helsinki-a is at `/etc/caddy/Caddyfile`
- Caddy auto-provisions TLS certificates for all listed domains
- Commented-out WebDAV block was replaced by the Nextcloud AIO reverse proxy
- Static sites (`pez.sh`, `pez.solutions`, etc.) are served from `/srv/` on helsinki-a

View file

@ -0,0 +1,762 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 10,
"links": [],
"liveNow": true,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "#EAB839",
"value": 1000
},
{
"color": "red",
"value": 2000
}
]
},
"unit": "watt"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 0,
"y": 0
},
"id": 3,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "avg_over_time(octopus_electricity_demand_watts{}[30m])",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "30m",
"title": "Average (30 min)",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "#EAB839",
"value": 1000
},
{
"color": "red",
"value": 2000
}
]
},
"unit": "watt"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 6,
"y": 0
},
"id": 6,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "avg_over_time(octopus_electricity_demand_watts{}[6h])",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "6h",
"title": "Average (6 hours)",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "#EAB839",
"value": 1000
},
{
"color": "red",
"value": 2000
}
]
},
"unit": "watt"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 12,
"y": 0
},
"id": 4,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "avg_over_time(octopus_electricity_demand_watts{}[24h])",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "1d",
"title": "Average (1 day)",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "#EAB839",
"value": 1000
},
{
"color": "red",
"value": 2000
}
]
},
"unit": "watt"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 18,
"y": 0
},
"id": 5,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "avg_over_time(octopus_electricity_demand_watts{}[7d])",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "7d",
"title": "Average (7 days)",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 18,
"x": 0,
"y": 6
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.3.3",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"editorMode": "builder",
"expr": "octopus_electricity_demand_watts",
"legendFormat": "Watts",
"range": true,
"refId": "A"
}
],
"title": "Wattage",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"max": 5000,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "yellow",
"value": 1000
},
{
"color": "red",
"value": 2000
}
]
},
"unit": "watt"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 6,
"x": 18,
"y": 6
},
"id": 2,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "standard",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "builder",
"exemplar": false,
"expr": "octopus_electricity_demand_watts",
"instant": true,
"legendFormat": "__auto",
"range": false,
"refId": "A"
}
],
"title": "Current Watts",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"decimals": 2,
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
},
"unit": "currencyGBP"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 0,
"y": 13
},
"id": 7,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "sum_over_time((octopus_electricity_consumption_kwh * on() octopus_electricity_unit_rate_pence)[$__range:30m]) / 100",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "1h",
"title": "Price",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"decimals": 2,
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
},
"unit": "currencyGBP"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 6,
"y": 13
},
"id": 8,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "sum_over_time((octopus_electricity_consumption_kwh * on() octopus_electricity_unit_rate_pence)[$__range:30m]) / 100",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "1d",
"title": "Price",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"decimals": 2,
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
},
"unit": "currencyGBP"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 12,
"y": 13
},
"id": 9,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "sum_over_time((octopus_electricity_consumption_kwh * on() octopus_electricity_unit_rate_pence)[$__range:30m]) / 100",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "1w",
"title": "Price",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezqqznn81wqof"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"decimals": 2,
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
},
"unit": "currencyGBP"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 6,
"x": 18,
"y": 13
},
"id": 10,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"percentChangeColorMode": "inverted",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": true,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.3.3",
"targets": [
{
"editorMode": "code",
"expr": "sum_over_time((octopus_electricity_consumption_kwh * on() octopus_electricity_unit_rate_pence)[$__range:30m]) / 100",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "30d",
"title": "Price",
"type": "stat"
}
],
"preload": false,
"refresh": "1m",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-24h",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Energy",
"uid": "5101a7c4-e5cd-4178-8acf-320588a7a25e",
"version": 5
}

View file

@ -1,10 +0,0 @@
# Nextcloud AIO
All-in-one Nextcloud deployment (self-managed containers).
- **Host:** london-b
- **URL:** https://cloud.pez.sh
- **Admin port:** 8080 (mastercontainer management UI)
- **Apache port:** 11000 (proxied by Caddy on helsinki-a)
- **Data:** Docker volume (`nextcloud_aio_mastercontainer`)
- **Note:** The mastercontainer spawns and manages its own sub-containers (database, redis, apache, etc.)

View file

@ -1,33 +0,0 @@
---
# Nextcloud AIO - All-in-one Nextcloud deployment
# Host: london-b (100.84.65.101)
# Data: Docker volume (nextcloud_aio_mastercontainer)
# Access: https://cloud.pez.sh (via Caddy reverse proxy on helsinki-a)
#
# Note: Nextcloud AIO manages its own sub-containers (apache, database,
# redis, etc.) via the mastercontainer. This compose file only defines
# the mastercontainer itself.
services:
nextcloud-aio-mastercontainer:
image: ghcr.io/nextcloud-releases/all-in-one:latest
container_name: nextcloud-aio-mastercontainer
restart: always
ports:
- "8080:8080"
environment:
SKIP_DOMAIN_VALIDATION: "false"
APACHE_PORT: 11000
APACHE_IP_BINDING: "0.0.0.0"
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- nextcloud-aio
networks:
nextcloud-aio:
driver: bridge
volumes:
nextcloud_aio_mastercontainer:

View file

@ -24,7 +24,6 @@ SERVICE_MAP["100.84.65.101:8787"]="Readarr"
SERVICE_MAP["100.84.65.101:8989"]="Sonarr"
SERVICE_MAP["100.84.65.101:9091"]="Transmission"
SERVICE_MAP["100.84.65.101:9696"]="Prowlarr"
SERVICE_MAP["100.84.65.101:11000"]="Nextcloud"
SERVICE_MAP["localhost:9091"]="Authelia"
SERVICE_MAP["100.84.65.101:8181"]="Miniflux"
SERVICE_MAP["localhost:3000"]="Forgejo"

View file

@ -1,17 +0,0 @@
[Unit]
Description=This Website Does Not Exist
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/thiswebsitedoesnotexist
ExecStart=/usr/bin/node app.js
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3721
EnvironmentFile=/opt/thiswebsitedoesnotexist/.env
[Install]
WantedBy=multi-user.target

View file

@ -36,15 +36,6 @@ resource "cloudflare_dns_record" "bitwarden" {
ttl = 1
}
resource "cloudflare_dns_record" "cloud" {
zone_id = cloudflare_zone.pez-sh.id
name = "cloud"
type = "A"
content = hcloud_server.helsinki-a.ipv4_address
proxied = false
ttl = 1
}
resource "cloudflare_dns_record" "download" {
zone_id = cloudflare_zone.pez-sh.id
name = "download"
@ -252,15 +243,6 @@ resource "cloudflare_dns_record" "status" {
ttl = 1
}
resource "cloudflare_dns_record" "thiswebsitedoesnotexist" {
zone_id = cloudflare_zone.pez-sh.id
name = "thiswebsitedoesnotexist"
type = "A"
content = hcloud_server.helsinki-a.ipv4_address
proxied = true
ttl = 1
}
resource "cloudflare_dns_record" "wow" {
zone_id = cloudflare_zone.pez-sh.id
name = "wow"