Commit Graph

56 Commits

Author SHA1 Message Date
Bastian de Byl 773a2bbc9c harden TrueNAS CIFS mounts so immich self-heals
TrueNAS was power-cycled, the CIFS mounts failed, and systemd never retried
-- mount units are not restarted on failure. SMB came back, nothing
remounted, and immich-server served an empty library for days while its
database still listed 14,181 assets pointing at /mnt/media/originals.

fstab carried no _netdev, no nofail and no automount, so there was no path
back without a human. Now:

  x-systemd.automount  any access re-attempts the mount; failure stops
                       being terminal
  _netdev / nofail     ordered after network-online, dead NAS cannot block boot
  soft                 I/O errors instead of blocking forever, so the
                       container can be restarted rather than wedging in
                       uninterruptible sleep
  idle-timeout         unmount when unused, clearing stale handles
  resilienthandles     SMB3 rides out brief blips

ansible.posix.mount mounts directly and never starts the generated
.automount unit, leaving the on-access trigger inactive -- enable it
explicitly, or the headline fix silently does nothing.

The containers are systemd USER units while the mounts are SYSTEM units, so
RequiresMountsFor= is unavailable. cifs-watchdog bridges the scopes: checks
health, recovers, and restarts ONLY immich-server (the sole consumer of both
paths; postgres/redis/ML use local volumes).

Two bugs the umount test caught, both worth knowing:
- `ls` cannot test mountedness. An unmounted mount point is an ordinary
  empty directory, so ls succeeds and recovery was skipped entirely.
- A drop repaired within a single run leaves prev=healthy, so keying the
  restart solely on the stored state skipped it while the container still
  held its stale view.

Also moves the SMB password out of /etc/fstab, which is 0644 and was
readable by every local user, into a 0600 credentials file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 14:49:22 -04:00
Bastian de Byl fec7d62acb feat(skudak-cloud): repair LibreSign, brand its mail, add Redis
LibreSign had been silently broken since it was first deployed in
January. Every step of the old before-starting hook ended in `|| echo`,
so six months of failures logged nothing.

LibreSign repair
- Root cause was a stale config_path: a valid OpenSSL root CA existed at
  generation 1, a failed CFSSL attempt left an empty generation 2, and
  config_path was left pointing at the empty one. Regenerated as
  "Skudak LLP" (was the pre-rename "Skudak Rennsport LLP").
- Deleted the hook. Java/PDFtk/jSignPdf live under data/appdata_*, a
  persisted volume, so they only ever needed installing once. Install and
  verification are now explicit tasks that actually fail.
- PHP_MEMORY_LIMIT 1024M -- the 512M image default fails opaquely
  mid-signature. LC_ALL/LANG so the JVM is not ANSI_X3.4-1968.
- signature_render_mode=GRAPHIC_ONLY. Any other mode halves the stamp
  width and overlays a name/date block that collides with the drawn mark
  and duplicates what our documents already typeset. The value must be
  exactly GRAPHIC_ONLY; a bare "GRAPHIC" is accepted by occ, matches no
  radio in the UI, and silently reverts to default.
- write_qrcode_on_footer=false, written with --type=boolean because
  FooterHandler reads it via getValueBool and the typed appconfig API
  does not coerce a string "0". The validation URL text is kept.
- identification_documents=0 -- the default gates signing behind an ID
  upload plus admin approval, so signers saw no way to sign.
- shareapi_restrict_user_enumeration_full_match=no, so an email owned by
  an existing account can be added as a signer. Root cause is in core
  (MailPlugin.php:163), not LibreSign. Do NOT set full_match_email=no --
  that disables email signer search entirely.

Mail branding (skudakmail app)
- Two supported extension points, no core patch and no LibreSign fork:
  mail_template_class for layout, subjects, button labels and the footer
  LibreSign never adds; and a BeforeMessageSent listener to embed the
  wordmark as a cid: part so it survives remote-image blocking.
- A third listener adds scoped CSS fixing the signing page being clipped
  on iOS Safari (100vh -> 100dvh). Patched upstream too.
- skudakmail-verify.php.j2 asserts all of the above through the real
  useTemplate() path and fails the play on drift. Every assertion was
  proven to fail when deliberately regressed.

