This commit is contained in:
2026-03-24 10:59:50 +01:00
commit 7c1c161ced
19 changed files with 856 additions and 0 deletions

318
flake.nix Normal file
View File

@@ -0,0 +1,318 @@
{
description = "kupyter rootless Kubernetes dev shell";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
get-all = pkgs.writeShellApplication {
name = "get-all";
runtimeInputs = [ pkgs.kubectl ];
text = ''kubectl get pods -A'';
};
cluster-start = pkgs.writeShellApplication {
name = "cluster-start";
runtimeInputs = [
pkgs.kind
pkgs.kubectl
];
text = ''
kind create cluster --name kupyter --wait 60s
kubectl config use-context kind-kupyter
echo " Cluster ready"
kubectl cluster-info
'';
};
cluster-stop = pkgs.writeShellApplication {
name = "cluster-stop";
runtimeInputs = [ pkgs.kind ];
text = ''
kind delete cluster --name kupyter
rm -f .kubeconfig
echo " Cluster deleted, kubeconfig cleared"
'';
};
tls-init = pkgs.writeShellApplication {
name = "tls-init";
runtimeInputs = [
pkgs.openssl
pkgs.kubectl
];
text = ''
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key \
-out tls.crt \
-subj "/CN=jupyterhub.local/O=kupyter"
kubectl create namespace jupyterhub --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret tls jupyterhub-tls \
--cert=tls.crt \
--key=tls.key \
--namespace jupyterhub
echo " TLS secret stored in jupyterhub namespace"
'';
};
helm-repos = pkgs.writeShellApplication {
name = "helm-repos";
runtimeInputs = [ pkgs.kubernetes-helm ];
text = ''
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add jupyterhub https://hub.jupyter.org/helm-chart/
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add ngshare https://libretexts.github.io/ngshare-helm-repo/
helm repo add prometheus https://prometheus-community.github.io/helm-charts
helm repo update
echo " all helm repos added and updated"
'';
};
ingress-install = pkgs.writeShellApplication {
name = "ingress-install";
runtimeInputs = [
pkgs.kubernetes-helm
pkgs.kubectl
];
text = ''
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.type=NodePort \
--set controller.service.nodePorts.http=30080 \
--set controller.service.nodePorts.https=30443
echo " ingress-nginx installed"
kubectl get pods -n ingress-nginx
'';
};
jupyterhub-install = pkgs.writeShellApplication {
name = "jupyterhub-install";
runtimeInputs = [
pkgs.kubernetes-helm
pkgs.kubectl
];
text = ''
kubectl create namespace jupyterhub --dry-run=client -o yaml | kubectl apply -f -
kubectl create configmap hub-logos \
--from-file=jupyterhub-80.png=./kupyter-notebook/logo.png \
--from-file=jupyterhub.svg=./kupyter-notebook/logo.svg \
--namespace jupyterhub \
--dry-run=client -o yaml | kubectl apply -f -
helm upgrade --install jupyterhub jupyterhub/jupyterhub \
--namespace jupyterhub \
--values config.yaml
kubectl apply -f jupyterhub-ingress.yaml
echo " jupyterhub installing"
kubectl get pods -n jupyterhub
'';
};
db-install = pkgs.writeShellApplication {
name = "db-install";
runtimeInputs = [
pkgs.kubernetes-helm
pkgs.kubectl
];
text = ''
helm upgrade --install jupyterhub-db bitnami/postgresql \
--namespace jupyterhub \
--set auth.username=jupyterhub \
--set auth.password=jupyterhub \
--set auth.database=jupyterhub
echo " postgres installing"
kubectl get pods -n jupyterhub
'';
};
notebook-build = pkgs.writeShellApplication {
name = "notebook-build";
runtimeInputs = [
pkgs.podman
pkgs.kind
];
text = ''
podman build -t kupyter-notebook:latest ./kupyter-notebook
podman save kupyter-notebook:latest -o /tmp/kupyter-notebook.tar
kind load image-archive /tmp/kupyter-notebook.tar --name kupyter
rm /tmp/kupyter-notebook.tar
echo " image built and loaded into cluster"
'';
};
hub-build = pkgs.writeShellApplication {
name = "hub-build";
runtimeInputs = [
pkgs.podman
pkgs.kind
];
text = ''
podman build -t kupyter-hub:latest -f Dockerfile.hub .
podman save kupyter-hub:latest -o /tmp/kupyter-hub.tar
kind load image-archive /tmp/kupyter-hub.tar --name kupyter
rm /tmp/kupyter-hub.tar
echo " hub image built and loaded"
'';
};
ngshare-install = pkgs.writeShellApplication {
name = "ngshare-install";
runtimeInputs = [
pkgs.kubernetes-helm
pkgs.kubectl
];
text = ''
helm upgrade --install ngshare ngshare/ngshare \
--namespace jupyterhub \
--set ngshare.token=822235aaaf83f0232c799fe948cbb1594b01d7d7b11af051871cc2d3fcb08fe8 \
--set ngshare.hub_api_token=822235aaaf83f0232c799fe948cbb1594b01d7d7b11af051871cc2d3fcb08fe8 \
--set ngshare.admins="admin,ngshare-setup" \
--values ngshare-values.yaml
echo "Waiting for ngshare..."
kubectl wait pod \
--for=condition=ready \
--selector=app.kubernetes.io/name=ngshare \
--namespace jupyterhub \
--timeout=120s
echo " ngshare installed"
kubectl get pods -n jupyterhub
'';
};
ngshare-courses = pkgs.writeShellApplication {
name = "ngshare-courses";
runtimeInputs = [ pkgs.kubectl ];
text = ''
HUB_POD=$(kubectl get pod -n jupyterhub -l component=hub -o name)
kubectl exec -n jupyterhub "$HUB_POD" -- curl -s -X POST \
"http://ngshare.jupyterhub.svc.cluster.local:8080/services/ngshare/course/Programmieren" \
-d "instructors=[\"instructor-Prog\"]" \
-H "Authorization: token setuptoken123456789012345678901234567890123456789012345678901234"
kubectl exec -n jupyterhub "$HUB_POD" -- curl -s -X POST \
"http://ngshare.jupyterhub.svc.cluster.local:8080/services/ngshare/course/Signale" \
-d "instructors=[\"instructor-Sig\"]" \
-H "Authorization: token setuptoken123456789012345678901234567890123456789012345678901234"
echo " courses created"
'';
};
monitoring-install = pkgs.writeShellApplication {
name = "monitoring-install";
runtimeInputs = [
pkgs.kubernetes-helm
pkgs.kubectl
];
text = ''
helm upgrade --install kube-prometheus-stack prometheus/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--wait
kubectl apply -f ./jupyterhub-monitor.yaml
echo " monitoring installed"
kubectl get pods -n monitoring
'';
};
rebuild-all = pkgs.writeShellApplication {
name = "rebuild-all";
runtimeInputs = [
pkgs.kind
pkgs.kubectl
pkgs.kubernetes-helm
pkgs.podman
];
text = ''
cluster-stop
cluster-start
tls-init
helm-repos
ingress-install
hub-build
notebook-build
db-install
ngshare-install
jupyterhub-install
monitoring-install
echo "Waiting for hub to be ready..."
kubectl wait pod \
--for=condition=ready \
--selector=component=hub \
--namespace jupyterhub \
--timeout=300s
ngshare-courses
'';
};
in
{
devShells.default = pkgs.mkShell {
name = "kupyter";
packages = [
get-all
cluster-start
cluster-stop
tls-init
helm-repos
ingress-install
jupyterhub-install
notebook-build
db-install
ngshare-install
ngshare-courses
hub-build
monitoring-install
rebuild-all
pkgs.openssl
pkgs.kubectl
pkgs.kubernetes-helm
pkgs.podman
pkgs.kind
];
shellHook = ''
export KUBECONFIG="$(pwd)/.kubeconfig"
export KIND_EXPERIMENTAL_PROVIDER=podman
echo ""
echo " kupyter dev shell"
echo " KUBECONFIG $(pwd)/.kubeconfig (session-local)"
echo " runtime podman (rootless)"
echo ""
echo " cluster-start # create cluster"
echo " cluster-stop # delete cluster + wipe kubeconfig"
echo " tls-init # generate self-signed cert"
echo " helm-repos # add and update helm repos"
echo " ingress-install # install nginx ingress"
echo " notebook-build # build and load notebook image"
echo " jupyterhub-install # install jupyterhub"
echo " get-all # show all pods"
echo ""
'';
};
}
);
}