Update config

This commit is contained in:
2025-11-07 21:32:34 +11:00
parent d24d00d16e
commit ee54d9c851
2 changed files with 10 additions and 612 deletions
-602
View File
@@ -1,602 +0,0 @@
# 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
+10 -10
View File
@@ -7,7 +7,7 @@ class Settings(BaseSettings):
# API Settings
API_V1_STR: str = "/api/v1"
PROJECT_NAME: str = "YouMusic"
# Directories
BASE_DIR: str = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
MUSIC_DIR: str = os.path.join(BASE_DIR, "data", "music")
@@ -15,30 +15,30 @@ class Settings(BaseSettings):
UPLOAD_DIR: str = os.path.join(BASE_DIR, "data", "uploads")
TEMP_DIR: str = os.path.join(BASE_DIR, "data", "temp")
CACHE_DIR: str = os.path.join(BASE_DIR, "data", "cache")
# Database
DATABASE_URL: str = "sqlite+aiosqlite:///./data/youmusic.db"
DATABASE_URL: str = os.getenv("DATABASE_URL", "sqlite+aiosqlite:///./data/youmusic.db")
# CORS
BACKEND_CORS_ORIGINS: list = ["*"]
# Download Settings
PROXY: Optional[str] = None
FFMPEG_LOCATION: str = "/usr/local/bin/ffmpeg"
FFMPEG_LOCATION: str = os.getenv("FFMPEG_LOCATION", "/usr/local/bin/ffmpeg")
# YT-DLP Settings
YT_DLP_FORMAT: str = "bestaudio/best"
YT_DLP_AUDIO_FORMAT: str = "mp3"
YT_DLP_AUDIO_QUALITY: str = "0"
# Scanner Settings
SCAN_INTERVAL: int = 3600 # Default 1 hour (in seconds)
DELETE_MISSING_FILES: bool = False # Don't delete missing files by default
AUTO_SCAN_ENABLED: bool = True # Enable automatic scanning
# Share Link Settings
SHARE_LINK_EXPIRATION_DAYS: int = 14 # Default expiration for share links
class Config:
case_sensitive = True
env_file = ".env"