mirror of
https://github.com/wahyd4/you-music.git
synced 2026-08-09 05:06:44 +10:00
498 lines
10 KiB
Markdown
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
|