fix: resolve MMDL hairpinning issue with CalDAV communication
- Add cal.thesatelliteoflove.com:172.20.0.5 to MMDL extra_hosts for internal communication - Update DEPLOYMENT_LEARNINGS.md with comprehensive hairpinning documentation - Update CLAUDE.md with hairpinning guidance and correct deployment commands - Document standard pattern for Docker container internal domain resolution 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1c9ab0f5e6
commit
ccab665d26
100
CLAUDE.md
Normal file
100
CLAUDE.md
Normal file
@ -0,0 +1,100 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Overview
|
||||
|
||||
This is a personal infrastructure Ansible playbook that automates deployment and management of 25+ self-hosted Docker services across two domains (`thesatelliteoflove.com` and `nerder.land`). The setup uses Tailscale VPN for secure networking and Caddy for reverse proxy with automated HTTPS.
|
||||
|
||||
**Important**: Always review `DEPLOYMENT_LEARNINGS.md` when working on this repository for lessons learned and troubleshooting guidance.
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Initial Setup
|
||||
```bash
|
||||
# Install Ansible dependencies
|
||||
ansible-galaxy install -r requirements.yml
|
||||
|
||||
# Bootstrap new server (creates user, installs Tailscale, security hardening)
|
||||
ansible-playbook bootstrap.yml -i hosts.yml
|
||||
|
||||
# Deploy all Docker services
|
||||
ansible-playbook site.yml -i hosts.yml
|
||||
|
||||
# Update DNS records in AWS Route53
|
||||
ansible-playbook dns.yml -i hosts.yml
|
||||
```
|
||||
|
||||
### Service Management
|
||||
```bash
|
||||
# Deploy specific services using tags
|
||||
ansible-playbook site.yml -i hosts.yml --tags caddy --vault-password-file vault_pass --extra-vars "@secrets.enc"
|
||||
ansible-playbook site.yml -i hosts.yml --tags authentik,gitea --vault-password-file vault_pass --extra-vars "@secrets.enc"
|
||||
ansible-playbook site.yml -i hosts.yml --tags docker --vault-password-file vault_pass --extra-vars "@secrets.enc" # all docker services
|
||||
|
||||
# Deploy only infrastructure components
|
||||
ansible-playbook site.yml -i hosts.yml --tags common,cron --vault-password-file vault_pass --extra-vars "@secrets.enc"
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Host Configuration
|
||||
- **Bootstrap Host** (`netcup`): 152.53.36.98 - Initial server setup target
|
||||
- **Docker Host** (`docker-01`): 100.70.169.99 - Main service deployment via Tailscale
|
||||
|
||||
### Role Structure
|
||||
- **bootstrap**: Initial server hardening, user creation, Tailscale VPN setup
|
||||
- **common**: Basic system configuration, UFW firewall management
|
||||
- **docker**: Comprehensive service deployment (25+ containerized applications)
|
||||
- **cron**: Scheduled task management (currently Warhammer RSS feed generation)
|
||||
|
||||
### Service Categories in Docker Role
|
||||
- **Infrastructure**: Caddy (reverse proxy), Authentik (SSO), Dockge (container management)
|
||||
- **Development**: Gitea, Code Server, Matrix (Conduit)
|
||||
- **Media**: Audiobookshelf, Calibre, Ghost blog, Pinchflat
|
||||
- **Productivity**: Paperless-NGX, TasksMD/MMDL, Baikal (CalDAV/CardDAV), Syncthing
|
||||
- **Communication**: GoToSocial (Fediverse), Postiz (social media management)
|
||||
- **Monitoring**: Changedetection, Glance dashboard, AppriseAPI
|
||||
|
||||
### Data Structure
|
||||
- All service data stored in `/opt/stacks/[service-name]/` on docker host
|
||||
- Docker Compose files generated from Jinja2 templates in `roles/docker/templates/`
|
||||
- Environment files templated for services requiring configuration
|
||||
|
||||
## Key Implementation Details
|
||||
|
||||
### Template-Driven Configuration
|
||||
The docker role uses Jinja2 templates extensively. When modifying services:
|
||||
- Update templates in `roles/docker/templates/[service]-compose.yml.j2`
|
||||
- Environment files use `.env.j2` templates where needed
|
||||
- Main task files in `roles/docker/tasks/` include service-specific deployment logic
|
||||
|
||||
### DNS Management
|
||||
The `dns.yml` playbook manages AWS Route53 records for both domains. All subdomains point to the netcup server (152.53.36.98), with Caddy handling internal routing to the docker host via Tailscale.
|
||||
|
||||
### Security Architecture
|
||||
- Tailscale provides secure networking between management and service hosts
|
||||
- Services are network-isolated using Docker
|
||||
- Caddy handles SSL termination with automatic Let's Encrypt certificates
|
||||
- UFW firewall managed through Docker integration script
|
||||
|
||||
### Service Dependencies
|
||||
Many services depend on Authentik for SSO. When deploying new services, consider:
|
||||
- Whether SSO integration is needed
|
||||
- Caddy routing configuration for subdomain access
|
||||
- Network connectivity requirements within Docker stack
|
||||
- Hairpinning fixes for internal service-to-service communication
|
||||
|
||||
### Hairpinning Resolution
|
||||
Services inside Docker containers cannot reach external domains that resolve to the same server. Fix by adding `extra_hosts` mappings:
|
||||
|
||||
```yaml
|
||||
extra_hosts:
|
||||
- "auth.thesatelliteoflove.com:172.20.0.5"
|
||||
- "cal.thesatelliteoflove.com:172.20.0.5"
|
||||
```
|
||||
|
||||
Common domains requiring hairpinning fixes:
|
||||
- `auth.thesatelliteoflove.com` (Authentik SSO)
|
||||
- `cal.thesatelliteoflove.com` (Baikal CalDAV)
|
||||
- Any service domain the container needs to communicate with
|
@ -10,6 +10,7 @@ services:
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
- "auth.thesatelliteoflove.com:172.20.0.5"
|
||||
- "cal.thesatelliteoflove.com:172.20.0.5"
|
||||
labels:
|
||||
glance.name: MMDL
|
||||
glance.icon: si:task
|
||||
|
Loading…
x
Reference in New Issue
Block a user