# Nextcloud Stack - Ansible Deployment Project

## 🎉 Project Complete!

This Ansible automation project provides complete, one-command deployment of a self-hosted Nextcloud productivity stack to Ubuntu-based LXC/VPS servers.

---

## 📦 What's Included

### Core Files

```
ansible-nextcloud-deployment/
├── setup.sh                          # ⭐ Interactive configuration wizard
├── Makefile                          # Convenient command shortcuts
├── ansible.cfg                       # Ansible configuration
├── .gitignore                        # Git ignore rules
│
├── inventory/                        # Generated by setup.sh
│   ├── hosts.yml                    # Server inventory (generated)
│   └── group_vars/all/
│       ├── vars.yml                 # Public variables (generated)
│       └── vault.yml                # Encrypted secrets (generated)
│
├── playbooks/                        # ⭐ Deployment playbooks
│   ├── site.yml                     # Main orchestrator
│   ├── 01-preflight-checks.yml      # DNS, connectivity validation
│   ├── 02-system-setup.yml          # Packages, firewall, security
│   ├── 03-docker-setup.yml          # Docker CE installation
│   ├── 04-tailscale-setup.yml       # VPN setup
│   ├── 05-deploy-stack.yml          # Docker Compose deployment
│   ├── 06-configure-caddy.yml       # Reverse proxy + SSL
│   ├── 07-setup-backups.yml         # Backup automation
│   ├── 08-post-deployment.yml       # Final verification
│   └── 99-rollback.yml              # Emergency rollback
│
├── roles/                            # ⭐ Ansible roles
│   ├── nextcloud_stack/
│   │   └── templates/
│   │       ├── docker-compose.yml.j2  # Complete stack definition
│   │       └── env.j2                 # Environment variables
│   └── caddy/
│       └── templates/
│           └── Caddyfile.j2           # Reverse proxy config
│
└── docs/                             # ⭐ Documentation
    ├── README.md                    # Project overview
    ├── DEPLOYMENT_GUIDE.md          # Quick start guide
    ├── TROUBLESHOOTING.md           # Common issues & solutions
    └── BACKUP_RESTORE.md            # Backup procedures
```

### Stack Components (12 Services)

**Public Services** (via HTTPS):
- Nextcloud (file sync & collaboration)
- OnlyOffice (document editor)
- Excalidraw (whiteboard)
- Obsidian (note-taking)

**Infrastructure**:
- PostgreSQL 18 (database)
- Redis 7 (cache)
- Caddy (reverse proxy + automatic SSL)

**Management** (Tailscale-only):
- Homarr (dashboard)
- Dockhand (container manager)
- Uptime Kuma (monitoring)

**Automation**:
- Watchtower (auto-updates with safety exclusions)

---

## 🚀 Quick Start

### 1. Configure

```bash
./setup.sh
```

Interactive wizard collects all configuration:
- Server details (IP, domain, SSH)
- User information
- Admin credentials
- Subdomain preferences
- Tailscale auth key (optional)
- Monitoring settings

**Generates:**
- `inventory/hosts.yml` - Server inventory
- `inventory/group_vars/all/vars.yml` - Public config
- `inventory/group_vars/all/vault.yml` - Encrypted secrets

### 2. Deploy

```bash
make deploy
```

Or:
```bash
ansible-playbook playbooks/site.yml --ask-vault-pass
```

**Duration:** 30-45 minutes per server

### 3. Access

- Nextcloud: `https://cloud.yourdomain.com`
- Homarr: `https://home.yourdomain.com` (Tailscale)
- Uptime Kuma: `https://uptime.yourdomain.com` (Tailscale)

---

## ✨ Key Features

### 🔒 Security

- **Firewall**: UFW configured (only SSH, HTTP, HTTPS, Tailscale open)
- **Fail2ban**: SSH brute-force protection (5 failures = 10 min ban)
- **Automatic Security Updates**: Unattended upgrades enabled
- **Secret Management**: Ansible Vault encryption for all credentials
- **Access Control**: Management UIs restricted to Tailscale network
- **SSL/TLS**: Automatic Let's Encrypt certificates via Caddy
- **Container Isolation**: Dedicated Docker network

