Wiki v1.0
Added a wiki
This commit is contained in:
420
config-templates/dokuwiki/data/pages/services/core/authelia.txt
Normal file
420
config-templates/dokuwiki/data/pages/services/core/authelia.txt
Normal file
@@ -0,0 +1,420 @@
|
||||
====== Authelia ======
|
||||
|
||||
Authelia is an open-source authentication and authorization server providing two-factor authentication and single sign-on (SSO) capabilities to secure access to your homelab services.
|
||||
|
||||
===== Overview =====
|
||||
|
||||
**Purpose:** SSO authentication server
|
||||
**URL:** `https://auth.yourdomain.duckdns.org`
|
||||
**Authentication:** Direct login (username/password + 2FA)
|
||||
**Deployment:** Automatic (core stack)
|
||||
**Storage:** File-based user database
|
||||
|
||||
===== Key Features =====
|
||||
|
||||
**Authentication Methods:**
|
||||
* **Username/Password**: Secure credential verification
|
||||
* **TOTP (Time-based One-Time Password)**: RFC 6238 compliant
|
||||
* **WebAuthn**: Hardware security key support
|
||||
* **Push Notifications**: Mobile authentication
|
||||
|
||||
**Authorization:**
|
||||
* **Domain-based policies**: Per-service access control
|
||||
* **Group membership**: Role-based permissions
|
||||
* **Bypass rules**: Direct access for media services
|
||||
* **Session management**: Secure token handling
|
||||
|
||||
**Security:**
|
||||
* **Argon2id hashing**: Memory-hard password hashing
|
||||
* **JWT tokens**: Secure session management
|
||||
* **CSRF protection**: Cross-site request forgery prevention
|
||||
* **Brute force protection**: Rate limiting and account lockout
|
||||
|
||||
**Integration:**
|
||||
* **Traefik middleware**: Reverse proxy authentication
|
||||
* **LDAP support**: External user directory integration
|
||||
* **SAML/OIDC**: Enterprise federation protocols
|
||||
* **API access**: RESTful authentication API
|
||||
|
||||
===== Configuration =====
|
||||
|
||||
**Main Configuration (configuration.yml):**
|
||||
```yaml
|
||||
---
|
||||
# Authelia configuration
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
|
||||
log:
|
||||
level: info
|
||||
format: json
|
||||
|
||||
jwt_secret: ${AUTHELIA_JWT_SECRET}
|
||||
session:
|
||||
name: authelia_session
|
||||
secret: ${AUTHELIA_SESSION_SECRET}
|
||||
expiration: 3600 # 1 hour
|
||||
inactivity: 300 # 5 minutes
|
||||
domain: yourdomain.duckdns.org
|
||||
|
||||
storage:
|
||||
encryption_key: ${AUTHELIA_STORAGE_ENCRYPTION_KEY}
|
||||
local:
|
||||
path: /config/db.sqlite3
|
||||
|
||||
access_control:
|
||||
default_policy: deny
|
||||
rules:
|
||||
# Admin services require 2FA
|
||||
- domain: "*.yourdomain.duckdns.org"
|
||||
policy: two_factor
|
||||
subject:
|
||||
- "group:admins"
|
||||
|
||||
# Media services bypass SSO
|
||||
- domain: "jellyfin.yourdomain.duckdns.org"
|
||||
policy: bypass
|
||||
- domain: "plex.yourdomain.duckdns.org"
|
||||
policy: bypass
|
||||
|
||||
api:
|
||||
disable_bearer_token: false
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /config/users_database.yml
|
||||
|
||||
notifier:
|
||||
filesystem:
|
||||
filename: /config/notification.txt
|
||||
```
|
||||
|
||||
**User Database (users_database.yml):**
|
||||
```yaml
|
||||
---
|
||||
users:
|
||||
admin:
|
||||
displayname: Administrator
|
||||
password: $argon2id$...
|
||||
email: admin@yourdomain.duckdns.org
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
```
|
||||
|
||||
===== Docker Compose =====
|
||||
|
||||
```yaml
|
||||
services:
|
||||
authelia:
|
||||
image: authelia/authelia:latest
|
||||
container_name: authelia
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik-network
|
||||
volumes:
|
||||
- ./authelia/configuration.yml:/config/configuration.yml:ro
|
||||
- ./authelia/users_database.yml:/config/users_database.yml
|
||||
- ./authelia/db.sqlite3:/config/db.sqlite3
|
||||
- ./authelia/notification.txt:/config/notification.txt
|
||||
environment:
|
||||
- AUTHELIA_JWT_SECRET=${AUTHELIA_JWT_SECRET}
|
||||
- AUTHELIA_SESSION_SECRET=${AUTHELIA_SESSION_SECRET}
|
||||
- AUTHELIA_STORAGE_ENCRYPTION_KEY=${AUTHELIA_STORAGE_ENCRYPTION_KEY}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.authelia.rule=Host(`auth.${DOMAIN}`)"
|
||||
- "traefik.http.routers.authelia.entrypoints=websecure"
|
||||
- "traefik.http.routers.authelia.tls.certresolver=letsencrypt"
|
||||
# No Authelia middleware for itself
|
||||
- "traefik.http.services.authelia.loadbalancer.server.port=9091"
|
||||
depends_on:
|
||||
- authelia-redis # If using Redis
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 256M
|
||||
reservations:
|
||||
cpus: '0.1'
|
||||
memory: 64M
|
||||
```
|
||||
|
||||
===== User Management =====
|
||||
|
||||
**Adding Users:**
|
||||
```yaml
|
||||
users:
|
||||
newuser:
|
||||
displayname: "New User"
|
||||
password: "$argon2id$..." # Generate with authelia crypto hash generate argon2
|
||||
email: newuser@example.com
|
||||
groups:
|
||||
- users
|
||||
```
|
||||
|
||||
**Password Hashing:**
|
||||
```bash
|
||||
# Generate Argon2id hash
|
||||
docker run authelia/authelia:latest authelia crypto hash generate argon2 --password 'mypassword'
|
||||
```
|
||||
|
||||
**Group Management:**
|
||||
```yaml
|
||||
# Define groups
|
||||
groups:
|
||||
admins:
|
||||
- admin
|
||||
users:
|
||||
- user1
|
||||
- user2
|
||||
media:
|
||||
- family
|
||||
```
|
||||
|
||||
===== Access Control Policies =====
|
||||
|
||||
**Policy Types:**
|
||||
* **deny**: Block all access
|
||||
* **one_factor**: Username + password only
|
||||
* **two_factor**: Username + password + 2FA
|
||||
* **bypass**: No authentication required
|
||||
|
||||
**Rule Structure:**
|
||||
```yaml
|
||||
rules:
|
||||
- domain: "*.yourdomain.duckdns.org"
|
||||
policy: two_factor
|
||||
subject:
|
||||
- "user:admin"
|
||||
- "group:admins"
|
||||
resources:
|
||||
- "^/api/.*" # API endpoints
|
||||
```
|
||||
|
||||
**Advanced Rules:**
|
||||
```yaml
|
||||
# Time-based access
|
||||
- domain: "*.yourdomain.duckdns.org"
|
||||
policy: two_factor
|
||||
subject: "group:admins"
|
||||
rules:
|
||||
- operator: present
|
||||
operand: http_request.header.Authorization
|
||||
|
||||
# IP-based restrictions
|
||||
- domain: "admin.yourdomain.duckdns.org"
|
||||
policy: deny
|
||||
networks:
|
||||
- "192.168.1.0/24" # Allow only local network
|
||||
```
|
||||
|
||||
===== Two-Factor Authentication =====
|
||||
|
||||
**TOTP Setup:**
|
||||
1. Access Authelia dashboard
|
||||
2. Go to **Settings** → **One-Time Password**
|
||||
3. Install authenticator app (Google Authenticator, Authy, etc.)
|
||||
4. Scan QR code or enter secret manually
|
||||
5. Enter verification code to enable
|
||||
|
||||
**WebAuthn (Hardware Keys):**
|
||||
* **Supported**: YubiKey, Google Titan, etc.
|
||||
* **Protocol**: FIDO2/WebAuthn
|
||||
* **Benefits**: Phishing-resistant, no shared secrets
|
||||
|
||||
**Backup Codes:**
|
||||
* Generate one-time use codes
|
||||
* Store securely (encrypted password manager)
|
||||
* Use only for emergency access
|
||||
|
||||
===== Integration with Traefik =====
|
||||
|
||||
**ForwardAuth Middleware:**
|
||||
```yaml
|
||||
# In Traefik dynamic configuration
|
||||
middlewares:
|
||||
authelia:
|
||||
forwardAuth:
|
||||
address: "http://authelia:9091/api/verify?rd=https://auth.yourdomain.duckdns.org/"
|
||||
trustForwardHeader: true
|
||||
authResponseHeaders:
|
||||
- "Remote-User"
|
||||
- "Remote-Groups"
|
||||
- "Remote-Name"
|
||||
- "Remote-Email"
|
||||
```
|
||||
|
||||
**Service Protection:**
|
||||
```yaml
|
||||
# Add to service labels
|
||||
labels:
|
||||
- "traefik.http.routers.service.middlewares=authelia@docker"
|
||||
```
|
||||
|
||||
**Bypass Configuration:**
|
||||
```yaml
|
||||
# In Authelia configuration.yml
|
||||
access_control:
|
||||
rules:
|
||||
- domain: "jellyfin.yourdomain.duckdns.org"
|
||||
policy: bypass
|
||||
- domain: "plex.yourdomain.duckdns.org"
|
||||
policy: bypass
|
||||
```
|
||||
|
||||
===== Session Management =====
|
||||
|
||||
**Session Configuration:**
|
||||
```yaml
|
||||
session:
|
||||
name: authelia_session
|
||||
secret: ${AUTHELIA_SESSION_SECRET}
|
||||
expiration: 3600 # 1 hour
|
||||
inactivity: 300 # 5 minutes
|
||||
domain: yourdomain.duckdns.org
|
||||
same_site: lax
|
||||
secure: true
|
||||
http_only: true
|
||||
```
|
||||
|
||||
**Session Security:**
|
||||
* **Secure cookies**: HTTPS only
|
||||
* **HttpOnly**: JavaScript protection
|
||||
* **SameSite**: CSRF protection
|
||||
* **Expiration**: Automatic logout
|
||||
|
||||
===== Monitoring & Logging =====
|
||||
|
||||
**Log Configuration:**
|
||||
```yaml
|
||||
log:
|
||||
level: info # debug, info, warn, error
|
||||
format: json # json or text
|
||||
file: /config/authelia.log
|
||||
```
|
||||
|
||||
**Monitoring Integration:**
|
||||
* **Prometheus metrics**: `/metrics` endpoint
|
||||
* **Health checks**: `/api/health` endpoint
|
||||
* **Log aggregation**: Loki integration
|
||||
* **Alerting**: Failed authentication notifications
|
||||
|
||||
**Audit Logging:**
|
||||
* **Authentication events**: Login/logout tracking
|
||||
* **Authorization decisions**: Access control logging
|
||||
* **Security events**: Failed attempts, lockouts
|
||||
* **Compliance**: Audit trail for security reviews
|
||||
|
||||
===== Security Best Practices =====
|
||||
|
||||
**Password Policies:**
|
||||
* **Complexity**: Minimum 12 characters, mixed case, numbers, symbols
|
||||
* **Expiration**: Regular rotation (90-180 days)
|
||||
* **History**: Prevent password reuse
|
||||
* **Lockout**: Account lockout after failed attempts
|
||||
|
||||
**Session Security:**
|
||||
* **Short sessions**: 1 hour maximum
|
||||
* **Inactivity timeout**: 5-15 minutes
|
||||
* **Secure cookies**: All security flags enabled
|
||||
* **Token rotation**: Regular token refresh
|
||||
|
||||
**Network Security:**
|
||||
* **HTTPS only**: No HTTP access
|
||||
* **HSTS**: HTTP Strict Transport Security
|
||||
* **CSP**: Content Security Policy
|
||||
* **Rate limiting**: Brute force protection
|
||||
|
||||
===== Troubleshooting =====
|
||||
|
||||
**Login Issues:**
|
||||
```bash
|
||||
# Check Authelia logs
|
||||
docker logs authelia
|
||||
|
||||
# Verify configuration
|
||||
docker exec authelia authelia validate-config /config/configuration.yml
|
||||
|
||||
# Test authentication API
|
||||
curl -k https://auth.yourdomain.duckdns.org/api/state
|
||||
```
|
||||
|
||||
**2FA Problems:**
|
||||
* Check system time synchronization
|
||||
* Verify TOTP secret/code
|
||||
* Clear browser cache
|
||||
* Try different authenticator app
|
||||
|
||||
**Middleware Issues:**
|
||||
```bash
|
||||
# Check Traefik logs
|
||||
docker logs traefik | grep authelia
|
||||
|
||||
# Test middleware
|
||||
curl -H "Host: service.yourdomain.duckdns.org" http://localhost/
|
||||
```
|
||||
|
||||
**Configuration Errors:**
|
||||
* Validate YAML syntax
|
||||
* Check file permissions
|
||||
* Verify environment variables
|
||||
* Test configuration with `authelia validate-config`
|
||||
|
||||
===== Advanced Features =====
|
||||
|
||||
**LDAP Integration:**
|
||||
```yaml
|
||||
authentication_backend:
|
||||
ldap:
|
||||
url: ldap://127.0.0.1
|
||||
base_dn: dc=example,dc=com
|
||||
username_attribute: uid
|
||||
additional_users_dn: ou=users
|
||||
users_filter: (&({username_attribute}={input})(objectClass=person))
|
||||
groups_filter: (&(member={dn})(objectClass=groupOfNames))
|
||||
group_name_attribute: cn
|
||||
mail_attribute: mail
|
||||
display_name_attribute: displayName
|
||||
```
|
||||
|
||||
**SAML/OIDC Identity Providers:**
|
||||
```yaml
|
||||
identity_providers:
|
||||
oidc:
|
||||
# OIDC configuration
|
||||
saml:
|
||||
# SAML configuration
|
||||
```
|
||||
|
||||
**Custom Themes:**
|
||||
```yaml
|
||||
theme: dark # light, dark, grey, auto
|
||||
```
|
||||
|
||||
**API Integration:**
|
||||
* **REST API**: Programmatic authentication
|
||||
* **Webhooks**: Event notifications
|
||||
* **SCIM**: User provisioning
|
||||
* **GraphQL**: Advanced queries
|
||||
|
||||
===== Backup & Recovery =====
|
||||
|
||||
**Configuration Backup:**
|
||||
* **Files**: `configuration.yml`, `users_database.yml`
|
||||
* **Database**: `db.sqlite3`
|
||||
* **Secrets**: Environment variables
|
||||
|
||||
**Password Recovery:**
|
||||
* **Backup codes**: One-time use recovery
|
||||
* **Admin reset**: Administrative password reset
|
||||
* **Self-service**: Password reset via email
|
||||
|
||||
**Disaster Recovery:**
|
||||
* **Configuration restore**: YAML file recovery
|
||||
* **Database recovery**: SQLite backup restoration
|
||||
* **Secret rotation**: Emergency credential management
|
||||
|
||||
Authelia provides enterprise-grade authentication and authorization for your homelab, ensuring secure access to all your services.
|
||||
|
||||
**Next:** Learn about [[services:core:duckdns|DuckDNS]] or [[services:core:gluetun|Gluetun]].
|
||||
289
config-templates/dokuwiki/data/pages/services/core/duckdns.txt
Normal file
289
config-templates/dokuwiki/data/pages/services/core/duckdns.txt
Normal file
@@ -0,0 +1,289 @@
|
||||
====== DuckDNS ======
|
||||
|
||||
DuckDNS is a free dynamic DNS service that automatically updates your domain's IP address. In the AI-Homelab, DuckDNS provides the domain name that Traefik uses for SSL certificates and service routing.
|
||||
|
||||
===== Overview =====
|
||||
|
||||
**Purpose:** Dynamic DNS service
|
||||
**URL:** https://duckdns.org (external service)
|
||||
**Authentication:** Token-based
|
||||
**Deployment:** Automatic (core stack)
|
||||
**Update Interval:** Every 5 minutes
|
||||
|
||||
===== Key Features =====
|
||||
|
||||
**Dynamic DNS:**
|
||||
* **Free service**: No cost for basic usage
|
||||
* **Multiple domains**: Support for multiple subdomains
|
||||
* **API integration**: RESTful API for updates
|
||||
* **IPv4/IPv6**: Support for both IP versions
|
||||
|
||||
**SSL Integration:**
|
||||
* **Wildcard certificates**: *.yourdomain.duckdns.org
|
||||
* **Let's Encrypt**: Automatic certificate generation
|
||||
* **DNS challenge**: Domain ownership verification
|
||||
* **Certificate renewal**: Automatic 90-day renewal
|
||||
|
||||
**Reliability:**
|
||||
* **High uptime**: 99.9%+ availability
|
||||
* **Global CDN**: Fast DNS resolution worldwide
|
||||
* **Redundant servers**: Multiple DNS servers
|
||||
* **Monitoring**: Service status monitoring
|
||||
|
||||
===== Configuration =====
|
||||
|
||||
**DuckDNS Account Setup:**
|
||||
1. Visit https://duckdns.org
|
||||
2. Create free account
|
||||
3. Choose domain name (your subdomain)
|
||||
4. Get API token from account settings
|
||||
|
||||
**Environment Variables:**
|
||||
```bash
|
||||
# Required
|
||||
DOMAIN=yourdomain.duckdns.org
|
||||
DUCKDNS_TOKEN=your-api-token
|
||||
|
||||
# Optional
|
||||
DUCKDNS_SUBDOMAINS=subdomain1,subdomain2
|
||||
```
|
||||
|
||||
**Container Configuration:**
|
||||
```yaml
|
||||
services:
|
||||
duckdns:
|
||||
image: lscr.io/linuxserver/duckdns:latest
|
||||
container_name: duckdns
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
- SUBDOMAINS=${DUCKDNS_SUBDOMAINS:-yourdomain}
|
||||
- TOKEN=${DUCKDNS_TOKEN}
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.1'
|
||||
memory: 64M
|
||||
reservations:
|
||||
cpus: '0.01'
|
||||
memory: 16M
|
||||
```
|
||||
|
||||
===== How It Works =====
|
||||
|
||||
**DNS Update Process:**
|
||||
1. **IP Detection**: Container detects current public IP
|
||||
2. **API Call**: Sends update request to DuckDNS API
|
||||
3. **DNS Update**: DuckDNS updates DNS records
|
||||
4. **Propagation**: DNS changes propagate globally
|
||||
5. **Verification**: Container verifies update success
|
||||
|
||||
**Update Frequency:**
|
||||
* **Interval**: Every 5 minutes
|
||||
* **Trigger**: Container startup + periodic updates
|
||||
* **Condition**: IP address change detected
|
||||
* **Logging**: Update success/failure logging
|
||||
|
||||
**API Integration:**
|
||||
```bash
|
||||
# Manual update (for testing)
|
||||
curl "https://www.duckdns.org/update?domains=yourdomain&token=your-token&ip="
|
||||
|
||||
# Check current IP
|
||||
curl "https://www.duckdns.org/update?domains=yourdomain&token=your-token&verbose=1"
|
||||
```
|
||||
|
||||
===== SSL Certificate Integration =====
|
||||
|
||||
**Traefik Configuration:**
|
||||
```yaml
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
email: your-email@example.com
|
||||
storage: /acme.json
|
||||
dnsChallenge:
|
||||
provider: duckdns
|
||||
delayBeforeCheck: 30
|
||||
```
|
||||
|
||||
**Certificate Generation:**
|
||||
* **Challenge Type**: DNS-01
|
||||
* **Record**: `_acme-challenge.yourdomain.duckdns.org`
|
||||
* **Value**: Generated by Let's Encrypt
|
||||
* **TTL**: 60 seconds (temporary)
|
||||
|
||||
**Wildcard Certificate:**
|
||||
* **Domain**: `*.yourdomain.duckdns.org`
|
||||
* **Coverage**: All subdomains automatically
|
||||
* **Type**: ECDSA P-256
|
||||
* **Validity**: 90 days
|
||||
* **Renewal**: Automatic (30 days before expiry)
|
||||
|
||||
===== Monitoring & Troubleshooting =====
|
||||
|
||||
**Container Logs:**
|
||||
```bash
|
||||
# View DuckDNS logs
|
||||
docker logs duckdns
|
||||
|
||||
# Follow logs in real-time
|
||||
docker logs -f duckdns
|
||||
```
|
||||
|
||||
**DNS Verification:**
|
||||
```bash
|
||||
# Check DNS resolution
|
||||
nslookup yourdomain.duckdns.org
|
||||
|
||||
# Check TXT record (during certificate generation)
|
||||
dig TXT _acme-challenge.yourdomain.duckdns.org
|
||||
|
||||
# Verify IP address
|
||||
curl -s https://api.ipify.org
|
||||
```
|
||||
|
||||
**Common Issues:**
|
||||
|
||||
**DNS Not Updating:**
|
||||
```bash
|
||||
# Check token validity
|
||||
curl "https://www.duckdns.org/update?domains=yourdomain&token=wrong-token"
|
||||
|
||||
# Verify internet connectivity
|
||||
ping -c 4 8.8.8.8
|
||||
|
||||
# Check container status
|
||||
docker ps | grep duckdns
|
||||
```
|
||||
|
||||
**SSL Certificate Issues:**
|
||||
* **Rate Limiting**: Let's Encrypt limits (20 certificates/week)
|
||||
* **DNS Propagation**: Wait 5-10 minutes after DNS update
|
||||
* **Token Issues**: Verify DuckDNS token is correct
|
||||
* **Port Forwarding**: Ensure 80/443 are forwarded
|
||||
|
||||
**Troubleshooting Steps:**
|
||||
1. **Check logs**: `docker logs duckdns`
|
||||
2. **Verify token**: Test API manually
|
||||
3. **Check IP**: Confirm current public IP
|
||||
4. **Test DNS**: Verify domain resolution
|
||||
5. **Restart container**: `docker restart duckdns`
|
||||
|
||||
===== Advanced Configuration =====
|
||||
|
||||
**Multiple Subdomains:**
|
||||
```bash
|
||||
# Environment variable
|
||||
DUCKDNS_SUBDOMAINS=sub1,sub2,sub3
|
||||
|
||||
# Or in compose
|
||||
environment:
|
||||
- SUBDOMAINS=sub1,sub2,sub3
|
||||
```
|
||||
|
||||
**IPv6 Support:**
|
||||
```bash
|
||||
# Enable IPv6 updates
|
||||
environment:
|
||||
- IPV6=1
|
||||
```
|
||||
|
||||
**Custom Update Interval:**
|
||||
```bash
|
||||
# Modify container command
|
||||
command: sh -c "while true; do /app/duckdns.sh; sleep 300; done"
|
||||
# 300 seconds = 5 minutes (default)
|
||||
```
|
||||
|
||||
===== Security Considerations =====
|
||||
|
||||
**Token Security:**
|
||||
* **Storage**: Environment variables (not in code)
|
||||
* **Access**: Limited to DuckDNS container only
|
||||
* **Rotation**: Regular token renewal
|
||||
* **Monitoring**: API usage monitoring
|
||||
|
||||
**DNS Security:**
|
||||
* **DNSSEC**: Not supported by DuckDNS
|
||||
* **Rate Limiting**: API call restrictions
|
||||
* **Monitoring**: DNS query logging
|
||||
* **Backup**: Secondary DNS provider consideration
|
||||
|
||||
===== Performance & Reliability =====
|
||||
|
||||
**Update Efficiency:**
|
||||
* **Conditional Updates**: Only when IP changes
|
||||
* **Fast API**: Quick response times
|
||||
* **Error Handling**: Retry logic for failures
|
||||
* **Logging**: Comprehensive update logging
|
||||
|
||||
**Global Distribution:**
|
||||
* **Anycast**: Multiple global DNS servers
|
||||
* **CDN**: Fast resolution worldwide
|
||||
* **Caching**: DNS record caching
|
||||
* **Redundancy**: Multiple server locations
|
||||
|
||||
===== Alternative DNS Providers =====
|
||||
|
||||
**If DuckDNS is insufficient:**
|
||||
|
||||
**Cloudflare:**
|
||||
* **Free tier**: 100,000 DNS queries/month
|
||||
* **API**: Full DNS management
|
||||
* **DNSSEC**: Supported
|
||||
* **Analytics**: Query statistics
|
||||
|
||||
**No-IP:**
|
||||
* **Free tier**: 30-day renewal requirement
|
||||
* **Multiple hosts**: Up to 3 free domains
|
||||
* **Client software**: Windows/Mac/Linux clients
|
||||
* **Groups**: Domain grouping
|
||||
|
||||
**Dynu:**
|
||||
* **Free tier**: 1 domain, 30-day renewal
|
||||
* **API**: RESTful API
|
||||
* **IPv6**: Supported
|
||||
* **Analytics**: Basic statistics
|
||||
|
||||
===== Migration Guide =====
|
||||
|
||||
**Switching DNS Providers:**
|
||||
1. **Register**: Create account with new provider
|
||||
2. **Configure**: Set up domain and get API token
|
||||
3. **Update**: Modify environment variables
|
||||
4. **Test**: Verify DNS resolution
|
||||
5. **SSL**: Update Traefik certificate resolver
|
||||
6. **Cleanup**: Remove old DuckDNS container
|
||||
|
||||
**Certificate Migration:**
|
||||
* **Backup**: Save acme.json file
|
||||
* **Update**: Change DNS provider in Traefik
|
||||
* **Renew**: Force certificate renewal
|
||||
* **Verify**: Test SSL certificate validity
|
||||
|
||||
===== Best Practices =====
|
||||
|
||||
**Domain Management:**
|
||||
* **Choose wisely**: Select available, memorable domain
|
||||
* **Documentation**: Record domain and token securely
|
||||
* **Backup**: Include DNS settings in backup
|
||||
* **Monitoring**: Monitor domain expiration
|
||||
|
||||
**SSL Management:**
|
||||
* **Wildcard**: Use for all subdomains
|
||||
* **Backup**: Regular acme.json backups
|
||||
* **Monitoring**: Certificate expiry alerts
|
||||
* **Testing**: Regular SSL validation
|
||||
|
||||
**Reliability:**
|
||||
* **Redundancy**: Consider secondary DNS
|
||||
* **Monitoring**: DNS and SSL health checks
|
||||
* **Updates**: Keep container updated
|
||||
* **Logging**: Monitor update success
|
||||
|
||||
DuckDNS provides the foundation for your homelab's domain name and SSL certificates, ensuring secure and reliable access to all your services.
|
||||
|
||||
**Next:** Learn about [[services:core:gluetun|Gluetun]] or explore [[architecture:networking|Network Architecture]].
|
||||
404
config-templates/dokuwiki/data/pages/services/core/gluetun.txt
Normal file
404
config-templates/dokuwiki/data/pages/services/core/gluetun.txt
Normal file
@@ -0,0 +1,404 @@
|
||||
====== Gluetun ======
|
||||
|
||||
Gluetun is a VPN client container that routes download services through VPN providers like Surfshark, NordVPN, or Mullvad. It provides network-level VPN protection for torrent clients and other download services.
|
||||
|
||||
===== Overview =====
|
||||
|
||||
**Purpose:** VPN client for download services
|
||||
**Supported VPNs:** Surfshark, NordVPN, Mullvad, ExpressVPN, ProtonVPN, and 20+ others
|
||||
**Network Mode:** Service-based routing
|
||||
**Deployment:** Core stack (always running)
|
||||
**Resource Usage:** Low (minimal CPU/memory)
|
||||
|
||||
===== Key Features =====
|
||||
|
||||
**VPN Providers:**
|
||||
* **Surfshark**: Primary recommended provider
|
||||
* **WireGuard/OpenVPN**: Multiple protocol support
|
||||
* **Port Forwarding**: Automatic port forwarding
|
||||
* **Kill Switch**: Network isolation when VPN fails
|
||||
|
||||
**Network Routing:**
|
||||
* **Service Mode**: `network_mode: "service:gluetun"`
|
||||
* **Port Mapping**: VPN ports mapped to host
|
||||
* **DNS**: VPN provider DNS servers
|
||||
* **Firewall**: Built-in firewall rules
|
||||
|
||||
**Security Features:**
|
||||
* **IP Leak Protection**: Prevents IP exposure
|
||||
* **DNS Leak Protection**: VPN DNS enforcement
|
||||
* **Kill Switch**: Automatic connection blocking
|
||||
* **Protocol Selection**: WireGuard/OpenVPN choice
|
||||
|
||||
===== Configuration =====
|
||||
|
||||
**Environment Variables:**
|
||||
```bash
|
||||
# VPN Provider (Surfshark recommended)
|
||||
VPN_SERVICE_PROVIDER=surfshark
|
||||
VPN_TYPE=wireguard
|
||||
|
||||
# Credentials
|
||||
VPN_USERNAME=your-username
|
||||
VPN_PASSWORD=your-password
|
||||
|
||||
# Optional: Specific server/country
|
||||
SERVER_COUNTRIES=Netherlands
|
||||
SERVER_CITIES=Amsterdam
|
||||
|
||||
# Optional: WireGuard specific
|
||||
WIREGUARD_PRIVATE_KEY=your-private-key
|
||||
WIREGUARD_ADDRESSES=10.0.0.0/8
|
||||
```
|
||||
|
||||
**Container Configuration:**
|
||||
```yaml
|
||||
services:
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun:latest
|
||||
container_name: gluetun
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
environment:
|
||||
- VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER}
|
||||
- VPN_TYPE=${VPN_TYPE}
|
||||
- VPN_USERNAME=${VPN_USERNAME}
|
||||
- VPN_PASSWORD=${VPN_PASSWORD}
|
||||
- SERVER_COUNTRIES=${SERVER_COUNTRIES:-Netherlands}
|
||||
volumes:
|
||||
- ./gluetun/config:/config
|
||||
ports:
|
||||
- 8080:8080 # qBittorrent WebUI
|
||||
- 6881:6881 # qBittorrent TCP
|
||||
- 6881:6881/udp # qBittorrent UDP
|
||||
networks:
|
||||
- traefik-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 256M
|
||||
reservations:
|
||||
cpus: '0.1'
|
||||
memory: 64M
|
||||
```
|
||||
|
||||
===== How VPN Routing Works =====
|
||||
|
||||
**Service-Based Routing:**
|
||||
```yaml
|
||||
# Download service configuration
|
||||
services:
|
||||
qbittorrent:
|
||||
image: lscr.io/linuxserver/qbittorrent:latest
|
||||
network_mode: "service:gluetun" # Routes through VPN
|
||||
depends_on:
|
||||
- gluetun
|
||||
volumes:
|
||||
- ./qbittorrent/config:/config
|
||||
- /mnt/downloads:/downloads
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
# No ports exposed - accessed via Gluetun
|
||||
```
|
||||
|
||||
**Network Flow:**
|
||||
1. **Gluetun Container**: Establishes VPN connection
|
||||
2. **Service Mode**: Download service shares Gluetun's network stack
|
||||
3. **VPN Routing**: All traffic from download service goes through VPN
|
||||
4. **Port Mapping**: VPN ports mapped to Gluetun container ports
|
||||
5. **Access**: Services access download client via Gluetun's IP/port
|
||||
|
||||
===== VPN Provider Setup =====
|
||||
|
||||
**Surfshark (Recommended):**
|
||||
1. **Sign up**: https://surfshark.com
|
||||
2. **Get credentials**: Username/password from account
|
||||
3. **WireGuard**: Generate private key (optional, faster)
|
||||
4. **Configure**: Use in environment variables
|
||||
|
||||
**WireGuard Setup (Optional but Recommended):**
|
||||
```bash
|
||||
# Generate private key
|
||||
wg genkey
|
||||
|
||||
# Or use Surfshark app to get key
|
||||
# Account -> Manual Setup -> WireGuard
|
||||
```
|
||||
|
||||
**Other Providers:**
|
||||
```yaml
|
||||
# NordVPN
|
||||
VPN_SERVICE_PROVIDER=nordvpn
|
||||
VPN_TYPE=openvpn
|
||||
|
||||
# Mullvad
|
||||
VPN_SERVICE_PROVIDER=mullvad
|
||||
VPN_TYPE=wireguard
|
||||
|
||||
# ExpressVPN
|
||||
VPN_SERVICE_PROVIDER=expressvpn
|
||||
VPN_TYPE=openvpn
|
||||
```
|
||||
|
||||
===== Port Management =====
|
||||
|
||||
**Port Forwarding:**
|
||||
```yaml
|
||||
# Gluetun ports (map download service ports)
|
||||
ports:
|
||||
- 8080:8080 # WebUI
|
||||
- 6881:6881 # TCP torrent port
|
||||
- 6881:6881/udp # UDP torrent port
|
||||
- 51413:51413 # Alternative torrent port
|
||||
- 51413:51413/udp
|
||||
```
|
||||
|
||||
**Dynamic Port Forwarding:**
|
||||
* **Automatic**: Some providers support automatic port forwarding
|
||||
* **Manual**: Configure specific ports in VPN provider
|
||||
* **Testing**: Verify port forwarding with online tools
|
||||
|
||||
**Port Forwarding Check:**
|
||||
```bash
|
||||
# Check if port is open
|
||||
curl -s "https://portchecker.co/check" --data "port=6881"
|
||||
|
||||
# Or use online port checker
|
||||
# Visit: https://www.yougetsignal.com/tools/open-ports/
|
||||
```
|
||||
|
||||
===== Monitoring & Troubleshooting =====
|
||||
|
||||
**Container Logs:**
|
||||
```bash
|
||||
# View Gluetun logs
|
||||
docker logs gluetun
|
||||
|
||||
# Follow logs in real-time
|
||||
docker logs -f gluetun
|
||||
```
|
||||
|
||||
**VPN Status Check:**
|
||||
```bash
|
||||
# Check VPN connection
|
||||
docker exec gluetun sh -c "curl -s ifconfig.me"
|
||||
|
||||
# Verify VPN IP (should be different from your real IP)
|
||||
docker exec gluetun sh -c "curl -s https://api.ipify.org"
|
||||
```
|
||||
|
||||
**Kill Switch Testing:**
|
||||
```bash
|
||||
# Test kill switch (disconnect VPN)
|
||||
docker exec gluetun sh -c "iptables -P OUTPUT DROP"
|
||||
|
||||
# Restore (reconnect VPN)
|
||||
docker restart gluetun
|
||||
```
|
||||
|
||||
**Common Issues:**
|
||||
|
||||
**VPN Connection Failed:**
|
||||
```bash
|
||||
# Check credentials
|
||||
docker logs gluetun | grep -i "auth\|login\|password"
|
||||
|
||||
# Verify server selection
|
||||
docker logs gluetun | grep -i "server\|country"
|
||||
|
||||
# Test VPN provider status
|
||||
# Visit provider status page
|
||||
```
|
||||
|
||||
**DNS Leaks:**
|
||||
```bash
|
||||
# Check DNS servers
|
||||
docker exec gluetun sh -c "cat /etc/resolv.conf"
|
||||
|
||||
# Test DNS leak
|
||||
# Visit: https://www.dnsleaktest.com
|
||||
```
|
||||
|
||||
**Port Forwarding Issues:**
|
||||
* **Provider Support**: Not all VPNs support port forwarding
|
||||
* **Server Selection**: Choose servers that support port forwarding
|
||||
* **Configuration**: Enable port forwarding in VPN account
|
||||
* **Testing**: Use port checking tools
|
||||
|
||||
**Troubleshooting Steps:**
|
||||
1. **Check logs**: `docker logs gluetun`
|
||||
2. **Verify credentials**: Test with VPN provider app
|
||||
3. **Test connection**: Manual VPN connection
|
||||
4. **Check ports**: Verify port forwarding
|
||||
5. **Restart**: `docker restart gluetun`
|
||||
|
||||
===== Security Considerations =====
|
||||
|
||||
**Kill Switch Protection:**
|
||||
* **Automatic**: Blocks all traffic if VPN disconnects
|
||||
* **Testing**: Regularly test kill switch functionality
|
||||
* **Monitoring**: Monitor VPN connection status
|
||||
* **Alerts**: Set up notifications for VPN failures
|
||||
|
||||
**IP Leak Prevention:**
|
||||
* **WebRTC**: Disable WebRTC in browsers
|
||||
* **IPv6**: Disable IPv6 if not needed
|
||||
* **DNS**: Use VPN DNS servers only
|
||||
* **Testing**: Regular leak testing
|
||||
|
||||
**Credential Security:**
|
||||
* **Storage**: Environment variables (not in code)
|
||||
* **Access**: Limited to Gluetun container
|
||||
* **Rotation**: Regular password changes
|
||||
* **2FA**: Enable 2FA on VPN account
|
||||
|
||||
===== Performance Optimization =====
|
||||
|
||||
**Protocol Selection:**
|
||||
* **WireGuard**: Faster, more secure (recommended)
|
||||
* **OpenVPN**: More compatible, slightly slower
|
||||
* **IKEv2**: Mobile-optimized
|
||||
|
||||
**Server Selection:**
|
||||
* **Location**: Choose closest servers
|
||||
* **Load**: Select less crowded servers
|
||||
* **Features**: Port forwarding capable servers
|
||||
* **Testing**: Test different server locations
|
||||
|
||||
**Resource Limits:**
|
||||
```yaml
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5' # Low CPU usage
|
||||
memory: 256M # Minimal memory
|
||||
reservations:
|
||||
cpus: '0.1'
|
||||
memory: 64M
|
||||
```
|
||||
|
||||
===== Advanced Configuration =====
|
||||
|
||||
**Custom VPN Configuration:**
|
||||
```yaml
|
||||
# Custom OpenVPN config
|
||||
volumes:
|
||||
- ./gluetun/config:/config
|
||||
- ./custom-config:/custom
|
||||
|
||||
environment:
|
||||
- VPN_TYPE=openvpn
|
||||
- OPENVPN_CUSTOM_CONFIG=/custom/my-config.ovpn
|
||||
```
|
||||
|
||||
**Multiple VPN Services:**
|
||||
```yaml
|
||||
# Separate Gluetun instances for different services
|
||||
services:
|
||||
gluetun-us:
|
||||
# US-based VPN
|
||||
environment:
|
||||
- SERVER_COUNTRIES=United States
|
||||
|
||||
gluetun-nl:
|
||||
# Netherlands-based VPN
|
||||
environment:
|
||||
- SERVER_COUNTRIES=Netherlands
|
||||
```
|
||||
|
||||
**Health Checks:**
|
||||
```yaml
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "https://api.ipify.org"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
===== Integration with Download Services =====
|
||||
|
||||
**qBittorrent Configuration:**
|
||||
```yaml
|
||||
# In qbittorrent config
|
||||
# Network settings
|
||||
Connection Limits:
|
||||
Global max number of upload slots: 20
|
||||
Max number of upload slots per torrent: 5
|
||||
|
||||
# BitTorrent settings
|
||||
Enable DHT: Yes
|
||||
Enable PeX: Yes
|
||||
Enable LSD: Yes
|
||||
|
||||
# WebUI settings
|
||||
IP Address: 0.0.0.0
|
||||
Port: 8080
|
||||
```
|
||||
|
||||
**Transmission Configuration:**
|
||||
```yaml
|
||||
# transmission-daemon settings.json
|
||||
{
|
||||
"rpc-port": 9091,
|
||||
"rpc-username": "admin",
|
||||
"rpc-password": "password",
|
||||
"rpc-whitelist-enabled": false,
|
||||
"download-dir": "/downloads",
|
||||
"incomplete-dir": "/downloads/incomplete"
|
||||
}
|
||||
```
|
||||
|
||||
===== Backup & Recovery =====
|
||||
|
||||
**Configuration Backup:**
|
||||
```bash
|
||||
# Backup Gluetun config
|
||||
docker run --rm \
|
||||
-v gluetun-config:/config \
|
||||
-v $(pwd)/backup:/backup \
|
||||
busybox tar czf /backup/gluetun-config.tar.gz /config
|
||||
```
|
||||
|
||||
**VPN Credential Rotation:**
|
||||
1. **Generate new credentials** in VPN provider
|
||||
2. **Update environment variables** in .env
|
||||
3. **Restart Gluetun**: `docker restart gluetun`
|
||||
4. **Verify connection**: Check logs and IP
|
||||
5. **Test downloads**: Verify torrent functionality
|
||||
|
||||
===== Best Practices =====
|
||||
|
||||
**VPN Selection:**
|
||||
* **Reliability**: Choose reputable providers
|
||||
* **Speed**: Test connection speeds
|
||||
* **Features**: Port forwarding, kill switch
|
||||
* **Privacy**: No-logs policy
|
||||
* **Cost**: Balance features vs price
|
||||
|
||||
**Security:**
|
||||
* **Kill Switch**: Always enabled
|
||||
* **Regular Testing**: Monthly leak tests
|
||||
* **Updates**: Keep Gluetun updated
|
||||
* **Monitoring**: VPN status monitoring
|
||||
|
||||
**Performance:**
|
||||
* **WireGuard**: Prefer over OpenVPN
|
||||
* **Server Location**: Closest available
|
||||
* **Load Balancing**: Distribute across servers
|
||||
* **Monitoring**: Track connection quality
|
||||
|
||||
**Maintenance:**
|
||||
* **Credential Rotation**: Regular password changes
|
||||
* **Log Review**: Monitor connection logs
|
||||
* **Update Checks**: Keep VPN client updated
|
||||
* **Backup**: Regular configuration backups
|
||||
|
||||
Gluetun provides essential VPN protection for download services, ensuring your torrenting and file sharing activities remain private and secure.
|
||||
|
||||
**Next:** Learn about [[services:core:sablier|Sablier]] or explore [[architecture:security|Security Architecture]].
|
||||
401
config-templates/dokuwiki/data/pages/services/core/sablier.txt
Normal file
401
config-templates/dokuwiki/data/pages/services/core/sablier.txt
Normal file
@@ -0,0 +1,401 @@
|
||||
====== Sablier ======
|
||||
|
||||
Sablier is a lazy loading service that starts Docker containers on-demand when accessed, then automatically stops them after a period of inactivity. This saves system resources by keeping unused services stopped until needed.
|
||||
|
||||
===== Overview =====
|
||||
|
||||
**Purpose:** On-demand container startup
|
||||
**Integration:** Traefik middleware
|
||||
**Resource Savings:** Significant CPU/memory reduction
|
||||
**Deployment:** Core stack (always running)
|
||||
**Configuration:** Label-based activation
|
||||
|
||||
===== Key Features =====
|
||||
|
||||
**Lazy Loading:**
|
||||
* **On-Demand Startup**: Containers start when accessed
|
||||
* **Automatic Shutdown**: Stop after inactivity timeout
|
||||
* **Resource Efficiency**: Save CPU/memory when not used
|
||||
* **Transparent**: No user experience changes
|
||||
|
||||
**Integration:**
|
||||
* **Traefik Middleware**: HTTP request triggering
|
||||
* **Label Configuration**: Simple Docker labels
|
||||
* **Group Management**: Related services as groups
|
||||
* **Health Checks**: Wait for service readiness
|
||||
|
||||
**Performance:**
|
||||
* **Fast Startup**: Quick container initialization
|
||||
* **Timeout Control**: Configurable inactivity periods
|
||||
* **Queue Management**: Handle multiple concurrent requests
|
||||
* **Monitoring**: Startup/shutdown tracking
|
||||
|
||||
===== Configuration =====
|
||||
|
||||
**Container Configuration:**
|
||||
```yaml
|
||||
services:
|
||||
sablier:
|
||||
image: acouvreur/sablier:latest
|
||||
container_name: sablier
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- SABLIER_STRATEGY=docker-api
|
||||
- SABLIER_DOCKER_API_VERSION=1.41
|
||||
- SABLIER_DOCKER_NETWORK=traefik-network
|
||||
- SABLIER_TIMEOUT=5m
|
||||
- SABLIER_SESSION_DURATION=168h
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
networks:
|
||||
- traefik-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.2'
|
||||
memory: 128M
|
||||
reservations:
|
||||
cpus: '0.05'
|
||||
memory: 32M
|
||||
```
|
||||
|
||||
**Service Integration Labels:**
|
||||
```yaml
|
||||
# Enable Sablier for a service
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=my-service-group"
|
||||
- "sablier.start-on-demand=true"
|
||||
- "sablier.timeout=5m" # Optional: per-service timeout
|
||||
```
|
||||
|
||||
===== How Lazy Loading Works =====
|
||||
|
||||
**Request Flow:**
|
||||
1. **HTTP Request**: User accesses service URL
|
||||
2. **Traefik Routing**: Request hits Traefik with Sablier middleware
|
||||
3. **Sablier Check**: Sablier checks if target service is running
|
||||
4. **Container Start**: If stopped, Sablier starts the container
|
||||
5. **Health Wait**: Waits for service to be ready
|
||||
6. **Request Forward**: Forwards request to running service
|
||||
7. **Timeout Reset**: Resets inactivity timer
|
||||
|
||||
**Automatic Shutdown:**
|
||||
* **Inactivity Detection**: No requests for timeout period
|
||||
* **Graceful Shutdown**: Container stopped cleanly
|
||||
* **Resource Recovery**: CPU/memory freed up
|
||||
* **Restart Ready**: Ready for next access
|
||||
|
||||
===== Service Configuration =====
|
||||
|
||||
**Basic Setup:**
|
||||
```yaml
|
||||
services:
|
||||
my-service:
|
||||
image: my-service:latest
|
||||
labels:
|
||||
# Traefik labels (normal)
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.my-service.rule=Host(`my-service.${DOMAIN}`)"
|
||||
- "traefik.http.routers.my-service.entrypoints=websecure"
|
||||
- "traefik.http.routers.my-service.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.my-service.middlewares=authelia@docker"
|
||||
|
||||
# Sablier labels (lazy loading)
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=my-service"
|
||||
- "sablier.start-on-demand=true"
|
||||
```
|
||||
|
||||
**Advanced Configuration:**
|
||||
```yaml
|
||||
labels:
|
||||
# Custom timeout (overrides global)
|
||||
- "sablier.timeout=10m"
|
||||
|
||||
# Custom session duration
|
||||
- "sablier.session-duration=24h"
|
||||
|
||||
# Group multiple services
|
||||
- "sablier.group=media-stack"
|
||||
```
|
||||
|
||||
===== Timeout Management =====
|
||||
|
||||
**Global Timeout:**
|
||||
```yaml
|
||||
environment:
|
||||
- SABLIER_TIMEOUT=5m # Default 5 minutes
|
||||
```
|
||||
|
||||
**Per-Service Timeout:**
|
||||
```yaml
|
||||
labels:
|
||||
- "sablier.timeout=15m" # Override for this service
|
||||
```
|
||||
|
||||
**Session Duration:**
|
||||
```yaml
|
||||
environment:
|
||||
- SABLIER_SESSION_DURATION=168h # 7 days default
|
||||
```
|
||||
|
||||
**Timeout Behavior:**
|
||||
* **Activity Reset**: Each request resets the timer
|
||||
* **Graceful Shutdown**: Clean container stop
|
||||
* **Resource Recovery**: Memory/CPU freed
|
||||
* **Quick Restart**: Fast startup on next access
|
||||
|
||||
===== Group Management =====
|
||||
|
||||
**Service Groups:**
|
||||
```yaml
|
||||
# Related services in same group
|
||||
services:
|
||||
sonarr:
|
||||
labels:
|
||||
- "sablier.group=media-management"
|
||||
|
||||
radarr:
|
||||
labels:
|
||||
- "sablier.group=media-management"
|
||||
|
||||
prowlarr:
|
||||
labels:
|
||||
- "sablier.group=media-management"
|
||||
```
|
||||
|
||||
**Group Benefits:**
|
||||
* **Coordinated Startup**: Start related services together
|
||||
* **Shared Timeout**: Group timeout applies to all
|
||||
* **Resource Management**: Better resource planning
|
||||
* **Dependency Handling**: Handle service dependencies
|
||||
|
||||
===== Monitoring & Troubleshooting =====
|
||||
|
||||
**Sablier Logs:**
|
||||
```bash
|
||||
# View Sablier logs
|
||||
docker logs sablier
|
||||
|
||||
# Follow logs in real-time
|
||||
docker logs -f sablier
|
||||
```
|
||||
|
||||
**Startup Monitoring:**
|
||||
```bash
|
||||
# Check service startup
|
||||
docker logs sablier | grep "Starting container"
|
||||
|
||||
# Monitor shutdowns
|
||||
docker logs sablier | grep "Stopping container"
|
||||
```
|
||||
|
||||
**Debug Mode:**
|
||||
```yaml
|
||||
environment:
|
||||
- SABLIER_LOG_LEVEL=debug
|
||||
```
|
||||
|
||||
**Common Issues:**
|
||||
|
||||
**Service Not Starting:**
|
||||
```bash
|
||||
# Check Sablier logs
|
||||
docker logs sablier | grep -i "error\|failed"
|
||||
|
||||
# Verify Docker socket access
|
||||
docker exec sablier ls -la /var/run/docker.sock
|
||||
|
||||
# Check network connectivity
|
||||
docker exec sablier ping -c 2 traefik
|
||||
```
|
||||
|
||||
**Timeout Issues:**
|
||||
* **Too Short**: Services stopping too quickly
|
||||
* **Too Long**: Resources not freed timely
|
||||
* **Per-Service**: Override global timeout
|
||||
* **Testing**: Monitor actual usage patterns
|
||||
|
||||
**Middleware Issues:**
|
||||
* **Traefik Config**: Verify middleware order
|
||||
* **Label Format**: Check label syntax
|
||||
* **Network Access**: Ensure Sablier can reach Docker API
|
||||
|
||||
**Troubleshooting Steps:**
|
||||
1. **Check logs**: `docker logs sablier`
|
||||
2. **Verify labels**: Check service configuration
|
||||
3. **Test startup**: Manual container start
|
||||
4. **Check network**: Verify Docker API access
|
||||
5. **Restart Sablier**: `docker restart sablier`
|
||||
|
||||
===== Performance Optimization =====
|
||||
|
||||
**Resource Limits:**
|
||||
```yaml
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.2' # Low CPU usage
|
||||
memory: 128M # Minimal memory
|
||||
reservations:
|
||||
cpus: '0.05'
|
||||
memory: 32M
|
||||
```
|
||||
|
||||
**Timeout Tuning:**
|
||||
* **Frequent Access**: Longer timeouts (15-30m)
|
||||
* **Infrequent Access**: Shorter timeouts (2-5m)
|
||||
* **Resource Intensive**: Consider manual management
|
||||
* **User Patterns**: Monitor and adjust based on usage
|
||||
|
||||
**Startup Optimization:**
|
||||
* **Health Checks**: Fast health check endpoints
|
||||
* **Dependencies**: Minimize startup dependencies
|
||||
* **Caching**: Use persistent volumes for data
|
||||
* **Pre-warming**: Keep critical services running
|
||||
|
||||
===== Security Considerations =====
|
||||
|
||||
**Docker Socket Access:**
|
||||
* **Read-Only**: Mount socket as read-only
|
||||
* **Limited Access**: Only Sablier container access
|
||||
* **Network Isolation**: Separate network for Sablier
|
||||
* **Monitoring**: Monitor Docker API usage
|
||||
|
||||
**Service Security:**
|
||||
* **No Direct Access**: Services only accessible via Traefik
|
||||
* **Authentication**: Authelia protection maintained
|
||||
* **SSL**: HTTPS encryption preserved
|
||||
* **Timeout Security**: Automatic cleanup prevents exposure
|
||||
|
||||
===== Advanced Configuration =====
|
||||
|
||||
**Custom Strategies:**
|
||||
```yaml
|
||||
environment:
|
||||
- SABLIER_STRATEGY=docker-api # Default
|
||||
# Alternative: kubernetes, swarm
|
||||
```
|
||||
|
||||
**Queue Management:**
|
||||
```yaml
|
||||
environment:
|
||||
- SABLIER_QUEUE_SIZE=10 # Concurrent startups
|
||||
- SABLIER_QUEUE_TIMEOUT=30s # Queue wait timeout
|
||||
```
|
||||
|
||||
**Health Check Configuration:**
|
||||
```yaml
|
||||
environment:
|
||||
- SABLIER_HEALTH_CHECK=true
|
||||
- SABLIER_HEALTH_CHECK_TIMEOUT=30s
|
||||
- SABLIER_HEALTH_CHECK_INTERVAL=5s
|
||||
```
|
||||
|
||||
**Dynamic Configuration:**
|
||||
```yaml
|
||||
# Via environment variables
|
||||
environment:
|
||||
- SABLIER_SERVICES=my-service:5m,other-service:10m
|
||||
```
|
||||
|
||||
===== Integration Examples =====
|
||||
|
||||
**Media Management Stack:**
|
||||
```yaml
|
||||
services:
|
||||
sonarr:
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=media-mgmt"
|
||||
- "sablier.timeout=15m"
|
||||
|
||||
radarr:
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=media-mgmt"
|
||||
- "sablier.timeout=15m"
|
||||
|
||||
prowlarr:
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=media-mgmt"
|
||||
- "sablier.timeout=10m"
|
||||
```
|
||||
|
||||
**Development Tools:**
|
||||
```yaml
|
||||
services:
|
||||
code-server:
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=dev-tools"
|
||||
- "sablier.timeout=2h" # Longer for development
|
||||
|
||||
jupyter:
|
||||
labels:
|
||||
- "sablier.enable=true"
|
||||
- "sablier.group=dev-tools"
|
||||
- "sablier.timeout=1h"
|
||||
```
|
||||
|
||||
===== Best Practices =====
|
||||
|
||||
**Service Selection:**
|
||||
* **Infrequently Used**: Perfect for rarely accessed services
|
||||
* **Resource Intensive**: Save resources on heavy services
|
||||
* **Development Tools**: Good for dev environments
|
||||
* **Always-On**: Keep critical services running
|
||||
|
||||
**Timeout Configuration:**
|
||||
* **Monitor Usage**: Track actual access patterns
|
||||
* **Adjust Gradually**: Start conservative, adjust based on logs
|
||||
* **Per-Service**: Different timeouts for different services
|
||||
* **User Feedback**: Consider user experience
|
||||
|
||||
**Resource Management:**
|
||||
* **Capacity Planning**: Calculate resource savings
|
||||
* **Monitoring**: Track startup/shutdown patterns
|
||||
* **Optimization**: Tune based on system resources
|
||||
* **Backup Plan**: Manual startup if needed
|
||||
|
||||
**Maintenance:**
|
||||
* **Log Review**: Regular log analysis
|
||||
* **Performance Monitoring**: Track resource usage
|
||||
* **Configuration Updates**: Update timeouts as needed
|
||||
* **Documentation**: Document lazy-loaded services
|
||||
|
||||
===== Monitoring & Alerts =====
|
||||
|
||||
**Log Analysis:**
|
||||
```bash
|
||||
# Startup events
|
||||
docker logs sablier | grep "Starting"
|
||||
|
||||
# Shutdown events
|
||||
docker logs sablier | grep "Stopping"
|
||||
|
||||
# Errors
|
||||
docker logs sablier | grep -i "error"
|
||||
```
|
||||
|
||||
**Performance Metrics:**
|
||||
* **Startup Time**: Time to service readiness
|
||||
* **Resource Usage**: CPU/memory before/after
|
||||
* **Access Patterns**: Frequency of service access
|
||||
* **Timeout Effectiveness**: Actual vs configured timeouts
|
||||
|
||||
**Health Monitoring:**
|
||||
```yaml
|
||||
# Add health check
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:10000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
Sablier significantly reduces resource usage by keeping unused services stopped until needed, while maintaining a seamless user experience through automatic on-demand startup.
|
||||
|
||||
**Next:** Explore [[architecture:storage|Storage Architecture]] or return to [[services:start|Services Overview]].
|
||||
366
config-templates/dokuwiki/data/pages/services/core/traefik.txt
Normal file
366
config-templates/dokuwiki/data/pages/services/core/traefik.txt
Normal file
@@ -0,0 +1,366 @@
|
||||
====== Traefik ======
|
||||
|
||||
Traefik is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. In the AI-Homelab, Traefik serves as the main entry point for all services, providing automatic HTTPS, load balancing, and routing.
|
||||
|
||||
===== Overview =====
|
||||
|
||||
**Purpose:** HTTP reverse proxy and load balancer
|
||||
**URL:** `https://traefik.yourdomain.duckdns.org`
|
||||
**Authentication:** Authelia SSO
|
||||
**Deployment:** Automatic (core stack)
|
||||
**Configuration:** File-based (YAML)
|
||||
|
||||
===== Key Features =====
|
||||
|
||||
**Automatic HTTPS:**
|
||||
* Let's Encrypt integration
|
||||
* Wildcard SSL certificates
|
||||
* Automatic renewal (90 days)
|
||||
* A+ SSL rating
|
||||
|
||||
**Service Discovery:**
|
||||
* Docker label-based routing
|
||||
* Dynamic configuration reloading
|
||||
* Zero-downtime deployments
|
||||
* Health check integration
|
||||
|
||||
**Load Balancing:**
|
||||
* Round-robin distribution
|
||||
* Weighted load balancing
|
||||
* Session stickiness
|
||||
* Circuit breaker protection
|
||||
|
||||
**Security:**
|
||||
* HTTP security headers
|
||||
* Rate limiting
|
||||
* IP whitelisting
|
||||
* CORS protection
|
||||
|
||||
===== Configuration =====
|
||||
|
||||
**Static Configuration (traefik.yml):**
|
||||
```yaml
|
||||
global:
|
||||
checkNewVersion: false
|
||||
sendAnonymousUsage: false
|
||||
|
||||
api:
|
||||
dashboard: true
|
||||
insecure: false
|
||||
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
http:
|
||||
redirections:
|
||||
entryPoint:
|
||||
to: websecure
|
||||
scheme: https
|
||||
websecure:
|
||||
address: ":443"
|
||||
http:
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
|
||||
providers:
|
||||
docker:
|
||||
endpoint: "unix:///var/run/docker.sock"
|
||||
exposedByDefault: false
|
||||
network: traefik-network
|
||||
file:
|
||||
directory: /dynamic
|
||||
watch: true
|
||||
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
email: your-email@example.com
|
||||
storage: /acme.json
|
||||
dnsChallenge:
|
||||
provider: duckdns
|
||||
delayBeforeCheck: 30
|
||||
```
|
||||
|
||||
**Dynamic Configuration (external.yml):**
|
||||
```yaml
|
||||
http:
|
||||
middlewares:
|
||||
authelia:
|
||||
forwardAuth:
|
||||
address: "http://authelia:9091/api/verify?rd=https://auth.yourdomain.duckdns.org/"
|
||||
trustForwardHeader: true
|
||||
authResponseHeaders:
|
||||
- "Remote-User"
|
||||
- "Remote-Groups"
|
||||
- "Remote-Name"
|
||||
- "Remote-Email"
|
||||
|
||||
security-headers:
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
X-Forwarded-Proto: "https"
|
||||
customResponseHeaders:
|
||||
X-Frame-Options: "SAMEORIGIN"
|
||||
X-Content-Type-Options: "nosniff"
|
||||
Referrer-Policy: "strict-origin-when-cross-origin"
|
||||
Permissions-Policy: "geolocation=(), microphone=(), camera=()"
|
||||
stsSeconds: 31536000
|
||||
stsIncludeSubdomains: true
|
||||
stsPreload: true
|
||||
```
|
||||
|
||||
===== Docker Compose =====
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.0
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik-network
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./traefik.yml:/etc/traefik/traefik.yml:ro
|
||||
- ./dynamic:/dynamic:ro
|
||||
- ./acme.json:/acme.json
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
- DUCKDNS_TOKEN=${DUCKDNS_TOKEN}
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)"
|
||||
- "traefik.http.routers.traefik.entrypoints=websecure"
|
||||
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.traefik.middlewares=authelia@docker"
|
||||
- "traefik.http.routers.traefik.service=api@internal"
|
||||
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 256M
|
||||
reservations:
|
||||
cpus: '0.1'
|
||||
memory: 64M
|
||||
```
|
||||
|
||||
===== Service Routing =====
|
||||
|
||||
**Standard Service Labels:**
|
||||
```yaml
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.service.rule=Host(`service.${DOMAIN}`)"
|
||||
- "traefik.http.routers.service.entrypoints=websecure"
|
||||
- "traefik.http.routers.service.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.service.middlewares=authelia@docker"
|
||||
- "traefik.http.services.service.loadbalancer.server.port=8080"
|
||||
```
|
||||
|
||||
**Router Components:**
|
||||
* **Rule**: Host matching (e.g., `Host(`service.domain.org`)`)
|
||||
* **EntryPoint**: HTTP/HTTPS endpoint
|
||||
* **TLS**: Certificate resolver
|
||||
* **Middlewares**: Authentication, security headers
|
||||
* **Service**: Backend service definition
|
||||
|
||||
**Advanced Routing:**
|
||||
```yaml
|
||||
# Path-based routing
|
||||
- "traefik.http.routers.api.rule=Host(`api.${DOMAIN}`) && PathPrefix(`/v1`)"
|
||||
- "traefik.http.routers.web.rule=Host(`app.${DOMAIN}`)"
|
||||
|
||||
# Header-based routing
|
||||
- "traefik.http.routers.mobile.rule=Host(`app.${DOMAIN}`) && Headers(`User-Agent`, `*Mobile*`)"
|
||||
|
||||
# Priority routing
|
||||
- "traefik.http.routers.specific.rule=Host(`service.${DOMAIN}`) && Path(`/api`)"
|
||||
- "traefik.http.routers.specific.priority=100"
|
||||
```
|
||||
|
||||
===== SSL Certificate Management =====
|
||||
|
||||
**Certificate Generation:**
|
||||
* **Challenge**: DNS-01 (DuckDNS)
|
||||
* **Provider**: Let's Encrypt
|
||||
* **Type**: ECDSA P-256
|
||||
* **Validity**: 90 days
|
||||
* **Renewal**: Automatic (30 days before expiry)
|
||||
|
||||
**Certificate Storage:**
|
||||
* **File**: `/opt/stacks/core/traefik/acme.json`
|
||||
* **Permissions**: 600 (owner read/write only)
|
||||
* **Backup**: Include in backup strategy
|
||||
* **Format**: JSON with encrypted private keys
|
||||
|
||||
**Troubleshooting SSL:**
|
||||
```bash
|
||||
# Check certificate status
|
||||
echo | openssl s_client -connect yourdomain.duckdns.org:443 -servername service.yourdomain.duckdns.org 2>/dev/null | openssl x509 -noout -subject -dates
|
||||
|
||||
# View Traefik logs
|
||||
docker logs traefik | grep certificate
|
||||
|
||||
# Check DNS TXT record
|
||||
dig TXT _acme-challenge.yourdomain.duckdns.org
|
||||
```
|
||||
|
||||
===== Monitoring & Logging =====
|
||||
|
||||
**Dashboard Access:**
|
||||
* URL: `https://traefik.yourdomain.duckdns.org`
|
||||
* Features: Real-time routing, health status, metrics
|
||||
* Authentication: Authelia SSO required
|
||||
|
||||
**Log Configuration:**
|
||||
```yaml
|
||||
log:
|
||||
level: INFO
|
||||
format: json
|
||||
|
||||
accessLog:
|
||||
filePath: /var/log/traefik/access.log
|
||||
format: json
|
||||
filters:
|
||||
statusCodes: ["200-299", "400-499", "500-599"]
|
||||
```
|
||||
|
||||
**Metrics Integration:**
|
||||
* **Prometheus**: `/metrics` endpoint
|
||||
* **Health Checks**: Service health monitoring
|
||||
* **Performance**: Response time tracking
|
||||
|
||||
===== Security Features =====
|
||||
|
||||
**Authentication Middleware:**
|
||||
* **Authelia Integration**: SSO for protected services
|
||||
* **Bypass Rules**: Direct access for media services
|
||||
* **Session Management**: Secure cookie handling
|
||||
|
||||
**Rate Limiting:**
|
||||
```yaml
|
||||
middlewares:
|
||||
rate-limit:
|
||||
rateLimit:
|
||||
burst: 100
|
||||
average: 50
|
||||
```
|
||||
|
||||
**IP Whitelisting:**
|
||||
```yaml
|
||||
middlewares:
|
||||
ip-whitelist:
|
||||
ipWhiteList:
|
||||
sourceRange:
|
||||
- "192.168.1.0/24"
|
||||
- "10.0.0.0/8"
|
||||
```
|
||||
|
||||
===== Performance Optimization =====
|
||||
|
||||
**Caching:**
|
||||
```yaml
|
||||
middlewares:
|
||||
cache:
|
||||
inFlightReq:
|
||||
amount: 64
|
||||
```
|
||||
|
||||
**Compression:**
|
||||
* **Gzip**: Automatic text compression
|
||||
* **Brotli**: Advanced compression (if supported)
|
||||
|
||||
**Connection Pooling:**
|
||||
* **Keep-Alive**: Persistent connections
|
||||
* **Connection Reuse**: Reduced latency
|
||||
* **Timeout Management**: Connection limits
|
||||
|
||||
===== Troubleshooting =====
|
||||
|
||||
**Service Not Accessible:**
|
||||
```bash
|
||||
# Check if service is running
|
||||
docker ps | grep service-name
|
||||
|
||||
# Verify Traefik labels
|
||||
docker inspect service-name | grep traefik
|
||||
|
||||
# Check Traefik logs
|
||||
docker logs traefik | grep service-name
|
||||
```
|
||||
|
||||
**SSL Issues:**
|
||||
* Verify DuckDNS token
|
||||
* Check DNS propagation
|
||||
* Confirm port forwarding
|
||||
* Review certificate logs
|
||||
|
||||
**Routing Problems:**
|
||||
* Validate router rules
|
||||
* Check middleware configuration
|
||||
* Test service connectivity
|
||||
* Review access logs
|
||||
|
||||
**Performance Issues:**
|
||||
* Monitor resource usage
|
||||
* Check connection limits
|
||||
* Review middleware stack
|
||||
* Analyze access patterns
|
||||
|
||||
===== External Service Proxying =====
|
||||
|
||||
**Proxying Non-Docker Services:**
|
||||
```yaml
|
||||
# In dynamic/external.yml
|
||||
http:
|
||||
routers:
|
||||
external-service:
|
||||
rule: "Host(`external.yourdomain.duckdns.org`)"
|
||||
service: external-service
|
||||
middlewares:
|
||||
- authelia@docker
|
||||
services:
|
||||
external-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://192.168.1.100:8123"
|
||||
```
|
||||
|
||||
**Use Cases:**
|
||||
* Raspberry Pi Home Assistant
|
||||
* NAS devices
|
||||
* Legacy applications
|
||||
* Network printers
|
||||
|
||||
===== Best Practices =====
|
||||
|
||||
**Configuration Management:**
|
||||
* Use version control for config files
|
||||
* Test changes in staging
|
||||
* Document custom routing rules
|
||||
* Regular backup of acme.json
|
||||
|
||||
**Security:**
|
||||
* Keep Traefik updated
|
||||
* Monitor access logs
|
||||
* Use strong authentication
|
||||
* Regular security audits
|
||||
|
||||
**Performance:**
|
||||
* Implement appropriate caching
|
||||
* Use connection pooling
|
||||
* Monitor resource usage
|
||||
* Optimize middleware stack
|
||||
|
||||
**Monitoring:**
|
||||
* Set up alerts for failures
|
||||
* Monitor certificate expiry
|
||||
* Track performance metrics
|
||||
* Regular log analysis
|
||||
|
||||
Traefik is the backbone of your homelab's networking infrastructure, providing secure, efficient, and reliable service routing.
|
||||
|
||||
**Next:** Learn about [[services:core:authelia|Authelia]] or [[services:core:duckdns|DuckDNS]].
|
||||
Reference in New Issue
Block a user