505 Commits

Author SHA1 Message Date
b5301684f4 feat: add Mattermost webhook URL to n8n environment
Added MATTERMOST_WEBHOOK_URL environment variable to n8n:
- Available as environment variable in workflow expressions
- Can be used in HTTP Request nodes to send notifications
- Enables easy integration with Mattermost from any workflow

Usage in n8n workflows:
- Use {{ $env.MATTERMOST_WEBHOOK_URL }} in expressions
- Send POST requests with JSON payload to notify Mattermost

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 20:12:06 +01:00
151fdc4b00 feat: configure Mattermost webhook integrations
Added Mattermost webhook notifications for infrastructure services:

- **Netdata**: Health monitoring alerts sent to Mattermost
  - Configured via MATTERMOST_WEBHOOK_URL environment variable
  - All alert roles route to Mattermost notifications channel

- **Restic/Backrest**: Backup status notifications
  - Webhook URL passed as environment variable
  - Backrest web UI can be configured to use the webhook

- **Watchtower**: Container update notifications
  - Uses Shoutrrr mattermost:// URL format
  - Sends notifications when containers are updated

Configuration:
- Webhook URL stored securely in .env file
- All services reference ${MATTERMOST_WEBHOOK_URL} variable
- Watchtower uses specialized Shoutrrr format URL

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 19:59:58 +01:00
5342dcfaf2 feat: add Mattermost team chat platform to replace Gotify
Added Mattermost stack to the docker-compose infrastructure:

- **Mattermost stack** (mattermost.pivoine.art):
  - Team collaboration and chat platform
  - PostgreSQL backend for message persistence
  - Email notifications via IONOS SMTP
  - Support for channels, direct messages, and integrations
  - Mobile and desktop app support
  - Full Traefik integration with SSL termination

Infrastructure updates:
- Updated PostgreSQL init script to create mattermost database
- Added environment variables to arty.yml for Mattermost configuration
- Updated compose.yaml include list
- Configured email settings for notifications and invitations

This will replace Gotify as the primary notification and messaging platform.
All services integrated with Traefik for SSL termination and include
Watchtower auto-update labels.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 19:43:11 +01:00
4e43563d06 fix: use apt instead of apk for Netdata Dockerfile
Netdata container is Debian-based, not Alpine. Updated package
manager from apk to apt-get for installing msmtp packages.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 19:27:36 +01:00
7b2c202acc feat: add msmtp to Netdata for email alerts
Created custom Dockerfile for Netdata container that includes msmtp
and msmtp-mta packages for sending email notifications.

Changes:
- Added netdata/Dockerfile extending netdata/netdata:latest
- Installed msmtp, msmtp-mta, and ca-certificates via apk
- Set proper permissions (600) for msmtprc config file
- Updated compose.yaml to build from custom Dockerfile

This enables Netdata to send health alarm notifications via email
using the IONOS SMTP configuration in msmtprc.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 19:27:06 +01:00
50404948f4 feat: configure SMTP email notifications across all services
Added comprehensive email configuration to enable notifications for
password resets, user invitations, system alerts, and backup failures.

**Services configured:**

- **Vaultwarden** (vault/compose.yaml):
  - SMTP settings for password resets, 2FA, emergency access emails
  - Uses IONOS SMTP with force_tls security
  - Sender: hi@pivoine.art

- **Linkwarden** (links/compose.yaml):
  - Email server configuration for user invitations
  - Password reset functionality via email
  - Uses smtp:// connection string format

- **n8n** (n8n/compose.yaml):
  - SMTP mode enabled for workflow notifications
  - User invitation emails
  - Password reset support
  - SSL-secured connection

- **Netdata** (netdata/compose.yaml, health_alarm_notify.conf, msmtprc):
  - Health alarm notifications via email
  - MSMTP configuration for sending alerts
  - Notifications sent to valknar@pivoine.art
  - Alerts for system issues, resource exhaustion, service failures

**Common SMTP settings** (from .env):
- Provider: IONOS (smtp.ionos.de:465)
- From address: hi@pivoine.art
- Transport: SMTP with TLS/SSL
- Admin email: valknar@pivoine.art

**Backrest notifications:**
- Configured via web UI at restic.pivoine.art
- Supports webhooks to Gotify for push notifications
- Email notifications can be added through UI settings