### 💾 Backups

- **Daily**: PostgreSQL database dumps (3:00 AM)
- **Weekly**: Full volume backups (Sundays, 3:00 AM)
- **Retention**: 30 days
- **Location**: `/opt/nextcloud-stack/backups/`
- **Off-site Ready**: rclone pre-installed
- **Automated**: Cron jobs configured
- **Tested**: Documented restore procedures

### 🔄 Updates

**Automated (Watchtower)**:
- Caddy, Excalidraw, Obsidian, Homarr, Dockhand, Uptime Kuma

**Monitor Only**:
- OnlyOffice (notifications, manual update)

**Manual Required**:
- Nextcloud, PostgreSQL, Redis (too critical to auto-update)

### 🌐 Multi-Server Support

Deploy identical stacks to multiple servers:
- Each server gets unique domain
- Fully independent deployments
- Shared Tailscale network (optional)

### 📊 Monitoring

- **Uptime Kuma**: Service health monitoring
- **Email Alerts**: Configurable notifications
- **Status Page**: Optional public status page
- **Container Health**: Docker healthchecks
- **SSL Monitoring**: Certificate expiry tracking

---

## 📚 Documentation

| Document | Purpose |
|----------|---------|
| [README.md](README.md) | Complete project overview, features, usage |
| [DEPLOYMENT_GUIDE.md](DEPLOYMENT_GUIDE.md) | Step-by-step deployment instructions |
| [TROUBLESHOOTING.md](TROUBLESHOOTING.md) | Common issues and solutions |
| [BACKUP_RESTORE.md](BACKUP_RESTORE.md) | Backup and restore procedures |
| [AGENTS.md](AGENTS.md) | Docker Compose & Ansible guidelines |

---

## 🛠️ Makefile Commands

```bash
make help          # Show all commands
make setup         # Run interactive setup
make ping          # Test connectivity
make check         # Run preflight checks
make deploy        # Full deployment
make deploy-dry    # Test run (no changes)
make status        # Show container status
make logs          # View all logs
make backup        # Run manual backup
make restart       # Restart all containers
make edit-vault    # Edit encrypted secrets
make rekey-vault   # Change vault password
```

---

## 🎯 Design Principles

### 1. **User-Friendly**
- Interactive setup script (no manual configuration editing)
- Automatic SSL certificates
- Clear documentation
- Helpful error messages

### 2. **Secure by Default**
- Minimal firewall rules
- Encrypted secrets (Ansible Vault)
- Tailscale-only admin interfaces
- Automatic security updates
- No hardcoded credentials

### 3. **Production-Ready**
- Automated backups
- Monitoring included
- Health checks configured
- Documented restore procedures
- Emergency rollback playbook

### 4. **Maintainable**
- Modular playbook structure
- Clear variable naming
- Comprehensive comments
- Role-based organization
- Git-friendly (.gitignore configured)

### 5. **Safe Updates**
- Critical services excluded from auto-update
- Watchtower uses label-based control
- Manual update procedures documented
- Rollback capability included

---

## 🔧 Deployment Flow

