Files
dotfiles_arch/ansible/README.md
2026-02-16 23:40:30 +01:00

383 lines
9.6 KiB
Markdown

# Nextcloud Stack - Automated Deployment with Ansible
Complete automation for deploying a self-hosted Nextcloud productivity stack on Ubuntu-based LXC/VPS servers.
## Features
- **12 Services**: Nextcloud, OnlyOffice, Excalidraw, Obsidian, Homarr, Dockhand, Uptime Kuma, PostgreSQL, Redis, Caddy, Watchtower
- **Automatic SSL**: Let's Encrypt certificates via Caddy
- **Secure Management**: Tailscale-only access for admin interfaces
- **Auto-updates**: Watchtower with safety exclusions for critical services
- **Automated Backups**: Daily database backups, weekly volume backups (30-day retention)
- **Monitoring**: Uptime Kuma with configurable alerts
- **Multi-server**: Deploy to multiple VPS servers with unique domains
## Quick Start
### Prerequisites
1. **Control Machine** (your laptop):
- Ansible 2.14+ installed
- SSH access to target servers
2. **Target Server(s)**:
- Ubuntu 20.04+ (LXC container or VPS)
- Root or sudo access
- Minimum 100GB disk space
- Ports 80, 443 available
3. **DNS Configuration** (BEFORE deployment):
```
cloud.yourdomain.com → YOUR_SERVER_IP
office.yourdomain.com → YOUR_SERVER_IP
draw.yourdomain.com → YOUR_SERVER_IP
notes.yourdomain.com → YOUR_SERVER_IP
home.yourdomain.com → YOUR_SERVER_IP
manage.yourdomain.com → YOUR_SERVER_IP
uptime.yourdomain.com → YOUR_SERVER_IP
```
### Installation
1. **Clone this repository**:
```bash
git clone <your-repo-url>
cd ansible-nextcloud-deployment
```
2. **Run interactive setup**:
```bash
./setup.sh
```
This will ask for:
- Server IP addresses and domains
- Your name and email
- Admin credentials
- Subdomain preferences
- Tailscale auth key (optional)
- Monitoring email
- Ansible Vault password
3. **Deploy the stack**:
```bash
make deploy
```
Or manually:
```bash
ansible-playbook playbooks/site.yml --ask-vault-pass
```
4. **Access your services**:
- Nextcloud: `https://cloud.yourdomain.com`
- OnlyOffice: `https://office.yourdomain.com`
- Homarr (Tailscale only): `https://home.yourdomain.com`
- Uptime Kuma (Tailscale only): `https://uptime.yourdomain.com`
## Project Structure
```
ansible-nextcloud-deployment/
├── setup.sh # Interactive configuration script
├── Makefile # Convenient command shortcuts
├── ansible.cfg # Ansible configuration
├── inventory/
│ ├── hosts.yml # Generated by setup.sh
│ └── group_vars/all/
│ ├── vars.yml # Public variables
│ └── vault.yml # Encrypted secrets
├── playbooks/
│ ├── site.yml # Main orchestrator
│ ├── 01-preflight-checks.yml # Pre-deployment validation
│ ├── 02-system-setup.yml # System packages & security
│ ├── 03-docker-setup.yml # Docker installation
│ ├── 04-tailscale-setup.yml # VPN setup
│ ├── 05-deploy-stack.yml # Docker Compose deployment
│ ├── 06-configure-caddy.yml # Reverse proxy configuration
│ ├── 07-setup-backups.yml # Backup automation
│ └── 08-post-deployment.yml # Final verification
└── roles/
├── nextcloud_stack/
│ └── templates/
│ ├── docker-compose.yml.j2
│ └── env.j2
└── caddy/
└── templates/
└── Caddyfile.j2
```
## 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 # Dry run (no changes)
make status # Show container status
make logs # View container logs
make backup # Run manual backup
make restart # Restart all containers
make edit-vault # Edit encrypted secrets
```
## Service Stack
| Service | Purpose | Port | Access | Auto-Update |
|---------|---------|------|--------|-------------|
| Caddy | Reverse proxy + SSL | 80, 443 | Public | ✅ |
| Nextcloud | File sync & collaboration | Internal | Public (via Caddy) | ❌ Manual |
| PostgreSQL 18 | Database | Internal | Internal only | ❌ Manual |
| Redis 7 | Cache layer | Internal | Internal only | ❌ Manual |
| OnlyOffice | Document editor | Internal | Public (via Caddy) | 👁️ Monitor |
| Excalidraw | Whiteboard tool | Internal | Public (via Caddy) | ✅ |
| Obsidian | Note-taking | Internal | Public (via Caddy) | ✅ |
| Homarr | Dashboard | Internal | Tailscale only | ✅ |
| Dockhand | Container manager | 3003 | Tailscale only | ✅ |
| Uptime Kuma | Monitoring | Internal | Tailscale only | ✅ |
| Watchtower | Auto-updater | N/A | N/A | N/A |
## Security Features
- **Firewall**: UFW configured with minimal open ports
- **Fail2ban**: SSH brute-force protection
- **Automatic Updates**: Unattended security updates enabled
- **Secret Management**: Ansible Vault encryption for all credentials
- **Access Control**: Management UIs restricted to Tailscale network
- **SSL/TLS**: Automatic Let's Encrypt certificates
- **Container Isolation**: Dedicated Docker network
## Backup System
- **Daily**: PostgreSQL database dumps (3:00 AM)
- **Weekly**: Full volume backups (Sundays)
- **Retention**: 30 days
- **Location**: `/opt/nextcloud-stack/backups/`
- **rclone**: Pre-installed for future remote backups
### Manual Backup
```bash
ssh user@server
cd /opt/nextcloud-stack
./backup.sh
```
### Restore from Backup
See [BACKUP_RESTORE.md](BACKUP_RESTORE.md) for detailed procedures.
## Tailscale Setup
If you didn't provide an auth key during setup:
```bash
ssh user@server
sudo tailscale up
```
Then access management interfaces via Tailscale IP or MagicDNS.
## Updating Services
### Safe to Auto-Update (Watchtower handles)
- Caddy, Excalidraw, Obsidian, Homarr, Dockhand, Uptime Kuma
### Monitor Only (notifications, no auto-update)
- OnlyOffice
### Manual Update Required
- Nextcloud
- PostgreSQL
- Redis
### Updating Nextcloud Manually
```bash
ssh user@server
cd /opt/nextcloud-stack
# 1. Backup
./backup.sh
# 2. Enable maintenance mode
docker exec -u www-data next php occ maintenance:mode --on
# 3. Update
docker compose pull next
docker compose up -d next
# 4. Run database migrations
docker exec -u www-data next php occ upgrade
# 5. Disable maintenance mode
docker exec -u www-data next php occ maintenance:mode --off
```
## Troubleshooting
### DNS Not Configured
**Error**: Let's Encrypt fails to issue certificates
**Solution**: Ensure all DNS A records point to your server IP. Check with:
```bash
dig +short cloud.yourdomain.com
```
### LXC Container Issues
**Error**: Docker fails to start
**Solution**: On LXC host, enable nested virtualization:
```bash
lxc config set CONTAINER_NAME security.nesting true
lxc restart CONTAINER_NAME
```
### Port Already in Use
**Error**: Port 80 or 443 already bound
**Solution**: Check what's using the ports:
```bash
sudo ss -tlnp | grep ':80\|:443'
sudo systemctl stop apache2 # or nginx
```
### Nextcloud Stuck in Maintenance Mode
```bash
docker exec -u www-data next php occ maintenance:mode --off
```
### View Logs
```bash
cd /opt/nextcloud-stack
docker compose logs -f [service-name]
```
## Post-Deployment Tasks
1. **Login to Nextcloud**:
- URL: `https://cloud.yourdomain.com`
- Username: (set during setup)
- Password: (stored in vault)
2. **Setup Uptime Kuma**:
- URL: `https://uptime.yourdomain.com` (via Tailscale)
- Create admin account on first visit
- Configure monitors for your services
3. **Configure Homarr Dashboard**:
- URL: `https://home.yourdomain.com` (via Tailscale)
- Add service tiles
- Customize layout
4. **Configure OnlyOffice in Nextcloud**:
- Nextcloud Settings → Administration → Office
- Document Editing Service: `https://office.yourdomain.com`
5. **Test Backups**:
```bash
make backup
```
## File Locations on Server
```
/opt/nextcloud-stack/
├── docker-compose.yml
├── .env
├── backup.sh
├── configs/
│ ├── caddy/Caddyfile
│ └── nextcloud/
├── data/
│ ├── homarr/
│ └── obsidian/
└── backups/
├── database/
└── volumes/
```
## Environment Variables
All secrets are stored in `inventory/group_vars/all/vault.yml` (encrypted).
To edit:
```bash
make edit-vault
```
## Multiple Server Deployment
The setup script supports multiple servers. Each can have its own domain:
```bash
Server 1: 192.168.1.100 → cloud1.example.com
Server 2: 192.168.1.101 → cloud2.anotherdomain.net
Server 3: 192.168.1.102 → personal.mydomain.org
```
Deploy to all:
```bash
make deploy
```
Deploy to specific server:
```bash
ansible-playbook playbooks/site.yml --limit server_hostname --ask-vault-pass
```
## Maintenance
### Check Container Status
```bash
make status
```
### Restart Services
```bash
make restart
```
### Update Images (safe services only)
```bash
make update
```
### View Logs
```bash
make logs
```
## Uninstallation
```bash
ssh user@server
cd /opt/nextcloud-stack
docker compose down -v # WARNING: Deletes all data!
cd /opt
rm -rf nextcloud-stack
```
## Support
- See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for common issues
- See [BACKUP_RESTORE.md](BACKUP_RESTORE.md) for backup procedures
- See [AGENTS.md](AGENTS.md) for development guidelines
## License
MIT
## Acknowledgments
- Nextcloud team
- Caddy web server
- Ansible community
- All open-source contributors
---
**Built with ❤️ for self-hosting enthusiasts**