All services now have proper email notification capabilities for
improved monitoring, user management, and security features.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 19:23:56 +01:00
7f892a47d7 fix: mount individual Netdata config files instead of directory
Changed from mounting entire go.d directory to mounting specific
config files (postgres.conf, filecheck.conf) to avoid conflicts
with Netdata's initialization script which needs to write to the
go.d directory during startup.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 18:53:26 +01:00
4b098b9463 feat: configure Netdata monitoring for PostgreSQL and Restic backups
Added monitoring configurations for infrastructure services:

- **PostgreSQL monitoring** (netdata/go.d/postgres.conf):
  - Configured go.d postgres collector with netdata user credentials
  - Monitors core PostgreSQL instance at 172.18.0.5:5432
  - Tracks database performance, connections, queries, and replication

- **Restic backup monitoring** (netdata/go.d/filecheck.conf):
  - Configured go.d filecheck collector for backup repository
  - Monitors /mnt/hidrive/users/valknar/Backup directory
  - Tracks backup repository size and modification times
  - Detects backup failures via directory state changes

Infrastructure updates:
- Mounted go.d configuration directory in Netdata container
- Mounted HiDrive backup directory (read-only) for monitoring
- Persistent collector configurations across container restarts

All monitoring visible in Netdata dashboard at netdata.pivoine.art
with HTTP Basic Auth protection.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 18:50:19 +01:00
3c7aad09ad security: add HTTP Basic Auth to Netdata dashboard
Added HTTP Basic Authentication to secure the Netdata monitoring dashboard:
- Added basicauth middleware using shared AUTH_USERS credentials
- Protects sensitive infrastructure metrics from unauthorized access
- Uses same credentials as Scrapy and other protected services
- Maintains SSL/TLS encryption via Traefik

Security improvements:
- Dashboard now requires username/password
- Prevents public access to server metrics
- Infrastructure monitoring data protected
- Follows security best practices from Netdata documentation

Access requires credentials stored in AUTH_USERS environment variable.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 18:37:01 +01:00
66579fa861 feat: add Netdata monitoring stack
Added Netdata real-time monitoring system at netdata.pivoine.art:
- Real-time infrastructure and container monitoring
- Auto-discovers all Docker containers
- Tracks CPU, memory, disk, network usage per service
- Low overhead monitoring (~1-3% CPU)
- Self-hosted with web dashboard on port 19999

Configuration:
- Created netdata/compose.yaml with full Traefik integration
- Added to main compose.yaml include list
- Added environment variables to arty.yml
- Mounted Docker socket for container metrics
- Mounted system directories for host metrics (/proc, /sys, /var/log)
- Three persistent volumes: config, lib, cache
- Required capabilities: SYS_PTRACE, SYS_ADMIN for system monitoring
- Watchtower enabled for automatic updates

Benefits for infrastructure:
- Monitor 20+ running services in real-time
- Track PostgreSQL, Redis, Traefik performance
- Watch backup processes (Backrest/Restic)
- Monitor Jellyfin transcoding load
- Alert on resource issues before they become critical
- Historical data for capacity planning

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 18:28:47 +01:00
955858a0a1 feat: add Excalidraw to Kit stack
Added Excalidraw collaborative drawing tool to the Kit toolkit at draw.kit.pivoine.art:
- Virtual whiteboard for sketching hand-drawn diagrams
- Infinite canvas with collaborative features
- Image: excalidraw/excalidraw:latest
- Exposed on port 80 via Traefik with SSL

Configuration:
- Added draw service to kit/compose.yaml
- Added KIT_DRAW_IMAGE and KIT_DRAW_TRAEFIK_HOST to arty.yml
- Health check disabled to prevent false negatives
- Follows same pattern as other Kit tools
- Watchtower enabled for automatic updates

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 17:32:12 +01:00
506d6bc580 fix: disable health check for Units service
Disabled health check for Units converter service as it was failing
due to IPv6 connection attempts. The service is running correctly
but the health check was trying to connect to [::1]:80 instead of
127.0.0.1:80, causing false negatives.

Similar to Pastel services, disabling the built-in health check.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 11:30:37 +01:00
a4f49251e3 fix: correct Units service port from 3000 to 80
Fixed port configuration for Units converter service:
- Changed loadbalancer.server.port from 3000 to 80
- Matches the actual nginx port in the units-ui container

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 11:28:28 +01:00
ad89b96dc0 feat: add Units converter tool to Kit stack
Added Units converter to the Kit toolkit at units.kit.pivoine.art:
- Unit conversion tool for length, weight, temperature, etc.
- Image: ghcr.io/valknarness/units-ui:latest
- Exposed on port 3000 via Traefik with SSL

