Fix fresh-deploy blockers and clean up architecture
- Seed postfix-accounts.cf before mailserver start to satisfy Dovecot's requirement for at least one account on first boot - Add failed_when: false to mail user/alias list tasks (files don't exist on first run) - Add forgejo_runner_version (was undefined); default to 12 - Create /srv/forgejo/data/gitea/conf before deploying app.ini - Decouple goaccess sync from restic: new enable_goaccess_sync flag with its own goaccess_sync_* variables - Move Docker installation to bootstrap exclusively; rename docker.yml to networks.yml (runs docker_network role only) - Add radicale_password to vault template and setup.sh - Fix goaccess sync tasks gated on enable_goaccess_sync - Add upstream bug comment to authorized_key deprecation warning - Update CLAUDE.md and README.md throughout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
75891c3271
commit
b38cd94fc8
23 changed files with 400 additions and 307 deletions
41
CLAUDE.md
41
CLAUDE.md
|
|
@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
|
||||
## Project Overview
|
||||
|
||||
Island is an Ansible-based self-hosting infrastructure stack that deploys email, web server, git hosting, Matrix homeserver, monitoring, and backup services using Docker Compose on Ubuntu servers.
|
||||
Linderhof is an Ansible-based self-hosting infrastructure stack that deploys email, web server, git hosting, Matrix homeserver, monitoring, and backup services using Docker Compose on Ubuntu servers.
|
||||
|
||||
## Common Commands
|
||||
|
||||
|
|
@ -37,23 +37,31 @@ Note: Inventory and vault password are set via `ANSIBLE_INVENTORY` and `ANSIBLE_
|
|||
**Deployment Pattern:** Each service is deployed to `/srv/<service>/` on the target host with a `compose.yml` and environment files.
|
||||
|
||||
**Standalone Playbooks** (not in `site.yml`):
|
||||
- `provision.yml` - Provision a cloud VM (Hetzner). Usage: `ansible-playbook playbooks/provision.yml`
|
||||
- `provision.yml` - Provision a cloud VM (Hetzner)
|
||||
- `dns.yml` - Manage DNS zones/records via Hetzner DNS API
|
||||
- `bootstrap.yml` - First-time server setup (run once as root before site.yml)
|
||||
|
||||
**Full deployment order** (fresh server):
|
||||
1. `provision.yml` - create server, auto-writes IP to hosts.yml and config.yml
|
||||
2. `dns.yml` - create DNS records
|
||||
3. `bootstrap.yml` - users, SSH hardening, packages, Docker (connects as root)
|
||||
4. `site.yml` - deploy all services
|
||||
|
||||
**Playbook Execution Order** (via `site.yml`):
|
||||
1. bootstrap.yml - SSH, sudo, users, base packages (manual only)
|
||||
2. docker.yml - Docker engine installation
|
||||
3. docker_network.yml - Pre-create all Docker networks (must run before any service)
|
||||
4. nebula.yml - Overlay network (Nebula)
|
||||
5. caddy.yml - Web server / reverse proxy
|
||||
6. mail.yml - Email (docker-mailserver + rainloop)
|
||||
7. forgejo.yml - Git server
|
||||
8. tuwunel.yml - Matrix homeserver (Tuwunel)
|
||||
9. monitoring.yml - Prometheus, Grafana, Loki, Alloy
|
||||
10. goaccess.yml - Web analytics
|
||||
11. diun.yml - Docker image update notifications
|
||||
12. restic.yml - Encrypted backups
|
||||
13. fail2ban.yml - Intrusion prevention
|
||||
1. networks.yml - Pre-create all Docker networks (must run before any service)
|
||||
2. nebula.yml - Overlay network (Nebula)
|
||||
3. caddy.yml - Web server / reverse proxy
|
||||
4. mail.yml - Email (docker-mailserver + rainloop)
|
||||
5. forgejo.yml - Git server
|
||||
6. tuwunel.yml - Matrix homeserver (Tuwunel)
|
||||
7. radicale.yml - CalDAV/CardDAV
|
||||
8. monitoring.yml - Prometheus, Grafana, Loki, Alloy
|
||||
9. goaccess.yml - Web analytics
|
||||
10. diun.yml - Docker image update notifications
|
||||
11. restic.yml - Encrypted backups
|
||||
12. fail2ban.yml - Intrusion prevention
|
||||
|
||||
**Mail TLS:** on first deployment, the mail role stops Caddy, runs certbot standalone to acquire a Let's Encrypt cert for `mail_hostname`, then restarts Caddy. subsequent runs skip this (cert already exists). Caddy owns port 80 so standalone is the only viable approach without a DNS challenge plugin.
|
||||
|
||||
**Role Structure:** Each role in `roles/` contains:
|
||||
- `tasks/main.yml` - Core provisioning tasks
|
||||
|
|
@ -90,6 +98,9 @@ caddy_sites:
|
|||
- `enable_forgejo`
|
||||
- `enable_tuwunel`
|
||||
- `enable_monitoring`
|
||||
- `enable_goaccess`
|
||||
- `enable_goaccess_sync`
|
||||
- `enable_radicale`
|
||||
- `enable_restic`
|
||||
- `enable_fail2ban`
|
||||
- `enable_nebula`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue