From 76ff73db488afcc1b361c898d20bc19b056ece6b Mon Sep 17 00:00:00 2001 From: minus Date: Sun, 31 Oct 2021 16:56:43 +0100 Subject: [PATCH] Add plain Kubernetes deployment --- kubernetes/README.md | 63 +++++++++++++++++++++++++++ kubernetes/invidious.yaml | 92 +++++++++++++++++++++++++++++++++++++++ kubernetes/postgres.yaml | 53 ++++++++++++++++++++++ kubernetes/web.yaml | 32 ++++++++++++++ 4 files changed, 240 insertions(+) create mode 100644 kubernetes/README.md create mode 100644 kubernetes/invidious.yaml create mode 100644 kubernetes/postgres.yaml create mode 100644 kubernetes/web.yaml diff --git a/kubernetes/README.md b/kubernetes/README.md new file mode 100644 index 00000000..bd1d1fbb --- /dev/null +++ b/kubernetes/README.md @@ -0,0 +1,63 @@ +# Invidious Kubernetes Deployment + +This is a plain deployment of Invidious and a PostgreSQL database to Kubernetes +which can easily be customized. It is only designed for personal use (only one +replica, very basic PostgreSQL setup, automatic updates). + +## Installing + +```sh +# Create a separate namespace for invidious +kubectl create ns invidious +kubectl config set-context --current --namespace=invidious + +# Run a PostgreSQL instance +pgpw=$(pwgen -s 32 1) +kubectl create secret generic postgres --from-literal=rootpassword="$pgpw" +kubectl apply -f postgres.yaml + +# Run invidious (you may want to copy and edit the config file before; an empty file works fine) +kubectl create configmap invidious --from-file=INVIDIOUS_CONFIG=../config/config.example.yml +kubectl create secret generic invidious --from-literal=INVIDIOUS_DATABASE_URL="postgresql://postgres:$pgpw@postgres/invidious" +kubectl apply -f invidious.yaml +``` + +### Making it reachable from the web + +To make Invidious reachable from the web you also need an Ingress (or +equivalent). This is a basic variant that requires +[cert-manager](https://cert-manager.io/docs/) and something that processes +Ingress objects (like [traefik](https://doc.traefik.io/traefik/)). + +```sh +sed s/invidious.example.org/your.invidious.domain/ web.yaml | kubectl apply -f - +``` + +## Upgrading + +### Automatic + +The deployment has annotations for [Keel](https://keel.sh) for automatic +updates. Keel can quickly be installed as follows, but you should make yourself +familiar with it if you intend to use it. + +```sh +curl 'https://sunstone.dev/keel?namespace=keel' | kubectl apply -f - +``` + +Note that the deployment is configured to even upgrade to new major versions, +preferring things to break over having an outdated and potentially vulnerable +instance. + +### Manual + +The `imagePullPolicy` is set to `Always`, so simply restarting the deployment +upgrades Indivious: + +```sh +kubectl rollout restart deployment invidious +``` + +## Uninstall + +Simply delete the namespace. diff --git a/kubernetes/invidious.yaml b/kubernetes/invidious.yaml new file mode 100644 index 00000000..b96e1201 --- /dev/null +++ b/kubernetes/invidious.yaml @@ -0,0 +1,92 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: invidious + labels: + app: invidious + annotations: + keel.sh/policy: major + keel.sh/trigger: poll + keel.sh/pollSchedule: "@midnight" +spec: + replicas: 1 + selector: + matchLabels: + app: invidious + template: + metadata: + labels: + app: invidious + spec: + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + initContainers: + - name: wait-for-postgresql + image: docker.io/library/postgres + args: + - /bin/sh + - -c + - until pg_isready -d "$INVIDIOUS_DATABASE_URL"; do echo waiting for database; sleep 2; done; + env: + - name: INVIDIOUS_DATABASE_URL + valueFrom: + secretKeyRef: + name: invidious + key: INVIDIOUS_DATABASE_URL + containers: + - name: invidious + image: quay.io/invidious/invidious + imagePullPolicy: Always + ports: + - containerPort: 3000 + env: + - name: INVIDIOUS_CONFIG + valueFrom: + configMapKeyRef: + name: invidious + key: INVIDIOUS_CONFIG + - name: INVIDIOUS_DATABASE_URL + valueFrom: + secretKeyRef: + name: invidious + key: INVIDIOUS_DATABASE_URL + # Let Invidious itself take care of initializing the database + - name: INVIDIOUS_CHECK_TABLES + value: "true" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + resources: {} + #requests: + # cpu: 100m + # memory: 64Mi + #limits: + # cpu: 800m + # memory: 512Mi + readinessProbe: + httpGet: + port: 3000 + path: / + livenessProbe: + httpGet: + port: 3000 + path: / + initialDelaySeconds: 15 + restartPolicy: Always +--- +apiVersion: v1 +kind: Service +metadata: + name: invidious-http +spec: + selector: + app: invidious + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 3000 diff --git a/kubernetes/postgres.yaml b/kubernetes/postgres.yaml new file mode 100644 index 00000000..de7a1c2b --- /dev/null +++ b/kubernetes/postgres.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Pod +metadata: + name: postgres + labels: + app: postgres + annotations: + keel.sh/policy: minor + keel.sh/trigger: poll + keel.sh/pollSchedule: "@midnight" +spec: + containers: + - name: postgres + image: docker.io/library/postgres:14 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: postgres + key: rootpassword + - name: POSTGRES_DB + value: invidious + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + volumes: + - name: data + persistentVolumeClaim: + claimName: postgres-data +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-data +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 8Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres +spec: + selector: + app: postgres + ports: + - protocol: TCP + port: 5432 diff --git a/kubernetes/web.yaml b/kubernetes/web.yaml new file mode 100644 index 00000000..f30b6e29 --- /dev/null +++ b/kubernetes/web.yaml @@ -0,0 +1,32 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: invidious-cert +spec: + secretName: invidious-cert + dnsNames: + - invidious.example.org + issuerRef: + name: letsencrypt + kind: ClusterIssuer +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: invidious +spec: + tls: + - hosts: + - invidious.example.org + secretName: invidious-cert + rules: + - host: invidious.example.org + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: invidious-http + port: + number: 80