feat: Add multi-arch Docker support with GitHub Actions workflow
Add comprehensive Docker deployment support: Docker Infrastructure: - Multi-stage Dockerfile optimized for amd64 and arm64 - Based on node:20-alpine for minimal size - Non-root user for security - Health check endpoint integration - Volume support for downloads GitHub Actions Workflow: - Multi-arch build using native runners (ubuntu-latest for amd64, ubuntu-24.04-arm for arm64) - Digest-based builds to avoid QEMU emulation - Automatic push to GHCR (ghcr.io/yachi/yt-dlp-mcp) - Manifest list creation for multi-platform support - Semantic versioning support - Build caching for faster builds Deployment Files: - docker-compose.yml for easy local deployment - .dockerignore for optimized build context - Comprehensive Docker deployment documentation Features: - Native multi-arch builds (no QEMU) - Automatic GHCR publishing on main branch - Version tagging (latest, semver, sha) - Resource limits and health checks - Production-ready configuration examples
This commit is contained in:
parent
8892f3df92
commit
2fa897d843
67
.dockerignore
Normal file
67
.dockerignore
Normal file
@ -0,0 +1,67 @@
|
||||
# Node modules
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Build output
|
||||
lib/
|
||||
dist/
|
||||
build/
|
||||
*.tsbuildinfo
|
||||
|
||||
# Test files
|
||||
src/__tests__/
|
||||
*.test.ts
|
||||
*.test.js
|
||||
*.spec.ts
|
||||
*.spec.js
|
||||
coverage/
|
||||
.nyc_output/
|
||||
|
||||
# Development files
|
||||
.git/
|
||||
.github/
|
||||
.gitignore
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# Documentation
|
||||
docs/
|
||||
*.md
|
||||
!README.md
|
||||
|
||||
# CI/CD
|
||||
.travis.yml
|
||||
.gitlab-ci.yml
|
||||
azure-pipelines.yml
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
*.tmp
|
||||
*.log
|
||||
|
||||
# Development tools
|
||||
.editorconfig
|
||||
.prettierrc*
|
||||
.eslintrc*
|
||||
jest.config.*
|
||||
tsconfig.json
|
||||
|
||||
# Package manager files
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
pnpm-lock.yaml
|
||||
136
.github/workflows/docker-multi-arch.yml
vendored
Normal file
136
.github/workflows/docker-multi-arch.yml
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
name: Build and Push Multi-Arch Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ${{ matrix.platform }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: linux/amd64
|
||||
runner: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
|
||||
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 GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels)
|
||||
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
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
||||
cache-from: type=gha,scope=${{ matrix.platform }}
|
||||
cache-to: type=gha,scope=${{ matrix.platform }},mode=max
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: digests-${{ strategy.job-index }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
name: Create manifest and push
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels)
|
||||
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
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Create manifest list and push
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||
|
||||
- name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
|
||||
88
Dockerfile
Normal file
88
Dockerfile
Normal file
@ -0,0 +1,88 @@
|
||||
# Multi-stage Dockerfile for yt-dlp-mcp HTTP server
|
||||
# Optimized for multi-arch builds (amd64, arm64)
|
||||
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache \
|
||||
python3 \
|
||||
make \
|
||||
g++
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY tsconfig.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY src ./src
|
||||
|
||||
# Build TypeScript
|
||||
RUN npm run prepare
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
# Install yt-dlp and runtime dependencies
|
||||
RUN apk add --no-cache \
|
||||
yt-dlp \
|
||||
ffmpeg \
|
||||
python3 \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S ytdlp && \
|
||||
adduser -u 1001 -S ytdlp -G ytdlp
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY --chown=ytdlp:ytdlp package*.json ./
|
||||
|
||||
# Install production dependencies only
|
||||
RUN npm ci --omit=dev && \
|
||||
npm cache clean --force
|
||||
|
||||
# Copy built application from builder
|
||||
COPY --chown=ytdlp:ytdlp --from=builder /app/lib ./lib
|
||||
COPY --chown=ytdlp:ytdlp --from=builder /app/docs ./docs
|
||||
COPY --chown=ytdlp:ytdlp README.md ./
|
||||
|
||||
# Create downloads directory
|
||||
RUN mkdir -p /downloads && \
|
||||
chown -R ytdlp:ytdlp /downloads
|
||||
|
||||
# Switch to non-root user
|
||||
USER ytdlp
|
||||
|
||||
# Environment variables
|
||||
ENV NODE_ENV=production \
|
||||
YTDLP_DOWNLOADS_DIR=/downloads \
|
||||
YTDLP_HTTP_PORT=3000 \
|
||||
YTDLP_HTTP_HOST=0.0.0.0
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)}).on('error', () => process.exit(1))"
|
||||
|
||||
# Volume for downloads
|
||||
VOLUME ["/downloads"]
|
||||
|
||||
# Default command - run HTTP server
|
||||
CMD ["node", "lib/server-http.mjs"]
|
||||
|
||||
# Labels
|
||||
LABEL org.opencontainers.image.title="yt-dlp-mcp"
|
||||
LABEL org.opencontainers.image.description="MCP server for yt-dlp with HTTP transport"
|
||||
LABEL org.opencontainers.image.vendor="kevinwatt"
|
||||
LABEL org.opencontainers.image.licenses="MIT"
|
||||
LABEL org.opencontainers.image.source="https://github.com/kevinwatt/yt-dlp-mcp"
|
||||
LABEL org.opencontainers.image.documentation="https://github.com/kevinwatt/yt-dlp-mcp#readme"
|
||||
64
docker-compose.yml
Normal file
64
docker-compose.yml
Normal file
@ -0,0 +1,64 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
yt-dlp-mcp:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: yt-dlp-mcp:local
|
||||
container_name: yt-dlp-mcp-server
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
# Server configuration
|
||||
- YTDLP_HTTP_PORT=3000
|
||||
- YTDLP_HTTP_HOST=0.0.0.0
|
||||
|
||||
# Security (set a secure API key in production)
|
||||
- YTDLP_API_KEY=${YTDLP_API_KEY:-}
|
||||
- YTDLP_CORS_ORIGIN=${YTDLP_CORS_ORIGIN:-*}
|
||||
|
||||
# Rate limiting
|
||||
- YTDLP_RATE_LIMIT=${YTDLP_RATE_LIMIT:-60}
|
||||
- YTDLP_SESSION_TIMEOUT=${YTDLP_SESSION_TIMEOUT:-3600000}
|
||||
|
||||
# Download configuration
|
||||
- YTDLP_DOWNLOADS_DIR=/downloads
|
||||
- YTDLP_DEFAULT_RESOLUTION=${YTDLP_DEFAULT_RESOLUTION:-720p}
|
||||
- YTDLP_DEFAULT_SUBTITLE_LANG=${YTDLP_DEFAULT_SUBTITLE_LANG:-en}
|
||||
|
||||
volumes:
|
||||
# Mount downloads directory to host
|
||||
- ./downloads:/downloads
|
||||
|
||||
restart: unless-stopped
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"]
|
||||
interval: 30s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Resource limits (adjust as needed)
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
|
||||
# Optional: nginx reverse proxy with SSL
|
||||
# nginx:
|
||||
# image: nginx:alpine
|
||||
# container_name: yt-dlp-mcp-proxy
|
||||
# ports:
|
||||
# - "443:443"
|
||||
# volumes:
|
||||
# - ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
# - ./ssl:/etc/nginx/ssl:ro
|
||||
# depends_on:
|
||||
# - yt-dlp-mcp
|
||||
# restart: unless-stopped
|
||||
412
docs/docker-deployment.md
Normal file
412
docs/docker-deployment.md
Normal file
@ -0,0 +1,412 @@
|
||||
# Docker Deployment Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide covers deploying yt-dlp-mcp using Docker with multi-architecture support (amd64 and arm64).
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Pre-built Images from GHCR
|
||||
|
||||
```bash
|
||||
# Pull the latest image
|
||||
docker pull ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
|
||||
# Run with default configuration
|
||||
docker run -d \
|
||||
--name yt-dlp-mcp \
|
||||
-p 3000:3000 \
|
||||
-v $(pwd)/downloads:/downloads \
|
||||
ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
```
|
||||
|
||||
### Using Docker Compose
|
||||
|
||||
1. Create a `docker-compose.yml` file (see repository root)
|
||||
2. Create a `.env` file for configuration:
|
||||
|
||||
```bash
|
||||
# Security
|
||||
YTDLP_API_KEY=your-secret-api-key-here
|
||||
|
||||
# CORS (use specific origin in production)
|
||||
YTDLP_CORS_ORIGIN=https://your-domain.com
|
||||
|
||||
# Rate limiting
|
||||
YTDLP_RATE_LIMIT=60
|
||||
|
||||
# Session timeout (1 hour = 3600000ms)
|
||||
YTDLP_SESSION_TIMEOUT=3600000
|
||||
|
||||
# Download preferences
|
||||
YTDLP_DEFAULT_RESOLUTION=720p
|
||||
YTDLP_DEFAULT_SUBTITLE_LANG=en
|
||||
```
|
||||
|
||||
3. Start the service:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. Check health:
|
||||
|
||||
```bash
|
||||
curl http://localhost:3000/health
|
||||
```
|
||||
|
||||
## Building Locally
|
||||
|
||||
### Build for Current Architecture
|
||||
|
||||
```bash
|
||||
docker build -t yt-dlp-mcp:local .
|
||||
```
|
||||
|
||||
### Build Multi-Architecture Image
|
||||
|
||||
```bash
|
||||
# Create and use a new builder
|
||||
docker buildx create --name mybuilder --use
|
||||
|
||||
# Build for multiple platforms
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
-t yt-dlp-mcp:multi-arch \
|
||||
--load \
|
||||
.
|
||||
```
|
||||
|
||||
## Image Details
|
||||
|
||||
### Multi-Architecture Support
|
||||
|
||||
The Docker images are built for multiple architectures:
|
||||
|
||||
- **linux/amd64** - Intel/AMD 64-bit (x86_64)
|
||||
- **linux/arm64** - ARM 64-bit (aarch64)
|
||||
|
||||
Docker automatically pulls the correct architecture for your system.
|
||||
|
||||
### Image Size
|
||||
|
||||
- **Compressed**: ~150 MB
|
||||
- **Uncompressed**: ~450 MB
|
||||
|
||||
Based on `node:20-alpine` for minimal footprint.
|
||||
|
||||
### Included Components
|
||||
|
||||
- Node.js 20 (Alpine)
|
||||
- yt-dlp (latest)
|
||||
- ffmpeg (for media processing)
|
||||
- Python 3 (for yt-dlp)
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
All server configuration can be set via environment variables:
|
||||
|
||||
#### Server Settings
|
||||
|
||||
```bash
|
||||
YTDLP_HTTP_PORT=3000 # Server port (default: 3000)
|
||||
YTDLP_HTTP_HOST=0.0.0.0 # Server host (default: 0.0.0.0)
|
||||
```
|
||||
|
||||
#### Security
|
||||
|
||||
```bash
|
||||
YTDLP_API_KEY=secret # API key for authentication
|
||||
YTDLP_CORS_ORIGIN=* # CORS allowed origin
|
||||
YTDLP_RATE_LIMIT=60 # Requests per minute per session
|
||||
YTDLP_SESSION_TIMEOUT=3600000 # Session timeout in milliseconds
|
||||
```
|
||||
|
||||
#### Downloads
|
||||
|
||||
```bash
|
||||
YTDLP_DOWNLOADS_DIR=/downloads # Download directory
|
||||
YTDLP_DEFAULT_RESOLUTION=720p # Default video resolution
|
||||
YTDLP_DEFAULT_SUBTITLE_LANG=en # Default subtitle language
|
||||
```
|
||||
|
||||
### Volumes
|
||||
|
||||
Mount a volume for persistent downloads:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
-v /path/on/host:/downloads \
|
||||
ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
```
|
||||
|
||||
### Port Mapping
|
||||
|
||||
Map container port to host:
|
||||
|
||||
```bash
|
||||
# Default port 3000
|
||||
docker run -d -p 3000:3000 ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
|
||||
# Custom port
|
||||
docker run -d -p 8080:3000 ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### With HTTPS (nginx reverse proxy)
|
||||
|
||||
1. Create `nginx.conf`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name yt-dlp.yourdomain.com;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/key.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://yt-dlp-mcp:3000;
|
||||
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;
|
||||
|
||||
# For SSE streaming
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Update `docker-compose.yml` to include nginx
|
||||
|
||||
3. Start services:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Resource Limits
|
||||
|
||||
Set resource limits for production:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
yt-dlp-mcp:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
||||
Configure logging driver:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
yt-dlp-mcp:
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
```
|
||||
|
||||
## Health Checks
|
||||
|
||||
The Docker image includes a health check:
|
||||
|
||||
```dockerfile
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD node -e "require('http').get('http://localhost:3000/health', ...)"
|
||||
```
|
||||
|
||||
Check container health:
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
# Look for "healthy" status
|
||||
|
||||
# Or inspect directly
|
||||
docker inspect --format='{{.State.Health.Status}}' yt-dlp-mcp
|
||||
```
|
||||
|
||||
## Kubernetes Deployment
|
||||
|
||||
### Basic Deployment
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: yt-dlp-mcp
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: yt-dlp-mcp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: yt-dlp-mcp
|
||||
spec:
|
||||
containers:
|
||||
- name: yt-dlp-mcp
|
||||
image: ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
- name: YTDLP_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: yt-dlp-secrets
|
||||
key: api-key
|
||||
- name: YTDLP_CORS_ORIGIN
|
||||
value: "https://your-domain.com"
|
||||
volumeMounts:
|
||||
- name: downloads
|
||||
mountPath: /downloads
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
volumes:
|
||||
- name: downloads
|
||||
persistentVolumeClaim:
|
||||
claimName: yt-dlp-downloads
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: yt-dlp-mcp
|
||||
spec:
|
||||
selector:
|
||||
app: yt-dlp-mcp
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
type: ClusterIP
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container won't start
|
||||
|
||||
Check logs:
|
||||
```bash
|
||||
docker logs yt-dlp-mcp
|
||||
```
|
||||
|
||||
Common issues:
|
||||
- yt-dlp not available: Image should include it automatically
|
||||
- Permission errors: Check volume mount permissions
|
||||
- Port already in use: Change host port mapping
|
||||
|
||||
### Health check failing
|
||||
|
||||
Verify the server is responding:
|
||||
```bash
|
||||
docker exec yt-dlp-mcp wget -qO- http://localhost:3000/health
|
||||
```
|
||||
|
||||
### Downloads not persisting
|
||||
|
||||
Ensure volume is mounted correctly:
|
||||
```bash
|
||||
docker inspect yt-dlp-mcp | grep -A 10 Mounts
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Always set an API key in production**:
|
||||
```bash
|
||||
YTDLP_API_KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
|
||||
2. **Use specific CORS origin**:
|
||||
```bash
|
||||
YTDLP_CORS_ORIGIN=https://your-domain.com
|
||||
```
|
||||
|
||||
3. **Run behind HTTPS proxy** (nginx, Caddy, Traefik)
|
||||
|
||||
4. **Use secrets management**:
|
||||
- Docker secrets
|
||||
- Kubernetes secrets
|
||||
- HashiCorp Vault
|
||||
|
||||
5. **Limit resource usage** with Docker resource constraints
|
||||
|
||||
6. **Regular updates**:
|
||||
```bash
|
||||
docker pull ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Prometheus Metrics (Future Enhancement)
|
||||
|
||||
The image is designed to support future Prometheus integration.
|
||||
|
||||
### Log Aggregation
|
||||
|
||||
Send logs to centralized logging:
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
driver: "fluentd"
|
||||
options:
|
||||
fluentd-address: "localhost:24224"
|
||||
tag: "yt-dlp-mcp"
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
The repository includes a multi-arch build workflow (`.github/workflows/docker-multi-arch.yml`):
|
||||
|
||||
- Builds for amd64 and arm64 on native runners
|
||||
- Pushes to GHCR automatically on main branch
|
||||
- Tags with semantic versioning
|
||||
|
||||
### Pulling Images
|
||||
|
||||
```bash
|
||||
# Latest
|
||||
ghcr.io/yachi/yt-dlp-mcp:latest
|
||||
|
||||
# Specific version
|
||||
ghcr.io/yachi/yt-dlp-mcp:v0.7.0
|
||||
|
||||
# By commit SHA
|
||||
ghcr.io/yachi/yt-dlp-mcp:sha-abc1234
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For issues with Docker deployment:
|
||||
- Check [GitHub Issues](https://github.com/yachi/yt-dlp-mcp/issues)
|
||||
- Review container logs: `docker logs yt-dlp-mcp`
|
||||
- Verify health: `curl http://localhost:3000/health`
|
||||
Loading…
x
Reference in New Issue
Block a user