Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
31aa999
Initial plan
Copilot Jan 8, 2026
72ff764
Add complete Nextcloud on AKS infrastructure code
Copilot Jan 8, 2026
1045ad7
Add deployment and architecture documentation
Copilot Jan 8, 2026
56b2277
Add security improvements: private PostgreSQL, random passwords, docu…
Copilot Jan 8, 2026
2a1651b
Fix code review issues: network config, PV namespace, secure credenti…
Copilot Jan 8, 2026
0dd64bb
Improve code quality: stronger passwords, better storage naming, clea…
Copilot Jan 8, 2026
1a56b4f
Fix deployment errors: remove deprecated docker_bridge_cidr, add rand…
Copilot Jan 25, 2026
7ef86d3
Fix LocationIsOfferRestricted error: change default region to eastus …
Copilot Jan 25, 2026
51b9d2a
Switch from PostgreSQL to MariaDB for westeurope compatibility
Copilot Jan 25, 2026
00967c9
Reduce MariaDB storage from 50GB to 5GB minimum with auto-grow
Copilot Jan 25, 2026
d2bd765
Switch from deprecated MariaDB to MySQL Flexible Server with 5GB stor…
Copilot Jan 25, 2026
c146f89
Fix MySQL Flexible Server storage minimum from 5GB to 20GB
Copilot Jan 25, 2026
3ed57e4
Add random suffix to MySQL server name for global uniqueness
Copilot Jan 25, 2026
4c6e6f2
Fix MySQL SKU from B_Standard_B1s to B_Standard_B1ms for westeurope s…
Copilot Jan 25, 2026
49a4e2d
Switch to containerized MySQL StatefulSet in AKS (removes Azure MySQL…
Copilot Jan 25, 2026
9537595
Update documentation for containerized MySQL deployment
Copilot Jan 25, 2026
d413b4a
Fix code review issues: secure MySQL health probe, update architectur…
Copilot Jan 25, 2026
4468f9d
Fix deployment script: add MySQL StatefulSet deployment and wait logic
Copilot Jan 25, 2026
d7a8808
Fix Nextcloud pod crashes: increase health probe initial delays for d…
Copilot Jan 25, 2026
712a2e0
Fix deployment script: improve MySQL readiness check with better time…
Copilot Jan 25, 2026
5457688
Fix MySQL readiness probe: add authentication credentials for mysqlad…
Copilot Jan 25, 2026
b1b3e84
Add startup probe to Nextcloud for better first-time initialization h…
Copilot Jan 25, 2026
1d590c0
Improve documentation clarity in startup probe comments
Copilot Jan 25, 2026
76b918e
Fix concurrent initialization: start with 1 replica, scale after init…
Copilot Jan 25, 2026
ccbfa00
Fix documentation: use consistent MySQL hostname across all examples
Copilot Jan 25, 2026
632af25
Extend Nextcloud startup probe to 20 minutes for slow database initia…
Copilot Jan 25, 2026
0b6c387
Fix documentation: add comments and fix kubectl exec command for sing…
Copilot Jan 25, 2026
dad2558
Add regular ClusterIP service for MySQL alongside headless service fo…
Copilot Jan 25, 2026
d6b2089
Fix slow initialization: split storage - only mount data/config dirs …
Copilot Jan 25, 2026
b47597f
Update documentation with faster initialization times and improved tr…
Copilot Jan 25, 2026
94bfcd9
Add *.westeurope.cloudapp.azure.com to trusted domains for public IP …
Copilot Jan 25, 2026
94850b4
Add init container to configure trusted domains using occ command for…
Copilot Jan 25, 2026
339e01d
Add error handling to init container occ commands
Copilot Jan 25, 2026
cb97a7f
Fix init container: mount data volume and check installation status b…
Copilot Jan 25, 2026
9abfc63
Revert "Add init container to configure trusted domains using occ com…
Jan 25, 2026
27e47d5
Update trusted domains
Jan 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Terraform files
*.tfstate
*.tfstate.*
.terraform/
.terraform.lock.hcl
terraform.tfvars
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Kubernetes secrets
*-secret.yaml
secrets/

# Environment files
.env
.env.local

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Temporary files
tmp/
temp/
*.tmp
309 changes: 308 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,308 @@
# aks-nextcloud
# Nextcloud on Azure Kubernetes Service (AKS)

This repository contains infrastructure as code (IaC) for deploying Nextcloud on Azure Kubernetes Service (AKS) using Terraform and Kubernetes manifests.

## Architecture

The infrastructure includes:

- **Azure Kubernetes Service (AKS)**: Container orchestration platform
- **MySQL (containerized)**: Database running as StatefulSet within AKS cluster
- **Azure Storage Account**: Persistent storage for Nextcloud user files and config using Azure Files
- **Azure Virtual Network**: Network isolation and security
- **Redis**: In-memory cache for improved performance
- **Kubernetes Resources**:
- Nextcloud application deployment
- MySQL StatefulSet with persistent storage
- Redis deployment for caching
- Persistent Volume Claims for data storage
- Services and Ingress for external access

### Storage Architecture

Nextcloud uses a **split storage approach** for optimal performance:

1. **Application Code** (container local filesystem):
- Nextcloud application files remain in the container
- Fast startup and execution
- No rsync overhead during initialization

2. **User Data** (Azure Files - 100GB):
- Mounted at `/var/www/html/data`
- Stores user-uploaded files
- ReadWriteMany access mode for multi-pod support

3. **Configuration** (Azure Files - 1GB):
- Mounted at `/var/www/html/config`
- Stores config.php and settings
- Shared across all Nextcloud pods for consistency

4. **Database** (Managed-CSI - 20GB):
- MySQL uses block storage for optimal performance
- Fast database operations

## Prerequisites

- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) (>= 2.30)
- [Terraform](https://www.terraform.io/downloads.html) (>= 1.0)
- [kubectl](https://kubernetes.io/docs/tasks/tools/) (>= 1.24)
- [kustomize](https://kustomize.io/) (>= 4.0) - optional, for Kustomize-based deployments
- Azure subscription with appropriate permissions

## Quick Start

### 1. Deploy Infrastructure with Terraform

```bash
# Login to Azure
az login

# Navigate to terraform directory
cd terraform

# Copy example variables file
cp terraform.tfvars.example terraform.tfvars

# Edit terraform.tfvars with your desired configuration
vim terraform.tfvars

# Initialize Terraform
terraform init

# Review the planned changes
terraform plan

# Apply the configuration
terraform apply
```

### 2. Configure kubectl

```bash
# Get AKS credentials
az aks get-credentials --resource-group <resource-group-name> --name <aks-cluster-name>

# Verify connection
kubectl get nodes
```

### 3. Update Kubernetes Secrets

After Terraform completes, update the secrets with actual values:

```bash
# Get Terraform outputs
terraform output -json > outputs.json

# Extract values (example using jq)
POSTGRES_FQDN=$(terraform output -raw mysql_fqdn)
POSTGRES_PASSWORD=$(terraform output -raw mysql_admin_password)
STORAGE_ACCOUNT_NAME=$(terraform output -raw storage_account_name)
STORAGE_ACCOUNT_KEY=$(terraform output -raw storage_account_key)

# Update secrets file
cd ../kubernetes/base
# Edit secrets.yaml and replace placeholder values
```

Or use a script to generate secrets:

```bash
# Example: Create secrets from Terraform outputs
kubectl create secret generic nextcloud-db \
--from-literal=db-host="$POSTGRES_FQDN" \
--from-literal=db-name="nextcloud" \
--from-literal=db-username="nextcloudadmin" \
--from-literal=db-password="$POSTGRES_PASSWORD" \
--namespace=nextcloud --dry-run=client -o yaml > secrets-db.yaml

kubectl create secret generic azure-storage \
--from-literal=azurestorageaccountname="$STORAGE_ACCOUNT_NAME" \
--from-literal=azurestorageaccountkey="$STORAGE_ACCOUNT_KEY" \
--namespace=nextcloud --dry-run=client -o yaml > secrets-storage.yaml
```

### 4. Deploy Nextcloud to Kubernetes

#### Option A: Using kubectl

```bash
cd kubernetes/base

# Create namespace
kubectl apply -f namespace.yaml

# Apply all resources
kubectl apply -f .
```

#### Option B: Using Kustomize (Recommended)

For development environment:
```bash
cd kubernetes/overlays/dev
kubectl apply -k .
```

For production environment:
```bash
cd kubernetes/overlays/prod
kubectl apply -k .
```

### 5. Access Nextcloud

```bash
# Get the external IP address
kubectl get service nextcloud -n nextcloud

# Wait for EXTERNAL-IP to be assigned
# Access Nextcloud at http://<EXTERNAL-IP>
```

**Important:** After first deployment, wait for Nextcloud initialization to complete (5-10 minutes), then scale to multiple replicas if needed:

```bash
# Check if Nextcloud is initialized
kubectl logs -n nextcloud -l app=nextcloud --tail=20
# Look for "Nextcloud is already installed"

# Scale to 2 replicas (after initialization completes)
kubectl scale deployment nextcloud -n nextcloud --replicas=2
```

For production with Ingress:
1. Install an Ingress controller (e.g., NGINX Ingress Controller)
2. Install cert-manager for TLS certificates
3. **Important:** Update the Ingress resource in `kubernetes/base/ingress.yaml` with your actual domain name (replace `nextcloud.example.com`)
4. Access Nextcloud at https://your-domain.com

## Configuration

### Terraform Variables

Key variables in `terraform/variables.tf`:

- `resource_group_name`: Azure resource group name
- `location`: Azure region (e.g., westeurope, eastus) - works in any region with containerized MySQL
- `prefix`: Prefix for resource names
- `node_count`: Initial number of AKS nodes
- `vm_size`: VM size for AKS nodes

Note: MySQL is deployed as a containerized StatefulSet within AKS, so no database-specific Terraform variables are needed.

### Kubernetes Configuration

Key configurations in `kubernetes/base/configmap.yaml`:

- `NEXTCLOUD_TRUSTED_DOMAINS`: Domains allowed to access Nextcloud
- `PHP_MEMORY_LIMIT`: PHP memory limit
- `PHP_UPLOAD_LIMIT`: Maximum file upload size
- `REDIS_HOST`: Redis hostname for caching

## Scaling

### Horizontal Pod Autoscaling

To enable HPA for Nextcloud:

```bash
kubectl autoscale deployment nextcloud \
--cpu-percent=70 \
--min=2 \
--max=10 \
-n nextcloud
```

### AKS Node Autoscaling

The AKS cluster is configured with autoscaling enabled. Adjust `min_node_count` and `max_node_count` in Terraform variables.

## Monitoring

Consider installing:

- **Prometheus & Grafana**: For metrics and monitoring
- **Azure Monitor**: For AKS and resource monitoring
- **Log Analytics**: For centralized logging

## Backup and Disaster Recovery

1. **Database Backups**: MySQL data is stored in Kubernetes persistent volumes. Use Velero or Azure Backup for Kubernetes for backup/restore
2. **File Backups**: Use Azure Storage snapshots or backup solutions
3. **Kubernetes Resources**: Store manifests in version control (this repository)

## Security Considerations

1. **Secrets Management**:
- Use Azure Key Vault for production secrets
- Consider External Secrets Operator or Sealed Secrets

2. **Network Security**:
- Configure Network Security Groups (NSGs)
- MySQL is internal to the cluster (not publicly accessible)
- Enable Pod Security Standards

3. **TLS/SSL**:
- Use cert-manager with Let's Encrypt for automatic certificate management
- Configure HTTPS-only access

4. **Database Security**:
- Use strong passwords (auto-generated in Terraform)
- Restrict firewall rules
- Enable SSL connections

## Troubleshooting

### Terraform deployment errors

Note: This deployment uses containerized MySQL which works in any Azure region without subscription restrictions.

### Check pod status
```bash
kubectl get pods -n nextcloud
kubectl describe pod <pod-name> -n nextcloud
kubectl logs <pod-name> -n nextcloud
```

### Check persistent volumes
```bash
kubectl get pv,pvc -n nextcloud
```

### Database connection issues
```bash
# Test from a debug pod
kubectl run -it --rm debug --image=mysql:8.0 --restart=Never -n nextcloud -- mysql -h mysql -u nextcloud -p
```

## Cleanup

To destroy all resources:

```bash
# Delete Kubernetes resources
kubectl delete namespace nextcloud

# Destroy Terraform infrastructure
cd terraform
terraform destroy
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request

## License

MIT License - See LICENSE file for details

## References

- [Nextcloud Documentation](https://docs.nextcloud.com/)
- [Azure AKS Documentation](https://docs.microsoft.com/en-us/azure/aks/)
- [Terraform Azure Provider](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs)
- [Kubernetes Documentation](https://kubernetes.io/docs/home/)
Loading