Redis
- memcache.locking was unset, so Nextcloud used DBLockingProvider and
  every file lock became a MariaDB write -- the contention behind the
  intermittent multi-second stalls. Verified after: db locks static,
  redis keys growing.
- requirepass lives in a mounted 0640 conf, not --requirepass, which
  would leak it into podman inspect, the systemd unit and ps. The file is
  chowned to uid 999 because redis-server does not run as root and the
  :ro mount stops the image fixing it itself.
- No maxmemory: cache is evictable, locks are NOT, and evicting a held
  lock permits concurrent writers to one file. No persistence either --
  a restored RDB could reinstate locks whose owner is long dead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 15:54:52 -04:00
Bastian de Byl c184099b2d refactor(backup): remove duplicate direct-to-S3 stage
A host-to-iDrive S3 stage was added here and is now removed. It would
have written the same data into the same `backup-all` bucket that the
TrueNAS cloud-sync task already fills -- duplicate storage, two writers
to one prefix, for no additional coverage.

Offsite to business-owned storage was already solved: the rsync feeds
/mnt/glacier/skudakcloud and TrueNAS cloud-syncs that to Skudak's own
iDrive e2 account. The earlier note in skudak/cloud.yml proposed adding
S3 *and then dropping the rsync* -- replacement, not addition -- and
building both was a misreading of it.

If offsite is ever moved onto this host it must REPLACE the rsync, not
run beside it. Settle first whether the TrueNAS -> iDrive leg is
independently verifiable; keeping this chain means trusting it.

Also removes the now-orphaned /etc/backup_s3 credential file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 15:54:27 -04:00
Bastian de Byl bc110ce69e back up Gitea + Skudak app data; drop PartKeepr and Pi-hole
Extends the Nextcloud backup machinery rather than adding a second
mechanism. cloud-backup.sh.j2 gains three guarded options, all no-ops for
the existing callers:

  backup_podman_user  Gitea runs rootless under `git`, not `podman`
  backup_db_type      postgres (Gitea) and mysql (BookStack) alongside
                      mariadb; each engine's completion trailer differs,
                      and grepping for the wrong one fails every run
  backup_sqlite_dbs   `sqlite3 .backup` for live WAL-mode SQLite, gated on
                      `pragma integrity_check` before promotion -- rsync
                      is either stale (no -wal) or torn (with it)

New instances: gitea-debyl, skudak-gitea, bookstack, partsy-skudak. The
alert handler is rendered once and shared, so its wording is now generic
rather than per-product; TAG stays nextcloud-backup because an external
Graylog rule matches on it.

`apply:` on the includes is load-bearing -- tags on a dynamic
include_tasks do not reach the tasks inside it.