Configuration:
- Added units service to kit/compose.yaml
- Added KIT_UNITS_IMAGE and KIT_UNITS_TRAEFIK_HOST to arty.yml
- Follows same pattern as other Kit tools (Vert, Paint, Pastel, Stirling)
- Watchtower enabled for automatic updates

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 10:40:30 +01:00
30856e88fc fix: rename sterling to stirling (correct spelling)
Fixed typo in Stirling PDF service naming:
- Renamed service from sterling to stirling
- Updated all variable names: KIT_STERLING_* to KIT_STIRLING_*
- Updated domain: sterling.kit.pivoine.art to stirling.kit.pivoine.art
- Updated container name: kit_sterling to kit_stirling

This matches the correct spelling of Stirling-PDF.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 19:09:05 +01:00
aab8470d77 feat: add Stirling PDF tool to Kit stack
Added Stirling PDF (S-PDF) to the Kit toolkit at sterling.kit.pivoine.art:
- PDF manipulation tool with 100+ features
- Merge, split, convert, OCR, compress PDFs
- Privacy-focused: local processing, no data collection
- Image: frooodle/s-pdf:latest
- Exposed on port 8080 via Traefik with SSL

Configuration:
- Added sterling service to kit/compose.yaml
- Added KIT_STERLING_IMAGE and KIT_STERLING_TRAEFIK_HOST to arty.yml
- Follows same pattern as other Kit tools (Vert, Paint, Pastel)
- Watchtower enabled for automatic updates

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 19:06:23 +01:00
8dabe7a40b refactor: remove Traefik exposure from Pastel API
Removed all Traefik labels from pastel_api service since the API
is now only accessed internally by pastel_ui via Docker network.

Changes:
- Removed traefik.enable and all HTTP/HTTPS router configurations
- Removed path prefix routing (/api)
- Kept only Watchtower label for auto-updates
- API now accessible only at http://pastel_api:3000 internally

This simplifies the configuration and improves security by not
exposing the API endpoint externally.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 16:12:04 +01:00
5d1094efbb fix: update Pastel UI to use internal API URL
Changed Pastel UI environment variable to use internal Docker
network communication instead of external HTTPS:
- Changed from NEXT_PUBLIC_API_URL/NEXT_PUBLIC_APP_URL to PASTEL_API_URL
- Use internal container name: http://pastel_api:3000
- Removes dependency on external domain resolution
- Improves performance by avoiding Traefik proxy for internal calls

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 16:10:34 +01:00
85e0aa4fb6 refactor: switch Filestash from custom build to official image
Removed custom Dockerfile and switched to using the official
machines/filestash image from Docker Hub:
- Removed stash/Dockerfile (custom build with ffmpeg)
- Updated compose.yaml to use ${STASH_IMAGE} variable
- Defaults to machines/filestash:latest

This simplifies maintenance and ensures we use the officially
maintained image with proper updates via Watchtower.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 15:57:51 +01:00
fed4f23015 fix: update Pastel UI environment variables format
Changed environment variable format from array to object syntax
for better Docker Compose compatibility:
- NEXT_PUBLIC_API_URL: https://pastel.kit.pivoine.art
- NEXT_PUBLIC_APP_URL: https://pastel.kit.pivoine.art

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 15:43:41 +01:00
e5aba18249 fix: add environment variables and disable health checks for Pastel services
Fixed Pastel color palette generator services in Kit stack:
- Disabled health checks for pastel_api (curl not available in image)
- Disabled health checks for pastel_ui (unnecessary)
- Added NEXT_PUBLIC_API_URL environment variable to pastel_ui
- Added NEXT_PUBLIC_APP_URL environment variable to pastel_ui

Health checks were showing containers as unhealthy even though services
were running correctly. The API health check used curl which isn't
installed in the image, causing false negatives.

Environment variables configure the Next.js frontend to correctly
connect to the API endpoint.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 15:37:26 +01:00
7b8b414dd3 fix: pastel ports 2025-11-07 15:18:59 +01:00
9a77bdb211 feat: add Pastel color palette generator to Kit stack
Added Pastel service with API and UI to the Kit toolkit:

**New Services:**
- pastel_api: Backend API for color palette generation
  - Image: ghcr.io/valknarness/pastel-api:latest
  - Routes: https://pastel.kit.pivoine.art/api

- pastel_ui: Frontend UI for interactive palette generation
  - Image: ghcr.io/valknarness/pastel-ui:latest
  - Routes: https://pastel.kit.pivoine.art

