Add docker file and k8s manifest

This commit is contained in:
2025-10-30 16:44:07 +11:00
parent 574d0c7ffd
commit 3a0b466cd9
5 changed files with 1326 additions and 3 deletions
+76
View File
@@ -0,0 +1,76 @@
name: Build and Push Docker Image
on:
push:
branches:
- main
- develop
tags:
- 'v*'
pull_request:
branches:
- main
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Summary
if: github.event_name != 'pull_request'
run: |
echo "### Docker Image Built and Pushed :rocket:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Registry:** ${{ env.REGISTRY }}" >> $GITHUB_STEP_SUMMARY
echo "**Image:** ${{ env.IMAGE_NAME }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Tags:**" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
+602
View File
@@ -0,0 +1,602 @@
# YouMusic Deployment Guide
Complete guide for deploying YouMusic to production using Docker and Kubernetes.
## Table of Contents
1. [Docker Deployment](#docker-deployment)
2. [Kubernetes Deployment](#kubernetes-deployment)
3. [Data Persistence](#data-persistence)
4. [Environment Configuration](#environment-configuration)
5. [Backup and Restore](#backup-and-restore)
---
## Docker Deployment
### Using Docker Compose (Recommended for Single Server)
The simplest way to deploy YouMusic is using Docker Compose:
```bash
# Start the service
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the service
docker-compose down
```
Your music player will be available at `http://localhost:8000`
### Using Docker Run
```bash
# Create data directory
mkdir -p ./data
# Run container
docker run -d \
--name youmusic \
-p 8000:8000 \
-v $(pwd)/data:/app/data \
-e DATABASE_URL=sqlite+aiosqlite:///./data/youmusic.db \
ghcr.io/wahyd4/youmusic:latest
# View logs
docker logs -f youmusic
```
### Building Custom Image
```bash
# Clone repository
git clone https://github.com/wahyd4/you-music.git
cd you-music
# Build image
docker build -t youmusic:custom .
# Run with custom image
docker run -d \
--name youmusic \
-p 8000:8000 \
-v $(pwd)/data:/app/data \
youmusic:custom
```
---
## Kubernetes Deployment
### Prerequisites
- k3s/k8s cluster
- kubectl configured
- cert-manager (for TLS)
- nginx-ingress controller
### Step-by-Step Deployment
#### 1. Build and Push Image
```bash
# Build the image
docker build -t youmusic:latest .
# Tag for registry
docker tag youmusic:latest ghcr.io/wahyd4/youmusic:latest
# Login to GitHub Container Registry
echo $GITHUB_TOKEN | docker login ghcr.io -u wahyd4 --password-stdin
# Push to registry
docker push ghcr.io/wahyd4/youmusic:latest
```
Or use GitHub Actions (automatic on push to main):
```bash
git push origin main
# Image will be built and pushed automatically
```
#### 2. Configure Manifest
Edit `k8s/manifest.yaml`:
```yaml
# Update image name (line 47)
image: "ghcr.io/wahyd4/youmusic:latest"
# Update domain (line 125-126)
- host: music.yourdomain.com
secretName: youmusic-tls
```
#### 3. Deploy to Cluster
```bash
# Apply manifest
kubectl apply -f k8s/manifest.yaml
# Check status
kubectl get pods -l app=youmusic
kubectl get svc youmusic
kubectl get ingress youmusic-ingress
```
#### 4. Verify Deployment
```bash
# Watch pod startup
kubectl get pods -l app=youmusic -w
# Check logs
kubectl logs -f deployment/youmusic
# Check ingress
kubectl describe ingress youmusic-ingress
```
#### 5. Access Application
```bash
# Get ingress IP/hostname
kubectl get ingress youmusic-ingress
# Wait for TLS certificate
kubectl get certificate youmusic-tls
# Access via domain
https://music.yourdomain.com
```
### Common Deployment Scenarios
#### Scenario 1: Private Registry
```bash
# Create secret
kubectl create secret docker-registry github-image-pull-secret \
--docker-server=ghcr.io \
--docker-username=wahyd4 \
--docker-password=$GITHUB_TOKEN
# Uncomment in manifest
# imagePullSecrets:
# - name: github-image-pull-secret
```
#### Scenario 2: Custom Storage
Update PVC in manifest:
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: youmusic-data-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: your-storage-class # Update this
resources:
requests:
storage: 100Gi # Adjust size
```
#### Scenario 3: Enable Authentication
Add to ingress annotations:
```yaml
nginx.ingress.kubernetes.io/auth-url: "https://auth.yourdomain.com/verify"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.yourdomain.com/login"
```
---
## Data Persistence
### Directory Structure
All persistent data is stored in `/app/data`:
```
/app/data/
├── youmusic.db # SQLite database
├── youmusic.db-shm # SQLite shared memory
├── youmusic.db-wal # SQLite write-ahead log
├── music/ # Music files
│ ├── song1.mp3
│ ├── song2.mp3
│ └── thumbnails/ # Song thumbnails
│ ├── song1.jpg
│ └── song2.jpg
├── uploads/ # User uploads
├── temp/ # Temporary downloads
└── cache/ # Cache directory
├── artists/ # Artist metadata
│ ├── Westlife.json
│ └── Taylor_Swift.json
└── artist_images/ # Artist avatars
├── Westlife.jpg
└── Taylor_Swift.jpg
```
### Volume Mounting
**Docker:**
```bash
-v /path/on/host:/app/data
```
**Kubernetes:**
```yaml
volumeMounts:
- name: data
mountPath: /app/data
```
### Storage Requirements
| Component | Size per Item | Example (100 items) |
|-----------|---------------|---------------------|
| Database | ~1KB per song | 100KB |
| Music Files | 3-10MB per song | 500MB |
| Thumbnails | 50-200KB per song | 10MB |
| Artist Info | 2KB per artist | 200KB |
| Artist Images | 100-200KB per artist | 15MB |
| **Total** | - | **~525MB** |
**Recommended PVC Size:**
- Small (100 songs): 10Gi
- Medium (500 songs): 25Gi
- Large (1000+ songs): 50Gi+
---
## Environment Configuration
### Required Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `DATABASE_URL` | SQLite connection string | `sqlite+aiosqlite:///./data/youmusic.db` |
| `MUSIC_DIR` | Music files directory | `/app/data/music` |
| `UPLOAD_DIR` | Upload directory | `/app/data/uploads` |
| `TEMP_DIR` | Temporary files | `/app/data/temp` |
| `BASE_DIR` | Application base path | `/app` |
### Optional Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `FFMPEG_LOCATION` | FFmpeg binary path | `ffmpeg` |
| `PROXY` | HTTP proxy for downloads | - |
### Setting Variables
**Docker:**
```bash
docker run -e DATABASE_URL="..." -e MUSIC_DIR="..." youmusic
```
**Docker Compose:**
```yaml
environment:
- DATABASE_URL=sqlite+aiosqlite:///./data/youmusic.db
- MUSIC_DIR=/app/data/music
```
**Kubernetes:**
```yaml
env:
- name: DATABASE_URL
value: "sqlite+aiosqlite:///./data/youmusic.db"
- name: MUSIC_DIR
value: "/app/data/music"
```
---
## Backup and Restore
### Docker Backup
```bash
# Stop container
docker stop youmusic
# Backup data directory
tar czf youmusic-backup-$(date +%Y%m%d).tar.gz ./data
# Restart container
docker start youmusic
```
### Docker Restore
```bash
# Stop container
docker stop youmusic
# Restore data
tar xzf youmusic-backup-20241030.tar.gz
# Start container
docker start youmusic
```
### Kubernetes Backup
```bash
# Get pod name
POD=$(kubectl get pod -l app=youmusic -o jsonpath='{.items[0].metadata.name}')
# Backup entire data directory
kubectl exec $POD -- tar czf - /app/data > youmusic-backup-$(date +%Y%m%d).tar.gz
# Or copy files directly
kubectl cp $POD:/app/data ./youmusic-backup
```
### Kubernetes Restore
```bash
# Get pod name
POD=$(kubectl get pod -l app=youmusic -o jsonpath='{.items[0].metadata.name}')
# Restore from tar
kubectl exec -i $POD -- tar xzf - -C /app < youmusic-backup-20241030.tar.gz
# Or copy files
kubectl cp ./youmusic-backup $POD:/app/data-restore
# Move files (exec into pod)
kubectl exec -it $POD -- bash
mv /app/data-restore/* /app/data/
```
### Database-Only Backup
```bash
# Docker
docker exec youmusic sqlite3 /app/data/youmusic.db ".backup /app/data/backup.db"
docker cp youmusic:/app/data/backup.db ./youmusic-db-backup.db
# Kubernetes
kubectl exec deployment/youmusic -- sqlite3 /app/data/youmusic.db ".backup /app/data/backup.db"
kubectl cp deployment/youmusic:/app/data/backup.db ./youmusic-db-backup.db
```
### Automated Backups
Create a CronJob for automated backups:
```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: youmusic-backup
spec:
schedule: "0 2 * * *" # Daily at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: alpine:latest
command:
- sh
- -c
- |
apk add --no-cache sqlite
cd /data
sqlite3 youmusic.db ".backup backup-$(date +%Y%m%d).db"
find /data -name "backup-*.db" -mtime +7 -delete
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: youmusic-data-pvc
restartPolicy: OnFailure
```
---
## Monitoring and Maintenance
### Health Checks
**Docker:**
```bash
# Check container health
docker inspect youmusic | grep Health -A 10
# Manual health check
curl http://localhost:8000/
```
**Kubernetes:**
```bash
# Check pod health
kubectl describe pod -l app=youmusic | grep -A 5 Conditions
# Check endpoints
kubectl get endpoints youmusic
```
### Log Management
**Docker:**
```bash
# View logs
docker logs youmusic
# Follow logs
docker logs -f youmusic
# Last 100 lines
docker logs --tail=100 youmusic
```
**Kubernetes:**
```bash
# View logs
kubectl logs deployment/youmusic
# Follow logs
kubectl logs -f deployment/youmusic
# Last 100 lines
kubectl logs --tail=100 deployment/youmusic
```
### Resource Monitoring
**Kubernetes:**
```bash
# Resource usage
kubectl top pod -l app=youmusic
# Detailed metrics
kubectl describe pod -l app=youmusic
```
### Updates
**Docker:**
```bash
# Pull latest image
docker pull ghcr.io/wahyd4/youmusic:latest
# Stop and remove old container
docker stop youmusic
docker rm youmusic
# Start new container
docker run -d --name youmusic ...
```
**Kubernetes:**
```bash
# Update image
kubectl set image deployment/youmusic \
youmusic=ghcr.io/wahyd4/youmusic:v2
# Or reapply manifest
kubectl apply -f k8s/manifest.yaml
# Check rollout
kubectl rollout status deployment/youmusic
# Rollback if needed
kubectl rollout undo deployment/youmusic
```
---
## Troubleshooting
### Common Issues
#### 1. Database Locked
**Cause:** Multiple instances trying to write to SQLite
**Solution:**
```bash
# Kubernetes: Ensure single replica
kubectl scale deployment/youmusic --replicas=1
# Check for hung processes
kubectl exec deployment/youmusic -- ps aux | grep python
```
#### 2. Permission Denied
**Cause:** Volume mount permission issues
**Solution:**
```bash
# Check permissions
kubectl exec deployment/youmusic -- ls -la /app/data
# Fix permissions
kubectl exec deployment/youmusic -- chmod -R 755 /app/data
```
#### 3. FFmpeg Not Found
**Cause:** FFmpeg not installed in container
**Check:**
```bash
kubectl exec deployment/youmusic -- which ffmpeg
```
**Solution:** Image already includes ffmpeg, ensure using correct image.
#### 4. Storage Full
**Check:**
```bash
kubectl exec deployment/youmusic -- df -h /app/data
```
**Solution:** Increase PVC size or clean up old files.
---
## Security Best Practices
1. **Use Authentication**
- Enable nginx auth
- Use OAuth2 proxy
- Restrict network access
2. **Regular Updates**
- Keep image updated
- Monitor security advisories
- Update dependencies
3. **Backup Regularly**
- Automated daily backups
- Test restore procedures
- Store backups securely
4. **Resource Limits**
- Set CPU/memory limits
- Monitor resource usage
- Scale appropriately
5. **Network Policies**
- Restrict ingress/egress
- Use TLS everywhere
- Limit exposed services
---
## Production Checklist
- [ ] Domain configured
- [ ] TLS certificate issued
- [ ] Storage provisioned
- [ ] Backups configured
- [ ] Authentication enabled
- [ ] Resource limits set
- [ ] Monitoring enabled
- [ ] Logs aggregated
- [ ] Health checks working
- [ ] Update strategy defined
---
**Last Updated:** 2024-10-30
**Version:** 1.0.0
+14 -3
View File
@@ -13,7 +13,7 @@ RUN npm run build
# Final image
FROM python:3.11-slim
FROM python:3.13-slim
# Install system dependencies
RUN apt-get update && apt-get install -y \
@@ -33,17 +33,28 @@ COPY backend/ ./backend/
# Copy frontend build from builder stage
COPY --from=frontend-builder /app/frontend/dist ./backend/static
# Create data directories
RUN mkdir -p /app/data/music /app/data/uploads /app/data/temp
# Create data directories with proper permissions
RUN mkdir -p /app/data/music \
/app/data/uploads \
/app/data/temp \
/app/data/cache/artists \
/app/data/cache/artist_images \
&& chmod -R 755 /app/data
# Expose port
EXPOSE 8000
# Environment variables
ENV PYTHONUNBUFFERED=1
ENV DATABASE_URL=sqlite+aiosqlite:///./data/youmusic.db
ENV MUSIC_DIR=/app/data/music
ENV UPLOAD_DIR=/app/data/uploads
ENV TEMP_DIR=/app/data/temp
ENV BASE_DIR=/app
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/ || exit 1
# Run the application
CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000"]
+475
View File
@@ -0,0 +1,475 @@
# 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
### 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 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
# 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;"
```
### 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
+159
View File
@@ -0,0 +1,159 @@
# PersistentVolumeClaim for YouMusic data (SQLite DB, music, cache, etc.)
apiVersion: v1
kind: PersistentVolume
metadata:
name: youmusic-data-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.1.5
path: "/fs/1000/nfs/k8s/you-music"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "youmusic-data-pvc"
spec:
storageClassName: ""
volumeName: youmusic-data-pv
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: youmusic
labels:
app: youmusic
spec:
selector:
matchLabels:
app: youmusic
replicas: 1 # Single replica due to SQLite (ReadWriteOnce)
strategy:
type: Recreate # Prevent multiple pods accessing SQLite simultaneously
template:
metadata:
labels:
app: youmusic
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: youmusic-data-pvc
containers:
- name: youmusic
image: "ghcr.io/wahyd4/youmusic:latest" # Update with your image
imagePullPolicy: Always
volumeMounts:
- name: data
mountPath: /app/data
env:
- name: PYTHONUNBUFFERED
value: "1"
- name: DATABASE_URL
value: "sqlite+aiosqlite:///./data/youmusic.db"
- name: MUSIC_DIR
value: "/app/data/music"
- name: UPLOAD_DIR
value: "/app/data/uploads"
- name: TEMP_DIR
value: "/app/data/temp"
- name: BASE_DIR
value: "/app"
- name: FFMPEG_LOCATION
value: "ffmpeg"
# Optional: Set proxy if needed
# - name: PROXY
# value: "http://proxy:port"
ports:
- containerPort: 8000
name: http
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 2048Mi
# If using private registry, add imagePullSecrets
# imagePullSecrets:
# - name: github-image-pull-secret
---
# Service
apiVersion: v1
kind: Service
metadata:
name: youmusic
labels:
app: youmusic
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: web
selector:
app: youmusic
---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: youmusic-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
# Increase upload size for large music files
nginx.ingress.kubernetes.io/proxy-body-size: 500m
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
# Optional: Enable authentication
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"
spec:
ingressClassName: nginx
tls:
- hosts:
- music.junv.cc # Update with your domain
secretName: youmusic-tls
rules:
- host: music.junv.cc # Update with your domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: youmusic
port:
number: 80