19 KiB
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
./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 inventoryinventory/group_vars/all/vars.yml- Public configinventory/group_vars/all/vault.yml- Encrypted secrets
2. Deploy
make deploy
Or:
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 | Complete project overview, features, usage |
| DEPLOYMENT_GUIDE.md | Step-by-step deployment instructions |
| TROUBLESHOOTING.md | Common issues and solutions |
| BACKUP_RESTORE.md | Backup and restore procedures |
| AGENTS.md | Docker Compose & Ansible guidelines |
🛠️ Makefile Commands
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
- Test the deployment on a test server first
- Verify DNS is configured correctly
- Run setup.sh and answer questions carefully
- Deploy with
make deploy - Access Nextcloud and complete initial setup
After Deployment
- Configure Uptime Kuma monitoring
- Customize Homarr dashboard
- Test backups with
make backup - Enable 2FA in Nextcloud
- Install additional Nextcloud apps as needed
Ongoing
- Monitor service health in Uptime Kuma
- Review backups monthly
- Test restore procedures quarterly
- Update Nextcloud when new versions release (manually)
- Check logs for any issues
💡 Tips & Best Practices
For LXC Containers
On LXC host, enable nested virtualization:
lxc config set CONTAINER_NAME security.nesting true
lxc restart CONTAINER_NAME
For Production Use
- Use strong passwords (not example passwords)
- Enable Nextcloud 2FA
- Configure off-site backups with rclone
- Set up Uptime Kuma email alerts
- 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
-
Watchtower is archived (December 2025)
- Still works, but no longer maintained
- Consider alternative update strategies long-term
-
OnlyOffice needs 2GB+ RAM
- May be slow on low-memory servers
- Consider disabling if not needed
-
First-time deployment takes 30-45 min
- Mostly Docker image downloads
- Subsequent deploys are faster
-
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 - Getting started
- TROUBLESHOOTING.md - Fix common issues
- 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! 🎉