**Features:**
- Color harmony algorithms
- Interactive palette generation
- Export in various formats
- Programmatic API access
- Path-based routing (UI on root, API on /api)

**Configuration:**
- Updated arty.yml with KIT_PASTEL_* variables
- Updated documentation (CLAUDE.md, README.md)
- Added Traefik labels with SSL, compression, security headers
- Watchtower auto-update enabled

Kit stack now includes 5 services:
- Landing page (kit.pivoine.art)
- Vert file converter (vert.kit.pivoine.art)
- Paint image editor (paint.kit.pivoine.art)
- Pastel color generator (pastel.kit.pivoine.art)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 14:43:50 +01:00
739982d8a7 feat: remove HTTP Basic Auth from Kit stack services
Removed authentication middleware from Vert and Paint services:
- Removed basicauth middleware labels from vert service
- Removed basicauth middleware labels from paint service
- Updated middleware chains to exclude auth
- Updated CLAUDE.md to reflect public access

All Kit stack services (landing, vert, paint) are now publicly
accessible without authentication as they are client-side tools
that don't require protection.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 12:14:46 +01:00
fc1c149ac6 feat: add Kit landing page at kit.pivoine.art
Added kit-ui landing page as the main entry point for the toolkit:
- Image: ghcr.io/valknarness/kit-ui:latest
- URL: https://kit.pivoine.art
- Provides links to Vert (file converter) and Paint (image editor)

Changes:
- Added landing service to kit/compose.yaml
- Updated arty.yml with KIT_TRAEFIK_HOST and KIT_LANDING_IMAGE
- Updated CLAUDE.md with landing page documentation
- Updated README.md with landing page reference

Toolkit structure:
- Landing: kit.pivoine.art (main hub)
- Vert: vert.kit.pivoine.art (file converter)
- Paint: paint.kit.pivoine.art (image editor)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 11:36:20 +01:00
401029b0e7 refactor: switch Kit stack from path to subdomain routing
Changed from path-based routing (kit.pivoine.art/vert, /paint) to
subdomain routing (vert.kit.pivoine.art, paint.kit.pivoine.art) to
fix CSS and JS asset loading issues.

Changes:
- Updated kit/compose.yaml: Removed path prefix stripping, using Host() rules
- Updated arty.yml: Added KIT_VERT_TRAEFIK_HOST and KIT_PAINT_TRAEFIK_HOST
- Updated CLAUDE.md: Changed URLs from paths to subdomains
- Updated README.md: Updated all Kit references to use subdomains

New URLs:
- File converter: https://vert.kit.pivoine.art
- Image editor: https://paint.kit.pivoine.art

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:26:30 +01:00
88c6187682 chore: remove vert-sablier.yaml as Vert no longer uses Sablier
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:18:21 +01:00
a703ad2d3a fix: move paint Dockerfile into kit directory
Moved Dockerfile from paint/ to kit/ directory and updated
build context to use local directory instead of ../paint.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:16:54 +01:00
805ad3f735 feat: consolidate Vert and Paint into unified Kit stack
Created new kit.pivoine.art stack with path-based routing:
- /vert: VERT file format converter (250+ formats)
- /paint: miniPaint image editor

Changes:
- Created kit/compose.yaml with both services
- Removed Sablier scale-to-zero from Vert (no longer needed)
- Deleted old vert/ and paint/ stack directories
- Updated compose.yaml includes (removed vert, paint; added kit)
- Updated arty.yml with KIT_* environment variables
- Updated CLAUDE.md documentation with new Kit section
- Updated README.md with consolidated toolkit entry

Benefits:
- Single domain for related utilities
- Simplified service management
- Maintained HTTP Basic Auth protection
- No Sablier dependency for Vert

Access:
- File converter: https://kit.pivoine.art/vert
- Image editor: https://kit.pivoine.art/paint

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 10:12:49 +01:00
31911e2d85 docs: update README.md with PairDrop, Jellyfin, and miniPaint
Added documentation for three new services:

- **DROP (PairDrop)**: Peer-to-peer file sharing with WebRTC
  - Direct device-to-device transfers (no server storage)
  - STUN-enabled cross-network support
  - Automatic device discovery
  - Share files, text, and clipboard content

- **JELLY (Jellyfin)**: Media streaming server
  - HiDrive photo and video streaming
  - Hardware transcoding support
  - Multi-device playback

- **PAINT (miniPaint)**: Web-based image editor
  - Layer support and filters
  - Client-side processing
  - PNG, JPG, GIF, WebP support