Business data (skudak-gitea, bookstack, partsy-skudak) goes to TrueNAS
and on to Skudak's own iDrive account; the personal bucket's
/skudak*/** excludes are permanent, not a stopgap.

Removals: PartKeepr is superseded by Partsy, and its teardown never
finished -- it targeted /etc/systemd/system/podman-partkeepr*.service,
wrong prefix and wrong scope, leaving enabled user units in failed state.
Pi-hole's role was already orphaned (absent from deploy_home.yml); its
port 53 rule went with it after confirming nothing listens there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 18:08:47 -04:00
Bastian de Byl 5776dbe1bf UPS monitoring, Nextcloud cron, container image bumps
ups role: NUT server on home.debyl.io for the CyberPower PR1500RT2U that backs
both it and truenas.localdomain, with staged shutdown (TrueNAS sheds at t+2min,
host at 10% charge) and best-effort IPMI power-on when mains returns. The 10%
threshold leans on ignorelb + override.battery.charge.low rather than a custom
poller, because CyberPower asserts its own low-battery flag far too early.
Credentials come from vault vars; nothing sensitive is templated in the clear.

Nextcloud background jobs: both instances have backgroundjobs_mode "cron", which
expects an external caller every ~5 minutes, and nothing was calling. The
personal instance had not run a background job since 2026-05-14 and skudak since
2024-11-20. Consequently trash and file versions never expired, stale chunked
uploads accumulated, calendar reminders never fired, and nextcloud.log was never
rotated -- which quietly made the existing log_rotate_size cap inert. Added a
systemd timer per instance, skipping cleanly when the container is down or in
maintenance so deploy windows don't show up as failed units.

Trash retention on the personal instance: the default "auto" only expires when
disk space demands it, so 66 GB of >30-day deletions sat on a host with 1.3 TB
free -- effectively unbounded. "auto, 30" makes the 30-day expiry unconditional
while still purging early under pressure.

Image bumps:
  nextcloud       33.0.0  -> 34.0.2   (both cloud and skudak-cloud)
  greg-time-bot   3.9.25  -> 3.10.0
  fulfillr        20260723.2044 -> 20260728.2155  (prod and dev)

The fulfillr bump records what is already deployed: both containers were rolled
to that image on 2026-07-29 for SCRUM-156 (digital product releases + customer
update campaign). Committing it keeps the repo from claiming an older tag than
the host is actually running, which would otherwise roll fulfillr backwards on
the next clean-checkout deploy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 13:00:51 -04:00
Bastian de Byl 0ab423ca55 harden nextcloud backups: db dumps, alerting, drift fix
The data-only rsync left no way to restore a working instance: mysql/ and
config/ were never backed up, so a recovery would have files but no shares,
users or metadata. Dump the database before syncing files (a DB older than
the files is repairable with occ files:scan; a newer one references blobs
that never made it into the backup) and ship config/ alongside it.

Capture the --chmod=Du=rwx,Dgo=rx flag that had been hand-added to the
deployed skudak-cloud script. It was outside git, so every deploy silently
reverted it. It now lives in backup_rsync_extra_args.

Add OnFailure= alerting. The units failed silently before, which is how an
iDrive sync failure sat unnoticed since May. msmtp rather than the esmtp
already installed: the OpenSRS relay is port 465 (implicit TLS) and libesmtp
only speaks STARTTLS.

Exclude nextcloud.log* from the sync and cap log_rotate_size. skudak-cloud
was running at loglevel 0 and had written a 64 GB log that was being rsynced
and pushed to S3; set it to 2 to match the home instance.

Stagger the timers (04:00 / 04:30) so both finish before the 05:00 TrueNAS
snapshot task, and bound TimeoutStartSec so a wedged rsync cannot leave the
unit activating forever and skip every subsequent trigger.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 16:03:18 -04:00
Bastian de Byl 5d0d15f414 SCRUM-97: Healthcheck + restart-on-unhealthy for fulfillr containers
After a power cycle a transient HMAC Secrets Manager blip leaves
go-fulfillr's gated routes unregistered (404) with the process still up,
so nothing restarts it. Add a podman healthcheck probing the new
dependency-free /api/v1/health/startup (503 until those routes register)
with healthcheck_failure_action: restart, so podman restarts the
container in place and the next boot self-heals.

- fulfillr.yml + fulfillr-dev.yml: healthcheck via busybox wget (ships in
  the alpine image), interval 30s / timeout 5s / retries 3 /
  start_period 30s (covers the ~14s HMAC retry backoff), failure_action
  restart. Existing restart_policy on-failure:3 kept (process-exit case).
- main.yml: bump fulfillr + fulfillr-dev image to 20260628.1930 (the
  build carrying the /health/startup probe).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 15:35:22 -04:00
Bastian de Byl 7d4a398bba Drop self-hosted AI (Ollama + SearXNG); gregtime switches to xAI Grok
The Ollama role and SearXNG container backed FISTO AI responses in the
greg-time Discord bot. greg-time 3.9.6 drops both (plus the Gemini path)
in favor of a single xAI Grok backend, so:

- remove the ollama role and its wiring in deploy_home.yml
- remove the searxng container task, template, and searxng_path default
- gregtime: swap OLLAMA_*/SEARXNG_URL/GEMINI_API_KEY env for XAI_API_KEY,
  bump image 3.6.5 -> 3.9.6
- vault: add xai_api_key, drop gemini_api_key

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 10:19:45 -04:00
Bastian de Byl e82ace6de3 fulfillr-dev: staging back-office container + Turso store prep
Add a second go-fulfillr container (fulfillr-dev) wired to the staging
Turso store + EasyPost/Stripe test keys via dev.json, served at
fulfillr-dev.debyltech.com (Caddy -> :9055), LAN-restricted like prod.

