# 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 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**