mirror of
https://github.com/R0m1k3/podcastic.git
synced 2026-10-11 17:26:20 +02:00
feat: add Unraid single-container deployment with docker-compose and comprehensive setup guide
This commit is contained in:
1 parent
9bb61cc8a7
commit
73585213ba
6 files changed
+753
-1
No files matched your search
@@ -2,7 +2,10 @@
|
|||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"Bash(rtk git:*)",
|
"Bash(rtk git:*)",
|
||||||
"Bash(rtk npm:*)"
|
"Bash(rtk npm:*)",
|
||||||
|
"Bash(git remote:*)",
|
||||||
|
"Bash(git branch:*)",
|
||||||
|
"Bash(git push:*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Submodule
+1
Submodule .claude/worktrees/upbeat-easley added at 9bb61cc8a7.
+55
@@ -0,0 +1,55 @@
|
|||||||
|
# ==========================================
|
||||||
|
# Podcastic - Unraid Configuration
|
||||||
|
# ==========================================
|
||||||
|
# All services in single container on port 3579
|
||||||
|
|
||||||
|
# Application Environment
|
||||||
|
NODE_ENV=production
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# DATABASE & CACHE (Internal - Don't change)
|
||||||
|
# ==========================================
|
||||||
|
MONGODB_URI=mongodb://127.0.0.1:27017/podcastic
|
||||||
|
REDIS_URL=redis://127.0.0.1:6379
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# SECURITY - CHANGE THESE!
|
||||||
|
# ==========================================
|
||||||
|
# JWT Secret - Use strong random string
|
||||||
|
# Generate: openssl rand -base64 32
|
||||||
|
JWT_SECRET=change-this-to-random-secret-key-in-production
|
||||||
|
JWT_EXPIRES_IN=7d
|
||||||
|
JWT_REFRESH_EXPIRES_IN=30d
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# OPTIONAL: PodcastIndex API (Podcast Search)
|
||||||
|
# ==========================================
|
||||||
|
# Leave empty to disable (manual RSS subscription still works)
|
||||||
|
# Get free keys: https://podcastindex-api.com/
|
||||||
|
PODCAST_INDEX_API_KEY=
|
||||||
|
PODCAST_INDEX_API_SECRET=
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# PORTS (Single container)
|
||||||
|
# ==========================================
|
||||||
|
# Frontend: http://your-unraid-ip:3579
|
||||||
|
# API: http://your-unraid-ip:3579/api
|
||||||
|
# Health: http://your-unraid-ip:3579/health
|
||||||
|
|
||||||
|
PORT=5000 # Internal backend port (don't change)
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Frontend Configuration
|
||||||
|
# ==========================================
|
||||||
|
VITE_API_URL=http://your-unraid-ip:3579/api
|
||||||
|
# Or use relative path:
|
||||||
|
# VITE_API_URL=/api
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# NOTES FOR UNRAID
|
||||||
|
# ==========================================
|
||||||
|
# 1. Change JWT_SECRET to a random string
|
||||||
|
# 2. If accessing from WAN, update VITE_API_URL to your domain
|
||||||
|
# 3. Optionally add PodcastIndex API keys for search feature
|
||||||
|
# 4. All data stored in /mnt/user/appdata/podcastic/
|
||||||
|
# 5. Logs in /mnt/user/appdata/podcastic/logs/
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
# Multi-stage build for Podcastic All-in-One Container
|
||||||
|
# Combines: Backend (Node.js), Frontend (React), Web Server (Nginx), Database (MongoDB), Cache (Redis)
|
||||||
|
|
||||||
|
# ==================== STAGE 1: Build Backend ====================
|
||||||
|
FROM node:20-alpine AS backend-builder
|
||||||
|
|
||||||
|
WORKDIR /build/backend
|
||||||
|
|
||||||
|
COPY backend/package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY backend/tsconfig.json ./
|
||||||
|
COPY backend/src ./src
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ==================== STAGE 2: Build Frontend ====================
|
||||||
|
FROM node:20-alpine AS frontend-builder
|
||||||
|
|
||||||
|
WORKDIR /build/frontend
|
||||||
|
|
||||||
|
COPY frontend/package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY frontend/tsconfig*.json ./
|
||||||
|
COPY frontend/vite.config.ts ./
|
||||||
|
COPY frontend/postcss.config.js ./
|
||||||
|
COPY frontend/tailwind.config.js ./
|
||||||
|
COPY frontend/index.html ./
|
||||||
|
COPY frontend/src ./src
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ==================== STAGE 3: Final Image ====================
|
||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
# Install supervisor to manage multiple processes, mongodb, redis, nginx
|
||||||
|
RUN apk add --no-cache supervisor nginx mongodb redis bash curl
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# ==================== Setup Backend ====================
|
||||||
|
COPY --from=backend-builder /build/backend/dist ./backend/dist
|
||||||
|
COPY --from=backend-builder /build/backend/package*.json ./backend/
|
||||||
|
RUN cd backend && npm ci --only=production
|
||||||
|
|
||||||
|
# ==================== Setup Frontend ====================
|
||||||
|
RUN mkdir -p /usr/share/nginx/html
|
||||||
|
COPY --from=frontend-builder /build/frontend/dist/* /usr/share/nginx/html/
|
||||||
|
|
||||||
|
# ==================== Setup Nginx ====================
|
||||||
|
RUN mkdir -p /etc/nginx/conf.d
|
||||||
|
|
||||||
|
COPY <<'EOF' /etc/nginx/conf.d/default.conf
|
||||||
|
server {
|
||||||
|
listen 3579;
|
||||||
|
server_name _;
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
# Frontend - Static files
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
expires 1d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static assets with long cache
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# API - Proxy to backend
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://127.0.0.1:5000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
proxy_pass http://127.0.0.1:5000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ==================== Setup Supervisor ====================
|
||||||
|
RUN mkdir -p /var/log/supervisor
|
||||||
|
|
||||||
|
COPY <<'EOF' /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
logfile=/var/log/supervisor/supervisord.log
|
||||||
|
pidfile=/var/run/supervisord.pid
|
||||||
|
|
||||||
|
[program:mongodb]
|
||||||
|
command=/usr/bin/mongod --dbpath /data/db --bind_ip 127.0.0.1
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stderr_logfile=/var/log/supervisor/mongodb.err.log
|
||||||
|
stdout_logfile=/var/log/supervisor/mongodb.out.log
|
||||||
|
|
||||||
|
[program:redis]
|
||||||
|
command=/usr/bin/redis-server --bind 127.0.0.1
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stderr_logfile=/var/log/supervisor/redis.err.log
|
||||||
|
stdout_logfile=/var/log/supervisor/redis.out.log
|
||||||
|
|
||||||
|
[program:backend]
|
||||||
|
command=/bin/bash -c "cd /app/backend && node dist/index.js"
|
||||||
|
environment=NODE_ENV=production,MONGODB_URI=mongodb://127.0.0.1:27017/podcastic,REDIS_URL=redis://127.0.0.1:6379
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stderr_logfile=/var/log/supervisor/backend.err.log
|
||||||
|
stdout_logfile=/var/log/supervisor/backend.out.log
|
||||||
|
|
||||||
|
[program:nginx]
|
||||||
|
command=/usr/sbin/nginx -g "daemon off;"
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stderr_logfile=/var/log/supervisor/nginx.err.log
|
||||||
|
stdout_logfile=/var/log/supervisor/nginx.out.log
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ==================== Create Data Directories ====================
|
||||||
|
RUN mkdir -p /data/db /data/redis
|
||||||
|
|
||||||
|
# ==================== Environment ====================
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV MONGODB_URI=mongodb://127.0.0.1:27017/podcastic
|
||||||
|
ENV REDIS_URL=redis://127.0.0.1:6379
|
||||||
|
ENV PORT=5000
|
||||||
|
|
||||||
|
# ==================== Health Check ====================
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||||
|
CMD curl -f http://127.0.0.1:3579/health || exit 1
|
||||||
|
|
||||||
|
# ==================== Expose Port ====================
|
||||||
|
EXPOSE 3579
|
||||||
|
|
||||||
|
# ==================== Entrypoint ====================
|
||||||
|
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
# 🐳 Podcastic - Unraid Installation Guide
|
||||||
|
|
||||||
|
Complete guide to install Podcastic on Unraid as a **single all-in-one container**.
|
||||||
|
|
||||||
|
## 📋 What's Included
|
||||||
|
|
||||||
|
This single Docker container includes:
|
||||||
|
- ✅ **Backend**: Node.js + Express.js API
|
||||||
|
- ✅ **Frontend**: React web interface
|
||||||
|
- ✅ **Database**: MongoDB (embedded)
|
||||||
|
- ✅ **Cache**: Redis (embedded)
|
||||||
|
- ✅ **Web Server**: Nginx reverse proxy
|
||||||
|
- ✅ **Process Manager**: Supervisor (manages all 5 services)
|
||||||
|
|
||||||
|
All in **ONE container** on port **3579**
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Unraid server with Docker support
|
||||||
|
- ~2GB RAM available
|
||||||
|
- ~20GB storage for database/media
|
||||||
|
- Internet connection
|
||||||
|
|
||||||
|
## Installation Steps
|
||||||
|
|
||||||
|
### Step 1: Clone Repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via terminal on Unraid
|
||||||
|
cd /mnt/user/appdata # or your preferred path
|
||||||
|
git clone https://github.com/R0m1k3/podcastic.git
|
||||||
|
cd podcastic
|
||||||
|
```
|
||||||
|
|
||||||
|
Or download as ZIP from GitHub and extract.
|
||||||
|
|
||||||
|
### Step 2: Configure Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copy template
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# Edit with your settings
|
||||||
|
nano .env
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key settings**:
|
||||||
|
```env
|
||||||
|
NODE_ENV=production
|
||||||
|
|
||||||
|
# JWT Secret - CHANGE THIS!
|
||||||
|
JWT_SECRET=your-super-secret-key-change-me-in-production
|
||||||
|
|
||||||
|
# Optional: PodcastIndex API for podcast search
|
||||||
|
PODCAST_INDEX_API_KEY=
|
||||||
|
PODCAST_INDEX_API_SECRET=
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Build Docker Image
|
||||||
|
|
||||||
|
Option A: Build locally (takes ~5-10 minutes)
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker-compose.unraid.yml build --no-cache
|
||||||
|
```
|
||||||
|
|
||||||
|
Option B: Use pre-built image (faster)
|
||||||
|
```bash
|
||||||
|
# Will be available after first push to Docker Hub
|
||||||
|
# docker pull r0m1k3/podcastic:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Start Container
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start
|
||||||
|
docker-compose -f docker-compose.unraid.yml up -d
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker-compose -f docker-compose.unraid.yml logs -f podcastic
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
docker ps | grep podcastic
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Access Application
|
||||||
|
|
||||||
|
Open browser:
|
||||||
|
```
|
||||||
|
http://your-unraid-ip:3579
|
||||||
|
```
|
||||||
|
|
||||||
|
**First Time Setup**:
|
||||||
|
1. Click "Create Account"
|
||||||
|
2. Register with email/password
|
||||||
|
3. Log in
|
||||||
|
4. Go to "Discover" to search podcasts
|
||||||
|
5. Subscribe and listen!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Container Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Single Container (podcastic)
|
||||||
|
├── Nginx (port 3579)
|
||||||
|
│ ├── Serves static frontend
|
||||||
|
│ └── Proxies /api to backend
|
||||||
|
├── Node.js Backend (internal port 5000)
|
||||||
|
│ ├── API routes
|
||||||
|
│ ├── Authentication
|
||||||
|
│ └── Database management
|
||||||
|
├── MongoDB (internal port 27017)
|
||||||
|
│ └── Podcast data storage
|
||||||
|
└── Redis (internal port 6379)
|
||||||
|
└── Cache & sessions
|
||||||
|
```
|
||||||
|
|
||||||
|
All services communicate **internally** - only port 3579 exposed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Unraid Integration
|
||||||
|
|
||||||
|
### Add to Unraid via WebUI
|
||||||
|
|
||||||
|
1. **Settings → Docker** → Enable Docker
|
||||||
|
2. **Docker** tab
|
||||||
|
3. Add custom template:
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Container version="2">
|
||||||
|
<Name>podcastic</Name>
|
||||||
|
<Repository>r0m1k3/podcastic:latest</Repository>
|
||||||
|
<Registry>https://hub.docker.com/</Registry>
|
||||||
|
<Network>bridge</Network>
|
||||||
|
<MyIP/>
|
||||||
|
<Shell>sh</Shell>
|
||||||
|
<Privileged>false</Privileged>
|
||||||
|
<Support/>
|
||||||
|
<Project/>
|
||||||
|
<Overview/>
|
||||||
|
<Category/>
|
||||||
|
<WebUI>http://[IP]:[PORT:3579]</WebUI>
|
||||||
|
<TemplateURL/>
|
||||||
|
<Icon/>
|
||||||
|
<ExtraParams/>
|
||||||
|
<PostArgs/>
|
||||||
|
<StaticNetwork>false</StaticNetwork>
|
||||||
|
<DonateText/>
|
||||||
|
<DonateLink/>
|
||||||
|
<Description>Podcastic - Multi-user podcast streaming application</Description>
|
||||||
|
<Networking>
|
||||||
|
<Mode>bridge</Mode>
|
||||||
|
<Publish>
|
||||||
|
<Port>
|
||||||
|
<HostPort>3579</HostPort>
|
||||||
|
<ContainerPort>3579</ContainerPort>
|
||||||
|
<Protocol>tcp</Protocol>
|
||||||
|
</Port>
|
||||||
|
</Publish>
|
||||||
|
</Networking>
|
||||||
|
<Data>
|
||||||
|
<Volume>
|
||||||
|
<HostDir>/mnt/user/appdata/podcastic/db</HostDir>
|
||||||
|
<ContainerDir>/data/db</ContainerDir>
|
||||||
|
<Mode>rw</Mode>
|
||||||
|
</Volume>
|
||||||
|
<Volume>
|
||||||
|
<HostDir>/mnt/user/appdata/podcastic/redis</HostDir>
|
||||||
|
<ContainerDir>/data/redis</ContainerDir>
|
||||||
|
<Mode>rw</Mode>
|
||||||
|
</Volume>
|
||||||
|
<Volume>
|
||||||
|
<HostDir>/mnt/user/appdata/podcastic/logs</HostDir>
|
||||||
|
<ContainerDir>/var/log/supervisor</ContainerDir>
|
||||||
|
<Mode>rw</Mode>
|
||||||
|
</Volume>
|
||||||
|
</Data>
|
||||||
|
<Environment>
|
||||||
|
<Variable>
|
||||||
|
<Name>JWT_SECRET</Name>
|
||||||
|
<Value>change-me-in-production</Value>
|
||||||
|
</Variable>
|
||||||
|
<Variable>
|
||||||
|
<Name>PODCAST_INDEX_API_KEY</Name>
|
||||||
|
<Value/>
|
||||||
|
</Variable>
|
||||||
|
<Variable>
|
||||||
|
<Name>PODCAST_INDEX_API_SECRET</Name>
|
||||||
|
<Value/>
|
||||||
|
</Variable>
|
||||||
|
</Environment>
|
||||||
|
</Container>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use Docker Compose tab with `docker-compose.unraid.yml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📂 Data Persistence
|
||||||
|
|
||||||
|
Data is saved to Unraid shares:
|
||||||
|
|
||||||
|
```
|
||||||
|
/mnt/user/appdata/podcastic/
|
||||||
|
├── db/ # MongoDB data (podcasts, users, episodes)
|
||||||
|
├── redis/ # Redis cache data
|
||||||
|
└── logs/ # Application logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup database
|
||||||
|
docker exec podcastic mongodump --out /backup/mongodb
|
||||||
|
|
||||||
|
# Copy to safe location
|
||||||
|
cp -r /mnt/user/appdata/podcastic /mnt/backup/podcastic-backup
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restore
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec podcastic mongorestore /backup/mongodb
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Management Commands
|
||||||
|
|
||||||
|
### View Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# All logs
|
||||||
|
docker logs -f podcastic
|
||||||
|
|
||||||
|
# Specific service
|
||||||
|
docker exec podcastic tail -f /var/log/supervisor/backend.out.log
|
||||||
|
docker exec podcastic tail -f /var/log/supervisor/mongodb.out.log
|
||||||
|
docker exec podcastic tail -f /var/log/supervisor/redis.out.log
|
||||||
|
docker exec podcastic tail -f /var/log/supervisor/nginx.out.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restart Container
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker-compose.unraid.yml restart podcastic
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stop Container
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker-compose.unraid.yml down
|
||||||
|
|
||||||
|
# Keep volumes (data persists)
|
||||||
|
# Data in /mnt/user/appdata/podcastic/ is preserved
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update to Latest
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pull latest code
|
||||||
|
cd /path/to/podcastic
|
||||||
|
git pull
|
||||||
|
|
||||||
|
# Rebuild and restart
|
||||||
|
docker-compose -f docker-compose.unraid.yml build --no-cache
|
||||||
|
docker-compose -f docker-compose.unraid.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 Troubleshooting
|
||||||
|
|
||||||
|
### Container won't start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check logs
|
||||||
|
docker logs podcastic
|
||||||
|
|
||||||
|
# Common issues:
|
||||||
|
# - Port 3579 in use: Change in docker-compose.unraid.yml
|
||||||
|
# - Insufficient RAM: Free up memory
|
||||||
|
# - Permission issues: Check volume permissions
|
||||||
|
```
|
||||||
|
|
||||||
|
### MongoDB not starting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check mongo logs
|
||||||
|
docker exec podcastic tail -f /var/log/supervisor/mongodb.out.log
|
||||||
|
|
||||||
|
# Repair database
|
||||||
|
docker exec podcastic mongod --repair --dbpath /data/db
|
||||||
|
```
|
||||||
|
|
||||||
|
### Can't access on port 3579
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check if container is running
|
||||||
|
docker ps | grep podcastic
|
||||||
|
|
||||||
|
# Check if port is open
|
||||||
|
netstat -tulpn | grep 3579
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
curl http://localhost:3579/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### Out of disk space
|
||||||
|
|
||||||
|
MongoDB can grow large. Check:
|
||||||
|
```bash
|
||||||
|
docker exec podcastic du -sh /data/db
|
||||||
|
|
||||||
|
# Clean old data (backup first!)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 Performance Optimization
|
||||||
|
|
||||||
|
### For Limited Resources
|
||||||
|
|
||||||
|
Edit `docker-compose.unraid.yml`:
|
||||||
|
```yaml
|
||||||
|
# Limit memory usage
|
||||||
|
mem_limit: 1g
|
||||||
|
cpus: '0.5'
|
||||||
|
```
|
||||||
|
|
||||||
|
### For High Performance
|
||||||
|
|
||||||
|
Increase limits:
|
||||||
|
```yaml
|
||||||
|
mem_limit: 4g
|
||||||
|
cpus: '2'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disable Unneeded Features
|
||||||
|
|
||||||
|
If only streaming (no search):
|
||||||
|
```env
|
||||||
|
PODCAST_INDEX_API_KEY= # Leave empty
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 Security Notes
|
||||||
|
|
||||||
|
### Change Default Secrets
|
||||||
|
|
||||||
|
```env
|
||||||
|
# MUST change in production!
|
||||||
|
JWT_SECRET=your-unique-secret-key-here
|
||||||
|
|
||||||
|
# Use strong password for first admin account
|
||||||
|
```
|
||||||
|
|
||||||
|
### Firewall Rules
|
||||||
|
|
||||||
|
Allow only trusted IPs:
|
||||||
|
```bash
|
||||||
|
# On Unraid, set firewall rules in UI
|
||||||
|
# Or use nginx config to restrict access
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSL/HTTPS Setup
|
||||||
|
|
||||||
|
If exposing to internet, use reverse proxy with SSL:
|
||||||
|
- Nginx Proxy Manager (separate container)
|
||||||
|
- Traefik (with Let's Encrypt)
|
||||||
|
- Unraid built-in reverse proxy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Monitoring
|
||||||
|
|
||||||
|
### Check Container Health
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Real-time stats
|
||||||
|
docker stats podcastic
|
||||||
|
|
||||||
|
# Service status
|
||||||
|
docker exec podcastic supervisorctl status
|
||||||
|
|
||||||
|
# Expected output:
|
||||||
|
# mongodb RUNNING pid 123, uptime 0:00:45
|
||||||
|
# redis RUNNING pid 124, uptime 0:00:45
|
||||||
|
# backend RUNNING pid 125, uptime 0:00:45
|
||||||
|
# nginx RUNNING pid 126, uptime 0:00:45
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Disk usage
|
||||||
|
du -sh /mnt/user/appdata/podcastic/
|
||||||
|
|
||||||
|
# Memory usage
|
||||||
|
docker exec podcastic free -h
|
||||||
|
|
||||||
|
# CPU usage
|
||||||
|
docker stats --no-stream podcastic
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🆘 Support
|
||||||
|
|
||||||
|
If issues occur:
|
||||||
|
|
||||||
|
1. **Check logs**:
|
||||||
|
```bash
|
||||||
|
docker logs podcastic
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Check service status**:
|
||||||
|
```bash
|
||||||
|
docker exec podcastic supervisorctl status
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Rebuild container**:
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker-compose.unraid.yml build --no-cache
|
||||||
|
docker-compose -f docker-compose.unraid.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Factory reset** (loses all data!):
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker-compose.unraid.yml down -v
|
||||||
|
rm -rf /mnt/user/appdata/podcastic
|
||||||
|
# Start fresh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Next Steps
|
||||||
|
|
||||||
|
1. **First Run**: Create account, set JWT_SECRET properly
|
||||||
|
2. **Configure PodcastIndex**: Optional, enables podcast search
|
||||||
|
3. **Add Podcasts**: Via Discover or RSS URLs
|
||||||
|
4. **Enjoy**: Start listening!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Additional Resources
|
||||||
|
|
||||||
|
- **Main README**: See README.md
|
||||||
|
- **Getting Started**: See GETTING_STARTED.md
|
||||||
|
- **PodcastIndex Setup**: See PODCAST_INDEX_SETUP.md
|
||||||
|
- **GitHub**: https://github.com/R0m1k3/podcastic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Last Updated**: 2026-04-16
|
||||||
|
**Tested on**: Unraid 6.12+
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
podcastic:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.unraid
|
||||||
|
container_name: podcastic
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3579:3579" # Web Interface (Frontend + API)
|
||||||
|
environment:
|
||||||
|
# Backend Config
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: 5000
|
||||||
|
|
||||||
|
# Database
|
||||||
|
MONGODB_URI: mongodb://127.0.0.1:27017/podcastic
|
||||||
|
REDIS_URL: redis://127.0.0.1:6379
|
||||||
|
|
||||||
|
# JWT Config
|
||||||
|
JWT_SECRET: ${JWT_SECRET:-change_me_in_production}
|
||||||
|
JWT_EXPIRES_IN: 7d
|
||||||
|
JWT_REFRESH_EXPIRES_IN: 30d
|
||||||
|
|
||||||
|
# PodcastIndex API (Optional - for podcast search)
|
||||||
|
PODCAST_INDEX_API_KEY: ${PODCAST_INDEX_API_KEY:-}
|
||||||
|
PODCAST_INDEX_API_SECRET: ${PODCAST_INDEX_API_SECRET:-}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# MongoDB data persistence
|
||||||
|
- podcastic_db:/data/db
|
||||||
|
# Redis data persistence (optional)
|
||||||
|
- podcastic_redis:/data/redis
|
||||||
|
# Application logs
|
||||||
|
- podcastic_logs:/var/log/supervisor
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- podcastic-network
|
||||||
|
|
||||||
|
# Resource limits (adjust based on your server)
|
||||||
|
# Uncomment to set limits:
|
||||||
|
# mem_limit: 2g
|
||||||
|
# cpus: '1'
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
podcastic_db:
|
||||||
|
driver: local
|
||||||
|
podcastic_redis:
|
||||||
|
driver: local
|
||||||
|
podcastic_logs:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
podcastic-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# USAGE:
|
||||||
|
# ============================================
|
||||||
|
#
|
||||||
|
# 1. Copy .env.example to .env and configure:
|
||||||
|
# cp .env.example .env
|
||||||
|
#
|
||||||
|
# 2. Build and start:
|
||||||
|
# docker-compose -f docker-compose.unraid.yml up -d
|
||||||
|
#
|
||||||
|
# 3. Access:
|
||||||
|
# http://your-server-ip:3579
|
||||||
|
#
|
||||||
|
# 4. View logs:
|
||||||
|
# docker-compose -f docker-compose.unraid.yml logs -f podcastic
|
||||||
|
#
|
||||||
|
# 5. Stop:
|
||||||
|
# docker-compose -f docker-compose.unraid.yml down
|
||||||
|
#
|
||||||
|
# 6. Backup data:
|
||||||
|
# docker run --rm -v podcastic_db:/data/db -v $(pwd):/backup \
|
||||||
|
# alpine tar czf /backup/podcastic-db.tar.gz -C /data db
|
||||||
|
#
|
||||||
|
# ============================================
|
||||||
Reference in new issue
Block a user