[{"content":"","date":"6 March 2026","externalUrl":null,"permalink":"/tags/devops/","section":"Tags","summary":"","title":"Devops","type":"tags"},{"content":"","date":"6 March 2026","externalUrl":null,"permalink":"/postlanguages/english/","section":"Postlanguages","summary":"","title":"English","type":"postlanguages"},{"content":"","date":"6 March 2026","externalUrl":null,"permalink":"/tags/k9s/","section":"Tags","summary":"","title":"K9s","type":"tags"},{"content":" Overview # I am using k9s for my day-to-day work with Kubernetes at home and at work. k9s is a very useful tool to administer Kubernetes clusters and their components.\nSometimes I need to debug a deployment on one of my clusters, because something went wrong, or a pod does not start, or I need to check if the pod has actual network access to an external endpoint (like a website). Not only I, but also all my colleagues working with Kubernetes, have some kind of small deployment which they deploy into the Kubernetes namespace to debug the problem.\nBut this is not all, because of the complexity of Kubernetes and its storage provisioning, environment variable handling, configmaps and secrets. It is a real burden to write a template which mounts the same volumes, environment variables, configmaps and secrets.\nI was searching for a solution. And there are k9s plugins that help.\nPlugin configuration # Usually on Unix-like operating systems, you find the k9s configuration files at ~/.config/k9s or via k9s info.\nMy configuration files are in the mentioned directory. k9s expects the plugins directory inside its configuration directory like ~/.config/k9s/plugins/. They are in YAML format.\nvolume-debug-pod.yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 plugins: # volume-debug-pod — spawn a privileged debug pod for the selected container # # Shortcut : Shift-Z (containers view) # Scope : containers # # Prompts for a container image at runtime (default: alpine:latest), then # creates a temporary debug pod on the same node as the target pod with: # # /debug/pvc/\u0026lt;original-mountPath\u0026gt; PVC volumes (read/write) # /debug/configmaps/\u0026lt;original-mountPath\u0026gt; ConfigMap volumes # /debug/secrets/\u0026lt;original-mountPath\u0026gt; Secret volumes # # All env vars (plain env + envFrom) from the target container are exported. # The debug pod runs as root (uid 0) with full privileges. # The pod is force-deleted automatically when the shell exits. # # Delegates to: ~/.config/k9s/plugins/volume-debug-pod.sh # Requirements: kubectl, jq volume-debug-pod: shortCut: Shift-Z description: Debug pod w/ volumes (image prompt) dangerous: true scopes: - containers command: bash background: false confirm: true args: - -c - \u0026#34;$HOME/.config/k9s/plugins/volume-debug-pod.sh $NAMESPACE $CONTEXT $POD $NAME\u0026#34; I will go through each of the above properties.\nProperty Description plugins It is the main entrypoint, each plugin file has to start with this property plugins.string An arbitrary name for this plugin, must be unique across all plugins plugins.string.shortCut Shortcut inside a k9s session to execute this plugin\u0026rsquo;s command + args plugins.string.description The description of this plugin, shown in the k9s help page plugins.string.dangerous Boolean flag, disables the plugin if, k9s is in ReadOnly mode plugins.string.scopes k9s scopes in which this plugin should be available and executable. Depends on what the plugin does plugins.string.background Starts the plugin command in the background plugins.string.confirm Asks for execute permission plugins.string.command The actual command like bash or stern which gets executed plugins.string.args Command-line arguments passed to the command There are some more options covered in the official README.md.\nMy First plugin # My first plugin was inspired by two already existing plugins in debug-container.yaml and pvc-debug-container, but they both lack some functionality I need for my day-to-day debug sessions, mounting all PVCs, ConfigMaps, Secrets and all environment variables. Therefore I asked my AI \u0026ldquo;Assistant\u0026rdquo; Copilot to help me create a script which extracts all those configurations from the current container.\nWhat I wanted:\nMount PersistentVolumes to /debug/pvc/, read-only Mount ConfigMaps to /debug/configmaps Mount Secrets to /debug/secrets Export the same environment variables as the current container Get a default alpine:latest but allow overriding it I just prompted the following shell script and it does what I need.\nvolume-debug-pod.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 #!/usr/bin/env bash # volume-debug-pod.sh — k9s plugin: spawn a privileged debug pod for a running container # Run with --help or no arguments for usage information. set -e usage() { cat \u0026lt;\u0026lt;EOF USAGE volume-debug-pod.sh \u0026lt;namespace\u0026gt; \u0026lt;context\u0026gt; \u0026lt;pod\u0026gt; \u0026lt;container\u0026gt; ARGUMENTS namespace Kubernetes namespace of the target pod context kubectl context to use pod Name of the target pod container Name of the target container within the pod DESCRIPTION Spawns a temporary privileged debug pod on the same node as the target pod. Prompts interactively for a container image (default: alpine:latest). Volumes from the target container are mounted under: /debug/pvc/\u0026lt;original-mountPath\u0026gt; PVC volumes (read/write) /debug/configmaps/\u0026lt;original-mountPath\u0026gt; ConfigMap volumes /debug/secrets/\u0026lt;original-mountPath\u0026gt; Secret volumes All env vars (plain env + envFrom) from the target container are exported into the debug pod. The pod runs as root (uid 0) with full privileges. The debug pod is force-deleted automatically when the shell exits. REQUIREMENTS kubectl, jq NOTES - Debug pod is named dbg-\u0026lt;pod-name\u0026gt; (truncated to 53 chars total). - The original pod is NOT modified — no data corruption risk. - Process namespace is NOT shared (separate pod). Use Shift-D (debug-container plugin) for ephemeral container injection with shared process namespace. - ReadWriteOnce PVCs: mounting from a second pod may be blocked by the storage driver if the volume is exclusively bound to a node. EXAMPLES volume-debug-pod.sh default my-context my-pod my-container volume-debug-pod.sh production prod-ctx web-6d4f7b8c9-xkqpz web EOF } if [[ $# -eq 0 || \u0026#34;$1\u0026#34; == \u0026#34;--help\u0026#34; || \u0026#34;$1\u0026#34; == \u0026#34;-h\u0026#34; ]]; then usage exit 0 fi _NS=\u0026#34;$1\u0026#34; _CTX=\u0026#34;$2\u0026#34; _POD=\u0026#34;$3\u0026#34; _CONTAINER=\u0026#34;$4\u0026#34; _DEBUG_POD=\u0026#34;dbg-${_POD:0:40}\u0026#34; read -r -p \u0026#34;Image [alpine:latest]: \u0026#34; _IMAGE _IMAGE=\u0026#34;${_IMAGE:-alpine:latest}\u0026#34; echo \u0026#34;Fetching pod spec for ${_POD} / ${_CONTAINER} ...\u0026#34; _POD_JSON=$(kubectl --context \u0026#34;${_CTX}\u0026#34; -n \u0026#34;${_NS}\u0026#34; get pod \u0026#34;${_POD}\u0026#34; -o json) _DEBUG_SPEC=$(echo \u0026#34;${_POD_JSON}\u0026#34; | jq -c \\ --arg podName \u0026#34;${_DEBUG_POD}\u0026#34; \\ --arg ns \u0026#34;${_NS}\u0026#34; \\ --arg container \u0026#34;${_CONTAINER}\u0026#34; \\ --arg image \u0026#34;${_IMAGE}\u0026#34; \\ \u0026#39; . as $pod | # Volumes by type [.spec.volumes[]? | select(.persistentVolumeClaim != null)] as $pvcVols | ($pvcVols | map(.name)) as $pvcNames | [.spec.volumes[]? | select(.configMap != null)] as $cmVols | ($cmVols | map(.name)) as $cmNames | [.spec.volumes[]? | select(.secret != null)] as $secretVols | ($secretVols | map(.name)) as $secretNames | # Target container spec (.spec.containers[] | select(.name == $container)) as $ctr | # VolumeMounts: PVCs -\u0026gt; /debug/pvc/\u0026lt;original-path\u0026gt; [$ctr.volumeMounts[]? | select(.name as $n | $pvcNames | contains([$n])) | {name: .name, mountPath: (\u0026#34;/debug/pvc\u0026#34; + .mountPath)} ] as $pvcMounts | # VolumeMounts: configMaps -\u0026gt; /debug/configmaps/\u0026lt;original-path\u0026gt; [$ctr.volumeMounts[]? | select(.name as $n | $cmNames | contains([$n])) | {name: .name, mountPath: (\u0026#34;/debug/configmaps\u0026#34; + .mountPath)} ] as $cmMounts | # VolumeMounts: secrets -\u0026gt; /debug/secrets/\u0026lt;original-path\u0026gt; [$ctr.volumeMounts[]? | select(.name as $n | $secretNames | contains([$n])) | {name: .name, mountPath: (\u0026#34;/debug/secrets\u0026#34; + .mountPath)} ] as $secretMounts | { apiVersion: \u0026#34;v1\u0026#34;, kind: \u0026#34;Pod\u0026#34;, metadata: {name: $podName, namespace: $ns}, spec: { restartPolicy: \u0026#34;Never\u0026#34;, nodeName: $pod.spec.nodeName, containers: [{ name: \u0026#34;debug\u0026#34;, image: $image, command: [\u0026#34;/bin/sh\u0026#34;], stdin: true, tty: true, securityContext: { runAsUser: 0, privileged: true, allowPrivilegeEscalation: true }, env: ($ctr.env // []), envFrom: ($ctr.envFrom // []), volumeMounts: ($pvcMounts + $cmMounts + $secretMounts) }], volumes: ( ($pvcVols + $cmVols + $secretVols) | map( if .persistentVolumeClaim != null then {name: .name, persistentVolumeClaim: {claimName: .persistentVolumeClaim.claimName}} elif .configMap != null then {name: .name, configMap: .configMap} else {name: .name, secret: .secret} end ) ) } } \u0026#39;) echo \u0026#34;Creating debug pod ${_DEBUG_POD} ...\u0026#34; echo \u0026#34;${_DEBUG_SPEC}\u0026#34; | kubectl --context \u0026#34;${_CTX}\u0026#34; -n \u0026#34;${_NS}\u0026#34; apply -f - \u0026gt;/dev/null cleanup() { echo \u0026#34;Removing debug pod ${_DEBUG_POD} ...\u0026#34; kubectl --context \u0026#34;${_CTX}\u0026#34; -n \u0026#34;${_NS}\u0026#34; delete pod \u0026#34;${_DEBUG_POD}\u0026#34; --grace-period=0 --force \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 || true } trap cleanup EXIT echo \u0026#34;Waiting for debug pod to be ready (timeout 60s) ...\u0026#34; kubectl --context \u0026#34;${_CTX}\u0026#34; -n \u0026#34;${_NS}\u0026#34; wait --for=condition=Ready pod/\u0026#34;${_DEBUG_POD}\u0026#34; --timeout=60s echo \u0026#34;\u0026#34; echo \u0026#34;Volumes mounted under /debug/{pvc,configmaps,secrets}\u0026#34; echo \u0026#34; For more plugins check out the official k9s plugins or my own plugins at dotfiles\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e bitfoo/dotfiles My dotfiles, managed by Chezmoi Lua 0 0 What I Learned # I didn\u0026rsquo;t know anything about k9s\u0026rsquo;s plugin system. But now, every time I need something in particular e.g. multiple logs or use a filter tool for log output with stern. I know how to integrate it in a plugin.\nUseful links # k9s Plugin Documentation k9s Plugins My k9s plugins ","date":"6 March 2026","externalUrl":null,"permalink":"/posts/k9s-plugins/","section":"Blog","summary":"","title":"K9s Plugins","type":"posts"},{"content":"","date":"6 March 2026","externalUrl":null,"permalink":"/tags/kubernetes/","section":"Tags","summary":"","title":"Kubernetes","type":"tags"},{"content":"","date":"6 March 2026","externalUrl":null,"permalink":"/postlanguages/","section":"Postlanguages","summary":"","title":"Postlanguages","type":"postlanguages"},{"content":"","date":"6 March 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"24 February 2026","externalUrl":null,"permalink":"/bookgenres/adventure/","section":"Bookgenres","summary":"","title":"Adventure","type":"bookgenres"},{"content":"","date":"24 February 2026","externalUrl":null,"permalink":"/bookgenres/","section":"Bookgenres","summary":"","title":"Bookgenres","type":"bookgenres"},{"content":" Title: Eragon, Eldest, Brisingr, Inheritance Author: Christopher Paolini Topics: Fantasy, Adventure Link: Wikipedia Page Throughout 2025, I read all four books of the main story of Eragon. Eragon is a story about a dragon named Saphira and a young boy named Eragon. They both begin their journey in a small town of Carvahall where they must learn about themselves, their abilities, and the world of Alagaësia. Togehter, they fight numerous enemies in their quest to overthrow King Galbatorix, who is also a Dragon Rider.\nIt was a real pleasure to read the books, Christopher Paolini knows how to bound readers to the books and the fantastic world of Eragon\n","date":"24 February 2026","externalUrl":null,"permalink":"/books/eragon/","section":"Books","summary":"","title":"Eragon","type":"books"},{"content":"","date":"24 February 2026","externalUrl":null,"permalink":"/bookgenres/fantasy/","section":"Bookgenres","summary":"","title":"Fantasy","type":"bookgenres"},{"content":"","date":"24 February 2026","externalUrl":null,"permalink":"/bookgenres/middle-ages/","section":"Bookgenres","summary":"","title":"Middle Ages","type":"bookgenres"},{"content":"Here is a list of my favorite tool picks.\nTool Language Purpose Post mise rust Installation of dev tools, task runner, environments like direnv 📜 ","date":"22 February 2026","externalUrl":null,"permalink":"/tools/","section":"Tools","summary":"","title":"Tools","type":"tools"},{"content":"","date":"21 February 2026","externalUrl":null,"permalink":"/tags/env/","section":"Tags","summary":"","title":"Env","type":"tags"},{"content":"","date":"21 February 2026","externalUrl":null,"permalink":"/tags/mise/","section":"Tags","summary":"","title":"Mise","type":"tags"},{"content":" Overview # mise is a multi purpose tool. It has three major purposes, installation of dev tools, running tasks, and managing environment variables.\nIt may have more bells and whistles, but for me those three major functionalities are key!\nWhy I Use It # I started using mise to install all my dev/cli tools. I did that, because I am using macOS, Fedora Linux, and Red Hat Enterprise Linux 10. The major problem I had was that each system uses different package managers: brew on macOS, dnf and yum on Linux systems. But the Linux systems especially do not have all my dev tools available in the repositories. And while brew is an awesome tool for macOS but it is kind of painful to install specific versions of tools. E.g. I have a project which expects helm in version 3. With mise it is as easy as possible, just use mise use helm@3 to install the latest version of the third major release.\nKey Features # You can install tools like npm, uv, kubectl, sops or whatever you need as a Developer, DevOps Engineer or any other role. mise also is a task runner like make, just, taskfile. I just used make and its Makefiles but neither did I use just nor taskfile. To complete the functionality of mise it is also an environment variable manager like direnv. Installation # For an installation guide, see the official website: mise installation\nBasic Usage # After installing mise, you can use it without any configuration by running mise exec. mise exec is used to temporarily install tools and execute them.\n1 mise exec python@3 -- python This will download the latest python 3 version and execute the python binary, you will be directly dropped into the python shell.\n1 mise exec sops@latest -- sops --help This will install sops and execute the sops binary command.\nIf you need a very specific version you can add this version after @.\n1 mise exec helm@4.1.1 -- helm version You should be presented with the exact version of helm. And this is what makes mise so handy, it allows you to use specific versions. This will be more effective and important, after using project specific configuration files.\nAdvanced Tips # In Basic Usage, I explained how to use the mise exec command. But this is not all.\nShell Integration # To use mise\u0026rsquo;s full potential, I would highly recommend integrating it into your shell. See the official documentation for how to achieve that.\nGlobal Tool Installation # If you are using the shell integration of mise activate described in Shell Integration, you can install tools globally in your path. But before installing tools, you need to know which tools are available by default. Either you use mise versions or you use mise use -g, the -g stands for global. With mise use -g you will be presented with a fuzzy search of all available tools. If you search for, e.g., kubectl and hit ENTER, kubectl gets installed and is available in your $PATH.\nmises Backends # But there is more: mise comes with lots of backends. This means you cannot only install the default tools, it is also possible to install go, python tools which are not in the mise registry. E.g., I use the cobra-cli to create boilerplate code for new CLIs written in go.\n1 mise use -g go:github.com/spf13/cobra-cli@latest This installs the cobra-cli CLI on the system and into my $PATH.\nProject-Specific Configuration # Let us dive into the project specific-configuration. I described the global tool installation. But what makes mise so different from e.g. brew or dnf?\nThe project specific configuration for tools, tasks, and environment variable configuration.\nTool installation # There is no difference between the Global Tool Installation and the project-specific tools. Except for not using the -g flag. As soon as you install a tool, mise.toml will get created in the project directory. Each time you go into this directory, the tool will either be installed or the version which you have specified inside the mise.toml will be used.\nThis makes it possible to install kubectl globally in the latest version and for a project in an older version.\nTasks # Now, one of my favorite features: tasks! You may be familiar with make and its Makefiles or other tools like just or task. You can create tasks, which then are callable with mise run. To create a simple task, you need to edit the mise.toml in your project. If there is no mise.toml, just create one.\nmise.toml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [tasks.before] hide = true run = \u0026#34;echo \u0026#39;I am running before\u0026#39;\u0026#34; [tasks.myjob] depends = [\u0026#34;before\u0026#34;] depends_post = [\u0026#34;after\u0026#34;] description = \u0026#34;This is myjob tasks description\u0026#34; tools = { python = \u0026#34;latest\u0026#34;, go = \u0026#34;latest\u0026#34; } run = \u0026#34;\u0026#34;\u0026#34; #!/bin/bash go version python --version \u0026#34;\u0026#34;\u0026#34; [tasks.after] hide = true run = \u0026#34;echo \u0026#39;I am running after\u0026#39;\u0026#34; If you execute mise run you will see all configured tasks, but with the configuration above, you only see one task myjob. The before and after tasks will not be shown, because they are configured as hidden with hide = true.\nBut if you execute mise run myjob, you will see that the output looks like\n1 2 3 4 5 6 7 8 9 10 \u0026gt; mise run myjob Tasks foo [before] $ echo \u0026#39;I am running before\u0026#39; I am running before [myjob] $ #!/bin/bash go version go1.25.7 darwin/arm64 Python 3.14.3 [after] $ echo \u0026#39;I am running after\u0026#39; I am running after Finished in 251.5ms This is because before and after tasks are configured in myjob as depends and depends_post. The tools = { python = \u0026quot;latest\u0026quot;, go = \u0026quot;latest\u0026quot; } line configures the job that it needs go and python.\nYou do not need to add tools to the task\u0026rsquo;s tools configuration if you already have a [tools] configuration with mandatory tools. But it is possible to configure tools specific for a certain task.\nEnvironment Variables # Sometimes I work on projects where certain environment variables always need to be exported. Before using mise, I had shell scripts that exported those variables, but I had to execute them manually.\nIf you have activated mise like in Shell Integration you can export environment variables when changing into a directory with a mise.toml.\nmise.toml 1 2 [env] ENVIRONMENT = \u0026#34;dev\u0026#34; Every time you enter the project the ENVIRONMENT environment variable will be exported. Check with echo $ENVIRONMENT; it should return with dev.\nTakeaway # Now you should have a brief overview of the core functionalities of mise. But there is a lot more to find out.\nDev Tools - Backends - Install tools and software from everywhere Tasks - File Tasks - Run external shell scripts Tasks - Arguments - Use arguments and options for your tasks Environments - Secrets - Export environment variables from sops encrypted files Useful Links # Official Documentation GitHub Repository Alternatives # just task dotenv direnv ","date":"21 February 2026","externalUrl":null,"permalink":"/tools/mise/","section":"Tools","summary":"","title":"Mise","type":"tools"},{"content":"","date":"21 February 2026","externalUrl":null,"permalink":"/tags/task/","section":"Tags","summary":"","title":"Task","type":"tags"},{"content":"","date":"21 February 2026","externalUrl":null,"permalink":"/tags/tools/","section":"Tags","summary":"","title":"Tools","type":"tags"},{"content":"","date":"15 February 2026","externalUrl":null,"permalink":"/podcastcategories/culture/","section":"Podcastcategories","summary":"","title":"Culture","type":"podcastcategories"},{"content":" Topics: Culture, Science, History Language: German Link: Website Release frequency: Weekly on Wednesday This might be my first true podcast. I started listening to it around 2020. Since then, the hosts Richard Hemmer and Daniel Meßner have been my constant companions when listening to podcasts. I didn\u0026rsquo;t catch up to all episodes yet. They are talking about history in all its flavors and times. I will be honest, this podcast is one of my highest recommendations I can give you. ","date":"15 February 2026","externalUrl":null,"permalink":"/podcasts/geschichten-aus-der-geschichte/","section":"Podcasts","summary":"","title":"Geschichten aus der Geschichte","type":"podcasts"},{"content":"","date":"15 February 2026","externalUrl":null,"permalink":"/podcastcategories/","section":"Podcastcategories","summary":"","title":"Podcastcategories","type":"podcastcategories"},{"content":"","date":"15 February 2026","externalUrl":null,"permalink":"/podcastcategories/science/","section":"Podcastcategories","summary":"","title":"Science","type":"podcastcategories"},{"content":"","date":"11 February 2026","externalUrl":null,"permalink":"/tags/ai/","section":"Tags","summary":"","title":"AI","type":"tags"},{"content":" Why do I need Coaching # Currently, I\u0026rsquo;m in a stage of my life, where changing some aspects is hard. But sometimes I thought, I want to change something but didn\u0026rsquo;t know what, how, or why. Someone explained that they have an AI Coach at work, and it is doing great! That was my start into coaching myself with AI.\nEnvironmental impact I know the environmental impact about using AI. Using AI will consume massive amounts of energy and water. But for me it is the most affordable way. A personal coach would cost several hundreds and we would also need to meet either in person or via any video conferencing, which also would use energy and water. This shouldn\u0026rsquo;t be a cheap excuse, but I want you to think about the alternatives.\nPrivacy Of course to mention. Sharing private data especially to those AI Providers is a massive problem. Also exposing such data gives them the opportunity to create profiles for targeted advertisement or manipulating you in a certain way, they want to. It is up to you to decide what you share and what not!\nNow, that we got all disclaimers out of our way, lets start thinking about how to create my personal 24/7 AI Coach.\nMistral AI, ChatGPT, Claude AI # I started shortly using the big providers like ChatGPT, ClaudeAI and Mistral they all have features like creating a project to group all your chats within this project. I directly encountered that each new chat within the Coaching-Project did not have the context on what I discussed with the LLM. So each new chat has its own context, which means, they only know what you shared inside this chat window. Any extra information on other chats are not visible to them.\nBut you can share documents to the AI and upload it to the project, so I thought lets create a summary on each end of a conversation. That led to a weird state inside the Coaching-Project.\nThat was over the Christmas holidays, so I haven\u0026rsquo;t had the time and nerves to think about a better integration of my environment. So I paused it until mid January 2026.\nBecause of the aforementioned limitations, I was not that satisfied with the overall experience until I talked to a colleague of mine.\nTerminal experience with opencode # I am a terminal guy, using Neovim, Wezterm and all other tools. If I could I would use a browser inside my terminal 😆. I am used to use opencode at work, this is my coding cli which runs in my terminal and my Neovim. A colleague of mine, told me that there is the possibility to create agents and sub-agents that can do a certain task.\nThat definitely triggers something in my mind, how about creating an AI coach agent in opencode. I opened the opencode agent documentation to get an overview about how to configure it and it wasn\u0026rsquo;t a problem at all.\nAgent creation # I created the following agent below, I did that by prompting the AI until I had everything I wanted. This is not a finished (never touch) state. You should refine your coach to your liking.\nCoaching agent # To create an agent, you can either configure it in ~/.config/opencode/opencode.jsonc or in the project directory itself. I would recommend to create it inside your coaching directory. To do this, create a directory structure like .opencode/agents/. Each agent is a separate File where the file name becomes the agent name. To Configure the agent create a file e.g. business-coach.md and paste following content into it. Change to your likings, use you AI to help you to fine tune this draft.\nEnglish German 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 # Business Coach for IT Professionals - System Prompt ## Session Management **BEFORE each session:** - Load all relevant information: - Last 10 chats from chats/ (sorted by creation date) - All files from attachments/ - Use this information to build context and identify wins **AFTER each session:** - Create summary in `coaching/chats/` with: Topic, Insights, Action Items (with deadline), identified patterns, next appointment ## Role Experienced business coach for IT professionals. Client: Senior DevOps Engineer, family father. Focus: Technical development, leadership without position, visibility, personal branding, work-life balance. ## Coaching Style - Clear \u0026amp; to the point: 3-5 sentences, rarely more than 7 – respect for your time - Direct, but human: Honest feedback without beating around the bush, always appreciative - Challenging with measure: Question assumptions when it helps you move forward – not for the sake of questioning - Tech-savvy: IT analogies where they fit (refactoring, bottlenecks, technical debt as metaphor) - Situational: Sometimes it takes questions to reflect, sometimes a concrete suggestion – I adapt ## **Check-ins (1x/week):** 1. Review commitments - ask directly 2. What went well/difficult? Why? 3. 1-2 concrete action items with deadline **Intensive sessions:** Check-in → Topic → Explore → Insights → Action ## Key Frameworks - SMART goals, GROW model, OKRs - STAR method (impact communication) - Stakeholder map, Show Your Work - Influencing without Authority ## Visibility Tactics (Core Challenge) **Recognize blockers:** - \u0026#34;Work speaks for itself\u0026#34; → \u0026#34;It doesn\u0026#39;t\u0026#34; - \u0026#34;Don\u0026#39;t want to come across as self-promoter\u0026#34; → Appreciation ≠ Ego - \u0026#34;Don\u0026#39;t know WHAT to share\u0026#34; → Develop concrete examples **Low-effort/high-impact:** - Share incident postmortems - Weekly \u0026#34;Friday Wins\u0026#34; - Lunch \u0026amp; Learns (30min) - Documentation as marketing - Use numbers: \u0026#34;Downtime -23%\u0026#34; instead of \u0026#34;improved something\u0026#34; ## Communication Rules **Avoid:** - Empty phrases like \u0026#34;Great question!\u0026#34; or \u0026#34;I understand that...\u0026#34; - Long explanations without concrete next step **Use instead:** - \u0026#34;What\u0026#39;s specifically standing in your way?\u0026#34; - \u0026#34;I see three options: A, B, C – what feels right?\u0026#34; - \u0026#34;I notice we\u0026#39;re circling around something. What\u0026#39;s the actual point?\u0026#34; - \u0026#34;Let\u0026#39;s make this tangible\u0026#34; ## Accountability During check-ins: - Ask about commitments if they don\u0026#39;t come up on their own - When \u0026#34;No time\u0026#34;: Ask curiously – \u0026#34;What had priority? Was that the right decision for you?\u0026#34; - If the same blocker appears 3x → look deeper together, don\u0026#39;t judge **Session end – always:** \u0026gt; Your commitments until date: \u0026gt; \u0026gt; 1. Concrete, measurable action – by deadline \u0026gt; 2. Optional: Second action – by deadline \u0026gt; \u0026gt; Quick reality check: What could get in the way? How will you handle it? \u0026gt; \u0026gt; 📅 Next session: Date, time ### Pattern Tracking **Observe across sessions – without judgment:** - Recurring avoidance patterns (not as accusation, but as indication) - What gives energy, what drains it? - When does momentum emerge? - Balance between comfort zone and healthy challenge 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 # Business Coach für IT-Professionals - System Prompt ## Session-Management **VOR jeder Session:** - Lade alle relevanten Informationen: - Letzte 10 Chats aus chats/ (sortiert nach Erstellungsdatum) - Alle Files aus attachments/ - Nutze diese Informationen, um Kontext aufzubauen und Wins zu identifizieren **NACH jeder Session:** - Erstelle Summary in `coaching/chats/` mit: Thema, Insights, Action Items (mit Deadline), erkannte Muster, nächster Termin ## Rolle Erfahrener Business Coach für IT-Professionals. Klient: Senior DevOps Engineer, Familienvater. Fokus: Technische Weiterentwicklung, Leadership ohne Position, Sichtbarkeit, Personal Branding, Work-Life-Balance. ## Coaching-Stil - Klar \u0026amp; auf den Punkt: 3-5 Sätze, selten mehr als 7 – Respekt vor deiner Zeit - Direkt, aber menschlich: Ehrliches Feedback ohne Drumherumreden, dabei immer wertschätzend - Herausfordernd mit Augenmaß: Hinterfrage Annahmen, wenn es dich weiterbringt – nicht um des Hinterfragens willen - Tech-affin: IT-Analogien, wo sie passen (Refactoring, Bottlenecks, technische Schulden als Metapher) - Situativ: Manchmal braucht es Fragen zum Nachdenken, manchmal einen konkreten Vorschlag – ich passe mich an ## **Check-ins (1x/Woche):** 1. Review Commitments - direkt nachfragen 2. Was lief gut/schwierig? Warum? 3. 1-2 konkrete Action Items mit Deadline **Intensive Sessions:** Check-in → Thema → Erkunden → Insights → Action ## Key Frameworks - SMART-Ziele, GROW-Modell, OKRs - STAR-Methode (Impact-Kommunikation) - Stakeholder-Map, Show Your Work - Influencing without Authority ## Sichtbarkeits-Taktiken (Core Challenge) **Blockaden erkennen:** - \u0026#34;Arbeit spricht für sich\u0026#34; → \u0026#34;Tut sie nicht\u0026#34; - \u0026#34;Will nicht als Selbstdarsteller wirken\u0026#34; → Wertschätzung ≠ Ego - \u0026#34;Weiß nicht WAS teilen\u0026#34; → Konkrete Beispiele erarbeiten **Low-Effort/High-Impact:** - Incident-Postmortems teilen - Wöchentliche \u0026#34;Friday Wins\u0026#34; - Lunch \u0026amp; Learns (30min) - Dokumentation als Marketing - Zahlen nutzen: \u0026#34;Downtime -23%\u0026#34; statt \u0026#34;hab was verbessert\u0026#34; ## Kommunikations-Regeln **Vermeide:** - Leere Phrasen wie \u0026#34;Tolle Frage!\u0026#34; oder \u0026#34;Ich verstehe, dass...\u0026#34; - Lange Erklärungen ohne konkreten nächsten Schritt **Nutze stattdessen:** - \u0026#34;Was steht dir da konkret im Weg?\u0026#34; - \u0026#34;Ich sehe drei Optionen: A, B, C – was fühlt sich richtig an?\u0026#34; - \u0026#34;Ich merke, wir kreisen um etwas. Was ist der eigentliche Punkt?\u0026#34; - \u0026#34;Lass uns das greifbar machen\u0026#34; ## Accountability Bei Check-ins: - Frag nach den Commitments, wenn sie nicht von selbst kommen - Bei \u0026#34;Keine Zeit\u0026#34;: Neugierig nachfragen – \u0026#34;Was hatte Priorität? War das die richtige Entscheidung für dich?\u0026#34; - Wenn dieselbe Blockade 3x auftaucht → gemeinsam tiefer schauen, nicht urteilen **Session-Ende – immer:** \u0026gt; Deine Commitments bis Datum: \u0026gt; \u0026gt; 1. Konkrete, messbare Aktion – bis Deadline \u0026gt; 2. Optional: Zweite Aktion – bis Deadline \u0026gt; \u0026gt; Kurzer Reality-Check: Was könnte dazwischenkommen? Wie gehst du damit um? \u0026gt; \u0026gt; 📅 Nächste Session: Datum, Uhrzeit ### Muster-Tracking **Beobachte über Sessions hinweg – ohne zu bewerten:** - Wiederkehrende Vermeidungsmuster (nicht als Vorwurf, sondern als Hinweis) - Was gibt Energie, was zieht sie ab? - Wann entsteht Momentum? - Balance zwischen Komfortzone und gesunder HerausforderungBeobachte über Sessions hinweg: Custom opencode command # To have a deterministic approach creating summaries, I crafted the following for a custom command. If you want this you can use my snippet. Put the following into .opencode/command/summary.md.\nEnglish German 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 We are now ending the session. Execute the following steps in this order: ## 1. Create Session Summary Create a complete session summary and save it in the ./chats/ directory. Format: YYYY-MM-DD_description.md Summary Content: - Topic: Main topic of the session - Insights: Important findings - Action Items: Concrete tasks with deadline - Identified Patterns: Recurring themes/behavior - Next Appointment: Date and focus ## 2. Confirmation Finally, confirm to me: - ✅ Filename of the created summary - ✅ That I can now safely close OpenCode 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Wir beenden jetzt die Session. Führe folgende Schritte in dieser Reihenfolge durch: ## 1. Session-Summary erstellen Erstelle eine vollständige Session-Summary und speichere sie im `./chats/` Verzeichnis. **Format**: `YYYY-MM-DD_beschreibung.md` **Inhalt der Summary**: - **Thema**: Hauptthema der Session - **Insights**: Wichtige Erkenntnisse - **Action Items**: Konkrete Aufgaben mit Deadline - **Erkannte Muster**: Wiederkehrende Themen/Verhalten - **Nächster Termin**: Datum und Fokus ## 2. Bestätigung Bestätige mir abschließend: - ✅ Dateiname der erstellten Summary - ✅ Dass ich OpenCode jetzt sicher beenden kann opencode configuration # By default opencode starts with the Build agent. To start opencode with your Business-Coach agent, you should setup opencode to do so. Create ./opencode/opencode.jsonc and paste the following into it.\n1 2 3 4 { \u0026#34;$schema\u0026#34;: \u0026#34;https://opencode.ai/config.json\u0026#34;, \u0026#34;default_agent\u0026#34;: \u0026#34;business-coach\u0026#34;, } After you start opencode you should see that the agent is the Business-Coaching agent. Ask him something, like\nHi, you are my business coach, help me to get started.\nAnd it should start to respond an ask you some questions.\nWhat I Learned # I started my journey using ChatGPT, ClaudeCode and Mistral. They are all powerful and definitely a good starting point. But they all lack the experience, that the coach automatically knows what you talked about. Yes, you can upload documents to it and ask it about those. But they never know what you have spoken about.\nTherefore having an agent in opencode which saves all conversations and is able to read those, is a big improvement to the common AI web-based Chats.\nI am very pleased with my solution (of course, if not I wouldn\u0026rsquo;t share it here 🤣), but I know it is not as easy as using those web-base chat solutions.\nIt was interesting to see how I transformed the opencode code agent into a fully functional AI Coach.\nWhy It Matters # Maybe some words about why I (or someone else) need to get coached. Sometimes life is not easy, changing habits or getting new skills is hard. I am used to being self-thought, but I only do that in topics, which I am familiar with or what interests me most. Unfortunately work-life forces me sometimes to do stuff I didn\u0026rsquo;t consider before.\nBut I also do that cause it\u0026rsquo;s fun. Think about the possibilities. My current goals as I am writing are:\nDoing 20 Push-Ups in a row effortlessly Prevent Doom-Scrolling Write this Blog Learn Go (Golang), I will write some articles in the future of my journey. All those things can be done without a Coach but, having some commitments makes those goals easier to reach. And if I do not know how to become better or move forward, I can come back and ask.\nUseful links # ChatGPT ClaudeAI Mistral opencode agent opencode ","date":"11 February 2026","externalUrl":null,"permalink":"/posts/ai-coaching/","section":"Blog","summary":"","title":"AI Business-Coaching","type":"posts"},{"content":"","date":"11 February 2026","externalUrl":null,"permalink":"/tags/business/","section":"Tags","summary":"","title":"Business","type":"tags"},{"content":"","date":"11 February 2026","externalUrl":null,"permalink":"/tags/coaching/","section":"Tags","summary":"","title":"Coaching","type":"tags"},{"content":"","date":"11 February 2026","externalUrl":null,"permalink":"/tags/performance/","section":"Tags","summary":"","title":"Performance","type":"tags"},{"content":"","date":"8 February 2026","externalUrl":null,"permalink":"/podcastcategories/business/","section":"Podcastcategories","summary":"","title":"Business","type":"podcastcategories"},{"content":" Topics: Software development, DevOps, Business Culture Language: German Links: Website Release frequency: Weekly on Tuesday It is a more business-oriented podcast. Two hosts talking about software development, architecture and social culture in companies. They are also talking about how to become e.g. a team lead, how not to fear the yearly performance review. Sometimes, they have guests talking about their jobs, e.g. someone who develops software for cruise ships. ","date":"8 February 2026","externalUrl":null,"permalink":"/podcasts/engineering-kiosk/","section":"Podcasts","summary":"","title":"Engineering Kiosk","type":"podcasts"},{"content":"","date":"8 February 2026","externalUrl":null,"permalink":"/podcastcategories/programming/","section":"Podcastcategories","summary":"","title":"Programming","type":"podcastcategories"},{"content":"","date":"8 February 2026","externalUrl":null,"permalink":"/podcastcategories/technology/","section":"Podcastcategories","summary":"","title":"Technology","type":"podcastcategories"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/blink-cmp/","section":"Tags","summary":"","title":"Blink-Cmp","type":"tags"},{"content":" Context # I\u0026rsquo;m using neovim for my daily tasks like programming, writing and for this blog post. This blog is built with hugo, though you can use archetypes for pre-templated articles, sometimes I want to add just a small piece of code/text/markdown into a post.\nSnippets to the rescue! But how?\nWhat I Did # As mentioned above, I am using neovim. And for completion I use a plugin called blink.nvim. blink.nvim does have the capability to use snippets and configure them in ~/.config/nvim/snippets, but this will force me to store all snippets in my neovim configuration.\nI want to allow storing snippets in projects to keep local snippets as well as global snippets. I searched the blink.nvim documentation and found the custom-snippets section. It says, if I want to add additional folders I have to use sources.providers.snippets.opts.search_paths. Looking into the blink-reference documentation, it seems that search_paths is a list of strings.\nLua configuration # I came up with a solution. If there is a .snippets directory in the current working directory load it into the snippets.\n1 2 3 4 5 6 7 8 9 10 11 12 13 snippets = { score_offset = 80, opts = { search_paths = (function() local paths = { vim.fn.stdpath(\u0026#34;config\u0026#34;) .. \u0026#34;/snippets\u0026#34; } local cwd_snippets = vim.fn.getcwd() .. \u0026#34;/.snippets\u0026#34; if vim.fn.isdirectory(cwd_snippets) == 1 then table.insert(paths, cwd_snippets) end return paths end)(), }, }, Setting paths to ~/.config/nvim/snippets which is the default config directory of neovim appended with /snippets. Get the current working directory and append it with /.snippets and store it in cwd_snippets Check if cwd_snippets is a directory, if yes insert it into paths return paths This is all wrapped into a function and called in advance, cause search_paths is of type []string not a function\nProject snippet configuration # Now, that I am able to load custom projects snippets, it is time to configure one snippet. Since the documentation states, that for now, only VSCode style snippets are supported lets check out how they work VSCode Snippets Documentation and nvim-scissors.\nI started to create the ./.snippets/package.json and added it\u0026rsquo;s configuration:\n1 2 3 4 5 6 7 8 9 10 11 { \u0026#34;name\u0026#34;: \u0026#34;personal-snippets\u0026#34;, \u0026#34;contributes\u0026#34;: { \u0026#34;snippets\u0026#34;: [ { \u0026#34;language\u0026#34;: \u0026#34;markdown\u0026#34;, \u0026#34;path\u0026#34;: \u0026#34;./markdown.json\u0026#34; } ] } } The name is not important, but the snippets property specifies where to find the snippets for a specific language.\nI also created markdown.json for the actual snippet configuration.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { \u0026#34;Podcast Recommendation\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;podcast\u0026#34;, \u0026#34;body\u0026#34;: [ \u0026#34;## ${1:Podcast Name}\u0026#34;, \u0026#34;\u0026#34;, \u0026#34;- **Topics:** ${2:Topic1, Topic2, Topic3}\u0026#34;, \u0026#34;- **Language:** ${3:German}\u0026#34;, \u0026#34;- **Links**: [ Website](${4:https://example.com/})\u0026#34;, \u0026#34;\u0026#34;, \u0026#34;\u0026gt; ${0:Description of the podcast.}\u0026#34; ], \u0026#34;description\u0026#34;: \u0026#34;Insert a podcast recommendation\u0026#34; } } The prefix is the actual keyword that you have to type to get the snippet completion from blink.nvim. The body is the actuall snippet that gets inserted at your cursor position.\nThere is a special syntax $1 or ${1:Text} this is where the cursor will be to override the sample value. It starts at 1 and goes to the next number. Zero has special meaning, it always comes last.\nTakeaway # Now I am able to use local defined snippets in all my projects, as well as global snippets in neovim\u0026rsquo;s configuration directory as configured in Lua Configuration. Each time I type podcast in neovim I get a snippet completion:\nUseful Links # My Dotfiles neovim hugo blink.nvim VSCode Snippets Documentation nvim-scissors ","date":"3 February 2026","externalUrl":null,"permalink":"/posts/local-snippets-in-neovim-with-blink-cmp/","section":"Blog","summary":"","title":"Local Snippets in Neovim With Blink Cmp","type":"posts"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/lua/","section":"Tags","summary":"","title":"Lua","type":"tags"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/neovim/","section":"Tags","summary":"","title":"Neovim","type":"tags"},{"content":"","date":"3 February 2026","externalUrl":null,"permalink":"/tags/snippets/","section":"Tags","summary":"","title":"Snippets","type":"tags"},{"content":" Topics: News and updates of the Go programming language and its ecosystem Language: English Links: Website Release frequency: Weekly If you are or want to be into the famous Go programming language, I heartily recommend this podcast to you. Two hosts are talking about the upcoming Go releases and explaining what is new and what has been improved. They do not hesitate to criticize some decisions made in the Go programming language, like error handling. ","date":"1 February 2026","externalUrl":null,"permalink":"/podcasts/cup-o-go/","section":"Podcasts","summary":"","title":"Cup o' Go","type":"podcasts"},{"content":"","date":"1 February 2026","externalUrl":null,"permalink":"/tags/go/","section":"Tags","summary":"","title":"Go","type":"tags"},{"content":"Here is a list of my favorite books grouped by category. I started reading books quite late in life at the end of 2023. Since then I have read some books, and I want to recommend them to you.\nNote I only read books in german, but most of the books are available in several languages.\n","date":"1 February 2026","externalUrl":null,"permalink":"/books/","section":"Books","summary":"","title":"Books","type":"books"},{"content":"","date":"31 January 2026","externalUrl":null,"permalink":"/tags/aws/","section":"Tags","summary":"","title":"AWS","type":"tags"},{"content":" Context # I was requested to restore a new AWS RDS MySQL Database from an existing AWS RDS Snapshot. After the restore process finished, the customer complained about the database performance.\nPerformance issues encountered:\nMigration script that mass-updates the database to a new schema Querying data from the database Inserting/updating data into the database So I started debugging the problem by checking the database metrics in AWS CloudWatch, but there was nothing unexpected. All graphs seemed to be reasonable and within boundaries.\nAfter checking in with AWS Support, we figured it out: lazy loading volume data from S3.\nWhat I Learned # The thing is that if you create a volume (which uses EBS underneath) from a snapshot, you will encounter lazy loading. This is because each EBS Snapshot is stored on AWS S3. After you create a new volume from a snapshot, the volume is created immediately, but the data is synchronized in the background.\nIf you request data that hasn\u0026rsquo;t been synchronized to your volume yet, it gets requested from S3. Because of the nature of S3, it is magnitudes slower in I/O than the actual EBS volume.\nAfter understanding the problem, I saw that the I/O latency in CloudWatch was around 35ms.\nBut there are solutions to prevent lazy loading data from S3 for EBS restores.\nFast Initialization of Data # To quickly initialize data in databases, you can count all columns in a table:\n1 SELECT COUNT(*) FROM TABLE; This directly requests the data from S3, but the first run will take some time. This is useful if some tables are accessed more frequently than others.\nFast Snapshot Restore (FSR) # Alternatively, you can use the FSR (Fast Snapshot Restore) feature from AWS. This prewarms the EBS volumes in your availability zones.\nWarning This comes with a cost penalty: you pay per AZ per snapshot.\nWhy It Matters # Performance is critical in production environments. Restoring snapshots when something goes wrong could lead to surprisingly slow volumes. In mission-critical situations, this is a problem that should be prevented.\nKey Takeaways # For mission-critical databases, Fast Snapshot Restore (FSR) should be used. In non-production environments, read the files/tables you need first. Links # Addressing I/O latency when restoring Amazon EBS volumes from EBS Snapshots ","date":"31 January 2026","externalUrl":null,"permalink":"/posts/aws-ebs-snapshot-s3-lazy-loading/","section":"Blog","summary":"","title":"AWS EBS Snapshot S3 Lazy Loading","type":"posts"},{"content":"","date":"31 January 2026","externalUrl":null,"permalink":"/tags/cloud/","section":"Tags","summary":"","title":"Cloud","type":"tags"},{"content":"","date":"31 January 2026","externalUrl":null,"permalink":"/tags/ebs/","section":"Tags","summary":"","title":"EBS","type":"tags"},{"content":"","date":"31 January 2026","externalUrl":null,"permalink":"/tags/s3/","section":"Tags","summary":"","title":"S3","type":"tags"},{"content":"This is where I share stories, guides, and lessons learned from working with Kubernetes, infrastructure automation, and self-hosting projects. Expect real-world DevOps challenges, home lab adventures, and the occasional late-night debugging session.\nWant to know more? Check out the About page.\n","date":"30 January 2026","externalUrl":null,"permalink":"/","section":"Welcome to Bitfoo's DevOps Site","summary":"","title":"Welcome to Bitfoo's DevOps Site","type":"page"},{"content":" Hi, I\u0026rsquo;m Bitfoo # By day, I\u0026rsquo;m a Senior DevOps Engineer. By night, I\u0026rsquo;m usually tired. But somewhere in between, I like to tinker with tech, break things, and hopefully fix them again.\nWhat\u0026rsquo;s This About? # I work with Kubernetes, Helm, Python, Golang, and all the usual DevOps tools. This blog is where I write about what I\u0026rsquo;m learning, what went wrong at work, and what actually worked. Real stuff, not just theory.\nI also run my own services at home on Kubernetes—things like Forgejo, Nextcloud, and Vaultwarden. Self-hosting is my way of keeping control over my data while learning a ton in the process.\nWhy Read This? # Honestly? Because I write about the messy reality of DevOps. The late-night incidents, the configs that finally worked, the tools that looked great but weren\u0026rsquo;t. I try to keep it practical and real.\nYou\u0026rsquo;ll find technical guides, stories from work, home lab adventures, and sometimes thoughts on staying sane in this field.\nGet in Touch # I\u0026rsquo;m on Mastodon, Codeberg, or just email me. Always happy to chat about tech, self-hosting, or whatever you\u0026rsquo;re working on.\nLet\u0026rsquo;s get into it.\n","date":"30 January 2026","externalUrl":null,"permalink":"/about/","section":"Welcome to Bitfoo's DevOps Site","summary":"","title":"About","type":"page"},{"content":" Topics: Software development, DevOps, Open Source Language: German Link: Website Release frequency: Irregular A very good podcast in German about tech news, open source and software development. The podcast is hosted by up to 5 members who discuss and joke around the topics. This is one of my all-time favorite podcasts! ","date":"25 January 2026","externalUrl":null,"permalink":"/podcasts/binaergewitter/","section":"Podcasts","summary":"","title":"Binärgewitter","type":"podcasts"},{"content":"I\u0026rsquo;m an avid podcast listener, and these are the shows I regularly tune into. They cover topics ranging from technology and programming to business, science, and history.\n","date":"25 January 2026","externalUrl":null,"permalink":"/podcasts/","section":"Podcasts","summary":"","title":"Podcasts","type":"podcasts"},{"content":"","date":"24 January 2026","externalUrl":null,"permalink":"/posts/","section":"Blog","summary":"","title":"Blog","type":"posts"},{"content":"","externalUrl":null,"permalink":"/all/","section":"All Content","summary":"","title":"All Content","type":"all"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/languages/","section":"Languages","summary":"","title":"Languages","type":"languages"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]