Updated:
- Core systems table with new services
- Ship architecture diagram
- Storage volumes list
- Navigation commands with usage instructions

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 22:14:16 +01:00
908287b844 fix: enable WS_FALLBACK and WS_SERVER for PairDrop device discovery
Enabled WebSocket server and fallback to help with device discovery
when devices appear to have the same public IP through the proxy.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 22:09:14 +01:00
9b43b75480 debug: enable DEBUG_MODE for PairDrop to diagnose connection issues
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 22:02:26 +01:00
e2b7db5912 docs: add PairDrop configuration to CLAUDE.md
Documented the PairDrop service with WebRTC STUN configuration:
- Service description and features
- RTC_CONFIG configuration with Google STUN servers
- Usage instructions for cross-network file sharing
- Technical details about WebRTC and NAT traversal

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 21:57:52 +01:00
f7ff2c2744 fix: use correct relative path for RTC config mount
Changed from ./drop/rtc_config.json to ./rtc_config.json since the
compose file is already in the drop/ directory. The previous path
caused Docker to create an empty directory instead of mounting the file.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 21:56:38 +01:00
9b8d294aa6 fix: correct RTC_CONFIG volume mount path for PairDrop
Changed mount path from /config/rtc_config.json to /rtc_config.json
to resolve EISDIR error where container was trying to read a directory
instead of the file.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 21:55:30 +01:00
0c4a817a09 feat: add WebRTC STUN server configuration to PairDrop
Added RTC configuration with Google's public STUN servers to enable
peer-to-peer connections across different networks (e.g., WiFi to
cellular data).

Changes:
- Created drop/rtc_config.json with 5 Google STUN servers
- Updated drop/compose.yaml to mount RTC config file
- Added RTC_CONFIG environment variable pointing to config file

This should resolve connectivity issues when devices are on different
networks or behind NAT.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 21:54:26 +01:00
7d961c2876 feat: add PairDrop file sharing service (drop.pivoine.art)
Added PairDrop stack for peer-to-peer file sharing:
- WebRTC-based direct file transfers between devices
- No file size limits or server storage
- End-to-end encrypted transfers
- Local network auto-discovery
- Cross-platform support (desktop, mobile, tablets)
- Progressive Web App installable on mobile
- Rate limiting enabled for security

PairDrop provides secure, private file sharing without uploading
files to any server - all transfers happen directly between devices.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 21:22:12 +01:00
5158817ac6 feat: add Jellyfin config backup to Restic
Added jellyfin-backup plan to Backrest configuration:
- Backs up /volumes/jelly_config daily at 9 AM
- Retention: 7 daily, 4 weekly, 6 monthly, 2 yearly
- Added jelly_config volume mount to restic/compose.yaml
- Updated documentation in CLAUDE.md

This ensures Jellyfin configuration, library metadata, and user
settings are backed up to HiDrive.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 20:40:51 +01:00
45c14a2a14 feat: add Jellyfin media server (jelly.pivoine.art)
Added Jellyfin stack for streaming photos and videos from HiDrive:
- Maps /mnt/hidrive/users/valknar/Pictures to /media/pictures (read-only)
- Maps /mnt/hidrive/users/valknar/Videos to /media/videos (read-only)
- Hardware transcoding support for optimal video playback
- Multi-device streaming (web, mobile, TV apps)
- Automatic media organization with metadata fetching

Jellyfin provides superior video playback compared to Filestash's
transcoding plugin, which has compatibility issues with named pipes
in containerized environments.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 20:36:01 +01:00
0af6e0f6a9 fix: add tmpfs mount to Filestash for video transcoding
Video transcoding was failing with 'Failed to open segment pipe:out000.ts'
because ffmpeg couldn't create named pipes. Added tmpfs mount with exec
permissions to /tmp to allow ffmpeg to create temporary files and pipes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 20:25:48 +01:00
816cf39e9b feat: add ffmpeg to Filestash for video transcoding support
Added custom Dockerfile to build Filestash with ffmpeg and ffprobe installed,
enabling the built-in video transcoding plugin for seamless video playback.

Changes:
- Created stash/Dockerfile extending machines/filestash:latest
- Installed ffmpeg package with apt-get
- Updated stash/compose.yaml to build from Dockerfile
- Video transcoding plugin will automatically detect ffmpeg presence

This enables Filestash to transcode mov, mkv, avi, mpeg, and other video
formats for in-browser playback without manual conversion.

