#BinderHub
2i2c has officially become part of the mybinder.org federation, introducing a new, cost-effective, and faster approach. We hope to make it easier for more people to join the federation by contributing a single-node BinderHub at 2i2c.mybinder.org.

More in our blog: https://2i2c.org/blog/2025/binde…
February 5, 2025 at 8:45 AM
This is a big deal! 2i2c is supporting mybinder.org traffic with a BinderHub that is almost 5x cheaper than previous deployments. I think it is a great sign for mybinder.org's sustainability.

2i2c.org/blog/2025/bi...

Here's a brief explainer (1/x)
February 5, 2025 at 3:15 PM
Are you looking for a way to simplify collaborations and enhance the reproducibility of your research?

📒With the ARDC #BinderHub Service, flexible and shareable computing environments are easier to access than ever. It's free for Australian researchers.

Learn more🔗 bit.ly/ardc-binder
March 27, 2025 at 3:49 AM
The new ARDC Nectar Research Cloud national node is now live at @aarnet.edu.au!
☁️It provides more capacity & resilience for our virtual desktop, #JupyterHub & #BinderHub services + supports national research platforms & projects, particularly those handling sensitive data
ardc.edu.au/article/nati...
National Node of ARDC Nectar Research Cloud Goes Live at AARNet | ARDC
The new national node of the ARDC Nectar Research Cloud is now operational, hosted by AARNet.
ardc.edu.au
March 30, 2025 at 11:10 PM
A key innovation is that we are running a *single-node Kubernetes deployment* on a VM using k3s. This means we can deploy BinderHub on *any* VM provider, which gives us many more options. For example, Hetzner is *way* cheaper than AWS, GCP, or Azure
February 5, 2025 at 3:15 PM
With rendered notebooks on the other pages (and ability to launch on binderhub resources) mgrover1.github.io/esds-intake-...

This took less than hour to setup and configure! Thankful for this suite of tools and how much easier they make it to do open science 🚀
Introduction to intake-esgf - intake-esm vs. intake-esgf ESDS Presentation
Github Pages based template for hackathons
mgrover1.github.io
April 28, 2025 at 8:42 PM
Whoops the link got cut off! Here is the full link to the blog post: 2i2c.org/blog/2025/bi...
2i2c joins the mybinder.org federation with a cheaper and faster way to deploy Binderhub | 2i2c
If you’re interested in supporting mybinder.org with cloud resources, financial resources, or human resources, please see the Support Binder page for how you can help. tl;dr: The 2i2c team is joining ...
2i2c.org
February 5, 2025 at 9:40 AM
Are you looking for a way to simplify collaborations and enhance the reproducibility of your research? 📒With the ARDC #BinderHub Service, flexible and shareable computing environments are easier to access than ever.
Learn more: https://ow.ly/y70Y50ZbB8k
#TipTuesday
June 16, 2026 at 5:30 AM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem...

Origin | Interest | Match
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 21, 2025 at 10:56 AM
#binderhub is on #openscience tool that runs on Kubernetes and allows users to create custom computing environments that can be shared and used by many remote users. However, to provide a reliable service to a growing number of users, BinderHub needs organisations to #donate computational power […]
Original post on akademienl.social
akademienl.social
January 20, 2025 at 3:07 PM
mybinder.org recently hit some port scanning abuse issues. We helped create tcpflowkiller to detect & stop port scanning for BinderHub! This will benefit each of the BinderHub federation member instances.