- fulfillr-dev.yml + dev.json.j2: the staging container, volumes, config
- defaults: fulfillr_dev_* vars; prod store URL stubbed off until cutover
- Caddyfile + caddy.yml: fulfillr-dev site block and static mount
- awsddns.yml: Route53 DDNS for the fulfillr-dev hostname
- production.json.j2: add store_database_url/store_auth, rename stripe key
  var to fulfillr_stripe_api_key
- vault.yml: dev + store/stripe secrets

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 00:23:07 -04:00
Bastian de Byl 4287f5774f noticket - updates, cleanup, housekeeping 2026-05-27 11:19:09 -04:00
Bastian de Byl 829befeb1c chore: bump container versions and remove n8n
- gitea: 1.25.2 -> 1.26.1 (debyl + skudak)
- caddy: 2.10.2 -> 2.11.2
- uptime-kuma: 2.0.2 -> 2.3.2 (debyl + skudak)
- bookstack: 25.7 -> 26.3.4
- home-assistant: 2026.1 -> 2026.5.1
- immich (server + ML): v2.5.0 -> v2.7.5
- remove n8n service (unused)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:44:09 -04:00
Bastian de Byl 43fbcf59a5 add n8n workflow automation and fix cloud backup rsync
- Add n8n container (n8nio/n8n:2.11.3) with Caddy reverse proxy at n8n.debyl.io
- Add --exclude .ssh to cloud backup rsync to prevent overwriting
  authorized_keys on TrueNAS backup targets

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:12:19 -04:00
Bastian de Byl f23fc62ada fix: move cloud backup keys and scripts out of container volume paths
SSH keys moved to /etc/ssh/backup_keys/ (ssh_home_t) and backup scripts
to /usr/local/bin/ (bin_t) to fix SELinux denials - container_file_t
context blocked rsync from exec'ing ssh. Also fixes skudak key path
mismatch (was truenas_skudak, key deployed as truenas_skudak-cloud).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:45:03 -05:00
Bastian de Byl 8fd220a16e noticket - update zomboid b42revamp modpack to collection 3672556207
Replaces old 168-mod collection (3636931465) with new 385-mod collection.
Cleaned BBCode artifacts from mod IDs, updated map folders for 32 maps.
LogCabin retained for player connect/disconnect logging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 13:59:33 -05:00
Bastian de Byl 9f95585daa noticket - updated gregtime 2026-02-17 14:21:02 -05:00
Bastian de Byl 495943b837 feat: add ollama and searxng, migrate to debyl.io hostname
- Add ollama role for local LLM inference (install, service, models)
- Add searxng container for private search
- Migrate hostname from home.bdebyl.net to home.debyl.io
  (inventory, awsddns, zomboid entrypoint, home_server_name)
- Update vault with new secrets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:13:25 -05:00
Bastian de Byl 3eb6938b62 feat: switch FISTO to dolphin-mistral with dolphin-phi fallback
Benchmarked uncensored models for the gregtime FISTO bot. dolphin-mistral
produces the best uncensored creative content, dolphin-phi is faster fallback.
Added OLLAMA_NUM_PREDICT env var (300) and bumped image to 3.3.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:56:52 -05:00
Bastian de Byl d10cd49cf0 refactor: use variables for graylog stack image versions
Move hardcoded image versions to variables defined in main.yml for
easier version management in one place.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 12:35:51 -05:00
Bastian de Byl 61692b36a2 refactor: reorganize fluent-bit and geoip out of containers
- Move fluent-bit to common role (systemd service, not a container)
- Move geoip to podman/tasks/data/ (data prep, not a container)
- Remove debyltech tag from geoip (not a debyltech service)
- Fix check_mode for fetch subuid task to enable dry-run mode

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 12:34:43 -05:00
Bastian de Byl 9d562c7188 feat: smart zomboid traffic filtering with packet-size detection
Replace per-IP hashlimit with smarter filtering that distinguishes
legitimate players from scanner bots based on packet behavior:
- Players send varied packet sizes (53, 37, 1472 bytes)
- Scanners only send 53-byte query packets

New firewall rule chain:
- Priority 2: Mark + ACCEPT non-query packets (verifies player)
- Priority 3: ACCEPT queries from verified IPs (1 hour TTL)
- Priority 4: LOG rate-limited queries from unverified IPs
- Priority 5: DROP rate-limited queries (2 burst, then 1/hour)

