Compare commits
41 Commits
ac030018c6
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 7fd79c9911 | |||
| 41eacfec02 | |||
| 0a0748b920 | |||
| d6e0e09e87 | |||
| 61c3020a5e | |||
| 972b973f58 | |||
| 8c5a7b78c6 | |||
| 675204816a | |||
| 3bb82dbc6b | |||
| 0f6233c3ec | |||
| 43fa56bf35 | |||
| 50c930eeaf | |||
| 8dde15b8ef | |||
| 6100d8dc69 | |||
| a92f0fcb28 | |||
| bd4604cdcc | |||
| 31db372b43 | |||
| 360e776745 | |||
| 5a819f70bb | |||
| b2c055ffb2 | |||
| 6e0b34843b | |||
| e8485e3bb7 | |||
| e8cd970960 | |||
| 78b59cec4f | |||
| e6d40a9f7e | |||
| 7733a1be46 | |||
| a5df98bc5a | |||
| fb9b0dd2f5 | |||
| 0dc214069c | |||
| a6c4be9530 | |||
| 6e338e6d65 | |||
| 41f16fa0b8 | |||
| 1b05728817 | |||
| 520a417316 | |||
| 88ed5360ca | |||
| 392d40def3 | |||
| 5ef4d832fb | |||
| 49afc0c084 | |||
| b2c82ceaa8 | |||
| b9286d7243 | |||
| 22931e6747 |
@@ -2,7 +2,7 @@ keys:
|
|||||||
- &admin_ppetru age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
- &admin_ppetru age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
||||||
- &server_zippy age1gtyw202hd07hddac9886as2cs8pm07e4exlnrgfm72lync75ng9qc5fjac
|
- &server_zippy age1gtyw202hd07hddac9886as2cs8pm07e4exlnrgfm72lync75ng9qc5fjac
|
||||||
- &server_chilly age16yqffw4yl5jqvsr7tyd883vn98zw0attuv9g5snc329juff6dy3qw2w5wp
|
- &server_chilly age16yqffw4yl5jqvsr7tyd883vn98zw0attuv9g5snc329juff6dy3qw2w5wp
|
||||||
- &server_sparky age10zxwwufrf5uu9cv9p9znse2ftfm74q9ce893us6cnvxjc7e3ypcqy709dy
|
- &server_sparky age14aml5s3sxksa8qthnt6apl3pu6egxyn0cz7pdzzvp2yl6wncad0q56udyj
|
||||||
- &server_stinky age1me78u46409q9ez6fj0qanrfffc5e9kuq7n7uuvlljfwwc2mdaezqmyzxhx
|
- &server_stinky age1me78u46409q9ez6fj0qanrfffc5e9kuq7n7uuvlljfwwc2mdaezqmyzxhx
|
||||||
- &server_beefy age1cs8uqj243lspyp042ueu5aes4t3azgyuaxl9au70ggrl2meulq4sgqpc7y
|
- &server_beefy age1cs8uqj243lspyp042ueu5aes4t3azgyuaxl9au70ggrl2meulq4sgqpc7y
|
||||||
- &server_alo_cloud_1 age1w5w4wfvtul3sge9mt205zvrkjaeh3qs9gsxhmq7df2g4dztnvv6qylup8z
|
- &server_alo_cloud_1 age1w5w4wfvtul3sge9mt205zvrkjaeh3qs9gsxhmq7df2g4dztnvv6qylup8z
|
||||||
|
|||||||
64
CLAUDE.md
64
CLAUDE.md
@@ -8,42 +8,35 @@ NixOS cluster configuration using flakes. Homelab infrastructure with Nomad/Cons
|
|||||||
├── common/
|
├── common/
|
||||||
│ ├── global/ # Applied to all hosts (backup, sops, users, etc.)
|
│ ├── global/ # Applied to all hosts (backup, sops, users, etc.)
|
||||||
│ ├── minimal-node.nix # Base (ssh, user, boot, impermanence)
|
│ ├── minimal-node.nix # Base (ssh, user, boot, impermanence)
|
||||||
│ ├── cluster-member.nix # Consul + storage clients (NFS/CIFS/GlusterFS)
|
│ ├── cluster-member.nix # Consul agent + storage mounts (NFS/CIFS)
|
||||||
│ ├── nomad-worker.nix # Nomad client (runs jobs) + Docker + NFS deps
|
│ ├── nomad-worker.nix # Nomad client (runs jobs) + Docker + NFS deps
|
||||||
│ ├── nomad-server.nix # Enables Consul + Nomad server mode
|
│ ├── nomad-server.nix # Enables Consul + Nomad server mode
|
||||||
│ ├── cluster-tools.nix # Just CLI tools (nomad, wander, damon)
|
│ ├── cluster-tools.nix # Just CLI tools (nomad, wander, damon)
|
||||||
│ ├── workstation-node.nix # Dev tools (wget, deploy-rs, docker, nix-ld)
|
│ ├── workstation-node.nix # Dev tools (wget, deploy-rs, docker, nix-ld)
|
||||||
│ ├── desktop-node.nix # Hyprland + GUI environment
|
│ ├── desktop-node.nix # Hyprland + GUI environment
|
||||||
│ ├── nfs-services-server.nix # NFS server + btrfs replication (zippy)
|
│ ├── nfs-services-server.nix # NFS server + btrfs replication
|
||||||
│ └── nfs-services-standby.nix # NFS standby + receive replication (c1)
|
│ └── nfs-services-standby.nix # NFS standby + receive replication
|
||||||
├── hosts/
|
├── hosts/ # Host configs - check imports for roles
|
||||||
│ ├── c1/, c2/, c3/ # Cattle nodes (quorum + workers)
|
|
||||||
│ ├── zippy/ # Primary storage + NFS server + worker (not quorum)
|
|
||||||
│ ├── chilly/ # Home Assistant VM + cluster member (Consul only)
|
|
||||||
│ ├── sparky/ # Desktop + cluster member (Consul only)
|
|
||||||
│ ├── fractal/ # (Proxmox, will become NixOS storage node)
|
|
||||||
│ └── sunny/ # (Standalone ethereum node, not in cluster)
|
|
||||||
├── docs/
|
├── docs/
|
||||||
│ ├── CLUSTER_REVAMP.md # Master plan for architecture changes
|
│ ├── CLUSTER_REVAMP.md # Master plan for architecture changes
|
||||||
│ ├── MIGRATION_TODO.md # Tracking checklist for migration
|
│ ├── MIGRATION_TODO.md # Tracking checklist for migration
|
||||||
│ └── NFS_FAILOVER.md # NFS failover procedures
|
│ ├── NFS_FAILOVER.md # NFS failover procedures
|
||||||
|
│ └── AUTH_SETUP.md # Authentication (Pocket ID + Traefik OIDC)
|
||||||
└── services/ # Nomad job specs (.hcl files)
|
└── services/ # Nomad job specs (.hcl files)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Current Architecture
|
## Current Architecture
|
||||||
|
|
||||||
### Storage Mounts
|
### Storage Mounts
|
||||||
- `/data/services` - NFS from `data-services.service.consul` (zippy primary, c1 standby)
|
- `/data/services` - NFS from `data-services.service.consul` (check nfs-services-server.nix for primary)
|
||||||
- `/data/media` - CIFS from fractal (existing, unchanged)
|
- `/data/media` - CIFS from fractal
|
||||||
- `/data/shared` - CIFS from fractal (existing, unchanged)
|
- `/data/shared` - CIFS from fractal
|
||||||
|
|
||||||
### Hosts
|
### Cluster Roles (check hosts/*/default.nix for each host's imports)
|
||||||
- **c1, c2, c3**: Cattle nodes, run most workloads, Nomad/Consul quorum members
|
- **Quorum**: hosts importing `nomad-server.nix` (3 expected for consensus)
|
||||||
- **zippy**: Primary NFS server, runs workloads (affinity), NOT quorum, replicates to c1 every 5min
|
- **Workers**: hosts importing `nomad-worker.nix` (run Nomad jobs)
|
||||||
- **chilly**: Home Assistant VM, cluster member (Consul agent + CLI tools), no workloads
|
- **NFS server**: host importing `nfs-services-server.nix` (affinity for direct disk access like DBs)
|
||||||
- **sparky**: Desktop/laptop, cluster member (Consul agent + CLI tools), no workloads
|
- **Standby**: hosts importing `nfs-services-standby.nix` (receive replication)
|
||||||
- **fractal**: Storage node (Proxmox/ZFS), will join quorum after GlusterFS removed
|
|
||||||
- **sunny**: Standalone ethereum staking node (not in cluster)
|
|
||||||
|
|
||||||
## Config Architecture
|
## Config Architecture
|
||||||
|
|
||||||
@@ -58,19 +51,22 @@ NixOS cluster configuration using flakes. Homelab infrastructure with Nomad/Cons
|
|||||||
- `workstation-node.nix` - Dev tools (deploy-rs, docker, nix-ld, emulation)
|
- `workstation-node.nix` - Dev tools (deploy-rs, docker, nix-ld, emulation)
|
||||||
- `desktop-node.nix` - Extends workstation + Hyprland/GUI
|
- `desktop-node.nix` - Extends workstation + Hyprland/GUI
|
||||||
|
|
||||||
**Host composition examples**:
|
**Composition patterns**:
|
||||||
- c1/c2/c3: `cluster-member + nomad-worker + nomad-server` (quorum + runs jobs)
|
- Quorum member: `cluster-member + nomad-worker + nomad-server`
|
||||||
- zippy: `cluster-member + nomad-worker` (runs jobs, not quorum)
|
- Worker only: `cluster-member + nomad-worker`
|
||||||
- chilly/sparky: `cluster-member + cluster-tools` (Consul + CLI only)
|
- CLI only: `cluster-member + cluster-tools` (Consul agent, no Nomad service)
|
||||||
|
- NFS primary: `cluster-member + nomad-worker + nfs-services-server`
|
||||||
|
- Standalone: `minimal-node` only (no cluster membership)
|
||||||
|
|
||||||
**Key insight**: Profiles (workstation/desktop) no longer imply cluster membership. Hosts explicitly declare roles via imports.
|
**Key insight**: Profiles (workstation/desktop) don't imply cluster roles. Check imports for actual roles.
|
||||||
|
|
||||||
## Key Patterns
|
## Key Patterns
|
||||||
|
|
||||||
**NFS Server/Standby**:
|
**NFS Server/Standby**:
|
||||||
- Primary (zippy): imports `nfs-services-server.nix`, sets `standbys = ["c1"]`
|
- Primary: imports `nfs-services-server.nix`, sets `standbys = [...]`
|
||||||
- Standby (c1): imports `nfs-services-standby.nix`, sets `replicationKeys = [...]`
|
- Standby: imports `nfs-services-standby.nix`, sets `replicationKeys = [...]`
|
||||||
- Replication: btrfs send/receive every 5min, incremental with fallback to full
|
- Replication: btrfs send/receive every 5min, incremental with fallback to full
|
||||||
|
- Check host configs for current primary/standby assignments
|
||||||
|
|
||||||
**Backups**:
|
**Backups**:
|
||||||
- Kopia client on all nodes → Kopia server on fractal
|
- Kopia client on all nodes → Kopia server on fractal
|
||||||
@@ -81,6 +77,12 @@ NixOS cluster configuration using flakes. Homelab infrastructure with Nomad/Cons
|
|||||||
- SOPS for secrets, files in `secrets/`
|
- SOPS for secrets, files in `secrets/`
|
||||||
- Keys managed per-host
|
- Keys managed per-host
|
||||||
|
|
||||||
|
**Authentication**:
|
||||||
|
- Pocket ID (OIDC provider) at `pocket-id.v.paler.net`
|
||||||
|
- Traefik uses `traefik-oidc-auth` plugin for SSO
|
||||||
|
- Services add `middlewares=oidc-auth@file` tag to protect
|
||||||
|
- See `docs/AUTH_SETUP.md` for details
|
||||||
|
|
||||||
## Migration Status
|
## Migration Status
|
||||||
|
|
||||||
**Phase 3 & 4**: COMPLETE! GlusterFS removed, all services on NFS
|
**Phase 3 & 4**: COMPLETE! GlusterFS removed, all services on NFS
|
||||||
@@ -92,7 +94,7 @@ See `docs/MIGRATION_TODO.md` for detailed checklist.
|
|||||||
|
|
||||||
**Deploy a host**: `deploy -s '.#hostname'`
|
**Deploy a host**: `deploy -s '.#hostname'`
|
||||||
**Deploy all**: `deploy`
|
**Deploy all**: `deploy`
|
||||||
**Check replication**: `ssh zippy journalctl -u replicate-services-to-c1.service -f`
|
**Check replication**: Check NFS primary host, then `ssh <primary> journalctl -u replicate-services-to-*.service -f`
|
||||||
**NFS failover**: See `docs/NFS_FAILOVER.md`
|
**NFS failover**: See `docs/NFS_FAILOVER.md`
|
||||||
**Nomad jobs**: `services/*.hcl` - service data stored at `/data/services/<service-name>`
|
**Nomad jobs**: `services/*.hcl` - service data stored at `/data/services/<service-name>`
|
||||||
|
|
||||||
@@ -106,8 +108,8 @@ See `docs/MIGRATION_TODO.md` for detailed checklist.
|
|||||||
## Important Files
|
## Important Files
|
||||||
|
|
||||||
- `common/global/backup.nix` - Kopia backup configuration
|
- `common/global/backup.nix` - Kopia backup configuration
|
||||||
- `hosts/zippy/default.nix` - NFS server config, replication targets
|
- `common/nfs-services-server.nix` - NFS server role (check hosts for which imports this)
|
||||||
- `hosts/c1/default.nix` - NFS standby config, authorized replication keys
|
- `common/nfs-services-standby.nix` - NFS standby role (check hosts for which imports this)
|
||||||
- `flake.nix` - Host definitions, nixpkgs inputs
|
- `flake.nix` - Host definitions, nixpkgs inputs
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
# this line prevents hanging on network split
|
# this line prevents hanging on network split
|
||||||
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.mount-timeout=5s";
|
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.mount-timeout=5s,nobrl";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
environment.systemPackages = [ pkgs.cifs-utils ];
|
environment.systemPackages = [ pkgs.cifs-utils ];
|
||||||
|
|||||||
@@ -103,11 +103,14 @@ in
|
|||||||
] ++ (lib.forEach cfg.standbys (standby: {
|
] ++ (lib.forEach cfg.standbys (standby: {
|
||||||
"replicate-services-to-${standby}" = {
|
"replicate-services-to-${standby}" = {
|
||||||
description = "Replicate /persist/services to ${standby}";
|
description = "Replicate /persist/services to ${standby}";
|
||||||
path = [ pkgs.btrfs-progs pkgs.openssh pkgs.coreutils pkgs.findutils pkgs.gnugrep ];
|
path = [ pkgs.btrfs-progs pkgs.openssh pkgs.coreutils pkgs.findutils pkgs.gnugrep pkgs.curl ];
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
START_TIME=$(date +%s)
|
||||||
|
REPLICATION_SUCCESS=0
|
||||||
|
|
||||||
SSH_KEY="/persist/root/.ssh/btrfs-replication"
|
SSH_KEY="/persist/root/.ssh/btrfs-replication"
|
||||||
if [ ! -f "$SSH_KEY" ]; then
|
if [ ! -f "$SSH_KEY" ]; then
|
||||||
echo "ERROR: SSH key not found at $SSH_KEY"
|
echo "ERROR: SSH key not found at $SSH_KEY"
|
||||||
@@ -130,15 +133,19 @@ in
|
|||||||
echo "Attempting incremental send from $(basename $PREV_LOCAL) to ${standby}"
|
echo "Attempting incremental send from $(basename $PREV_LOCAL) to ${standby}"
|
||||||
|
|
||||||
# Try incremental send, if it fails (e.g., parent missing on receiver), fall back to full
|
# Try incremental send, if it fails (e.g., parent missing on receiver), fall back to full
|
||||||
if btrfs send -p "$PREV_LOCAL" "$SNAPSHOT_PATH" | \
|
# Use -c to help with broken Received UUID chains
|
||||||
|
if btrfs send -p "$PREV_LOCAL" -c "$PREV_LOCAL" "$SNAPSHOT_PATH" | \
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=accept-new root@${standby} \
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=accept-new root@${standby} \
|
||||||
"btrfs receive /persist/services-standby"; then
|
"btrfs receive /persist/services-standby"; then
|
||||||
echo "Incremental send completed successfully"
|
echo "Incremental send completed successfully"
|
||||||
|
REPLICATION_SUCCESS=1
|
||||||
else
|
else
|
||||||
echo "Incremental send failed (likely missing parent on receiver), falling back to full send"
|
echo "Incremental send failed (likely missing parent on receiver), falling back to full send"
|
||||||
|
# Plain full send without clone source (receiver may have no snapshots)
|
||||||
btrfs send "$SNAPSHOT_PATH" | \
|
btrfs send "$SNAPSHOT_PATH" | \
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=accept-new root@${standby} \
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=accept-new root@${standby} \
|
||||||
"btrfs receive /persist/services-standby"
|
"btrfs receive /persist/services-standby"
|
||||||
|
REPLICATION_SUCCESS=1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# First snapshot, do full send
|
# First snapshot, do full send
|
||||||
@@ -146,10 +153,28 @@ in
|
|||||||
btrfs send "$SNAPSHOT_PATH" | \
|
btrfs send "$SNAPSHOT_PATH" | \
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=accept-new root@${standby} \
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=accept-new root@${standby} \
|
||||||
"btrfs receive /persist/services-standby"
|
"btrfs receive /persist/services-standby"
|
||||||
|
REPLICATION_SUCCESS=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Cleanup old snapshots on sender (keep last 24 hours = 288 snapshots at 5min intervals)
|
# Cleanup old snapshots on sender (keep last 10 snapshots, sorted by name/timestamp)
|
||||||
find /persist -maxdepth 1 -name 'services@*' -mmin +1440 -exec btrfs subvolume delete {} \;
|
ls -1d /persist/services@* 2>/dev/null | sort | head -n -10 | xargs -r btrfs subvolume delete
|
||||||
|
|
||||||
|
# Calculate metrics
|
||||||
|
END_TIME=$(date +%s)
|
||||||
|
DURATION=$((END_TIME - START_TIME))
|
||||||
|
SNAPSHOT_COUNT=$(ls -1d /persist/services@* 2>/dev/null | wc -l)
|
||||||
|
|
||||||
|
# Push metrics to Prometheus pushgateway
|
||||||
|
cat <<METRICS | curl -s --data-binary @- http://pushgateway.service.consul:9091/metrics/job/nfs_replication/instance/${standby} || true
|
||||||
|
# TYPE nfs_replication_last_success_timestamp gauge
|
||||||
|
nfs_replication_last_success_timestamp $END_TIME
|
||||||
|
# TYPE nfs_replication_duration_seconds gauge
|
||||||
|
nfs_replication_duration_seconds $DURATION
|
||||||
|
# TYPE nfs_replication_snapshot_count gauge
|
||||||
|
nfs_replication_snapshot_count $SNAPSHOT_COUNT
|
||||||
|
# TYPE nfs_replication_success gauge
|
||||||
|
nfs_replication_success $REPLICATION_SUCCESS
|
||||||
|
METRICS
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
|||||||
@@ -39,26 +39,27 @@ in
|
|||||||
noCheck = true;
|
noCheck = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Cleanup old snapshots on standby (keep last 4 hours for HA failover)
|
# Cleanup old snapshots on standby (keep last 10 snapshots)
|
||||||
systemd.services.cleanup-services-standby-snapshots = {
|
systemd.services.cleanup-services-standby-snapshots = {
|
||||||
description = "Cleanup old btrfs snapshots in services-standby";
|
description = "Cleanup old btrfs snapshots in services-standby";
|
||||||
path = [ pkgs.btrfs-progs pkgs.findutils pkgs.coreutils ];
|
path = [ pkgs.btrfs-progs pkgs.findutils pkgs.coreutils pkgs.curl ];
|
||||||
script = ''
|
script = ''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Keep at least 2 hours of snapshots (24 snapshots at 5min intervals)
|
# Cleanup old snapshots on standby (keep last 10 snapshots, sorted by name/timestamp)
|
||||||
MIN_KEEP=24
|
ls -1d /persist/services-standby/services@* 2>/dev/null | sort | head -n -10 | xargs -r btrfs subvolume delete || true
|
||||||
|
|
||||||
# Count existing snapshots
|
# Calculate metrics
|
||||||
count=$(find /persist/services-standby -maxdepth 1 -name 'services@*' -type d | wc -l)
|
CLEANUP_TIME=$(date +%s)
|
||||||
|
SNAPSHOT_COUNT=$(ls -1d /persist/services-standby/services@* 2>/dev/null | wc -l)
|
||||||
|
|
||||||
# Only delete old snapshots if we have more than the minimum
|
# Push metrics to Prometheus pushgateway
|
||||||
if [ $count -gt $MIN_KEEP ]; then
|
cat <<METRICS | curl -s --data-binary @- http://pushgateway.service.consul:9091/metrics/job/nfs_standby_cleanup/instance/$(hostname) || true
|
||||||
# Delete snapshots older than 4 hours
|
# TYPE nfs_standby_snapshot_count gauge
|
||||||
find /persist/services-standby -maxdepth 1 -name 'services@*' -mmin +240 -exec btrfs subvolume delete {} \; || true
|
nfs_standby_snapshot_count $SNAPSHOT_COUNT
|
||||||
else
|
# TYPE nfs_standby_cleanup_last_run_timestamp gauge
|
||||||
echo "Only $count snapshots found, keeping all (minimum: $MIN_KEEP)"
|
nfs_standby_cleanup_last_run_timestamp $CLEANUP_TIME
|
||||||
fi
|
METRICS
|
||||||
'';
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
|
|||||||
55
docs/AUTH_SETUP.md
Normal file
55
docs/AUTH_SETUP.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Authentication Setup
|
||||||
|
|
||||||
|
SSO for homelab services using OIDC.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
**Pocket ID** (`pocket-id.v.paler.net`) - Lightweight OIDC provider, data in `/data/services/pocket-id`
|
||||||
|
|
||||||
|
**Traefik** - Uses `traefik-oidc-auth` plugin (v0.16.0) to protect services
|
||||||
|
- Plugin downloaded from GitHub at startup, cached in `/data/services/traefik/plugins-storage`
|
||||||
|
- Middleware config in `/data/services/traefik/rules/middlewares.yml`
|
||||||
|
- Protected services add tag: `traefik.http.routers.<name>.middlewares=oidc-auth@file`
|
||||||
|
|
||||||
|
## Flow
|
||||||
|
|
||||||
|
1. User hits protected service → Traefik intercepts
|
||||||
|
2. Redirects to Pocket ID for login
|
||||||
|
3. Pocket ID returns OIDC token
|
||||||
|
4. Traefik validates and forwards with `X-Oidc-Username` header
|
||||||
|
|
||||||
|
## Protected Services
|
||||||
|
|
||||||
|
Use `oidc-auth@file` middleware (grep codebase for full list):
|
||||||
|
- Wikis (TiddlyWiki instances)
|
||||||
|
- Media stack (Radarr, Sonarr, Plex, etc.)
|
||||||
|
- Infrastructure (Traefik dashboard, Loki, Jupyter, Unifi)
|
||||||
|
|
||||||
|
## Key Files
|
||||||
|
|
||||||
|
- `services/pocket-id.hcl` - OIDC provider
|
||||||
|
- `services/traefik.hcl` - Plugin declaration
|
||||||
|
- `/data/services/traefik/rules/middlewares.yml` - Middleware definitions (oidc-auth, simple-auth fallback)
|
||||||
|
|
||||||
|
## Cold Start Notes
|
||||||
|
|
||||||
|
- Traefik needs internet to download plugin on first start
|
||||||
|
- Pocket ID needs `/data/services` NFS mounted
|
||||||
|
- Pocket ID down = all protected services inaccessible
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Infinite redirects**: Check `TRUST_PROXY=true` on Pocket ID
|
||||||
|
|
||||||
|
**Plugin not loading**: Clear cache in `/data/services/traefik/plugins-storage/`, restart Traefik
|
||||||
|
|
||||||
|
**401 after login**: Verify client ID/secret in middlewares.yml matches Pocket ID client config
|
||||||
|
|
||||||
|
## Migration History
|
||||||
|
|
||||||
|
- Previous: Authentik with forwardAuth (removed Nov 2024)
|
||||||
|
- Current: Pocket ID + traefik-oidc-auth (simpler, lighter)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Manage users/clients via Pocket ID UI. Basic auth fallback available via `simple-auth` middleware.*
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
* remote docker images used, can't come up if internet is down
|
* remote docker images used, can't come up if internet is down
|
||||||
* local docker images pulled from gitea, can't come up if gitea isn't up (yet)
|
* local docker images pulled from gitea, can't come up if gitea isn't up (yet)
|
||||||
|
* traefik-oidc-auth plugin downloaded from GitHub at startup (cached in /data/services/traefik/plugins-storage)
|
||||||
* renovate system of some kind
|
* renovate system of some kind
|
||||||
|
* vector (or other log ingestion) everywhere, consider moving it off docker if possible
|
||||||
|
* monitor backup-persist success/fail
|
||||||
|
|
||||||
|
|||||||
138
flake.lock
generated
138
flake.lock
generated
@@ -62,11 +62,11 @@
|
|||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761420385,
|
"lastModified": 1763766218,
|
||||||
"narHash": "sha256-bfBSmKNHry6L/NGBmdymmEA5P/XLzuLDRw2kqaHDsLc=",
|
"narHash": "sha256-CM694zS6IeO/tFvUW7zhlb8t67+6L9QfvCDgQy0nVyQ=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "browser-previews",
|
"repo": "browser-previews",
|
||||||
"rev": "c5eae237f38310ed4c9bea0f6c19e0fe04ad61ef",
|
"rev": "04f8550aa62ccda42a6eb839a4ccf6cdcf3d953d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -84,11 +84,11 @@
|
|||||||
"utils": "utils"
|
"utils": "utils"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756719547,
|
"lastModified": 1762286984,
|
||||||
"narHash": "sha256-N9gBKUmjwRKPxAafXEk1EGadfk2qDZPBQp4vXWPHINQ=",
|
"narHash": "sha256-9I2H9x5We6Pl+DBYHjR1s3UT8wgwcpAH03kn9CqtdQc=",
|
||||||
"owner": "serokell",
|
"owner": "serokell",
|
||||||
"repo": "deploy-rs",
|
"repo": "deploy-rs",
|
||||||
"rev": "125ae9e3ecf62fb2c0fd4f2d894eb971f1ecaed2",
|
"rev": "9c870f63e28ec1e83305f7f6cb73c941e699f74f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -105,11 +105,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1741473158,
|
"lastModified": 1762521437,
|
||||||
"narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=",
|
"narHash": "sha256-RXN+lcx4DEn3ZS+LqEJSUu/HH+dwGvy0syN7hTo/Chg=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "devshell",
|
"repo": "devshell",
|
||||||
"rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0",
|
"rev": "07bacc9531f5f4df6657c0a02a806443685f384a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -125,11 +125,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760701190,
|
"lastModified": 1764110879,
|
||||||
"narHash": "sha256-y7UhnWlER8r776JsySqsbTUh2Txf7K30smfHlqdaIQw=",
|
"narHash": "sha256-xanUzIb0tf3kJ+PoOFmXEXV1jM3PjkDT/TQ5DYeNYRc=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "3a9450b26e69dcb6f8de6e2b07b3fc1c288d85f5",
|
"rev": "aecba248f9a7d68c5d1ed15de2d1c8a4c994a3c5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -141,7 +141,6 @@
|
|||||||
"ethereum-nix": {
|
"ethereum-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"devshell": "devshell",
|
"devshell": "devshell",
|
||||||
"flake-compat": "flake-compat_2",
|
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"flake-utils": "flake-utils_2",
|
"flake-utils": "flake-utils_2",
|
||||||
"foundry-nix": "foundry-nix",
|
"foundry-nix": "foundry-nix",
|
||||||
@@ -153,11 +152,11 @@
|
|||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761647152,
|
"lastModified": 1764174664,
|
||||||
"narHash": "sha256-zuciw00Auu3tNquWiznfIVxgVZepLsaIqC7cwC1+GQ4=",
|
"narHash": "sha256-CYAjcXbI6RzQ3cWKiW/u3ZiJCeVX9PQd2J0+V8zX7c8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "ethereum.nix",
|
"repo": "ethereum.nix",
|
||||||
"rev": "7046ba564c47d7cb298493175ea3c3e9b1186c2e",
|
"rev": "e3a1e2d86a6bc1ef25bdb395d9c770b471d53e7f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -183,21 +182,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat_2": {
|
"flake-compat_2": {
|
||||||
"locked": {
|
|
||||||
"lastModified": 1746162366,
|
|
||||||
"narHash": "sha256-5SSSZ/oQkwfcAz/o/6TlejlVGqeK08wyREBQ5qFFPhM=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f158086a2ecdbb138cd0429410e44994f1b7e4b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat_3": {
|
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1747046372,
|
"lastModified": 1747046372,
|
||||||
@@ -218,11 +202,11 @@
|
|||||||
"nixpkgs-lib": "nixpkgs-lib"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760948891,
|
"lastModified": 1762980239,
|
||||||
"narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=",
|
"narHash": "sha256-8oNVE8TrD19ulHinjaqONf9QWCKK+w4url56cdStMpM=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04",
|
"rev": "52a2caecc898d0b46b2b905f058ccc5081f842da",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -239,11 +223,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760948891,
|
"lastModified": 1763759067,
|
||||||
"narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=",
|
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04",
|
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -324,11 +308,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1759569036,
|
"lastModified": 1762247499,
|
||||||
"narHash": "sha256-FuxbXLDArxD1NeRR8zNnsb8Xww5/+qdMwzN1m8Kow/M=",
|
"narHash": "sha256-dPBqjoBcP3yczY7EUQP6BXf58wauRl+lZVZ/fabgq3E=",
|
||||||
"owner": "shazow",
|
"owner": "shazow",
|
||||||
"repo": "foundry.nix",
|
"repo": "foundry.nix",
|
||||||
"rev": "47ba6d3b02bf3faaa857d3572df82ff186d5279a",
|
"rev": "ae6473c7190edea0e505f433293688014b556b29",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -368,11 +352,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758463745,
|
"lastModified": 1763992789,
|
||||||
"narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=",
|
"narHash": "sha256-WHkdBlw6oyxXIra/vQPYLtqY+3G8dUVZM8bEXk0t8x4=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3",
|
"rev": "44831a7eaba4360fb81f2acc5ea6de5fde90aaa3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -732,11 +716,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761451000,
|
"lastModified": 1763870992,
|
||||||
"narHash": "sha256-qBJL6xEIjqYq9zOcG2vf2nPTeVBppNJzvO0LuQWMwMo=",
|
"narHash": "sha256-NPyc76Wxmv/vAsXJ8F+/8fXECHYcv2YGSqdiSHp/F/A=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix-index-database",
|
"repo": "nix-index-database",
|
||||||
"rev": "ed6b293161b378a7368cda38659eb8d3d9a0dac4",
|
"rev": "d7423982c7a26586aa237d130b14c8b302c7a367",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -747,11 +731,11 @@
|
|||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760958188,
|
"lastModified": 1764328224,
|
||||||
"narHash": "sha256-2m1S4jl+GEDtlt2QqeHil8Ny456dcGSKJAM7q3j/BFU=",
|
"narHash": "sha256-hFyF1XQd+XrRx7WZCrGJp544dykexD8Q5SrJJZpEQYg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "d6645c340ef7d821602fd2cd199e8d1eed10afbc",
|
"rev": "d62603a997438e19182af69d3ce7be07565ecad4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -763,11 +747,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761468971,
|
"lastModified": 1763948260,
|
||||||
"narHash": "sha256-vY2OLVg5ZTobdroQKQQSipSIkHlxOTrIF1fsMzPh8w8=",
|
"narHash": "sha256-dY9qLD0H0zOUgU3vWacPY6Qc421BeQAfm8kBuBtPVE0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "78e34d1667d32d8a0ffc3eba4591ff256e80576e",
|
"rev": "1c8ba8d3f7634acac4a2094eef7c32ad9106532c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -779,11 +763,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-lib": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1754788789,
|
"lastModified": 1761765539,
|
||||||
"narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=",
|
"narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixpkgs.lib",
|
"repo": "nixpkgs.lib",
|
||||||
"rev": "a73b9c743612e4244d865a2fdee11865283c04e6",
|
"rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -809,11 +793,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761349956,
|
"lastModified": 1763191728,
|
||||||
"narHash": "sha256-tH3wHnOJms+U4k/rK2Nn1RfBrhffX92jLP/2VndSn0w=",
|
"narHash": "sha256-esRhOS0APE6k40Hs/jjReXg+rx+J5LkWw7cuWFKlwYA=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "02f2cb8e0feb4596d20cc52fda73ccee960e3538",
|
"rev": "1d4c88323ac36805d09657d13a5273aea1b34f0c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -825,11 +809,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable_2": {
|
"nixpkgs-unstable_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761373498,
|
"lastModified": 1764242076,
|
||||||
"narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=",
|
"narHash": "sha256-sKoIWfnijJ0+9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce",
|
"rev": "2fad6eac6077f03fe109c4d4eb171cf96791faa4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -865,11 +849,11 @@
|
|||||||
"systems": "systems_5"
|
"systems": "systems_5"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761657569,
|
"lastModified": 1764238240,
|
||||||
"narHash": "sha256-2D4Tw5Vp52RU5amnBvq0/z+zgZqafwl4bhg8dJBBjXI=",
|
"narHash": "sha256-7Znm3koZ4sF+O41Y7rJqf651BPEbjIUYF3r9H23GRGw=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixvim",
|
"repo": "nixvim",
|
||||||
"rev": "03c0dabb9a63f52bc2ebf571f3755720df1ca81e",
|
"rev": "f1e07ba53abd0fb4872a365cba45562144ad6130",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -888,11 +872,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760652422,
|
"lastModified": 1761730856,
|
||||||
"narHash": "sha256-C88Pgz38QIl9JxQceexqL2G7sw9vodHWx1Uaq+NRJrw=",
|
"narHash": "sha256-t1i5p/vSWwueZSC0Z2BImxx3BjoUDNKyC2mk24krcMY=",
|
||||||
"owner": "NuschtOS",
|
"owner": "NuschtOS",
|
||||||
"repo": "search",
|
"repo": "search",
|
||||||
"rev": "3ebeebe8b6a49dfb11f771f761e0310f7c48d726",
|
"rev": "e29de6db0cb3182e9aee75a3b1fd1919d995d85b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -913,11 +897,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760558991,
|
"lastModified": 1762999930,
|
||||||
"narHash": "sha256-E8MMVwy7QNURBtCLiCjFXfv7uZUEg6QVSZLu4q9YGpk=",
|
"narHash": "sha256-uKyxLwiN6sD6EmRSno66y1a8oqISr1XiWxbWHoMJT7I=",
|
||||||
"owner": "henrysipp",
|
"owner": "henrysipp",
|
||||||
"repo": "omarchy-nix",
|
"repo": "omarchy-nix",
|
||||||
"rev": "fba993c589920fbe68d9f7918e52903c476adad2",
|
"rev": "308e0f85a0deb820c01cfbe1b4faee1daab4da12",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -928,7 +912,7 @@
|
|||||||
},
|
},
|
||||||
"pre-commit-hooks": {
|
"pre-commit-hooks": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat_3",
|
"flake-compat": "flake-compat_2",
|
||||||
"gitignore": "gitignore",
|
"gitignore": "gitignore",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"omarchy-nix",
|
"omarchy-nix",
|
||||||
@@ -974,11 +958,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760998189,
|
"lastModified": 1764021963,
|
||||||
"narHash": "sha256-ee2e1/AeGL5X8oy/HXsZQvZnae6XfEVdstGopKucYLY=",
|
"narHash": "sha256-1m84V2ROwNEbqeS9t37/mkry23GBhfMt8qb6aHHmjuc=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "5a7d18b5c55642df5c432aadb757140edfeb70b3",
|
"rev": "c482a1c1bbe030be6688ed7dc84f7213f304f1ec",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1085,11 +1069,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761311587,
|
"lastModified": 1762938485,
|
||||||
"narHash": "sha256-Msq86cR5SjozQGCnC6H8C+0cD4rnx91BPltZ9KK613Y=",
|
"narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "2eddae033e4e74bf581c2d1dfa101f9033dbd2dc",
|
"rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, inputs, ... }:
|
{ pkgs, lib, inputs, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../../common/global
|
../../common/global
|
||||||
@@ -12,4 +12,27 @@
|
|||||||
|
|
||||||
networking.hostName = "alo-cloud-1";
|
networking.hostName = "alo-cloud-1";
|
||||||
services.tailscaleAutoconnect.authkey = "tskey-auth-kbdARC7CNTRL-pNQddmWV9q5C2sRV3WGep5ehjJ1qvcfD";
|
services.tailscaleAutoconnect.authkey = "tskey-auth-kbdARC7CNTRL-pNQddmWV9q5C2sRV3WGep5ehjJ1qvcfD";
|
||||||
|
|
||||||
|
services.tailscale = {
|
||||||
|
enable = true;
|
||||||
|
useRoutingFeatures = lib.mkForce "server"; # enables IPv4/IPv6 forwarding + loose rp_filter
|
||||||
|
extraUpFlags = [ "--advertise-exit-node" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.nat = {
|
||||||
|
enable = true;
|
||||||
|
externalInterface = "enp1s0";
|
||||||
|
internalInterfaces = [ "tailscale0" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
enable = lib.mkForce true;
|
||||||
|
allowedTCPPorts = [ 80 443 ]; # Public web traffic only
|
||||||
|
allowedUDPPorts = [ 41641 ]; # Tailscale
|
||||||
|
trustedInterfaces = [ "tailscale0" ]; # Full access via VPN
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
settings.PasswordAuthentication = false; # Keys only
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,7 @@
|
|||||||
networking.hostName = "beefy";
|
networking.hostName = "beefy";
|
||||||
networking.cluster.primaryInterface = "enp1s0";
|
networking.cluster.primaryInterface = "enp1s0";
|
||||||
services.tailscaleAutoconnect.authkey = "tskey-auth-k79UsDTw2v11CNTRL-oYqji35BE9c7CqM89Dzs9cBF14PmqYsi";
|
services.tailscaleAutoconnect.authkey = "tskey-auth-k79UsDTw2v11CNTRL-oYqji35BE9c7CqM89Dzs9cBF14PmqYsi";
|
||||||
|
|
||||||
|
# Enable all SysRq functions for debugging hangs
|
||||||
|
boot.kernel.sysctl."kernel.sysrq" = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
networking.hostName = "c1";
|
networking.hostName = "c1";
|
||||||
services.tailscaleAutoconnect.authkey = "tskey-auth-k2nQ771YHM11CNTRL-YVpoumL2mgR6nLPG51vNhRpEKMDN7gLAi";
|
services.tailscaleAutoconnect.authkey = "tskey-auth-k2nQ771YHM11CNTRL-YVpoumL2mgR6nLPG51vNhRpEKMDN7gLAi";
|
||||||
|
|
||||||
# NFS standby configuration: accept replication from zippy
|
|
||||||
nfsServicesStandby.replicationKeys = [
|
nfsServicesStandby.replicationKeys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHyTKsMCbwCIlMcC/aopgz5Yfx/Q9QdlWC9jzMLgYFAV root@zippy-replication"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHyTKsMCbwCIlMcC/aopgz5Yfx/Q9QdlWC9jzMLgYFAV root@zippy-replication"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO5s73FSUiysHijWRGYCJY8lCtZkX1DGKAqp2671REDq root@sparky-replication"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,20 +5,22 @@
|
|||||||
../../common/global
|
../../common/global
|
||||||
../../common/cluster-member.nix
|
../../common/cluster-member.nix
|
||||||
../../common/nomad-worker.nix
|
../../common/nomad-worker.nix
|
||||||
../../common/nfs-services-standby.nix
|
../../common/nfs-services-server.nix
|
||||||
|
# To move NFS server role to another host:
|
||||||
|
# 1. Follow procedure in docs/NFS_FAILOVER.md
|
||||||
|
# 2. Replace above line with: ../../common/nfs-services-standby.nix
|
||||||
|
# 3. Add nfsServicesStandby.replicationKeys with the new server's public key
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
diskLayout = {
|
diskLayout = {
|
||||||
mainDiskDevice = "/dev/disk/by-id/nvme-Samsung_SSD_970_EVO_Plus_250GB_S4EUNF0MA33640P";
|
mainDiskDevice = "/dev/disk/by-id/nvme-KIOXIA-EXCERIA_with_Heatsink_SSD_84GF7016FA4S";
|
||||||
#keyDiskDevice = "/dev/disk/by-id/usb-Intenso_Micro_Line_22080777660468-0:0";
|
#keyDiskDevice = "/dev/disk/by-id/usb-Intenso_Micro_Line_22080777660468-0:0";
|
||||||
keyDiskDevice = "/dev/sda";
|
keyDiskDevice = "/dev/sda";
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.hostName = "sparky";
|
networking.hostName = "sparky";
|
||||||
services.tailscaleAutoconnect.authkey = "tskey-auth-kBCKN7QNv411CNTRL-n5Td7Jw7h3TAjubEeLmy1THy33JvD9JnM";
|
services.tailscaleAutoconnect.authkey = "tskey-auth-k6VC79UrzN11CNTRL-rvPmd4viyrQ261ifCrfTrQve7c2FesxrG";
|
||||||
|
|
||||||
nfsServicesStandby.replicationKeys = [
|
nfsServicesServer.standbys = [ "c1" ];
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHyTKsMCbwCIlMcC/aopgz5Yfx/Q9QdlWC9jzMLgYFAV root@zippy-replication"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,6 @@
|
|||||||
../../common/global
|
../../common/global
|
||||||
../../common/cluster-member.nix # Consul + storage clients
|
../../common/cluster-member.nix # Consul + storage clients
|
||||||
../../common/nomad-worker.nix # Nomad client (runs jobs)
|
../../common/nomad-worker.nix # Nomad client (runs jobs)
|
||||||
# NOTE: zippy is NOT a server - no nomad-server.nix import
|
|
||||||
../../common/nfs-services-server.nix # NFS server for /data/services
|
|
||||||
# To move NFS server role to another host:
|
|
||||||
# 1. Follow procedure in docs/NFS_FAILOVER.md
|
|
||||||
# 2. Replace above line with: ../../common/nfs-services-standby.nix
|
|
||||||
# 3. Add nfsServicesStandby.replicationKeys with the new server's public key
|
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -22,9 +16,4 @@
|
|||||||
|
|
||||||
networking.hostName = "zippy";
|
networking.hostName = "zippy";
|
||||||
services.tailscaleAutoconnect.authkey = "tskey-auth-ktKyQ59f2p11CNTRL-ut8E71dLWPXsVtb92hevNX9RTjmk4owBf";
|
services.tailscaleAutoconnect.authkey = "tskey-auth-ktKyQ59f2p11CNTRL-ut8E71dLWPXsVtb92hevNX9RTjmk4owBf";
|
||||||
|
|
||||||
nfsServicesServer.standbys = [
|
|
||||||
"c1"
|
|
||||||
"sparky"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
kopia: ENC[AES256_GCM,data:FrvSs1th,iv:GnoJ9ec26Wx8rH/G5yuN2CwmBp2ITD2C264cYQ2t6io=,tag:zn67Rikn7PXS2jOTf+KQ3Q==,type:str]
|
kopia: ENC[AES256_GCM,data:/6jqArNgeBoGnEdJ1eshrsG8RJs=,iv:2nNdrKczus70QDdvO/MC2wJubGnAf3M8PtzSe1aoBF4=,tag:aOoktsqhQLXr0YkjYZq4OQ==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- recipient: age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
- recipient: age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
||||||
@@ -19,7 +19,7 @@ sops:
|
|||||||
R21jYU96SGVHOUxmZjlldS96K2VqbWcKC28wLdT/zx6yHluCLqB/cFRmc0Alq6AH
|
R21jYU96SGVHOUxmZjlldS96K2VqbWcKC28wLdT/zx6yHluCLqB/cFRmc0Alq6AH
|
||||||
DqmAaxRhOg/SI5ljCX1gE5BB9rNIJ1Gq8+li7wCpsdfLMr5Yy/HAsw==
|
DqmAaxRhOg/SI5ljCX1gE5BB9rNIJ1Gq8+li7wCpsdfLMr5Yy/HAsw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-10-29T15:41:56Z"
|
lastmodified: "2025-11-04T20:25:17Z"
|
||||||
mac: ENC[AES256_GCM,data:AM5Srw03yvk6gKVf3KF/N5ilYKgF0KKObA98N4KbLGNsxsAagvmQtvzWurgDmOvihbKyBlNyOCjBVCHrKwfzzdCHj0+9lcuCtZ5CC/zOy9a7LMFJvpElj0pQUxpODU+6HcGtdrQQpsfEkzrMBzw1wsJhJ9vC1rp0YdUqK7+wS5g=,iv:M0mTIlXZPdyiTUf/8vYJvmDTMB9bOwH2BKTexPpS/2Q=,tag:CFylsJEP9mePMcRoxrxgwA==,type:str]
|
mac: ENC[AES256_GCM,data:llS+R5Pj51ZUkU8FkJx2KqqE4D42Uno3Btn31FadIl4kFamnrL6uJjbiNEJpFFO+SchXD3l7VCatbBhMSoxsPYd+rdDRT2klq+iIcZU/k413GC87xdmHIwWE+L2pujv36iBjtM+HJTSvXI0xOxjUmzH4FPdEa1r3Z5yGNnCI+Q4=,iv:ld6pSEzvKTSZtBb+QjHyqqj2VT05YegxBrUR2yxhjKY=,tag:7/vYBh8lDOcVXJL3esTIZQ==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.11.0
|
version: 3.11.0
|
||||||
|
|||||||
@@ -4,92 +4,92 @@ sops:
|
|||||||
- recipient: age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
- recipient: age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5cU1JS1VOWGF6aC9VaTZ0
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4WExPaEtTdEljYkF1ZUQw
|
||||||
UzFuUklwTUxEUy9LdUhxaEhRWkZ4VHRNWkNnCituRXNieW5WcUR6MmM2OW1ha3E3
|
UHhRNDJZb2wydWVUaXFmR213SjJsNDFKU0FjCnJ3Tk1yZDZkU3orcHZ2UDY3elRi
|
||||||
NXNuMWMvcnUvZ2ZZYnhzSnR3dUxIWXcKLS0tIEJXdENxbXVhZ3l0M0oyZGladUdU
|
WW9FMXU0cDNjV3QrOWo3MVB0UzMwakUKLS0tIEhQVldBVWhmR0k0WW9jTE0xc2ZW
|
||||||
MTU3RS81SnlwZW81a2JQQVhYa0FwZkEKPvwH91RMG6t5Uwztp5rTjThYCh8lkIEe
|
RWp4ZjlVN0FWaURlRHNONDhXdmJpS1EKZVXYyFRFD9KdyWuMoQytkQk4VxpBRyAV
|
||||||
LevB8nj5HmlLWYhVdrl/P78DHkbDb2jZrmsbh14cbMx+Z7Z3a1SMQw==
|
lF4FA99wjGMhHFNQExnqYYLYtFkA18/SB6pkneOjdhIvEr0IFLJEqg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1gtyw202hd07hddac9886as2cs8pm07e4exlnrgfm72lync75ng9qc5fjac
|
- recipient: age1gtyw202hd07hddac9886as2cs8pm07e4exlnrgfm72lync75ng9qc5fjac
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiR0FyemxNeFBlbFM2TGgr
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjZ29wdk1aOHZJYWFjaG9v
|
||||||
WjFxemZXQjdrdmxuZjc1V0NBZjcyTTNsTlZJClAyS3ZmdmJIdmJqb3dUYU1TSEdn
|
RGxsek95QmtrZS9xRWdKMFdLSHZ3NmlZRGxzCnBvRXZkYnkxdkhJWkY0Ukg1M0dE
|
||||||
aW9Lc3RnbWNkTGpnRlVuZmhpaXZHeW8KLS0tIDdnNHZ2dlFLSUFUSTBySDBneXBr
|
dWc3QWtCdkV5Ymd4MkxhZWl0ZDNCZXcKLS0tIGMrVWtNNWtscm9STUN1aHVZc2Ny
|
||||||
TmRYdFBQT1ZDZ0NGMnkyQU1LWmtSSVUKJz1v/z97cBXvAqvkDnSM7Jp5lK/BtvY/
|
Vm1oaFFTbTBpRWxuR3gxbUZ0YkZieVkKdaSSXrDzAUGkj3w8/YcFZaJTiUUEbJdw
|
||||||
sf7V1Gqg5XEE678rAFT/O+vpaniHevr47bt89bKOVCFb3FaheAmgbA==
|
GjuLz7bxX8+HQvhSbu6/KCwG6R4j1eO5Zg1w0wYtyeUOV1HfZEGQog==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age16yqffw4yl5jqvsr7tyd883vn98zw0attuv9g5snc329juff6dy3qw2w5wp
|
- recipient: age16yqffw4yl5jqvsr7tyd883vn98zw0attuv9g5snc329juff6dy3qw2w5wp
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArWktWbk4rMlQwa3ZrNjVv
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIMGpibmNRUDRFaFVOTDB4
|
||||||
WkRTSWVIVFltbUJVeCt6dnE0WFROYldqSkRFCjJPa2dWN0h3alg4NnVIVFRUUEc2
|
RVdTc1RrTmRPb0dlZGlpcGxuRlJ1L2w5MVVBCi9HdXNGZmdSaVZsQWRoa2RpVDNV
|
||||||
WjNzb3lObFRWUG12RjNFMTZJVlYrNUkKLS0tIFZLMFV6cXo0bFVNVWFlYnNUVXl6
|
OXBtS0pwYnhjS2hCUk10UUtwam4zMWcKLS0tIFV0dVpQNGpSOEVoZnE5OGpCZkxa
|
||||||
VUphbmpLL2FDcjB6WVFySkw1QTJIYWsKriG/2kyw63mjnWBkyKMRKqqf82ZYYIMy
|
MFMxSG95dmJncGJzR29mQkVzNjFIQUEKrJ0MDTBmiwiAaLt7CJ1pjlxuFvZJuRkR
|
||||||
TJ6Zuls71RmxTh0WRVFF5/iOoL1YmD2uOeYwwM+Kc8itzBj5vZxGOQ==
|
EuLYOYLdVaxgZ442io5OE7wme0P4LLcxSAreDG84GVs67JHvsFE89g==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age10zxwwufrf5uu9cv9p9znse2ftfm74q9ce893us6cnvxjc7e3ypcqy709dy
|
- recipient: age14aml5s3sxksa8qthnt6apl3pu6egxyn0cz7pdzzvp2yl6wncad0q56udyj
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsbnArTnU3WUU4MmFWOEVx
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBucHdSNGNyRkVITmNDVkpx
|
||||||
M2ZiZkJjUTBIb3NHSFo3N3l3dDhzZTdZTjM0CkJxWi9nVHZDVTBTaUhLME1LeVF3
|
QVFKK0VucFNSMnNqSGRFRmRoRWpsZ0srUUhrCkwwY2pDSkJ0aGlqc3U3ZXNJUVl0
|
||||||
dlRuWWJTUUgrU3l3aHhiWFJyT1ZQRFUKLS0tIHhRVFV3Y3ZXRWdoc1lkYTJWK0tk
|
bXZMSVg3bDhaK3d1MTBnL1BQVUhkMUkKLS0tIDdxSk1DMVpsbnI1QlFnNEFJYXRD
|
||||||
Ni94RkZQak1nbVl0TmZ2SnVGQTFQVFkKaSe+6pTXj+YxZvl2fUflrobjblr7sFse
|
RTNxYUxlUGxsM1NvekZ4R1hQVE9KMk0KocfE75DTfQMj/RsznOdeF82aO8WwO4HD
|
||||||
kpJziK/UYVvp8FsOoBYdqyfNyi+yCn+J2q+EfDlgHHCipvNm7/Q/lQ==
|
1xakOM2FHoHi60Q5uOWzfGtz0i+R4ue9hafa5Esn01TOjc3qWSlW3A==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1me78u46409q9ez6fj0qanrfffc5e9kuq7n7uuvlljfwwc2mdaezqmyzxhx
|
- recipient: age1me78u46409q9ez6fj0qanrfffc5e9kuq7n7uuvlljfwwc2mdaezqmyzxhx
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSa0NRY3JLZjQ4L215QTdF
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYTEhiSDZvZTg3ZWxJRXlu
|
||||||
clVtWE5ZMHVFSEE2U1E4dUI3Vk5hNGQrakF3CmQwRFNKWFNVOE1zRWpHQ3g4czdz
|
a0ozOXRVL2lia054SkNLc2tEYmlZUCt1NW1JCkorK0hub1pLQTE0QThEUDRDWXJV
|
||||||
MkV6cFB0UjFBM0xaeFNBNExBc1BsTk0KLS0tIGtCSHdHZ0FoVndBS0xpbHg4S1NL
|
YWtGamNxMTFIYjVDT2RqTXh0Z2hVTjAKLS0tIGxoRTAwc3FKVVNSQndtbTZmc3BR
|
||||||
QVF6KzdmSnVEcUxUa2xReU9OY1JHRzgKShY79DAGVzlN5a3DmKVeb35eaQ6esIcJ
|
QnMrK2lMT25tR1ErV2xvS01JWWswVUEKtrGaLETMfY2D8qmgml/fgGxkvQLoiMTP
|
||||||
KPUyYjezvnnmU/HC10Ft3Dlw1m6foWbL2BqgvuYscTtN58cWWrtH3Q==
|
l3a7Y6kwutuzRnmW1tnWv7yoPbTn+BDwfOwBcnesl2x0aJ5iLUKruA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1cs8uqj243lspyp042ueu5aes4t3azgyuaxl9au70ggrl2meulq4sgqpc7y
|
- recipient: age1cs8uqj243lspyp042ueu5aes4t3azgyuaxl9au70ggrl2meulq4sgqpc7y
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0NTg1eXp5ZGZkbmUzdjhG
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqMFJ1bzQxWjlZTmF6eEl0
|
||||||
RzZaMnJmZ2h0MmEyOVpVTzR4QUFQbVpHOTM0CjJmaFUzcjRnUEVZcitDQ0VGUUQ5
|
d3VVd0VsbGZGdDBKRG9uNEhaMThmWmpuQ1hFClA1aDhwRU1Pb2pibGh6T0pqdmlq
|
||||||
eDVRcDRZNVh6cUZsWktmMnM1UHBFTjAKLS0tIHE4QWZPZEpuZUQ3OE55OWlVMk9t
|
S3cxM0wyWWlCL3U5TjV4Vkg4blRsUVkKLS0tIENnYk5GbmZWbFo4cElON1Z0ZVlv
|
||||||
eTBUZHFTcElOMk5LQ1lHUUJVQUtGSGcKh+51nVjiyGQ9GbBPBDEy7QgPDJ1V8uK/
|
ZDdsci9rcG5Wc2V0NlQ3MWx1cFF4dUkKumFT4xtjGDBGK+/SV27Dh/vyGMJAEZNo
|
||||||
rihPxs6KkvwUPHaoPQdgv5tCfIf4VIxEcSM4peST9iuLZdw2pThAHQ==
|
9gTmVLfR9vXVAXUdOMcqgo7Nl4OJCS4HrDxvVCoER/bVoQVRiPzuXw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1w5w4wfvtul3sge9mt205zvrkjaeh3qs9gsxhmq7df2g4dztnvv6qylup8z
|
- recipient: age1w5w4wfvtul3sge9mt205zvrkjaeh3qs9gsxhmq7df2g4dztnvv6qylup8z
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyOFkrb1JiU1F4cVlOOGhn
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCM2E5a2lsZGJzRnk5N3Rr
|
||||||
alFzemVlMTdqL3dXMzBZSkptUEx6Zi9WV0RzCnM5L0dMcG9uRjd3amhycHJkSmFS
|
bWRwRlI2c0c4NzBNdEVqMGZFWTZtNDlvSzJFCmFPM05XbndsazRGWEw3Zy83dldm
|
||||||
NzUxYm50SDA4K1NnUEFNNjZueUoyYmsKLS0tIG1FQ3NQQm9jTEdkSytxQ2RKNmVO
|
eXhEZUZQZWk5bVNwaEk5SDRka0NOWjAKLS0tIHNvZ016Rjh5bmYwRUxyRWRydFpI
|
||||||
RjdoTUMvSDVIZlFJU0RaQTVLRERzTk0KBofmLU596Ij5FMAo2CZ/H0xl7Oe/0xxj
|
Z0NHYjFzem55bVNORGlVbVNxR2psc2cK6JpNZwznwgl61d/W9g+48/894TQRe4gJ
|
||||||
3baiF/IEJ1JrhrQnd/+UEermMb5T6caj8rbryybmSzb33JV+DBylOw==
|
nl4oDwRPbZwJZgdAKQVfTTujB0QbWpJc24mDGD4I4CydqTKwy6FN3A==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1wwufz86tm3auxn6pn27c47s8rvu7en58rk00nghtaxsdpw0gya6qj6qxdt
|
- recipient: age1wwufz86tm3auxn6pn27c47s8rvu7en58rk00nghtaxsdpw0gya6qj6qxdt
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCeEQybTlXaFoxNmtGUXFs
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlK1A1eVdRQThQUHdqbHdk
|
||||||
aG9zQStLTXIydlJQaWowbnhUQjlza2dPVTFjCnZzdEZGbGF4ckN6SlVLSGVKQmdM
|
b1MyMlBJUFluTm13ZWwwc1RNbThFZUMrNXhzCnRPTVhPSzUzM0VtaUVJbFl5Wllj
|
||||||
UFI3WGJtK2U4aE0zMmpGYnFMVFRUU0kKLS0tIEZsazliSExnTWlKRWRlek1La2oy
|
NUlndzc3Yzhjd1JSb3czajI3UmRDZ1kKLS0tIE03M1hab1MxU0I2VExBWlh2TnJC
|
||||||
dmZ6dEFJNy9wYjBVbzc3dnFJc2ZGYXMK4dVqqtiKABFm4EfTPAVGU4PvpU8S5DqW
|
eGRXRTlsWmlpenJrVkMxakJZVTV0cE0KMQCKscSLnCu3NsurFFiDaUGjJbyIAwd0
|
||||||
PDayS5ta4XPeE0U7rxGrKTnFtd9SGlZH46/JIJj95mjZEwqJD/dGkQ==
|
HTutCiuPYVI4zznQ3RZDBeO5L6a/twXxMRTePUCwOkRNWRWpzR9nxg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1jy7pe4530s8w904wtvrmpxvteztqy5ewdt92a7y3lq87sg9jce5qxxuydt
|
- recipient: age1jy7pe4530s8w904wtvrmpxvteztqy5ewdt92a7y3lq87sg9jce5qxxuydt
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6NXFiUVJnMU4xNXBza0Rp
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1VEJmMWlnemFGNExWYUI4
|
||||||
NG01Tk9GblpqcVNQVkUvc29sNlVnKzd4STM4CjFZMG55c1VZUEgzbWVtZE1jTmYz
|
QWRwRktwODNvSmlEcGJORHNlQXNVeXVpbFNrCms0QUFNdDlrNjMxazU1UTcwc2JF
|
||||||
eVZETm56MXQrbVNKeE94bWFIK09Vc1UKLS0tIHk4T3ZJTXVJUzFULzBiemxCNW8w
|
RC9JUnJsWmgyc01zZU9JQmxuM3V6STQKLS0tIGxQZGFsZ0pNTjQ3QW1sS0E2Y2RM
|
||||||
SVE3UnRJdDFOYXV1SU5hc0pJa2wrNFUK2b0PpYfHbDOi50eq3pSJngdaP4DLKwqR
|
aVVrNW1BNXQ5UDk1UEtVVWJPNHpwUFUKcArFPFknBj8ss1lD38YtMaB06L/ASeu5
|
||||||
sggB0M0ztRARE/uTQkGtQv1hxvjrahZCaoV3MvLAGlEq+YgmMMMPfQ==
|
u4ff0rTDx237snaSFg5RIJ+6uxX16p5ODg3xOYGOMkDeuTLdl2bg3A==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1zjgqu3zks5kvlw6hvy6ytyygq7n25lu0uj2435zlf30smpxuy4hshpmfer
|
- recipient: age1zjgqu3zks5kvlw6hvy6ytyygq7n25lu0uj2435zlf30smpxuy4hshpmfer
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuRzN3UlpvbTlrSG9Na3FM
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArWTNkaFlrQkJHRnd4cTBw
|
||||||
QVBjVGV3cVZhbjVacDBFTEFXK05IM2FUOHhNCklJbWx1bGZmR1NIQ0dkaUlraWl1
|
N3dnTXk3SlJkQkZDdWpLcEpNQ2Z2RHZoVjBJCjBaK1MzbzdaaXluR1dFaFFNaGEx
|
||||||
UThTbmZSc243UllKOTJPZlJTYldBdFUKLS0tIExnRFBSN2lIWklKcW8wZ3BjWWUv
|
VTNrVU0yeG9KQkhqUkYxU3VBM0E0R1UKLS0tIDJHek9vVldSZGN0M0c0UHcySGhk
|
||||||
U25jb0UxY2U0YTkzNTNiWFd2Vmt6OEEK5LlRKtvtxDMEyCNrKkHH7YxVM6ZPt00F
|
Z2RoZno4bmhidytlL2ZmNWUzNTcwcVEKXvgaO8Uo0R+Kc8lizLtVxmTi0W5XHjYw
|
||||||
z0dwvmcB7DfOTzOnbXMwf6A/NAV/u4kXuZWGXLYFeso/c2kBlaQuUA==
|
7evdCHQHmFl0vg/bGOJBmcTUhioJv06D0LR3XMl9I6ufXDNaT/NHxw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-04-04T09:34:06Z"
|
lastmodified: "2025-04-04T09:34:06Z"
|
||||||
mac: ENC[AES256_GCM,data:YIcRrsPparPfPaI2+MLlKsxu7M19H8nndOsrDLuh/5BXzIZNiuTIWyvxODyhI745rDwlibO+7Q0QctanhTl4+IzGaYtuY4i+rb+3dzBMpcdT2VAbtCHHxcltWeanRGFq2K3WM2tbnQCERst5kejfn0Razjq3UU5vNwfBsdJMwGc=,iv:izDxy0ufVnH8ImkZIngcYhGuj0PGpLqBD/ZDvQyE+5I=,tag:oYBUEQS52pr09h5OvOadNg==,type:str]
|
mac: ENC[AES256_GCM,data:YIcRrsPparPfPaI2+MLlKsxu7M19H8nndOsrDLuh/5BXzIZNiuTIWyvxODyhI745rDwlibO+7Q0QctanhTl4+IzGaYtuY4i+rb+3dzBMpcdT2VAbtCHHxcltWeanRGFq2K3WM2tbnQCERst5kejfn0Razjq3UU5vNwfBsdJMwGc=,iv:izDxy0ufVnH8ImkZIngcYhGuj0PGpLqBD/ZDvQyE+5I=,tag:oYBUEQS52pr09h5OvOadNg==,type:str]
|
||||||
|
|||||||
@@ -4,20 +4,20 @@ sops:
|
|||||||
- recipient: age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
- recipient: age1df9ukkmg9yn9cjeheq9m6wspa420su8qarmq570rdvf2de3rl38saqauwn
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkdHVtQ3hHSjVuRkxRMklO
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtSjhXazlWd3YwNVFKVkw4
|
||||||
NEJjeERFUDBMRkVTTGVGTTJIR1lwM25kZWpRCitlUFIvUTVPUloreEFIWjIvT1dL
|
dDMydVFCN1lLeUJOWkxuSGJ1a0srNm9PaWswCm8yZ3hiOWFHUlAzNVRrck53OElD
|
||||||
S2hBY2NUWHdxOVhRejU0eUpZa1FMY00KLS0tIEZ3bDRIdlQzaVQ5U0kyRjYyeUor
|
b056YmV4S2NtNnEzRkpnRVNEblV5blkKLS0tIG1ramoya3RHV1FJZGlFU2ZSeUtS
|
||||||
c1M2V2J1Q2R3alI3b3NoYk5SK1AzKzgKbOhSxwTpLr7wwbN+nY4aK+6WmpofBxNX
|
KzJlbEsvYWlXaHhEQU5oOS9HaDdYSDAKvlhKgi4Pf8xVB5MnO33GWYg313mRdUGu
|
||||||
CEaEBz98KTTrSQ9Qvm1+/yep95l7i0HPQGdGwCRNKdvUoXzk1KalpQ==
|
kFCs5b1N96x9JOS7zgnM0AKDY8IPBSe33tmDqtYygwPdkOys1PmZkw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age10zxwwufrf5uu9cv9p9znse2ftfm74q9ce893us6cnvxjc7e3ypcqy709dy
|
- recipient: age14aml5s3sxksa8qthnt6apl3pu6egxyn0cz7pdzzvp2yl6wncad0q56udyj
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZb2oyd1ZGR2FXVFlhT2d3
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYTVovQld2RkRxaW90b3lR
|
||||||
NFVlU3VlR1BEWFRyTDBYZFFlQjZxUXVyK240CkdLRmk5M01ZTloyREtwQ3hpRkxZ
|
NGFtbWVLZUNHdnlZVWkrL1RXUHBVeGdvSDJrClJmSmZRZmdjcy8rNnJBVmVUWDZq
|
||||||
RDRKYVlRVFVLYzVSenU3THhFc0ZrdjgKLS0tIG1iMWh1TTZIZDEwazVKY1g3NXg0
|
M2lPbDBhT0Y0NkJ5a1FNYnU3Zkl0TkEKLS0tIGxqM2h2TDB2akl4ODlYY042R1Z4
|
||||||
NFRKemkwcnBxR0NIbXBGcm8xejdUMjgKOAGxkrvtvf7Y9W5BteL12HuUWA/d5Bah
|
ZVJWN3pZelFJR0Jid3JseEZKVFZtYmsKmKXQRjnghuF/s9z2Xk98sFvxic91fGa2
|
||||||
wVoeBK21Zxz/GodBpVCuDnJ5DwM3c+7O3jnvtTShIW00evDhJIvcvA==
|
V7IGmpqAYQV3jJ1G4cjJxtpidQ6fLCqlnR+sq+y8+dT+LN7i+Zbnnw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-10-19T17:33:13Z"
|
lastmodified: "2025-10-19T17:33:13Z"
|
||||||
mac: ENC[AES256_GCM,data:IwEyBr/I7BJa0gWZ494dCT0ogyP2PbnUg5fLOn15vZAHIyYtTB3dI3gV5Lx7oPdqOPlI61MsShIYBnk0uBChpNu6O4oiGUfwvBfegzlDyHHERLx+S7nZpcwmf/3JoNXwq0f2OtOu8nA6Q1V4gVjFFNWUCAh5cq106vG1awsQkn0=,iv:j+JcVtKz2RfyWu55dUeJJTRK6prB9DGLvcjiAAdVySM=,tag:Pg5sKiLzYUFoN9Duu+nF0w==,type:str]
|
mac: ENC[AES256_GCM,data:IwEyBr/I7BJa0gWZ494dCT0ogyP2PbnUg5fLOn15vZAHIyYtTB3dI3gV5Lx7oPdqOPlI61MsShIYBnk0uBChpNu6O4oiGUfwvBfegzlDyHHERLx+S7nZpcwmf/3JoNXwq0f2OtOu8nA6Q1V4gVjFFNWUCAh5cq106vG1awsQkn0=,iv:j+JcVtKz2RfyWu55dUeJJTRK6prB9DGLvcjiAAdVySM=,tag:Pg5sKiLzYUFoN9Duu+nF0w==,type:str]
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ job "adminer" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.adminer.entryPoints=websecure",
|
"traefik.http.routers.adminer.entryPoints=websecure",
|
||||||
"traefik.http.routers.adminer.middlewares=authentik@file",
|
"traefik.http.routers.adminer.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
job "authentik" {
|
|
||||||
datacenters = ["alo"]
|
|
||||||
|
|
||||||
group "auth" {
|
|
||||||
network {
|
|
||||||
port "http" {
|
|
||||||
# traefik forwardAuth hardcodes this port
|
|
||||||
static = 9000
|
|
||||||
}
|
|
||||||
port "https" {
|
|
||||||
to = 9443
|
|
||||||
}
|
|
||||||
port "metrics" {
|
|
||||||
to = 9300
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task "server" {
|
|
||||||
driver = "docker"
|
|
||||||
|
|
||||||
config {
|
|
||||||
image = "ghcr.io/goauthentik/server:${var.authentik_version}"
|
|
||||||
ports = [
|
|
||||||
"http",
|
|
||||||
"https",
|
|
||||||
"metrics"
|
|
||||||
]
|
|
||||||
command = "server"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
AUTHENTIK_REDIS__HOST = "redis.service.consul"
|
|
||||||
AUTHENTIK_POSTGRESQL__HOST = "postgres.service.consul"
|
|
||||||
AUTHENTIK_POSTGRESQL__NAME = "${var.pg_db}"
|
|
||||||
AUTHENTIK_POSTGRESQL__USER = "${var.pg_user}"
|
|
||||||
AUTHENTIK_POSTGRESQL__PASSWORD = "${var.pg_password}"
|
|
||||||
AUTHENTIK_SECRET_KEY = "${var.secret_key}"
|
|
||||||
AUTHENTIK_EMAIL__HOST = "192.168.1.1"
|
|
||||||
AUTHENTIK_EMAIL__FROM = "authentik@paler.net"
|
|
||||||
}
|
|
||||||
|
|
||||||
resources {
|
|
||||||
cpu = 2000
|
|
||||||
memory = 1024
|
|
||||||
}
|
|
||||||
|
|
||||||
service {
|
|
||||||
name = "authentik"
|
|
||||||
port = "http"
|
|
||||||
tags = [
|
|
||||||
"traefik.enable=true",
|
|
||||||
# Main UI
|
|
||||||
"traefik.http.routers.authentik.entryPoints=websecure",
|
|
||||||
"traefik.http.routers.authentik.rule=Host(`authentik.v.paler.net`) || Host(`authentik.alo.land`)",
|
|
||||||
# Embedded outpost for forward auth
|
|
||||||
"traefik.http.routers.authentik-palernet.entryPoints=websecure",
|
|
||||||
"traefik.http.routers.authentik-palernet.rule=HostRegexp(`{subdomain:[a-z0-9-]+}.v.paler.net`) && PathPrefix(`/outpost.goauthentik.io/`)",
|
|
||||||
"traefik.http.routers.authentik-aloland.entryPoints=websecure",
|
|
||||||
"traefik.http.routers.authentik-aloland.rule=HostRegexp(`{subdomain:[a-z0-9-]+}.alo.land`) && PathPrefix(`/outpost.goauthentik.io/`)",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
service {
|
|
||||||
name = "authentik-metrics"
|
|
||||||
port = "metrics"
|
|
||||||
tags = [ "metrics" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task "worker" {
|
|
||||||
driver = "docker"
|
|
||||||
|
|
||||||
config {
|
|
||||||
image = "ghcr.io/goauthentik/server:${var.authentik_version}"
|
|
||||||
command = "worker"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
AUTHENTIK_REDIS__HOST = "redis.service.consul"
|
|
||||||
AUTHENTIK_POSTGRESQL__HOST = "postgres.service.consul"
|
|
||||||
AUTHENTIK_POSTGRESQL__NAME = "${var.pg_db}"
|
|
||||||
AUTHENTIK_POSTGRESQL__USER = "${var.pg_user}"
|
|
||||||
AUTHENTIK_POSTGRESQL__PASSWORD = "${var.pg_password}"
|
|
||||||
AUTHENTIK_SECRET_KEY = "${var.secret_key}"
|
|
||||||
AUTHENTIK_EMAIL__HOST = "192.168.1.1"
|
|
||||||
AUTHENTIK_EMAIL__FROM = "authentik@paler.net"
|
|
||||||
}
|
|
||||||
|
|
||||||
resources {
|
|
||||||
memory = 600
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "pg_user" {
|
|
||||||
type = string
|
|
||||||
default = "authentik"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "pg_password" {
|
|
||||||
type = string
|
|
||||||
default = "aQueiquuo6aiyah5eoch"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "pg_db" {
|
|
||||||
type = string
|
|
||||||
default = "authentik"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "secret_key" {
|
|
||||||
type = string
|
|
||||||
default = "uUzCYhGV93Z8wKLAScuGFqBskxyzSfG4cz6bnXq6McM67Ho7p9"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "authentik_version" {
|
|
||||||
type = string
|
|
||||||
default = "2025.6"
|
|
||||||
}
|
|
||||||
@@ -37,7 +37,7 @@ job "beancount" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.finances.entryPoints=websecure",
|
"traefik.http.routers.finances.entryPoints=websecure",
|
||||||
"traefik.http.routers.finances.middlewares=authentik@file",
|
"traefik.http.routers.finances.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ job "evcc" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.evcc.entryPoints=websecure",
|
"traefik.http.routers.evcc.entryPoints=websecure",
|
||||||
"traefik.http.routers.evcc.middlewares=authentik@file",
|
"traefik.http.routers.evcc.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ job "gitea" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.gitea.entryPoints=websecure",
|
"traefik.http.routers.gitea.entryPoints=websecure",
|
||||||
|
"traefik.http.services.gitea.loadBalancer.serversTransport=gitea-transport@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,19 +25,22 @@ job "grafana" {
|
|||||||
GF_SERVER_ROOT_URL = "https://grafana.v.paler.net"
|
GF_SERVER_ROOT_URL = "https://grafana.v.paler.net"
|
||||||
GF_AUTH_BASIC_ENABLED = "false"
|
GF_AUTH_BASIC_ENABLED = "false"
|
||||||
GF_AUTH_GENERIC_OAUTH_ENABLED = "true"
|
GF_AUTH_GENERIC_OAUTH_ENABLED = "true"
|
||||||
GF_AUTH_GENERIC_OAUTH_NAME = "authentik"
|
GF_AUTH_GENERIC_OAUTH_NAME = "Pocket ID"
|
||||||
GF_AUTH_GENERIC_OAUTH_CLIENT_ID = "E78NG1AZeW6FaAox0mUhaTSrHeqFgNkWG12My2zx"
|
GF_AUTH_GENERIC_OAUTH_CLIENT_ID = "99e44cf2-ecc6-4e82-8882-129c017f8a4a"
|
||||||
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET = "N7u2RfFZ5KVLdEkhlpUTzymGxeK5rLo9SYZLSGGBXJDr46p5g5uv1qZ4Jm2d1rP4aJX4PSzauZlxHhkG2byiBFMbdo6K742KXcEimZsOBFiNKeWOHxofYerBnPuoECQW"
|
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET = "NjJ9Uro4MK7siqLGSmkiQmjFuESulqQN"
|
||||||
GF_AUTH_GENERIC_OAUTH_SCOPES = "openid profile email offline_access"
|
GF_AUTH_GENERIC_OAUTH_SCOPES = "openid profile email groups"
|
||||||
GF_AUTH_GENERIC_OAUTH_AUTH_URL = "https://authentik.v.paler.net/application/o/authorize/"
|
GF_AUTH_GENERIC_OAUTH_AUTH_URL = "https://pocket-id.v.paler.net/authorize"
|
||||||
GF_AUTH_GENERIC_OAUTH_TOKEN_URL = "https://authentik.v.paler.net/application/o/token/"
|
GF_AUTH_GENERIC_OAUTH_TOKEN_URL = "https://pocket-id.v.paler.net/api/oidc/token"
|
||||||
GF_AUTH_GENERIC_OAUTH_API_URL = "https://authentik.v.paler.net/application/o/userinfo/"
|
GF_AUTH_GENERIC_OAUTH_API_URL = "https://pocket-id.v.paler.net/api/oidc/userinfo"
|
||||||
GF_AUTH_SIGNOUT_REDIRECT_URL = "https://authentik.v.paler.net/application/o/grafana/end-session/"
|
GF_AUTH_SIGNOUT_REDIRECT_URL = "https://pocket-id.v.paler.net/logout"
|
||||||
# Optionally enable auto-login (bypasses Grafana login screen)
|
# Optionally enable auto-login (bypasses Grafana login screen)
|
||||||
GF_AUTH_OAUTH_AUTO_LOGIN = "true"
|
GF_AUTH_OAUTH_AUTO_LOGIN = "true"
|
||||||
# Optionally map user groups to Grafana roles
|
# Optionally map user groups to Grafana roles
|
||||||
GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH = "contains(groups[*], 'Grafana Admins') && 'Admin' || contains(groups[*], 'Grafana Editors') && 'Editor' || 'Viewer'"
|
GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH = "contains(groups[*], 'admins') && 'Admin' || contains(groups[*], 'residents') && 'Editor' || 'Viewer'"
|
||||||
GF_AUTH_GENERIC_OAUTH_USE_REFRESH_TOKEN = "true"
|
GF_AUTH_GENERIC_OAUTH_USE_REFRESH_TOKEN = "true"
|
||||||
|
GF_AUTH_GENERIC_OAUTH_EMAIL_ATTRIBUTE_PATH = "email"
|
||||||
|
GF_AUTH_GENERIC_OAUTH_LOGIN_ATTRIBUTE_PATH = "preferred_username"
|
||||||
|
GF_AUTH_GENERIC_OAUTH_NAME_ATTRIBUTE_PATH = "name"
|
||||||
#GF_LOG_LEVEL = "debug"
|
#GF_LOG_LEVEL = "debug"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
50
services/homepage.hcl
Normal file
50
services/homepage.hcl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
job "homepage" {
|
||||||
|
datacenters = ["alo"]
|
||||||
|
|
||||||
|
group "app" {
|
||||||
|
network {
|
||||||
|
port "http" { to = 3000 }
|
||||||
|
}
|
||||||
|
|
||||||
|
task "homepage" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "ghcr.io/gethomepage/homepage:latest"
|
||||||
|
ports = [ "http" ]
|
||||||
|
volumes = [
|
||||||
|
"/data/services/homepage:/app/config",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
PUID = 1000
|
||||||
|
PGID = 1000
|
||||||
|
HOMEPAGE_ALLOWED_HOSTS = "homepage.v.paler.net"
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 200
|
||||||
|
memory = 256
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "homepage"
|
||||||
|
port = "http"
|
||||||
|
|
||||||
|
tags = [
|
||||||
|
"traefik.enable=true",
|
||||||
|
"traefik.http.routers.homepage.entryPoints=websecure",
|
||||||
|
"traefik.http.routers.homepage.middlewares=oidc-auth@file",
|
||||||
|
]
|
||||||
|
|
||||||
|
check {
|
||||||
|
type = "http"
|
||||||
|
path = "/"
|
||||||
|
interval = "10s"
|
||||||
|
timeout = "5s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ job "jupyter" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.jupyter.entryPoints=websecure",
|
"traefik.http.routers.jupyter.entryPoints=websecure",
|
||||||
"traefik.http.routers.jupyter.middlewares=authentik@file",
|
"traefik.http.routers.jupyter.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ EOH
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.loki.entryPoints=websecure",
|
"traefik.http.routers.loki.entryPoints=websecure",
|
||||||
"traefik.http.routers.loki.middlewares=authentik@file",
|
"traefik.http.routers.loki.middlewares=oidc-auth@file",
|
||||||
"metrics",
|
"metrics",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ job "maps" {
|
|||||||
to = 80
|
to = 80
|
||||||
}
|
}
|
||||||
port "php" {
|
port "php" {
|
||||||
static = 9001
|
static = 9000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,12 @@ job "media" {
|
|||||||
|
|
||||||
group "servers" {
|
group "servers" {
|
||||||
network {
|
network {
|
||||||
port "radarr" { to = 7878 }
|
port "radarr" { static = 7878 }
|
||||||
port "sonarr" { to = 8989 }
|
port "sonarr" { static = 8989 }
|
||||||
port "bazarr" { to = 6767 }
|
port "bazarr" { to = 6767 }
|
||||||
|
port "prowlarr" { static = 9696 }
|
||||||
|
port "jellyseerr" { static = 5055 }
|
||||||
|
port "flaresolverr" { static = 8191 }
|
||||||
port "pms" { static = 32400 }
|
port "pms" { static = 32400 }
|
||||||
port "qbt_ui" { static = 8080 }
|
port "qbt_ui" { static = 8080 }
|
||||||
port "qbt_torrent" { static = 51413 }
|
port "qbt_torrent" { static = 51413 }
|
||||||
@@ -34,7 +37,7 @@ job "media" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resources {
|
resources {
|
||||||
cpu = 200
|
cpu = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
service {
|
service {
|
||||||
@@ -44,7 +47,7 @@ job "media" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.radarr.entryPoints=websecure",
|
"traefik.http.routers.radarr.entryPoints=websecure",
|
||||||
"traefik.http.routers.radarr.middlewares=authentik@file",
|
"traefik.http.routers.radarr.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,7 +71,8 @@ job "media" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resources {
|
resources {
|
||||||
cpu = 200
|
cpu = 1000
|
||||||
|
memory = 500
|
||||||
}
|
}
|
||||||
|
|
||||||
service {
|
service {
|
||||||
@@ -78,20 +82,54 @@ job "media" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.sonarr.entryPoints=websecure",
|
"traefik.http.routers.sonarr.entryPoints=websecure",
|
||||||
"traefik.http.routers.sonarr.middlewares=authentik@file",
|
"traefik.http.routers.sonarr.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task "bazarr" {
|
# task "bazarr" {
|
||||||
|
# driver = "docker"
|
||||||
|
#
|
||||||
|
# config {
|
||||||
|
# image = "ghcr.io/hotio/bazarr:latest"
|
||||||
|
# ports = [ "bazarr" ]
|
||||||
|
# volumes = [
|
||||||
|
# "/data/services/media/bazarr:/config",
|
||||||
|
# "/data/media/media:/data/media",
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# env {
|
||||||
|
# PUID = 1000
|
||||||
|
# PGID = 1000
|
||||||
|
# TZ = "Europe/Lisbon"
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# resources {
|
||||||
|
# cpu = 200
|
||||||
|
# memory = 500
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# service {
|
||||||
|
# name = "bazarr"
|
||||||
|
# port = "bazarr"
|
||||||
|
#
|
||||||
|
# tags = [
|
||||||
|
# "traefik.enable=true",
|
||||||
|
# "traefik.http.routers.bazarr.entryPoints=websecure",
|
||||||
|
# "traefik.http.routers.bazarr.middlewares=oidc-auth@file",
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
task "prowlarr" {
|
||||||
driver = "docker"
|
driver = "docker"
|
||||||
|
|
||||||
config {
|
config {
|
||||||
image = "ghcr.io/hotio/bazarr:latest"
|
image = "ghcr.io/hotio/prowlarr:latest"
|
||||||
ports = [ "bazarr" ]
|
ports = [ "prowlarr" ]
|
||||||
volumes = [
|
volumes = [
|
||||||
"/data/services/media/bazarr:/config",
|
"/data/services/media/prowlarr:/config",
|
||||||
"/data/media/media:/data/media",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,17 +144,93 @@ job "media" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
service {
|
service {
|
||||||
name = "bazarr"
|
name = "prowlarr"
|
||||||
port = "bazarr"
|
port = "prowlarr"
|
||||||
|
|
||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.bazarr.entryPoints=websecure",
|
"traefik.http.routers.prowlarr.entryPoints=websecure",
|
||||||
"traefik.http.routers.bazarr.middlewares=authentik@file",
|
"traefik.http.routers.prowlarr.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task "jellyseerr" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "fallenbagel/jellyseerr:latest"
|
||||||
|
ports = [ "jellyseerr" ]
|
||||||
|
volumes = [
|
||||||
|
"/data/services/media/jellyseerr:/app/config",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
TZ = "Europe/Lisbon"
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 200
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "jellyseerr"
|
||||||
|
port = "jellyseerr"
|
||||||
|
|
||||||
|
tags = [
|
||||||
|
"traefik.enable=true",
|
||||||
|
"traefik.http.routers.jellyseerr.entryPoints=websecure",
|
||||||
|
"traefik.http.routers.jellyseerr.middlewares=oidc-auth@file",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "flaresolverr" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "ghcr.io/flaresolverr/flaresolverr:latest"
|
||||||
|
ports = [ "flaresolverr" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
LOG_LEVEL = "info"
|
||||||
|
TZ = "Europe/Lisbon"
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 500
|
||||||
|
memory = 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "flaresolverr"
|
||||||
|
port = "flaresolverr"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "recyclarr" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "ghcr.io/recyclarr/recyclarr:latest"
|
||||||
|
volumes = [
|
||||||
|
"/data/services/media/recyclarr:/config",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
TZ = "Europe/Lisbon"
|
||||||
|
CRON_SCHEDULE = "0 0 * * *" # Daily at midnight
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 100
|
||||||
|
memory = 256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
task "plex" {
|
task "plex" {
|
||||||
driver = "docker"
|
driver = "docker"
|
||||||
|
|
||||||
@@ -138,7 +252,7 @@ job "media" {
|
|||||||
|
|
||||||
resources {
|
resources {
|
||||||
cpu = 2000
|
cpu = 2000
|
||||||
memory = 1000
|
memory = 2000
|
||||||
}
|
}
|
||||||
|
|
||||||
service {
|
service {
|
||||||
@@ -148,7 +262,7 @@ job "media" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.plex.entryPoints=websecure",
|
"traefik.http.routers.plex.entryPoints=websecure",
|
||||||
"traefik.http.routers.plex.middlewares=authentik@file",
|
"traefik.http.routers.plex.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,7 +291,7 @@ job "media" {
|
|||||||
|
|
||||||
resources {
|
resources {
|
||||||
cpu = 2000
|
cpu = 2000
|
||||||
memory = 1000
|
memory = 1500
|
||||||
}
|
}
|
||||||
|
|
||||||
service {
|
service {
|
||||||
@@ -187,7 +301,7 @@ job "media" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.torrent.entryPoints=websecure",
|
"traefik.http.routers.torrent.entryPoints=websecure",
|
||||||
"traefik.http.routers.torrent.middlewares=authentik@file",
|
"traefik.http.routers.torrent.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ job "netbox" {
|
|||||||
REMOTE_AUTH_ENABLED = "true"
|
REMOTE_AUTH_ENABLED = "true"
|
||||||
REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth"
|
REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth"
|
||||||
|
|
||||||
SOCIAL_AUTH_OIDC_ENDPOINT = "https://authentik.v.paler.net/application/o/netbox/"
|
SOCIAL_AUTH_OIDC_ENDPOINT = "https://pocket-id.v.paler.net/"
|
||||||
SOCIAL_AUTH_OIDC_KEY = "XiPhZmWy2mp8hQyHLXCwk7njRNPSLTp2vSHhvWYI"
|
SOCIAL_AUTH_OIDC_KEY = "6ce1f1bb-d5e8-4ba5-b136-2643dc8bcbcf"
|
||||||
SOCIAL_AUTH_OIDC_SECRET = "Kkop2dStx0gN52V1LfPnoxcaemuur6zMsvRnqpWSDe2qSngJVcqWfvFXaNeTbdURRB6TPwjlaNJ5BXR2ChcSmokWGTGargu84Ox1D6M2zXTsfLFj9B149Mhblos4mJL1"
|
SOCIAL_AUTH_OIDC_SECRET = "Af7sJvCn9BuijoJXrB5aWv6fTmEqLCAf"
|
||||||
LOGOUT_REDIRECT_URL = "https://authentik.v.paler.net/application/o/netbox/end-session/"
|
LOGOUT_REDIRECT_URL = "https://pocket-id.v.paler.net/logout"
|
||||||
}
|
}
|
||||||
|
|
||||||
resources {
|
resources {
|
||||||
|
|||||||
39
services/ollama.hcl
Normal file
39
services/ollama.hcl
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
job "ollama" {
|
||||||
|
datacenters = ["alo"]
|
||||||
|
type = "service"
|
||||||
|
|
||||||
|
group "ollama" {
|
||||||
|
network {
|
||||||
|
port "http" {
|
||||||
|
static = 11434
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "server" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "ollama/ollama:latest"
|
||||||
|
ports = ["http"]
|
||||||
|
volumes = ["/data/services/ollama:/root/.ollama"]
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "ollama"
|
||||||
|
port = "http"
|
||||||
|
|
||||||
|
check {
|
||||||
|
type = "http"
|
||||||
|
path = "/"
|
||||||
|
interval = "30s"
|
||||||
|
timeout = "5s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 8000
|
||||||
|
memory = 2048
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
services/pocket-id.hcl
Normal file
51
services/pocket-id.hcl
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
job "pocket-id" {
|
||||||
|
datacenters = ["alo"]
|
||||||
|
|
||||||
|
group "app" {
|
||||||
|
network {
|
||||||
|
port "http" {
|
||||||
|
to = 1411
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task "server" {
|
||||||
|
driver = "docker"
|
||||||
|
|
||||||
|
config {
|
||||||
|
image = "ghcr.io/pocket-id/pocket-id:v1"
|
||||||
|
ports = ["http"]
|
||||||
|
volumes = [
|
||||||
|
"/data/services/pocket-id:/app/data",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
APP_URL = "https://pocket-id.v.paler.net"
|
||||||
|
TRUST_PROXY = "true"
|
||||||
|
MAXMIND_LICENSE_KEY = "${var.maxmind_license_key}"
|
||||||
|
PUID = "1000"
|
||||||
|
PGID = "1000"
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
cpu = 500
|
||||||
|
memory = 512
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "pocket-id"
|
||||||
|
port = "http"
|
||||||
|
|
||||||
|
tags = [
|
||||||
|
"traefik.enable=true",
|
||||||
|
"traefik.http.routers.pocket-id.entryPoints=websecure",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "maxmind_license_key" {
|
||||||
|
type = string
|
||||||
|
default = "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"
|
||||||
|
}
|
||||||
@@ -91,15 +91,15 @@ job "postgres" {
|
|||||||
PGADMIN_CONFIG_OAUTH2_AUTO_CREATE_USER = "True"
|
PGADMIN_CONFIG_OAUTH2_AUTO_CREATE_USER = "True"
|
||||||
PGADMIN_CONFIG_OAUTH2_CONFIG = <<EOH
|
PGADMIN_CONFIG_OAUTH2_CONFIG = <<EOH
|
||||||
[{
|
[{
|
||||||
'OAUTH2_NAME' : 'authentik',
|
'OAUTH2_NAME' : 'pocket-id',
|
||||||
'OAUTH2_DISPLAY_NAME' : 'SSO',
|
'OAUTH2_DISPLAY_NAME' : 'SSO',
|
||||||
'OAUTH2_CLIENT_ID' : 'o4p3B03ayTQ2kpwmM7GswbcfO78JHCTdoZqKJEut',
|
'OAUTH2_CLIENT_ID' : '180133da-1bd7-4cde-9c18-2f277e962dab',
|
||||||
'OAUTH2_CLIENT_SECRET' : '7UYHONOCVdjpRMK9Ojwds0qPPpxCiztbIRhK7FJ2IFBpUgN6tnmpEjlkPYimiGKfaHLhy4XE7kQm7Et1Jm0hgyia0iB1VIlp623ckppbwkM6IfpTE1LfEmTMtPrxSngx',
|
'OAUTH2_CLIENT_SECRET' : 'ELYNAfiWSGYJQUXUDOdpm7tTtyLbrs4E',
|
||||||
'OAUTH2_TOKEN_URL' : 'https://authentik.v.paler.net/application/o/token/',
|
'OAUTH2_TOKEN_URL' : 'https://pocket-id.v.paler.net/api/oidc/token',
|
||||||
'OAUTH2_AUTHORIZATION_URL' : 'https://authentik.v.paler.net/application/o/authorize/',
|
'OAUTH2_AUTHORIZATION_URL' : 'https://pocket-id.v.paler.net/authorize',
|
||||||
'OAUTH2_API_BASE_URL' : 'https://authentik.v.paler.net/',
|
'OAUTH2_API_BASE_URL' : 'https://pocket-id.v.paler.net/',
|
||||||
'OAUTH2_USERINFO_ENDPOINT' : 'https://authentik.v.paler.net/application/o/userinfo/',
|
'OAUTH2_USERINFO_ENDPOINT' : 'https://pocket-id.v.paler.net/api/oidc/userinfo',
|
||||||
'OAUTH2_SERVER_METADATA_URL' : 'https://authentik.v.paler.net/application/o/pgadmin/.well-known/openid-configuration',
|
'OAUTH2_SERVER_METADATA_URL' : 'https://pocket-id.v.paler.net/.well-known/openid-configuration',
|
||||||
'OAUTH2_SCOPE' : 'openid email profile',
|
'OAUTH2_SCOPE' : 'openid email profile',
|
||||||
'OAUTH2_ICON' : 'fa-database',
|
'OAUTH2_ICON' : 'fa-database',
|
||||||
'OAUTH2_BUTTON_COLOR' : '#00ff00'
|
'OAUTH2_BUTTON_COLOR' : '#00ff00'
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ job "prometheus" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.prometheus.entryPoints=websecure",
|
"traefik.http.routers.prometheus.entryPoints=websecure",
|
||||||
"traefik.http.routers.prometheus.middlewares=authentik@file",
|
"traefik.http.routers.prometheus.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
|
|
||||||
check {
|
check {
|
||||||
|
|||||||
82
services/tiddlywiki-mcp.hcl
Normal file
82
services/tiddlywiki-mcp.hcl
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
job "tiddlywiki-mcp" {
|
||||||
|
datacenters = ["alo"]
|
||||||
|
|
||||||
|
group "captainslog" {
|
||||||
|
network {
|
||||||
|
port "http" {
|
||||||
|
static = 3500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
volume "services" {
|
||||||
|
type = "host"
|
||||||
|
source = "services"
|
||||||
|
read_only = false
|
||||||
|
}
|
||||||
|
|
||||||
|
volume "nix-store" {
|
||||||
|
type = "host"
|
||||||
|
source = "nix-store"
|
||||||
|
read_only = true
|
||||||
|
}
|
||||||
|
|
||||||
|
volume "sw" {
|
||||||
|
type = "host"
|
||||||
|
source = "sw"
|
||||||
|
read_only = true
|
||||||
|
}
|
||||||
|
|
||||||
|
task "mcp-server" {
|
||||||
|
driver = "exec"
|
||||||
|
|
||||||
|
config {
|
||||||
|
command = "/sw/bin/node"
|
||||||
|
args = ["/data/services/tiddlywiki-mcp/dist/index.js"]
|
||||||
|
}
|
||||||
|
|
||||||
|
env {
|
||||||
|
MCP_TRANSPORT = "http"
|
||||||
|
MCP_PORT = "${NOMAD_PORT_http}"
|
||||||
|
CONSUL_SERVICE = "captainslog.service.consul"
|
||||||
|
AUTH_HEADER = "X-Oidc-Username"
|
||||||
|
AUTH_USER = "claude-code"
|
||||||
|
}
|
||||||
|
|
||||||
|
volume_mount {
|
||||||
|
volume = "services"
|
||||||
|
destination = "/data/services"
|
||||||
|
read_only = false
|
||||||
|
}
|
||||||
|
|
||||||
|
volume_mount {
|
||||||
|
volume = "nix-store"
|
||||||
|
destination = "/nix/store"
|
||||||
|
read_only = true
|
||||||
|
}
|
||||||
|
|
||||||
|
volume_mount {
|
||||||
|
volume = "sw"
|
||||||
|
destination = "/sw"
|
||||||
|
read_only = true
|
||||||
|
}
|
||||||
|
|
||||||
|
service {
|
||||||
|
name = "tiddlywiki-mcp-captainslog"
|
||||||
|
port = "http"
|
||||||
|
|
||||||
|
check {
|
||||||
|
type = "http"
|
||||||
|
path = "/health"
|
||||||
|
interval = "10s"
|
||||||
|
timeout = "2s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resources {
|
||||||
|
memory = 256
|
||||||
|
}
|
||||||
|
|
||||||
|
user = "ppetru"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ job "traefik" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.api.entryPoints=websecure",
|
"traefik.http.routers.api.entryPoints=websecure",
|
||||||
"traefik.http.routers.api.middlewares=authentik@file",
|
"traefik.http.routers.api.middlewares=oidc-auth@file",
|
||||||
"traefik.http.routers.api.rule=Host(`traefik.v.paler.net`)",
|
"traefik.http.routers.api.rule=Host(`traefik.v.paler.net`)",
|
||||||
"traefik.http.routers.api.service=api@internal",
|
"traefik.http.routers.api.service=api@internal",
|
||||||
]
|
]
|
||||||
@@ -63,6 +63,7 @@ job "traefik" {
|
|||||||
volumes = [
|
volumes = [
|
||||||
"local/traefik.yml:/etc/traefik/traefik.yml",
|
"local/traefik.yml:/etc/traefik/traefik.yml",
|
||||||
"/data/services/traefik:/config",
|
"/data/services/traefik:/config",
|
||||||
|
"/data/services/traefik/plugins-storage:/plugins-storage",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +76,12 @@ global:
|
|||||||
#log:
|
#log:
|
||||||
# level: debug
|
# level: debug
|
||||||
|
|
||||||
|
experimental:
|
||||||
|
plugins:
|
||||||
|
traefik-oidc-auth:
|
||||||
|
moduleName: "github.com/sevensolutions/traefik-oidc-auth"
|
||||||
|
version: "v0.16.0"
|
||||||
|
|
||||||
api:
|
api:
|
||||||
dashboard: true
|
dashboard: true
|
||||||
|
|
||||||
@@ -145,7 +152,7 @@ EOH
|
|||||||
}
|
}
|
||||||
|
|
||||||
resources {
|
resources {
|
||||||
cpu = 100
|
cpu = 200
|
||||||
memory = 512
|
memory = 512
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ job "unifi" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.unifi.entryPoints=websecure",
|
"traefik.http.routers.unifi.entryPoints=websecure",
|
||||||
"traefik.http.routers.unifi.middlewares=authentik@file",
|
"traefik.http.routers.unifi.middlewares=oidc-auth@file",
|
||||||
"traefik.http.services.unifi.loadbalancer.server.scheme=https",
|
"traefik.http.services.unifi.loadbalancer.server.scheme=https",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ job "urbit" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.urbit.entryPoints=websecure",
|
"traefik.http.routers.urbit.entryPoints=websecure",
|
||||||
"traefik.http.routers.urbit.middlewares=authentik@file",
|
"traefik.http.routers.urbit.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ EOH
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.webodm.entryPoints=websecure",
|
"traefik.http.routers.webodm.entryPoints=websecure",
|
||||||
"traefik.http.routers.webodm.middlewares=authentik@file",
|
"traefik.http.routers.webodm.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ EOH
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.clusterodm.entryPoints=websecure",
|
"traefik.http.routers.clusterodm.entryPoints=websecure",
|
||||||
"traefik.http.routers.clusterodm.middlewares=authentik@file",
|
"traefik.http.routers.clusterodm.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ job "whoami" {
|
|||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.whoami.rule=Host(`test.alo.land`)",
|
"traefik.http.routers.whoami.rule=Host(`test.alo.land`)",
|
||||||
"traefik.http.routers.whoami.entryPoints=websecure",
|
"traefik.http.routers.whoami.entryPoints=websecure",
|
||||||
"traefik.http.routers.whoami.middlewares=authentik@file",
|
"traefik.http.routers.whoami.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ job "wiki" {
|
|||||||
"--listen",
|
"--listen",
|
||||||
"host=0.0.0.0",
|
"host=0.0.0.0",
|
||||||
"port=${NOMAD_PORT_captainslog}",
|
"port=${NOMAD_PORT_captainslog}",
|
||||||
"authenticated-user-header=X-authentik-username",
|
"authenticated-user-header=X-Oidc-Username",
|
||||||
"readers=ppetru",
|
"readers=ppetru,claude-code",
|
||||||
"writers=ppetru",
|
"writers=ppetru,claude-code",
|
||||||
"admin=ppetru",
|
"admin=ppetru",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ job "wiki" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.captainslog.entryPoints=websecure",
|
"traefik.http.routers.captainslog.entryPoints=websecure",
|
||||||
"traefik.http.routers.captainslog.middlewares=authentik@file",
|
"traefik.http.routers.captainslog.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ job "wiki" {
|
|||||||
"--listen",
|
"--listen",
|
||||||
"host=0.0.0.0",
|
"host=0.0.0.0",
|
||||||
"port=${NOMAD_PORT_alo}",
|
"port=${NOMAD_PORT_alo}",
|
||||||
"authenticated-user-header=X-authentik-username",
|
"authenticated-user-header=X-Oidc-Username",
|
||||||
"readers=ppetru,ines",
|
"readers=ppetru,ines",
|
||||||
"writers=ppetru,ines",
|
"writers=ppetru,ines",
|
||||||
"admin=ppetru",
|
"admin=ppetru",
|
||||||
@@ -112,7 +112,7 @@ job "wiki" {
|
|||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.alowiki.rule=Host(`wiki.alo.land`)",
|
"traefik.http.routers.alowiki.rule=Host(`wiki.alo.land`)",
|
||||||
"traefik.http.routers.alowiki.entryPoints=websecure",
|
"traefik.http.routers.alowiki.entryPoints=websecure",
|
||||||
"traefik.http.routers.alowiki.middlewares=authentik@file",
|
"traefik.http.routers.alowiki.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ job "wiki" {
|
|||||||
"--listen",
|
"--listen",
|
||||||
"host=0.0.0.0",
|
"host=0.0.0.0",
|
||||||
"port=${NOMAD_PORT_pispace}",
|
"port=${NOMAD_PORT_pispace}",
|
||||||
"authenticated-user-header=X-authentik-username",
|
"authenticated-user-header=X-Oidc-Username",
|
||||||
"readers=ppetru,ines",
|
"readers=ppetru,ines",
|
||||||
"writers=ppetru,ines",
|
"writers=ppetru,ines",
|
||||||
"admin=ppetru",
|
"admin=ppetru",
|
||||||
@@ -160,7 +160,7 @@ job "wiki" {
|
|||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.pispace.rule=Host(`pi.paler.net`)",
|
"traefik.http.routers.pispace.rule=Host(`pi.paler.net`)",
|
||||||
"traefik.http.routers.pispace.entryPoints=websecure",
|
"traefik.http.routers.pispace.entryPoints=websecure",
|
||||||
"traefik.http.routers.pispace.middlewares=authentik@file",
|
"traefik.http.routers.pispace.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ job "wiki" {
|
|||||||
"--listen",
|
"--listen",
|
||||||
"host=0.0.0.0",
|
"host=0.0.0.0",
|
||||||
"port=${NOMAD_PORT_grok}",
|
"port=${NOMAD_PORT_grok}",
|
||||||
"authenticated-user-header=X-authentik-username",
|
"authenticated-user-header=X-Oidc-Username",
|
||||||
"readers=ppetru",
|
"readers=ppetru",
|
||||||
"writers=ppetru",
|
"writers=ppetru",
|
||||||
"admin=ppetru",
|
"admin=ppetru",
|
||||||
@@ -207,7 +207,7 @@ job "wiki" {
|
|||||||
tags = [
|
tags = [
|
||||||
"traefik.enable=true",
|
"traefik.enable=true",
|
||||||
"traefik.http.routers.groktw.entryPoints=websecure",
|
"traefik.http.routers.groktw.entryPoints=websecure",
|
||||||
"traefik.http.routers.groktw.middlewares=authentik@file",
|
"traefik.http.routers.groktw.middlewares=oidc-auth@file",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user