Learn more 👉 2i2c.org/blog/2025/my...
The Binder Project
Reproducible, sharable, open, interactive computing environments.
mybinder.org
October 15, 2025 at 1:01 PM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 2:02 PM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 12:00 PM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 10:01 AM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 8:02 AM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 6:00 AM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 4:00 AM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 1:59 AM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 26, 2025 at 12:00 AM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 25, 2025 at 9:59 PM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 25, 2025 at 7:58 PM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 25, 2025 at 5:58 PM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 25, 2025 at 3:58 PM
Emmanuel Kasper: How configuration is passed from the BinderHub helm chart to a running BinderHub
### Context: At $WORK I am doing a lot of datascience work around Jupyter Notebooks and their ecosystem. Right now I am setting BinderHub, which is a service to start a Jupyter Notebook from a git repo in your browser. For setting up BinderHub I am using the BinderHub helm chart, and I was wondering how configuration changes are propagated from the BinderHub helm chart to the process running in a Kubernetes Pod. After going through this I can say I am not right now a great fan of Helm, as it looks to me like an unnecessary, overengineered abstraction layer on top of Kubernetes manifests. Or maybe it is just that I don’t want to learn the golang templating synthax. I am looking forward to testing Kustomize as an alternative, but I havn’t had the chance yet. ### Starting from the list of config parameters available: Although many parameters are mentioned in the installer document, you have to go to the developer doc at https://binderhub.readthedocs.io/en/latest/reference/ref-index.html to get a whole overview. In my case I want to set the `hostname` parameter for the Gitlab Repoprovider. This is the relevelant snippet in the developer doc: hostname c.GitLabRepoProvider.hostname = Unicode('gitlab.com') The host of the GitLab instance The string `c.GitLabRepoProvider.hostname` here means, that the value of the `hostname` parameter will be loaded at the path config.GitLabRepoProvider inside a configuration file. Using the yaml synthax this means the configuration file should contain a snippet like: config: GitlabRepoProvider hostname: my-domain.com ### Digging through Kubernetes constructs: Helm values files When installing BinderHub using the provided helm chart, we can either put the configuration snippet in the config.yaml or secret.yaml helm values files. In my case I have put the snippet in config.yaml, since the hostname is not a secret thing, I can verify with **`yq`** that it correctly set: $ yq --raw-output '.config.GitLabRepoProvider.hostname' config.yaml my-domain.com How do we make sure this parameter is properly applied to our running binder processes ? As said previouly this parameter is passed as a value file to **`helm`** (–value or -f option) in the command: $ helm upgrade \ binderhub \ jupyterhub/binderhub \ --install \ --version=$(RELEASE) \ --create-namespace \ --namespace=binderhub \ --values secret.yaml \ --values config.yaml \ --debug According to the helm documentation in https://helm.sh/docs/helm/helm_install/ the values file are concatenated to form a single object, and priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called ‘Test’, the value set in override.yaml would take precedence: $ helm install --values myvalues.yaml --values override.yaml myredis ./redis ### Digging through Kubernetes constructs: Secrets and Volumes When `helm upgrade` is run the helm values of type `config` are stashed in a Kubernetes secret `binder-secret`: https://github.com/jupyterhub/binderhub/blob/main/helm-chart/binderhub/templates/secret.yaml#L12 stringData: {{- /* Stash away relevant Helm template values for the BinderHub Python application to read from in binderhub_config.py. */}} values.yaml: | {{- pick .Values "config" "imageBuilderType" "cors" "dind" "pink" "extraConfig" | toYaml | nindent 4 }} We can verify that our hostname is passed to our Secret: $ kubectl get secret binder-secret -o yaml | yq --raw-output '.data."values.yaml"' | base64 --decode ... GitLabRepoProvider: hostname: my-domain.com ... Finally a configuration file inside the Binder pod is populated from the Secret, using the Kubernetes Volume construct. Looking at the Pod, we do see a volume called `config`, created from the `binder-secret` Secret: $ kubectl get pod -l component=binder -o yaml | grep --context 4 binder-secret volumes: - name: config secret: defaultMode: 420 secretName: binder-secret That volume is mounted inside the pod at `/etc/binderhub/config`: volumeMounts: - mountPath: /etc/binderhub/config/ name: config readOnly: true ### Runtime verification Looking inside our pod we see our hostname value available in a file underneath the mount point: oc exec binder-74d9c7db95-qtp8r -- grep hostname /etc/binderhub/config/values.yaml hostname: my-domain.com
00formicapunk00.wordpress.com
October 25, 2025 at 1:57 PM