Also includes:
- Fail2ban zomboid jail with tighter thresholds (5 retries/4h, 1w ban)
- Graylog streams for zomboid-connections, zomboid-ratelimit, fail2ban
- GeoIP pipeline enrichment for zomboid traffic
- Fluent-bit inputs for ratelimit logs and fail2ban events
- Remove Legendary Katana mod (Workshop 3418366499) - removed from Steam
- Bump Immich to v2.5.0
- Fix fulfillr config (nil → null)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:09:26 -05:00
Bastian de Byl 33eceff1fe feat: add personal uptime kuma instance at uptime.debyl.io
- Add uptime-kuma-personal container on port 3002
- Add Caddy config for uptime.debyl.io with IP restriction
- Update both uptime-kuma instances to 2.0.2
- Rename debyltech tag from uptime-kuma to uptime-debyltech

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 08:04:33 -05:00
Bastian de Byl bc26fcd1f9 chore: fluent-bit zomboid, zomboid stats, home assistant, gregbot 2026-01-24 17:08:05 -05:00
Bastian de Byl 9a95eecfd5 chore: zomboid stats for gregtime, updates 2026-01-23 12:02:57 -05:00
Bastian de Byl 86e1b88d5a chore: bump image versions
- fulfillr: 20260109.0522 -> 20260123.0109
- gregtime: 1.9.0 -> 2.0.8

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 23:11:57 -05:00
Bastian de Byl c2d117bd95 feat: add systemd timer for zomboid container stats
Deploy systemd timer that writes zomboid container stats to
zomboid-stats.json every 30 seconds for gregtime to read.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 23:10:05 -05:00
Bastian de Byl 9974e2f773 chore: gregtime to use gemini API key 2026-01-18 12:50:17 -05:00
Bastian de Byl ca1a12ba60 noticket - gregtime updates 2026-01-16 21:55:34 -05:00
Bastian de Byl c96aeafb3f feat: add git.skudak.com Gitea instance and skudak domain migrations
Gitea Skudak (git.skudak.com):
- New Gitea instance with PostgreSQL in podman pod under git user
- SSH access via Gitea's built-in SSH server on port 2222
- Registration restricted to @skudak.com emails with email confirmation
- SMTP configured for email delivery

Domain migrations:
- wiki.skudakrennsport.com → wiki.skudak.com (302 redirect)
- cloud.skudakrennsport.com + cloud.skudak.com (dual-domain serving)
- BookStack APP_URL updated to wiki.skudak.com
- Nextcloud trusted_domains updated for cloud.skudak.com