```
┌─────────────────────────────────────────────────────────────┐
│ 1. SETUP (./setup.sh)                                       │
│    • Collect server details, domains, credentials           │
│    • Generate encrypted inventory & variables               │
│    • Create Ansible Vault with secrets                      │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 2. PREFLIGHT CHECKS (01-preflight-checks.yml)              │
│    • Verify Ansible version, SSH connectivity               │
│    • Check disk space, ports availability                   │
│    • Validate DNS records, detect LXC                       │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 3. SYSTEM SETUP (02-system-setup.yml)                      │
│    • Update packages, install essentials                    │
│    • Configure UFW firewall, fail2ban                       │
│    • Enable automatic security updates                      │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 4. DOCKER SETUP (03-docker-setup.yml)                      │
│    • Remove old Docker installations                        │
│    • Install Docker CE + Compose v2                         │
│    • Configure Docker daemon                                │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 5. TAILSCALE SETUP (04-tailscale-setup.yml)                │
│    • Install Tailscale                                      │
│    • Activate if auth key provided                          │
│    • Enable systemd service                                 │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 6. DEPLOY STACK (05-deploy-stack.yml)                      │
│    • Create directory structure                             │
│    • Template docker-compose.yml, .env, configs             │
│    • Pull Docker images, start containers                   │
│    • Wait for services healthy                              │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 7. CONFIGURE CADDY (06-configure-caddy.yml)                │
│    • Validate Caddyfile syntax                              │
│    • Reload Caddy configuration                             │
│    • Obtain Let's Encrypt SSL certificates                  │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 8. SETUP BACKUPS (07-setup-backups.yml)                    │
│    • Create backup script                                   │
│    • Configure cron jobs (daily/weekly)                     │
│    • Run test backup                                        │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ 9. POST-DEPLOYMENT (08-post-deployment.yml)                │
│    • Verify all containers running                          │
│    • Install Nextcloud apps                                 │
│    • Configure background jobs                              │
│    • Create deployment report                               │
└─────────────────────────────────────────────────────────────┘
                            ↓
                    ✅ DEPLOYMENT COMPLETE!
```

---

## 🧩 Template Files

### docker-compose.yml.j2

Complete Docker Compose stack with:
- All 12 services configured
- Health checks for critical services
- Proper dependencies (depends_on with conditions)
- Watchtower labels for update control
- Named volumes and networks
- Environment variables from .env

**Location**: `roles/nextcloud_stack/templates/docker-compose.yml.j2`

### Caddyfile.j2

Caddy reverse proxy configuration with:
- Automatic SSL for all domains
- Public services (Nextcloud, OnlyOffice, etc.)
- Tailscale-restricted services (Homarr, Dockhand, Uptime Kuma)
- Security headers
- Large file upload support (10GB)
- Optional public status page

**Location**: `roles/caddy/templates/Caddyfile.j2`

### env.j2

Environment variables template with:
- Database credentials
- Redis password
- Nextcloud admin credentials
- Application secrets (Homarr)
- Domain configuration
- Timezone settings

**Location**: `roles/nextcloud_stack/templates/env.j2`

---

## 🔐 Security Considerations

### Secrets Management

All sensitive data encrypted with Ansible Vault:
- Database passwords
- Admin credentials
- Application secrets
- Tailscale auth keys

**Never committed in plain text!**

### Network Security

- **Public**: Only Nextcloud and productivity apps
- **Tailscale-only**: All management interfaces
- **Internal**: Database and Redis (no external access)

### Firewall Rules (UFW)

```
22/tcp   - SSH
80/tcp   - HTTP (redirects to HTTPS)
443/tcp  - HTTPS
443/udp  - HTTP/3 (QUIC)
41641/udp - Tailscale
Default: DENY
```

### Update Strategy

**Why not auto-update everything?**

- **Nextcloud**: Database migrations may fail automatically
- **PostgreSQL**: Schema changes could break Nextcloud
- **Redis**: Unlikely issues, but excluded for consistency

**Safe to auto-update:**
- Stateless applications (Excalidraw, Obsidian)
- Infrastructure (Caddy)
- Management tools (Homarr, Dockhand)

---

## 📊 Resource Usage (Approximate)

### Disk Space

- Docker images: ~5GB
- Initial volumes: ~2GB
- Backups (30 days): ~50GB
- **Total recommended**: 100GB minimum

### Memory

- PostgreSQL: ~256MB
- Redis: ~256MB (configured limit)
- Nextcloud: ~512MB
- OnlyOffice: ~2GB
- Other services: ~1GB combined
- **Total**: 4-6GB RAM recommended

