Add minimal dockerfile, k8s example

There's already a nice docker setup for this, but I've been
using this in kubernetes pretty nicely as a cronjob.
This commit is contained in:
Kai Giokas 2025-03-17 11:35:19 -05:00
parent 665ded7cec
commit 87dd0b0966
No known key found for this signature in database
7 changed files with 161 additions and 0 deletions

13
docker/Dockerfile.minimal Normal file
View file

@ -0,0 +1,13 @@
FROM python:alpine
# Install required non-python dependencies.
# Just using the built-in ffmpeg for ease of creation.
RUN apk add --no-cache ffmpeg aria2
RUN --mount=type=cache,target=/root/.cache \
pip install ytdl-sub
VOLUME /config
VOLUME /media
# Default to a non-root user after build.
USER nobody

24
kubernetes/README.md Normal file
View file

@ -0,0 +1,24 @@
# Deploying with Kubernetes
## TL;DR
```console
$ git clone git@github.com:jmbannon/ytdl-sub.git
$ cd ytdl-sub/kubernetes
$ $EDITOR kustomization.yaml subs.yaml presets.yaml
$ kuzomise build . | kubectl apply -f -
```
## Configuration
Make sure you set the following to the right values for your kubernetes setup:
- `storageClassName` for each of the volumes in `./volumes.yaml`
- `namespace` in `kustomization.yaml`
- `images` overrides in `kustomization.yaml` if you don't want to use the minimal image
- `schedule` in `cronjob.yaml` if you want to run on a different schedule (defaults to
hourly.)
It should build a valid configuration without changing these kubernetes settings, but
it will probably not be what you're expecting.
See the normal documentation for configuring the `subs.yaml` and `presets.yaml` files.

0
kubernetes/config.yaml Normal file
View file

64
kubernetes/cronjob.yaml Normal file
View file

@ -0,0 +1,64 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: ytdl
spec:
schedule: '@hourly'
successfulJobsHistoryLimit: 3
concurrencyPolicy: Forbid
jobTemplate:
metadata:
labels:
app: ytdl
spec:
parallelism: 1
template:
metadata:
labels:
app: ytdl
spec:
containers:
- name: ytdl
image: kaictl/ytdl-sub:notlatest
command:
- ytdl-sub
- sub
volumeMounts:
# Where to download to
- mountPath: /media
name: media
# Storage for .ytdl-sub-working-directory.
- mountPath: /cache
name: cache
# Configuration and preset files location.
- mountPath: /config
name: config
# Run in the cache directory, just for ease of use.
workingDir: /cache/
# Run as non-root so we don't have security issues.
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: false
runAsNonRoot: true
volumes:
- name: media
persistentVolumeClaim:
claimName: yt-media
- name: cache
persistentVolumeClaim:
claimName: yt-cache
- name: config
configMap:
name: ytdl
# More security settings. Runs as `nobody`.
securityContext:
fsGroup: 65534
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 65534
runAsNonRoot: false
runAsUser: 65534

View file

@ -0,0 +1,22 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Set this to wherever you want your jobs to run. It should exist already.
namespace: ytdl-sub
images:
# Override this with your own image if you would like.
# This is a smaller image than the default that includes all the editor stuff.
- name: kaictl/ytdl-sub
newName: kaictl/ytdl-sub
newTag: latest
resources:
- ./volumes.yaml
- ./cronjob.yaml
configMapGenerator:
- name: ytdl-config
files:
- ./config.yaml
- ./subscriptions.yaml

View file

38
kubernetes/volumes.yaml Normal file
View file

@ -0,0 +1,38 @@
# Final media storage.
# This should have enough space to store all the media you download. If you already have
# a media volume that you're serving stuff from (plex, etc.), then you can mount it
# here, or do the opposite and mount this volume to your running media server pods.
# It's recommended to use a separate volume from your other media downloads for safety.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: yt-media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
# Set to the size of the storage volume you need
storage: 100Gi
# Will use the default storage class if not set, otherwise set to your desired
# storageclass name.
#storageClassName: my-video-storage-name
---
# For persistence of your cache, it is recommended to use a PVC for your /cache
# directory. Make sure the storage is fast enough, since it will be used as a cache for
# downloading a lot of small files, as well as temporary files while ytdl and ffmpeg do
# their work.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: yt-cache
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
# You probably don't need much storage, but that depends on the kinds of videos
# you download. I'd recommend at least 10Gi.
storage: 16Gi
#storageClassName: my-fast-storage-name