Infrastructure:
- SELinux context for git user container storage (container_file_t)
- Firewall rule for port 2222/tcp (Gitea Skudak SSH)
- Caddy reverse proxy for git.skudak.com

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 22:27:02 -05:00
Bastian de Byl 9e665a841d chore: non-cifs nextcloud, partsy, zomboid updates 2026-01-15 16:48:07 -05:00
Bastian de Byl 34b45853e2 graylog updates, test.debyl.io, scripts for reference 2026-01-13 16:08:38 -05:00
Bastian de Byl 6af3c5dc69 feat: add comprehensive access logging to Graylog with GeoIP
- Add fluent-bit inputs for Caddy access logs (JSON) and SSH logs
- Create GeoIP task to download MaxMind GeoLite2-City database
- Mount GeoIP database in Graylog container
- Enable Gitea access logging via environment variables
- Add parsers.conf for Caddy JSON log parsing
- Remove unused nosql/redis container and configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 15:16:21 -05:00
Bastian de Byl d9bf3e5c75 chore: fixed gregtime, updated immich 2026-01-03 21:50:05 -05:00
Bastian de Byl 3f84ecaf5b feat: migrate fulfillr container from ECR to Gitea Packages
- Change image source from AWS ECR to git.debyl.io/debyltech/fulfillr
- Update login task from ECR to Gitea registry authentication
- Add Gitea registry credentials to vault

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 20:48:56 -05:00
Bastian de Byl cf200d82d6 chore: gitea-actions improvements, graylog/fluent-bit logging, zomboid mod
- Gitea actions: add handlers, improve deps and service template
- Graylog: simplify container config, add Caddy reverse proxy
- Add fluent-bit container for log forwarding
- Add ClimbDownRope mod (Workshop ID: 3000725405) to zomboid

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 17:20:18 -05:00
Bastian de Byl 2fd44fd450 feat: deploy gelf-proxy as container via Gitea registry
- Add Gitea container registry login task
- Add graylog.yml with full stack (MongoDB, OpenSearch, Graylog, gelf-proxy)
- Use container image instead of binary for gelf-proxy
- Image tagged from git.debyl.io/debyltech/gelf-proxy

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 18:53:36 -05:00
Bastian de Byl 4d835e86a0 chore: zomboid improvements, gregtime improvements with rcon 2025-12-22 12:31:43 -05:00
Bastian de Byl 38561cb968 gitea, zomboid updates, ssh key fixes 2025-12-19 10:39:56 -05:00
Bastian de Byl adce3e2dd4 chore: zomboid improvements, immich and other updates 2025-12-14 22:07:49 -05:00
Bastian de Byl 68803214d4 fix: home automations part 2 2025-12-14 18:50:38 -05:00
Bastian de Byl dd22154a02 Merge branch 'master' of github.com:bdebyl/deploy_home 2025-12-13 21:18:36 -05:00
Bastian de Byl 8c21923358 zomboid added, caddyfile updates, debylio migration, ddns migration 2025-12-13 21:18:33 -05:00
Bastian de Byl 2303e0ddc8 bumped cloud versions, remove signup, venv improvements, ansible bump 2025-11-17 15:31:36 -05:00
Bastian de Byl 28fe5937fe updates for gregtime, caddyfile, added uptime-kuma 2025-11-02 14:18:45 -05:00
Bastian de Byl 37c7259cf7 replace partkeepr with partsy, make private 2025-10-21 16:40:56 -04:00
Bastian de Byl 9c9da4f47c Complete infrastructure migration from nginx + ModSecurity to Caddy
This commit finalizes the comprehensive migration from nginx + ModSecurity + manual LetsEncrypt
to Caddy v2 with automatic HTTPS. The migration eliminates over 2000 lines of complex
configuration in favor of a single, simplified Caddyfile.

## Major Changes:

### Infrastructure Transformation
- **Web Server**: Replaced nginx with Caddy v2 for automatic HTTPS and simplified configuration
- **SSL/TLS**: Removed manual LetsEncrypt management, now fully automated by Caddy
- **Security**: Replaced ModSecurity WAF with Caddy's built-in security features
- **CI/CD**: Decommissioned Drone CI infrastructure completely

### Configuration Simplification
- **Before**: 20+ nginx site configs, ModSecurity rules, LetsEncrypt cron jobs
- **After**: Single Caddyfile with automatic HTTPS, security headers, and IP restrictions
- **Reduction**: 75% less configuration code while maintaining all functionality

### Files Added
- Caddy container deployment and configuration tasks
- Single Caddyfile template replacing all nginx configs
- Updated documentation (CLAUDE.md, TODO.md)

### Files Removed
- Complete nginx role and all site configurations (24 files)
- SSL role with LetsEncrypt management (6 files)
- Drone CI infrastructure (1 file)
- nginx static files and ModSecurity includes (2 files)

## Verified Functionality
All websites confirmed working with HTTPS certificates automatically provisioned:
- photos.bdebyl.net, parts.bdebyl.net, cloud.bdebyl.net
- wiki.skudakrennsport.com, cloud.skudakrennsport.com
- fulfillr.debyltech.com (with IP restrictions)
- Proper security headers and WebSocket support

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 20:38:45 -04:00
Bastian de Byl a6df909de8 noticket - removed logs references 2025-03-06 12:42:14 -05:00
Bastian de Byl 6b813362ca noticket - cleanup of unused sites, containers 2025-03-01 20:47:53 -05:00
Bastian de Byl 761bb67b5c noticket - add self-hosted bitwarden for skudak 2025-02-07 19:39:32 -05:00
Bastian de Byl fced2a0038 noticket - add base site, update secrets 2025-02-03 12:34:41 -05:00
Bastian de Byl 65495ba863 noticket - updates to photos/immich 2025-01-08 15:09:31 -05:00