Note: Enable the video transcoding feature in Filestash admin panel at
https://stash.pivoine.art/admin after deployment.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 20:09:34 +01:00
4881d65434 feat: add HTTP Basic Auth to paint service
Protected paint.pivoine.art with HTTP Basic Auth using shared AUTH_USERS
credentials, matching the security setup of scrapy and other protected services.

Changes:
- Added basicauth middleware with AUTH_USERS variable
- Added compression middleware
- Updated router middlewares chain to include auth, compress, and security headers

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 19:47:51 +01:00
ab35b2bca1 feat: add miniPaint stack (paint.pivoine.art)
Added new paint service stack to the docker-compose infrastructure:

- **Paint stack** (paint.pivoine.art):
  - miniPaint: Web-based image editor built from GitHub
  - Multi-stage Docker build clones from https://github.com/viliusle/miniPaint
  - Features: layers, filters, drawing tools, text, shapes support
  - Client-side processing with no server uploads
  - Stateless architecture (no backups needed)

Infrastructure updates:
- Created paint/compose.yaml with Traefik routing and SSL
- Created paint/Dockerfile with Node.js build stage and nginx serve
- Added PAINT environment variables to arty.yml
- Updated compose.yaml include list
- Updated CLAUDE.md documentation

All services integrated with Traefik for SSL termination and include
Watchtower auto-update labels.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 19:44:14 +01:00
dac3e89f47 fix: correct Go template syntax for AUTH_USERS variable 2025-11-06 19:01:10 +01:00
fb7aab6991 fix: use AUTH_USERS environment variable in VERT auth middleware
Properly configured AUTH_USERS environment variable for Traefik container
to use in the vert-sablier.yaml dynamic configuration via Go templating.

Changes:
- Added AUTH_USERS environment variable to proxy compose file
- Updated vert-auth middleware to use {{ env AUTH_USERS }} template
- Fixed environment syntax to use map format instead of list format

This keeps credentials secure in the .env file (not tracked in git) while
the tracked vert-sablier.yaml file only contains the template reference.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 18:53:03 +01:00
a304d9e347 fix: remove quotes from basicAuth users 2025-11-06 18:47:23 +01:00
ef88bf4b90 fix: use hardcoded credentials in VERT auth middleware
Removed AUTH_USERS environment variable from Traefik container as Docker
Compose was incorrectly expanding the $ signs in the htpasswd hash.

Instead, hardcoded the credentials directly in the vert-sablier.yaml dynamic
configuration file (which is not tracked in git, so changes remain local).

The AUTH_USERS variable with $$ escaping continues to work correctly in
Docker labels for other services.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 18:45:56 +01:00
71e3a0aea9 fix: define VERT middlewares in file provider with environment variable
Fixed "middleware does not exist" error for VERT by defining all middlewares
in the file provider configuration instead of relying on Docker provider
middlewares from a stopped container (Sablier scale-to-zero).

Changes:
- Added vert-auth middleware using AUTH_USERS environment variable
- Added vert-compress middleware for gzip compression
- Passed AUTH_USERS to Traefik container via environment section
- Removed @docker suffixes from middleware references

This ensures middlewares are always available, even when the VERT container
is stopped by Sablier's dynamic scaling feature.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 18:41:08 +01:00
bad220c304 fix: define VERT service in file provider instead of referencing Docker provider
Fixed "the service 'vert-web-secure@docker' does not exist" error by defining
the service directly in the vert-sablier.yaml file provider configuration.

Previously, the router was defined in the file provider but tried to reference
a service from the Docker provider (@docker suffix), which caused a mismatch.
Now both the router and service are defined in the same file provider, while
still using Docker-based middlewares (auth, compression).

Changes:
- Added services.vert-web-secure with loadBalancer pointing to vert_app:80
- Changed router service reference from "vert-web-secure@docker" to "vert-web-secure"

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 18:35:01 +01:00
145273c35c fix: remove global TLS options to resolve Traefik startup race condition
Removed the global `--entrypoints.web-secure.http.tls.options=default@file`
configuration from proxy/compose.yaml that was causing "unknown TLS options"
errors during Traefik startup.

The issue occurred because Traefik attempted to apply TLS options to all
routers before the file provider finished loading security.yaml, creating
a race condition. Services now use Let's Encrypt certificates without
explicit TLS options at the entrypoint level.

The TLS security settings (minimum TLS 1.2, strong cipher suites, etc.)
remain defined in proxy/dynamic/security.yaml and can be applied to
individual services via their router configurations if needed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 18:32:38 +01:00