Files
you-music/k8s/README.md
T
2025-10-30 22:35:02 +11:00

498 lines
10 KiB
Markdown

# Kubernetes Deployment Guide for YouMusic
This guide explains how to deploy YouMusic to your k3s cluster.
## Prerequisites
- k3s cluster running
- kubectl configured to access your cluster
- cert-manager installed (for TLS certificates)
- nginx ingress controller installed
- Optional: Private container registry credentials
## Quick Start
### 0. Database Migrations
YouMusic now uses Alembic for database migrations. An init container will automatically run migrations before the app starts.
**How it works:**
- Init container runs `/app/backend/run-migrations.sh`
- Executes `alembic upgrade head`
- Must complete successfully before app starts
- Shares the same data volume with the app
### 1. Build and Push Docker Image
```bash
# Build the image
docker build -t youmusic:latest .
# Tag for your registry (example with GitHub Container Registry)
docker tag youmusic:latest ghcr.io/wahyd4/youmusic:latest
# Push to registry
docker push ghcr.io/wahyd4/youmusic:latest
```
### 2. Update Manifest
Edit `k8s/manifest.yaml` and update:
```yaml
# Line 47: Update image name
image: "ghcr.io/wahyd4/youmusic:latest"
# Line 125-126: Update domain name
- host: music.junv.cc # Your domain
secretName: youmusic-tls
```
### 3. Create Secret for Private Registry (Optional)
If using private registry:
```bash
kubectl create secret docker-registry github-image-pull-secret \
--docker-server=ghcr.io \
--docker-username=your-github-username \
--docker-password=your-github-token \
--docker-email=your-email@example.com
```
Then uncomment in manifest:
```yaml
imagePullSecrets:
- name: github-image-pull-secret
```
### 4. Deploy to Kubernetes
```bash
# Apply the manifest
kubectl apply -f k8s/manifest.yaml
# Check deployment status
kubectl get pods -l app=youmusic
kubectl get svc youmusic
kubectl get ingress youmusic-ingress
```
### 5. Verify Deployment
```bash
# Check pod logs
kubectl logs -f deployment/youmusic
# Check migration init container logs
kubectl logs -l app=youmusic -c youmusic-migrations
# Check if pod is running
kubectl get pods
# Describe pod for details
kubectl describe pod -l app=youmusic
```
## Manifest Structure
### PersistentVolumeClaim (PVC)
```yaml
- Name: youmusic-data-pvc
- Size: 50Gi
- Access: ReadWriteOnce (single node)
- Storage Class: local-path (default in k3s)
```
**Stores:**
- SQLite database (`/app/data/youmusic.db`)
- Music files (`/app/data/music/`)
- Uploaded files (`/app/data/uploads/`)
- Thumbnails (`/app/data/music/thumbnails/`)
- Artist cache (`/app/data/cache/artists/`)
- Artist images (`/app/data/cache/artist_images/`)
### Deployment
```yaml
- Replicas: 1 (SQLite limitation)
- Strategy: Recreate (prevent multiple pods)
- Image: Your registry image
- Resources:
- Requests: 200m CPU, 512Mi RAM
- Limits: 2000m CPU, 2048Mi RAM
```
**Environment Variables:**
- `DATABASE_URL`: SQLite connection string
- `MUSIC_DIR`: Music files directory
- `UPLOAD_DIR`: Upload directory
- `TEMP_DIR`: Temporary files
- `BASE_DIR`: Application base directory
**Health Checks:**
- Liveness: HTTP GET / every 10s
- Readiness: HTTP GET / every 5s
### Service
```yaml
- Type: ClusterIP
- Port: 80 → 8000 (container)
```
### Ingress
```yaml
- Class: nginx
- TLS: Enabled (Let's Encrypt)
- Max Upload: 500MB
- Timeouts: 600s
```
**Annotations:**
- `proxy-body-size: 500m` - Large file uploads
- `proxy-read-timeout: 600` - Long downloads
- `proxy-send-timeout: 600` - Long uploads
## Configuration Options
### Storage Class
Update if using different storage:
```yaml
storageClassName: nfs-client # Or your storage class
```
### Domain Configuration
Update your domain in:
```yaml
spec:
tls:
- hosts:
- your-domain.com
secretName: youmusic-tls
rules:
- host: your-domain.com
```
### Enable Authentication (Optional)
Uncomment in ingress annotations:
```yaml
nginx.ingress.kubernetes.io/auth-url: "https://pass.junv.cc/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://pass.junv.cc/?redirect=https%3A%2F%2F$host$request_uri"
```
### Resource Limits
Adjust based on your needs:
```yaml
resources:
requests:
cpu: 200m # Increase for better performance
memory: 512Mi # Increase if many downloads
limits:
cpu: 2000m # Max CPU
memory: 2048Mi # Max memory
```
## Persistent Data
All data is stored in the PVC:
```
/app/data/
├── youmusic.db # SQLite database
├── music/ # Downloaded music files
│ ├── song1.mp3
│ ├── song2.mp3
│ └── thumbnails/ # Song thumbnails
│ ├── song1.jpg
│ └── song2.jpg
├── uploads/ # User uploaded files
├── temp/ # Temporary download files
└── cache/ # Cache directory
├── artists/ # Artist metadata JSON
│ └── Westlife.json
└── artist_images/ # Artist avatars
└── Westlife.jpg
```
### Backup Data
```bash
# Get pod name
POD=$(kubectl get pod -l app=youmusic -o jsonpath='{.items[0].metadata.name}')
# Copy data from pod
kubectl cp $POD:/app/data ./youmusic-backup
# Or use exec to tar
kubectl exec $POD -- tar czf - /app/data > youmusic-backup.tar.gz
```
### Restore Data
```bash
# Copy backup to pod
kubectl cp ./youmusic-backup $POD:/app/data-restore
# Or restore from tar
kubectl exec -i $POD -- tar xzf - -C /app < youmusic-backup.tar.gz
```
## Monitoring
### View Logs
```bash
# Follow logs
kubectl logs -f deployment/youmusic
# Last 100 lines
kubectl logs --tail=100 deployment/youmusic
# All containers (if multiple)
kubectl logs -f -l app=youmusic --all-containers
```
### Pod Status
```bash
# Get pod details
kubectl describe pod -l app=youmusic
# Get events
kubectl get events --sort-by=.metadata.creationTimestamp
```
### Resource Usage
```bash
# CPU and memory usage
kubectl top pod -l app=youmusic
# Node resources
kubectl top nodes
```
## Troubleshooting
### Pod Not Starting
```bash
# Check pod status
kubectl get pods -l app=youmusic
# Check events
kubectl describe pod -l app=youmusic
# Check logs
kubectl logs deployment/youmusic
```
**Common Issues:**
- Image pull errors → Check imagePullSecrets
- Permission denied → Check volume permissions
- Database locked → Ensure single replica only
### Database Issues
```bash
# Check migration init container logs
kubectl logs -l app=youmusic -c youmusic-migrations
# Exec into pod
kubectl exec -it deployment/youmusic -- bash
# Check database
cd /app/data
ls -la youmusic.db
# Check SQLite
sqlite3 youmusic.db "SELECT COUNT(*) FROM music;"
# Manually run migrations if needed
cd /app/backend
./migrate.sh current
./migrate.sh history
./migrate.sh upgrade
```
### Storage Full
```bash
# Check disk usage
kubectl exec deployment/youmusic -- df -h /app/data
# Check directory sizes
kubectl exec deployment/youmusic -- du -sh /app/data/*
```
**Solution:** Increase PVC size:
```yaml
resources:
requests:
storage: 100Gi # Increase from 50Gi
```
Then:
```bash
kubectl patch pvc youmusic-data-pvc -p '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'
```
### Ingress Not Working
```bash
# Check ingress
kubectl get ingress youmusic-ingress
kubectl describe ingress youmusic-ingress
# Check cert-manager
kubectl get certificate
kubectl describe certificate youmusic-tls
```
## Scaling Limitations
⚠️ **Important:** YouMusic uses SQLite, which does NOT support multiple concurrent writers.
**Limitations:**
- ✅ Can handle multiple readers
- ❌ Cannot scale replicas > 1
- ❌ ReadWriteOnce PVC (single node only)
**For Production at Scale:**
- Consider migrating to PostgreSQL/MySQL
- Update DATABASE_URL environment variable
- Enable multi-replica deployment
## Updates
### Update Image
```bash
# Build new version
docker build -t ghcr.io/wahyd4/youmusic:v2 .
docker push ghcr.io/wahyd4/youmusic:v2
# Update deployment
kubectl set image deployment/youmusic youmusic=ghcr.io/wahyd4/youmusic:v2
# Or edit manifest and reapply
kubectl apply -f k8s/manifest.yaml
# Check rollout status
kubectl rollout status deployment/youmusic
```
### Rollback
```bash
# View rollout history
kubectl rollout history deployment/youmusic
# Rollback to previous version
kubectl rollout undo deployment/youmusic
# Rollback to specific revision
kubectl rollout undo deployment/youmusic --to-revision=2
```
## Clean Up
```bash
# Delete all resources
kubectl delete -f k8s/manifest.yaml
# Delete PVC (will delete all data!)
kubectl delete pvc youmusic-data-pvc
```
⚠️ **Warning:** Deleting the PVC will permanently delete all music, database, and cache!
## Advanced Configuration
### Using NFS Storage
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: youmusic-nfs-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.1.5
path: "/nfs/youmusic"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: youmusic-data-pvc
spec:
storageClassName: ""
volumeName: youmusic-nfs-pv
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
```
### Multiple Environments
```bash
# Create namespace
kubectl create namespace youmusic-prod
kubectl create namespace youmusic-dev
# Deploy to specific namespace
kubectl apply -f k8s/manifest.yaml -n youmusic-prod
kubectl apply -f k8s/manifest-dev.yaml -n youmusic-dev
```
## Security Considerations
1. **Enable Authentication** (Recommended)
- Use nginx ingress auth
- Integrate with OAuth2 proxy
- Restrict access to trusted users
2. **Network Policies**
- Restrict pod-to-pod communication
- Limit egress for downloads
3. **Resource Limits**
- Set CPU/memory limits
- Prevent resource exhaustion
4. **Secrets Management**
- Use Kubernetes secrets for sensitive data
- Consider using sealed-secrets or external-secrets
## Support
For issues or questions:
- Check logs: `kubectl logs deployment/youmusic`
- Review events: `kubectl get events`
- Check documentation: See main README.md
- GitHub Issues: [Your repo URL]
---
**Deployment Version:** 1.0.0
**Last Updated:** 2024-10-30