### Network

- **Inbound**: 80, 443 (HTTP/HTTPS), 41641 (Tailscale)
- **Outbound**: Internet access required for Let's Encrypt, Docker images, updates

---

## 🎓 Next Steps

### Immediate

1. **Test the deployment** on a test server first
2. **Verify DNS** is configured correctly
3. **Run setup.sh** and answer questions carefully
4. **Deploy** with `make deploy`
5. **Access Nextcloud** and complete initial setup

### After Deployment

1. **Configure Uptime Kuma** monitoring
2. **Customize Homarr** dashboard
3. **Test backups** with `make backup`
4. **Enable 2FA** in Nextcloud
5. **Install additional Nextcloud apps** as needed

### Ongoing

1. **Monitor** service health in Uptime Kuma
2. **Review backups** monthly
3. **Test restore** procedures quarterly
4. **Update Nextcloud** when new versions release (manually)
5. **Check logs** for any issues

---

## 💡 Tips & Best Practices

### For LXC Containers

**On LXC host, enable nested virtualization:**
```bash
lxc config set CONTAINER_NAME security.nesting true
lxc restart CONTAINER_NAME
```

### For Production Use

1. Use strong passwords (not example passwords)
2. Enable Nextcloud 2FA
3. Configure off-site backups with rclone
4. Set up Uptime Kuma email alerts
5. Review logs regularly

### For Multiple Servers

Each server can have:
- Different domain
- Different subdomain preferences
- Same or different Tailscale network

Just run `setup.sh` and add all servers when prompted.

---

## 🐛 Known Limitations

1. **Watchtower is archived** (December 2025)
   - Still works, but no longer maintained
   - Consider alternative update strategies long-term

2. **OnlyOffice needs 2GB+ RAM**
   - May be slow on low-memory servers
   - Consider disabling if not needed

3. **First-time deployment takes 30-45 min**
   - Mostly Docker image downloads
   - Subsequent deploys are faster

4. **Let's Encrypt rate limits**
   - 50 certs/week per domain
   - Use staging server for testing

---

## 📜 License

MIT License - Use freely, modify as needed

---

## 🙏 Acknowledgments

Built with these amazing open-source projects:

- **Nextcloud** - File sync and collaboration
- **Caddy** - Automatic HTTPS web server
- **Ansible** - IT automation
- **Docker** - Containerization
- **PostgreSQL** - Database
- **Tailscale** - Zero-config VPN
- **OnlyOffice**, **Excalidraw**, **Obsidian** - Productivity tools
- **Homarr**, **Dockhand**, **Uptime Kuma** - Management & monitoring

---

## 📞 Support

**Documentation:**
- [DEPLOYMENT_GUIDE.md](DEPLOYMENT_GUIDE.md) - Getting started
- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - Fix common issues
- [BACKUP_RESTORE.md](BACKUP_RESTORE.md) - Backup procedures

**Project Files:**
All source code, playbooks, and templates included in this repository.

---

## ✅ Checklist for New Users

Before deploying:
- [ ] Read DEPLOYMENT_GUIDE.md
- [ ] Install Ansible 2.14+ on control machine
- [ ] Have Ubuntu 20.04+ server ready
- [ ] Configure DNS A records
- [ ] Test SSH access to server
- [ ] Have domain name ready
- [ ] Decide on subdomain preferences

After deploying:
- [ ] Access Nextcloud web UI
- [ ] Complete Nextcloud setup wizard
- [ ] Setup Uptime Kuma monitoring
- [ ] Configure Homarr dashboard
- [ ] Test backup with `make backup`
- [ ] Enable Nextcloud 2FA
- [ ] Review deployment report
- [ ] Save Ansible Vault password securely

---

**Project Status**: ✅ Complete and Ready for Use

**Last Updated**: 2026-02-16

**Version**: 1.0

---

**Happy self-hosting! 🎉**
