<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://cwoebker.com/atom.xml" rel="self" type="application/atom+xml" /><link href="https://cwoebker.com/" rel="alternate" type="text/html" /><updated>2026-05-20T07:22:09+02:00</updated><id>https://cwoebker.com/atom.xml</id><title type="html">Cecil Woebker</title><subtitle>Cecil&apos;s blog - insights on technology and science</subtitle><author><name>cwoebker</name></author><entry><title type="html">Agency, Ten Years On</title><link href="https://cwoebker.com/posts/agency-ten-years-on" rel="alternate" type="text/html" title="Agency, Ten Years On" /><published>2026-05-19T10:00:00+02:00</published><updated>2026-05-19T10:00:00+02:00</updated><id>https://cwoebker.com/posts/agency-ten-years-on</id><content type="html" xml:base="https://cwoebker.com/posts/agency-ten-years-on"><![CDATA[<p>Agency has become quite the buzzword on tech Twitter/X over the past year or so.
You see it as advice for founders, as praise for a specific kind of engineer, sometimes as a one-word verdict on a candidate.
It surprised me when I started noticing it, because the word highlights something that has been running my career since 2012 and I had never thought of it as something other people would name.
The first place I saw what it meant was the Stanford high school summer program, and the place that turned it from an instinct into a habit was the CDTM in Munich.</p>

<p>CDTM stands for Center for Digital Technology and Management.
It is an honors program jointly run by TUM and LMU in Munich for students who want to work somewhere between technology and business, usually because they want to start companies.
I joined in the fall of 2016 and graduated in the summer of 2018.
This year is roughly ten years out from when I applied, which made me want to write down what stuck and how it applies now.</p>

<p>Quick disclaimer on the word, since “agency” on Twitter has drifted into something close to a grindset cult, where the proof is how early you got up and how visibly you suffered.
The version I picked up at Stanford and refined at CDTM is more grounded and more useful for me: the habit of acting on what reality is telling you, before anyone hands you permission or certainty, and usually before the next step is obvious.
Most of the time it does not look like much: sending the email, showing up somewhere you were not formally invited, starting something for which nobody is asking you.</p>

<h2 id="the-seed-in-2012">The seed in 2012</h2>

<p>I was 17 in the summer of 2012 and spent a few weeks at a Stanford summer program for high schoolers.
I had stumbled across it on my own while starting to research US colleges, and applied without anyone pushing me to do so. Partly because I did not yet have plans for the long American summer break I was still not used to — having grown up in Germany, where the longest school break was only six weeks.
I lived on campus, took real Stanford classes, and ate in the same dining halls as the regular students.
I was halfway through high school in Worcester, Massachusetts at the time, so I had already absorbed a lot about how American universities work.</p>

<p>What drew me in was not the classes.
It was watching the actual Stanford students around me.
They were starting companies, joining ones that two friends had started the week before, building things in dorm rooms, cold-emailing professors, walking into labs and asking to help.
Nobody was waiting for someone to give them permission, and nobody was waiting for the path to look obvious before they started walking on it.</p>

<p>I went back to Worcester and tried to act like the Stanford students, and it stuck.
I launched Anigmo.org with online “Tic-Tac-Toe” and “Connect Four” games that you could play against the computer and wrote my Worcester Academy capstone about it, which is still on the <a href="/research">research page</a>.
A small anagram generator, a sudoku web app, and a screenshot tool called Screen followed, all still listed on the <a href="/projects">projects page</a>.
Nobody had assigned any of it, and that was the point.
I simply got into the habit of having an idea and executing on it — for no apparent reason other than enjoying the building process itself — and taking it one step after another.</p>

<p>I graduated in 2013, moved back to Munich, and started at TUM that fall.
I freelanced through most of undergrad and ran a small consulting company called CW Technologies on the side.
By the time I applied to the CDTM in 2016, I already thought of myself as someone who builds things, but I had not yet seen what it looks like when a whole room operates that way.</p>

<h2 id="cdtm-the-proof-at-scale">CDTM: the proof at scale</h2>

<p>The thing about CDTM is that you are surrounded by other people who act.
Self-selection does most of the work.
Students apply because they want to build startups, the program filters for the ones who already start things on their own, and the result is two years of being in rooms where the default question is not whether something can be done but who is going to do it.</p>

<p>CDTM did not give anyone agency — everyone there already had it.
What it added was a structured place to nurture that habit and point it at problems that mattered.</p>

<p>Not everything CDTM gave me was about agency, and the Trend Seminar is a good example of that.
It was more about timing: how to read an emerging space and form a view on when something is ready to be built and accepted by a market.
Different than the computer games I built as a high school student that no one really needed.
You pick a topic, study it for many weeks, and write a report on it that’s printed and shared online for anyone to read.
Our cohort looked broadly at diabetes, and my own subgroup argued that automatic closed-loop systems for managing insulin intake were the future.
They were not yet a real consumer category in 2016, when the first hybrid system had only just received FDA approval and there was nothing you could really buy off a shelf.
A decade later, automated insulin delivery is the <a href="https://diabetes.org/newsroom/press-releases/american-diabetes-association-releases-standards-care-diabetes-2026">ADA-recommended treatment</a> for type-1 diabetes, with five FDA-approved systems on the market.</p>

<p>The point was less the report and more the muscle of taking a vague trend and turning it into something concrete that other people can argue with.
I still use that muscle when I try to point remberg in a direction.</p>

<p>The other half of CDTM was the project work.
MPD (Managing Product Development) is the course where a small team takes on a real product brief from an industry partner and runs with it for a semester.
A European aerospace company gave my team a spec in 2016 for an internal assistant to help their engineers look up technical documentation.
We put chat front and center, which was not the obvious answer at the time, well before LLMs made it the default interface for everything.
One of my classmates had a deep NLP background and ran with that part of the stack.<sup id="fnref:florian"><a href="#fn:florian" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>In hindsight, what we shipped looked almost exactly like the AI assistants every enterprise is rolling out now, just with much worse intent classification and no real generation underneath.
The point of MPD was not the chatbot, of course; it was that you spend a semester acting as if you actually own a product and a customer relationship, and after a couple of semesters built that way you stop expecting a syllabus to tell you what to do.</p>

<p>Two of my three co-founders, the original introduction to remberg, and several of our best hires all came through the CDTM network.
Being in the room with people who already act is most of what makes any of this work.</p>

<p>What shaped me further was the time abroad.
CDTM had a connection to the chair at the Georgia Tech Research Network Operations Center, and that introduction was the only part of getting to Atlanta that came from the program.
Everything else I had to figure out myself: the visa, the flights, housing once I got there, the research project I wanted to work on, and getting into the courses I wanted to sit in by just walking in and asking the professor.
The semester after that I did the same thing at MIT, starting again from a single introduction and building the rest of the stay myself.
Those two semesters are the closest CDTM ever got to formal training in agency, except that nobody framed it as training — it was just what you did.</p>

<p>I wrote about the Georgia Tech semester in <a href="/posts/studying-gatech">Studying at the Georgia Institute of Technology</a> shortly after it finished.
Re-reading it now, the through line is plain: the research, the courses, the social side, almost all of it you have to build for yourself.</p>

<h2 id="what-it-looks-like-now">What it looks like now</h2>

<p>remberg is what came out of all of that.
It started during my MIT semester in the spring of 2018.
I was on a research track, writing papers, getting published, and starting to find academia intriguing.
I was also interviewing with strategy consulting firms on the side, which was the other path that felt safe at the time.
Then the offer came through the CDTM network: three guys back in Munich were building something together and were looking for a fourth person on the software side.<sup id="fnref:manuel"><a href="#fn:manuel" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>
Saying yes meant not finishing my master’s degree, dropping the research track, and stepping off the consulting interview pipeline.
Pushing against the path my family and broader society expected of me was a real struggle, and probably the hardest piece of agency I have had to find.
I am very glad I did it.</p>

<p>We started with a hardware product called Wunderbox, pivoted quickly to an after-sales SaaS for equipment-as-a-service, and over time landed on a maintenance management system for industrial customers.
Each of those pivots was, in retrospect, an act of agency: looking at what reality was telling us and changing what we were doing instead of waiting for permission to change it.
There were many more micro-shifts in between, like in most startups, but writing about the evolution of remberg is another job in itself.</p>

<p>My own scope in those years stretched well past what a CTO normally owns.
I leaned into finance, legal, and operations as well, making the calls in those domains rather than just executing the tasks.
I had some prior exposure to those areas, and a family member in tax consulting I could ask when I got stuck.
The rest I just took on, because on a four-person founding team nobody else was going to.
Hiring a Head of Finance in 2022 took a lot of that load off, and bringing in a VP Operations more recently took even more.
That has finally let me focus fully on AI and engineering again.</p>

<p>My job as CTO inside remberg has changed shape every year or two.
2018 was prototyping.
2019 to 2021 was being a software engineer.
2022 was hiring and being a more public face for the company while we grew from 15 to 70 people, a lot of that in product and engineering, which meant trading days of writing code for back-to-back hiring calls and being a more extroverted version of myself than I find natural.
2023 was organizational design and, at the end of the year, letting go of people across product, design, and engineering, a decision I think we came out of stronger.
2024 was building up the velocity in product and engineering.
2025 and 2026 have been pulled back to engineering, infrastructure, and architecture, with the Head of Engineering doing a tremendous job at running the organization.
None of those transitions felt like a job description being handed to me, but like noticing what was missing, what the company needed at a certain time, and stepping into it.</p>

<h2 id="should-you-still-do-cdtm-in-2026">Should you still do CDTM in 2026?</h2>

<p>I get this question occasionally from people who are deciding between top European programs in the AI era.
The short version of my answer is a simple yes.
The three things CDTM gave me that have aged well are the habit of self-organizing whatever comes next, the people I am still in the room with, and a sense of how to read where a market is heading.
AI does not weaken the need for any of them.
If anything, the surface area of what a small motivated group can build has expanded a lot in the last two years, and the bottleneck has moved further toward whether you actually start.
Pick a program where the people around you act, and act around them.</p>

<p>If you cannot apply to a program like CDTM, the conditions are reproducible without one.
Find a small group of people who already build things in their spare time, pick a deadline together (even one you make up), and ship something against it.</p>

<p>A second lever is unsolicited work: pick a question that an industry partner would pay to have answered and answer it for free.
Volunteer in a lab, write to a researcher, run a one-day hackathon, take a customer call you have no business taking.
None of that requires admissions, and most of the lift of CDTM came from doing exactly those things in a room where everyone else was doing them too.</p>

<p>Find me on X or write me an email if you have any questions.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:florian">
      <p>My friend Florian Scherer actually founded his own startup, <a href="https://rematiq.com">Rematiq</a>. Go check them out. <a href="#fnref:florian" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:manuel">
      <p>That introduction came from my friend Manuel Grossmann, another CDTM classmate who has since started his own VC firm, <a href="https://www.aminocollective.com/">Amino Collective</a>. Agency wins. <a href="#fnref:manuel" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>cwoebker</name></author><category term="education" /><summary type="html"><![CDATA[Agency has become quite the buzzword on tech Twitter/X over the past year or so. I picked up what the word actually means at a Stanford high school summer program in 2012 and turned it into a habit at the CDTM in Munich between 2016 and 2018. Ten years out from when I applied, I wrote down what stuck: the seminars and the project work, the self-organized research semesters in the US, the friction of dropping out of my master's to co-found remberg, what it has taken to keep finding agency inside the company since, and why I think the lesson matters more in the age of AI rather than less.]]></summary></entry><entry><title type="html">Fogernetes: Deployment and Management of Fog Computing Applications</title><link href="https://cwoebker.com/posts/fogernetes-deployment-management-fog-computing" rel="alternate" type="text/html" title="Fogernetes: Deployment and Management of Fog Computing Applications" /><published>2018-10-22T10:00:00+02:00</published><updated>2018-10-22T10:00:00+02:00</updated><id>https://cwoebker.com/posts/fogernetes-deployment-management-fog-computing</id><content type="html" xml:base="https://cwoebker.com/posts/fogernetes-deployment-management-fog-computing"><![CDATA[<p>Recently, I had the unique chance to present the work I completed during the final year of my undergraduate studies.
I conducted research on software deployment in the area of fog computing and was fortunate enough to publish at a conference in Taipei.
While this wasn’t my first published work, it was my first paper as main author.
It was the first time that I was responsible for the publishing process myself.
One of the benefits of this is that I also had the chance to present my work at the actual conference.
I thought it might be nice to share my experiences throughout this process.</p>

<p>Let’s start by talking about what I actually worked on.</p>

<p><img src="/assets/img/posts/fogernetes-noms.jpg" alt="NOMS" /></p>

<h2 id="my-research">My Research</h2>

<p>While I was trying to find a topic for my thesis at the beginning of 2017, I stumbled upon the area of fog computing.
Fog computing is a rather new terminology which extends the concept of cloud computing to the edge of the network.
As we look at computing systems that span traditional server farms as well as smaller devices located closer to where they are being used, new issues emerge.
Deploying software on all these different, heterogeneous devices is more complicated than for cloud computing.
And, while many deployment solutions for cloud computing exist, there hasn’t been that much focus on deployment in fog computing environments.
In my work, I focused on using Kubernetes, a deployment and orchestration system developed by Google, in a fog computing setting.
I developed a process for using it for fog computing and validated how well the system can work.</p>

<p>After I finished my thesis in the summer of 2017, my supervisor convinced me to publish a paper about this work.
This meant reworking some of my findings and results.
I had to squash my seemingly endless thesis into a 6-page paper.
While it takes a lot of effort to figure out which pieces are the most essential, the process also helps to better understand your own work.</p>

<p>Feel free to read through the final abstract or learn more about the topic on my <a href="/research#fogernetes-deployment-and-management-of-fog-computing-applications">research page</a>.</p>

<blockquote>
  <p>Devices used in fog and edge computing are heterogeneous, decentralized and distributed. These computing environments are unpredictable and their applications are becoming more complex. This leads to challenges regarding deployment and management of fog and edge applications. It is important to ensure that quality of service, availability, reliability and real-time characteristics are guaranteed during deployment to take advantage of fog computing. In this paper, we present Fogernetes, a fog computing platform that enables management and deployment of fog applications with specific requirements on heterogeneous devices with different capabilities. Fogernetes allows matching requirements of application components with device capabilities by using a labeling system. Based on a case study, we evaluate and test Fogernetes and examine its practical applicability for the deployment and management of fog computing applications. Fodeo serves as an example application. Fodeo analyzes video streams from multiple cameras and detects objects in them. Fogernetes enables the deployment of Fodeo components on appropriate devices by matching requirements and capabilities.</p>
</blockquote>

<h2 id="publishing-process">Publishing Process</h2>

<p>Publishing a paper isn’t always a straightforward process.
Let’s check out the timeline of the entire process:</p>

<ul>
  <li><strong>August 2017</strong> - I started my semester abroad after submitting my thesis.
We decided to try and publish at a conference. 💪</li>
  <li><strong>September 2017</strong> - We had to find the right conference and prepare a short paper summarizing the findings. ✍️</li>
  <li><strong>October 2017</strong> - We decided to submit the paper to the <a href="http://conferences.computer.org/IC2E/2018/">IC2E 2018</a> conference. 📨</li>
  <li><strong>December 2017</strong> - I am finishing my semester abroad, we received news that we were not accepted.
The year 2017 was almost over, and we had nothing to show for it. 😟</li>
  <li><strong>January 2018</strong> - With the new year lending us energy, we decided to go for another round.
We aim to submit for the <a href="https://sites.google.com/view/dominos2018/home">DOMINOS 2018</a> workshop at the <a href="http://noms2018.ieee-noms.org">NOMS 2018</a> conference in Taipei. 💪</li>
</ul>

<p>It has now been one year since I first learned about this research topic.</p>
<ul>
  <li><strong>February 2018</strong> - After getting an unforeseen extension on the deadline, we were able to successfully submit the paper. 📨</li>
  <li><strong>March 2018</strong> - The big news: we were accepted. 🎉</li>
  <li><strong>March 2018</strong> - If you are fortunate enough to be accepted at your conference or journal of choice, the work is not over.
I also had to prepare a <a href="/research#fogernetes-deployment-and-management-of-fog-computing-applications">presentation and a poster</a>. 🏋️‍♀️</li>
  <li><strong>April 2018</strong> - The conference happened in Taipei.
I was lucky enough to get some funding to present the work. 🌏</li>
  <li><strong>August 2018</strong> - The paper finally shows up in the <a href="https://ieeexplore.ieee.org/document/8406321/">IEEE library</a>. 📚</li>
</ul>

<p>It has now been one year since I submitted my thesis and more than 18 months since I started to look into this topic.</p>

<blockquote class="twitter-tweet" align="center"><a href="https://twitter.com/dominos_iot/status/988302781080485888"></a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<p>As you have realized by now, this whole process can take quite some time.
It took forever, from the first time I approached my supervisor about the topic, to eventually having the work published in conference proceedings.
While I did find the research, the publishing work, and the entire process quite rewarding and insightful, I also realized that I would face this issue again if I decided to continue with a career in research.
With computer science being such a fast-moving field, the pressure to get published and the headaches you get during this long process can distract from the actual work.
I spent the past year “just getting published” (at least it felt like that) and not actually doing the stuff that interests me.
And while this was rewarding the first time, I currently feel as if this would get annoying rather quickly.
Here in Germany, universities are <a href="https://www.nature.com/articles/d41586-018-00093-7">in a fight with Elsevier</a>.
You quickly realize how this publishing system is in some ways inherently broken.
It is frustrating.
This is why I have decided to just put some of the other stuff I did on ArXiV and be done with it.
Currently, it doesn’t seem worth investing so much time into this processes.
I do believe that it would become easier with more experience.</p>

<p>I want to point out that:</p>

<ul>
  <li>I would definitely do it again, as I have learned a lot.</li>
  <li>Getting published is not as infeasible as it may seem in the first place.</li>
  <li>Anyone who is pursuing a research project and is thinking of doing it should go for it.</li>
</ul>

<p>For me, the true challenge has become to work on something that is so interesting, so unique, and so rewarding that I do not need a conference or a journal to make other people aware of my work.
After all, this is why I started this blog in the first place.
For now, that means I am done with traditional publishing and I will try to find my own process, let it be in research or with something else.</p>

<h2 id="tldr">TL;DR</h2>

<ol>
  <li>Doing research is liberating and fun.
You can truly pursue what you are interested in.</li>
  <li>The long timelines of conferences make it quite hard to focus on doing actual work.</li>
  <li>Exchanging ideas at a conference and presenting your work is very rewarding and it is an amazing opportunity to meet some of your peers.</li>
  <li>I would recommend everyone I meet to try to publish their work.</li>
  <li>In the future, I will just continue to upload my papers here or on ArXiV.</li>
</ol>

<h2 id="thank-you">Thank you</h2>

<p>Finally, I want to say: <strong>Thank you!</strong>.</p>

<p>Thank you to the <strong>Chair for Applied Software Engineering</strong> at the Technical University Munich where I have been a student assistant since 2015.
Thank you to <strong>Prof. Bruegge</strong> for having taught me so much and making my research and especially this trip possible in the first place.
Also, thank you to <strong>Andreas Seitz</strong> for guiding me throughout this time.
From the first pages of my thesis to the final version of my own published work, I could not have done it without him.</p>

<blockquote class="twitter-tweet" align="center"><a href="https://twitter.com/dominos_iot/status/988842283616235520"></a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>]]></content><author><name>cwoebker</name></author><category term="education" /><summary type="html"><![CDATA[Fogernetes]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cwoebker.com/assets/img/posts/fogernetes-noms.jpg" /><media:content medium="image" url="https://cwoebker.com/assets/img/posts/fogernetes-noms.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Update: Introducing xdg specification support for como and pen</title><link href="https://cwoebker.com/posts/update-xdg-specification-como-pen" rel="alternate" type="text/html" title="Update: Introducing xdg specification support for como and pen" /><published>2018-10-09T10:00:00+02:00</published><updated>2018-10-09T10:00:00+02:00</updated><id>https://cwoebker.com/posts/update-xdg-specification-como-pen</id><content type="html" xml:base="https://cwoebker.com/posts/update-xdg-specification-como-pen"><![CDATA[<p>If you’ve used your current Linux or Mac computer for a while, you might have encountered a rather cluttered home directory.
Every small utility and library claims just another file or folder for themselves.
Since these files and folders all start with a dot (e.g. “.ssh”), they shouldn’t usually be shown in your file browser.
But, if you enable to show hidden files by default your home directory will become quite messy.
It turns out that there is the <a href="https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG Base Directory Specification</a> that aims to fix this issue while also separating config files, cache files, and data files.
Recently, I took some time to configure most tools to adhere to the XDG standard.
The Arch Linux wiki provides some <a href="https://wiki.archlinux.org/index.php/XDG_Base_Directory">pretty good information</a> on how to achieve this.
Unfortunately, I realize that I am also at fault for this.
The command line tools I developed were also storing their data files in your home directory by default.</p>

<p>I am happy to say that I finally updated my command line tools, pen and como, to adhere to the XDG standard.
The new location for their data files will be in <code class="language-plaintext highlighter-rouge">$XDG_DATA_HOME</code> or in <code class="language-plaintext highlighter-rouge">$HOME/.local/share</code>, depending on whether the former environment variable is set.
You will now find new versions for both tools at PyPi:</p>

<ul>
  <li><a href="https://github.com/cwoebker/pen">pen</a> <strong>v0.4.1</strong></li>
  <li><a href="https://github.com/cwoebker/como">como</a> <strong>v0.6.2</strong></li>
</ul>

<p>You can upgrade with <code class="language-plaintext highlighter-rouge">pip install como --upgrade</code> and <code class="language-plaintext highlighter-rouge">pip install penpal --upgrade</code>.</p>

<h2 id="pen"><a href="/posts/pen-terminal-notes">Pen</a></h2>

<p>The new default location is: <code class="language-plaintext highlighter-rouge">$XDG_DATA_HOME/pen/pen</code></p>

<p>Please be aware that no automatic migration will take place.
If you have previously configured the path of your data file with the <code class="language-plaintext highlighter-rouge">pen path</code> command, the program will still adhere to this setting.
Otherwise, you can either move the data file to the new default location or you can reconfigure your old path.</p>

<h2 id="como"><a href="/posts/como-batteries-complete">Como</a></h2>

<p>The new default location is: <code class="language-plaintext highlighter-rouge">$XDG_DATA_HOME/como/como</code></p>

<p>Again, please be aware that no automatic migration will take place.
You can either export your data before the upgrade (or download it from <a href="https://como.cwoebker.com">como.cwoebker.com</a>) or you can simply move the data file to the new location manually.</p>

<p>In other news I also updated como so that it now supports MacOS Mojave.</p>

<h2 id="feedback-requested">Feedback requested!</h2>

<p>If you try out these new versions, please let me know if you encounter any issues or problems.
I will do my best to fix them as soon as possible.</p>]]></content><author><name>cwoebker</name></author><summary type="html"><![CDATA[If you've used your current Linux or Mac computer for a while, you might have encountered a rather cluttered home directory. Every small utility and library claims just another file or folder for themselves. Since these files and folders all start with a dot (e.g. ".ssh"), they shouldn't usually be shown in your file browser. But, if you enable to show hidden files by default your home directory will become quite messy. It turns out that there is the XDG Base Directory Specification that aims to fix this issue while also separating config files, cache files, and data files.]]></summary></entry><entry><title type="html">Favicon Madness in 2018</title><link href="https://cwoebker.com/posts/favicon-madness" rel="alternate" type="text/html" title="Favicon Madness in 2018" /><published>2018-03-09T09:00:00+01:00</published><updated>2018-03-09T09:00:00+01:00</updated><id>https://cwoebker.com/posts/favicon-madness</id><content type="html" xml:base="https://cwoebker.com/posts/favicon-madness"><![CDATA[<blockquote class="twitter-tweet" align="center"><a href="https://twitter.com/holman/status/966075816021958656"></a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<p>Just two weeks ago, I saw a tweet by <a href="https://twitter.com/holman">@holman</a>, complaining about the current state of favicons on the internet.
For those of you who don’t know what a “favicon” is: It is short for favorite icon and is a small image that is representative of a website.
It usually shows up before the url or inside of a tab in your browser.
After I saw this tweet, I decided to also improve this website in order to support the favicon rules of 2018.
Back in the early days of the internet all of this was rather straightforward.
All you needed was a <code class="language-plaintext highlighter-rouge">favicon.ico</code> file in the root directory of your website and you would be all set and ready to go.
<img src="/assets/img/avatar160.png" alt="Favicon" title="Favicon" class="right-img" style="max-width: 160px;" />
And today this still works for the most part, but different companies have established new standards in order to use website logos in places such as mobile device home screens or pinned tabs.</p>

<p>In this post, I will list and describe the files that I use on this blog to adhere to these various standards, as well as point you to an easy-to-use solution to do the same!
So let’s make sure my <strong>beautiful</strong> favicon shows up everywhere!</p>

<h2 id="favicon-overview">Favicon: Overview</h2>

<p>In the table below, I list and describe the different files that I made available at the root of my website:</p>

<table class="table table-striped table-bordered table-condensed">
  <thead>
    <tr>
      <th>Filename</th>
      <th>Description</th>
      <th>Source</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>apple-touch-icon-precomposed.png</td>
      <td>Icon used for the homescreen on Apple devices.</td>
      <td><a href="https://mathiasbynens.be/notes/touch-icons">Apple Touch Icons</a></td>
    </tr>
    <tr>
      <td>apple-touch-icon.png</td>
      <td>Icon used for the homescreen on Apple devices.</td>
      <td><a href="https://mathiasbynens.be/notes/touch-icons">Apple Touch Icons</a></td>
    </tr>
    <tr>
      <td>safari-pinned-tab.svg</td>
      <td>Masked icon for the safari pinned tab.</td>
      <td><a href="https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/pinnedTabs/pinnedTabs.html">Apple Documentation</a></td>
    </tr>
    <tr>
      <td>browserconfig.xml</td>
      <td>Browser configuration for the tiles on Windows 8 and 10.</td>
      <td><a href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/dn320426(v=vs.85)">Microsoft browser configuration</a></td>
    </tr>
    <tr>
      <td>mstile-150x150x.png</td>
      <td>The actual tile image for Windows.</td>
      <td><a href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/dn320426(v=vs.85)">Microsoft browser configuration</a></td>
    </tr>
    <tr>
      <td>android-chrome-192x192.png</td>
      <td>Icon used for the homescreen on Android devices.</td>
      <td><a href="https://developer.chrome.com/multidevice/android/installtohomescreen">Chrome Homescreen Documentation</a></td>
    </tr>
    <tr>
      <td>favicon.ico</td>
      <td>The classical favicon. Contains multiple sizes.</td>
      <td><a href="https://en.wikipedia.org/wiki/Favicon">Favicon Wiki</a></td>
    </tr>
    <tr>
      <td>favicon-16x16.png</td>
      <td>Smaller version of the favicon.</td>
      <td><a href="https://en.wikipedia.org/wiki/Favicon">Favicon Wiki</a></td>
    </tr>
    <tr>
      <td>favicon-32x32.png</td>
      <td>Medium version of the favicon.</td>
      <td><a href="https://en.wikipedia.org/wiki/Favicon">Favicon Wiki</a></td>
    </tr>
    <tr>
      <td>site.webmanifest</td>
      <td>Defines different website information about the site (such as name, icon, and description).</td>
      <td><a href="https://developer.mozilla.org/en-US/docs/Web/Manifest">Mozilla Webmanifest</a></td>
    </tr>
  </tbody>
</table>

<p>In general, I have also found audreyr’s github project <a href="https://github.com/audreyr/favicon-cheat-sheet">favicon-cheat-sheet</a> to be really helpful on all of this.
Next, we will look at the actual HTML code needed to tell different browsers about all these files.</p>

<h2 id="favicon-html">Favicon: HTML</h2>

<p>There are four different standards to support if you want to cover the majority of clients and use cases.
On the one hand, we need to make sure to adhere to the original favicon standard.
On the other hand, we also want to comply with the new standards put forth by Apple, Google, and Microsoft.
These new standards, like described in the table above, are mostly there to have a website image that can be used on a mobile home screen, a tab, or a computer desktop.</p>

<p>In order to tell the browsers about some of these files, I also added the following to the <code class="language-plaintext highlighter-rouge">&lt;head&gt;</code> of my webpage.</p>

<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"icon"</span> <span class="na">type=</span><span class="s">"image/png"</span> <span class="na">sizes=</span><span class="s">"32x32"</span> <span class="na">href=</span><span class="s">"/favicon-32x32.png"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"icon"</span> <span class="na">type=</span><span class="s">"image/png"</span> <span class="na">sizes=</span><span class="s">"16x16"</span> <span class="na">href=</span><span class="s">"/favicon-16x16.png"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"manifest"</span> <span class="na">href=</span><span class="s">"/site.webmanifest"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"application-name"</span> <span class="na">content=</span><span class="s">"cwoebker"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"theme-color"</span> <span class="na">content=</span><span class="s">"#ffffff"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-TileColor"</span> <span class="na">content=</span><span class="s">"#516930"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-TileImage"</span> <span class="na">content=</span><span class="s">"/mstile-150x150.png"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"apple-mobile-web-app-title"</span> <span class="na">content=</span><span class="s">"cwoebker"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"180x180"</span> <span class="na">href=</span><span class="s">"/apple-touch-icon.png"</span><span class="nt">&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"mask-icon"</span> <span class="na">href=</span><span class="s">"/safari-pinned-tab.svg"</span> <span class="na">color=</span><span class="s">"#516930"</span><span class="nt">&gt;</span></code></pre></figure>

<h2 id="favicons-simple-solution">Favicons: Simple Solution</h2>

<p>If you also want to adhere to these rules, you don’t have to figure everything out by yourself.
There are various online tools that can automatically generate all the necessary code and files for you.
I used <a href="https://realfavicongenerator.net">https://realfavicongenerator.net</a>. You can also use this tool in order to check for any current issues with your favicon configuration.</p>

<p>Stay tuned for my upcoming post about automating your deployments with gulp if you want to learn more about my current website setup.
For the original build that this whole site is layered on top of, see <a href="/posts/jekyll-blogging">Jekyll Blogging</a>.</p>]]></content><author><name>cwoebker</name></author><category term="blog" /><category term="devops" /><summary type="html"><![CDATA[Just two weeks ago, I saw a tweet by @holman, complaining about the current state of favicons on the internet. For those of you who don't know what a "favicon" is: It is short for favorite icon and is a small image that is representative of a website. It usually shows up before the URL or inside of a tab in your browser. After I saw that tweet, I decided to also improve this website in order to support the favicon rules of 2018. Back in the early days of the internet all of this was rather straightforward. All you needed was a favicon.ico file in the root directory of your website and you would be all set and ready to go.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cwoebker.com/assets/img/avatar.png" /><media:content medium="image" url="https://cwoebker.com/assets/img/avatar.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Studying at the Georgia Institute of Technology</title><link href="https://cwoebker.com/posts/studying-gatech" rel="alternate" type="text/html" title="Studying at the Georgia Institute of Technology" /><published>2018-01-14T09:00:00+01:00</published><updated>2018-01-14T09:00:00+01:00</updated><id>https://cwoebker.com/posts/studying-gatech</id><content type="html" xml:base="https://cwoebker.com/posts/studying-gatech"><![CDATA[<p>In the fall of 2017, after having handed in my bachelor thesis at the Technical University Munich, I started an exchange semester at the Georgia Institute of Technology in Atlanta.
At that point, except for vacations, I hadn’t left Germany for a longer period of time since I graduated from high school in the United States.
Needless to say, I was very excited to come back.
Through the CDTM program in Munich, I became aware of the Research Network Operations Center at Georgia Tech and managed to get accepted as a Visiting Researcher.
Due to the fact that their research areas align quite nicely with my thesis topic, it was a pretty decent fit for both parties.
My time at Georgia Tech was basically split up evenly between research and coursework.
For me, this was the first semester in college where I could freely choose the courses I wanted to take.
Having attended Worcester Academy, I had already learned to appreciate the benefits of freely designing your own course plan, so I was very excited about this compared to the more rigid structures in Germany.</p>

<h2 id="georgia-tech">Georgia Tech</h2>

<p><img src="/assets/img/posts/gatech-tower.jpg" alt="Georgia Tech" /></p>

<p>Georgia Tech, short for the Georgia Institute of Technology, was founded in 1885 and is located in the heart of Midtown Atlanta.
With roughly 25,000 students it is one of the larger technical universities in the US and consistently ranks among the top ten public universities in the country.
The College of Engineering and the School of Computing are the strongest programs — both usually land in the top five nationally.
What makes the campus feel a bit different from most US schools is how embedded it is in the city.
Tech Square, just across the highway from the main campus, is where a lot of the research institutes and startups are concentrated, which blurs the line between university and industry in a way I found pretty interesting.</p>

<h2 id="research-network-operations-center">Research Network Operations Center</h2>

<p>I spent most of my time at the Georgia Tech Research Network Operations Center, or in short, GT-RNOC.
The RNOC is led by Russ Clark and Matthew Sanders.
It is a research institute located at Tech Square right in midtown Atlanta and just over the highway from the main campus.
The main focus of their work is in the area of mobile application systems, networked devices, and the internet of things.
They also run a smart home setup that serves as a testbed for various IoT projects.
The team is quite interdisciplinary — people come from engineering, computing, and design, and a good amount of the work is done in cooperation with external companies.</p>

<h2 id="my-work">My Work</h2>

<p>During my time at Georgia Tech, I had the chance to work on multiple different projects and applications.
As a visiting researcher at RNOC I created a new cluster management system as a self-serve platform based on OpenShift Origin.</p>

<p>For my own research project I evaluated the applicability of existing orchestration frameworks in the area of IoT.
I set up a small Raspberry Pi cluster and evaluated the performance of some of the major orchestration providers.
If you are curious about my research projects in general, you can find more on my <a href="/research">research page</a>.</p>

<p>Finally I took part in the Convergence Innovation Competition (CIC) at Georgia Tech.
With our application Avocado we won the 2nd prize in the category Health &amp; Wellness.</p>

<p><img src="/assets/img/posts/avocado-group-picture.jpg" alt="Avocado Team" />
<a href="/assets/paper/woebker2018-cic-avocado-poster.pdf">(project poster)</a></p>

<h2 id="my-life">My Life</h2>

<p>Of course, apart from the work I did at the RNOC, I also had the chance to explore the social life surrounding Georgia Tech and Atlanta.
Early in the semester I went through fraternity orientation, which was interesting to witness up close — it is quite a different culture from what I was used to in Germany.
Football season was another highlight: watching the Yellow Jackets play at Bobby Dodd Stadium in the fall is a pretty big deal around campus and I enjoyed every minute of it.
I also made it out of the city a few times — a hiking trip through Tennessee was a great way to decompress after a long stretch of work.</p>

<h2 id="outlook">Outlook</h2>

<p>Right now, after having enjoyed the holidays back home, I am at MIT in Boston doing another exchange, after which I plan to return to Munich to continue my master’s degree.
Let me know if you have any questions or want to learn more about life as a visiting researcher.</p>]]></content><author><name>cwoebker</name></author><category term="education" /><summary type="html"><![CDATA[In the fall of 2017, after finishing my bachelor thesis in Munich, I did an exchange semester at the Georgia Institute of Technology in Atlanta as a Visiting Researcher at the Research Network Operations Center. Here is a look at what my time there was like — the research, the coursework, and the experience of being back in the US.]]></summary></entry><entry><title type="html">Language Learning 101</title><link href="https://cwoebker.com/posts/language-learning-101" rel="alternate" type="text/html" title="Language Learning 101" /><published>2017-12-18T09:00:00+01:00</published><updated>2017-12-18T09:00:00+01:00</updated><id>https://cwoebker.com/posts/language-learning-101</id><content type="html" xml:base="https://cwoebker.com/posts/language-learning-101"><![CDATA[<p>In one of my last posts, I talked about <a href="/posts/forming-habits">habits and their power to change who you are</a>.
For me, the habits I acquired supported me in my endeavour to learn a new language.
Since about one and a half years, I’ve been trying to learn Spanish.
Ever since I first took up a class back in high school, I was hoping to become fluent in another language. 
Unfortunately, I dropped out of that high school class after the first week was over:
I had already become tired of having to learn vocabulary each and every day.</p>

<p>This aversion towards learning vocabulary made it impossible for me to make progress back then.
Creating habits around language learning and simplifying the learning process changed that for me.</p>

<p>I’ve tried out <a href="https://www.duolingo.com">Duolingo</a> before, and while I liked the playful approach of collecting points and opening up additional content it never quite caught on with me.
I never felt like Duolingo would be able to provide me with everything I needed to know about a language and I was put off by the prospect of having to learn spanish for multiple years without making reasonable progress towards fluency.
Additionally I learned about an application called <a href="https://ankiweb.net">Anki</a> through a polyglot named Gabriel Wyner.
After having been quite successful in learning multiple languages himself, Gabriel Wyner created a project called <a href="https://fluent-forever.com">Fluent Forever</a>.
Using the Anki application, he provided some decks that help you to learn the basic words and sounds of a language.
Inspired by the prospect of learning a new language in a rather short amount of time and with a simple mobile application, I reevaluated how I could reach my goal.
I came up with a three-phase plan, which I am still adhering to as of today:</p>

<ol>
  <li><em>Start by learning as much vocabulary as possible. Create a daily habit of learning 10 to 20 new words each day. 
Define a goal for how many words I want to learn.</em></li>
  <li><em>Begin to read and watch spanish media: Books, movies, tv shows, etc.</em></li>
  <li><em>Get into regular contact with native spanish speakers in order to get used to the language and figure out the grammar of the language.</em></li>
</ol>

<p><img src="/assets/img/posts/duolingo-streak-5.png" alt="Streak" title="Year-long Duolingo Streak" class="left-img" style="width: 52%;" /></p>

<p>Right now, I am at the end of the first phase.
I have used Duolingo and Anki to make it as easy as possible for me to keep up with my daily habit.
Actually, I finally reached a year-long Duolingo streak just recently.
For Anki I’ve been using a <a href="https://ankiweb.net/shared/info/241428882">deck</a> from their large public online collection.
(Due to the fact that Anki keeps track of a bunch of different statistics, I am planning on doing another post once I finish this deck to dive into some of those numbers.)</p>

<p>Until recently, I wasn’t quite sure whether this whole plan would ever work out.
But then, a couple of weeks ago, I was in Mexico visiting an old high school friend of mine.
And to my surprise, my vocabulary was good enough to create basic sentences and understand a lot of different conversations during my day-to-day activities.</p>

<p><img src="/assets/img/posts/anki_2017_overview.png" alt="Anki" title="Anki Deck Overview" class="right-img" style="width: 35%;" /></p>

<p>Of course, I need more practice and immersion to make this perfect, but by starting out with a larger collection of words you take away a huge hindrance on the way to achieve fluency.
Mastering this vocabulary allows you to truly focus on the conversations, the grammar and other important quirks of a language.</p>

<p>What comes next is going to be more difficult: <strong>mastering Spanish</strong>.
From here on out keeping up with my habit will not be as easy as opening up a mobile application every day, but I hope that I will find a way that works for me.
Time will tell if I can immerse myself enough to achieve my goal.</p>

<p>If any of you have any tips or ideas on what else might help, let me know.
I would love to hear your thoughts!</p>]]></content><author><name>cwoebker</name></author><category term="education" /><summary type="html"><![CDATA[Ever since I first took up a class back in high school, I was hoping to become fluent in another language. Unfortunately, I dropped out of that high school class after the first week was over: I had already become tired of having to learn vocabulary each and every day. This aversion towards learning vocabulary made it impossible for me to make progress back then. Creating habits around language learning and simplifying the learning process changed that for me.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cwoebker.com/assets/img/hero/mexico-chichen-itza.jpg" /><media:content medium="image" url="https://cwoebker.com/assets/img/hero/mexico-chichen-itza.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">SSH Tricks - Making your life simple</title><link href="https://cwoebker.com/posts/ssh-tricks" rel="alternate" type="text/html" title="SSH Tricks - Making your life simple" /><published>2017-11-03T09:00:00+01:00</published><updated>2017-11-03T09:00:00+01:00</updated><id>https://cwoebker.com/posts/ssh-tricks</id><content type="html" xml:base="https://cwoebker.com/posts/ssh-tricks"><![CDATA[<p>If you have ever lost a server mid-session, you know how annoying it is to be stuck in an SSH session until the client finally times out and gives you the terminal back.
I put up with that for years, until I found a better way.</p>

<p>If you log in to a server with <code class="language-plaintext highlighter-rouge">ssh</code>, you can type the following three characters: <code class="language-plaintext highlighter-rouge">Enter</code>, <code class="language-plaintext highlighter-rouge">~</code>, and <code class="language-plaintext highlighter-rouge">?</code>.
The result should look similar to this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Supported escape sequences:
 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&amp;   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)
</code></pre></div></div>

<p>Turns out, you can control SSH using escape sequences that aren’t executed on the server like all the other input, but used to control the local client.
To solve the issue described above we can just enter: <code class="language-plaintext highlighter-rouge">Enter</code>, <code class="language-plaintext highlighter-rouge">~</code>, and <code class="language-plaintext highlighter-rouge">.</code> and terminate the current connection.</p>

<p>I will describe the purpose of the escape sequence below:</p>

<p><strong>~.</strong>   - Ends the current connection right away.</p>

<p><strong>~C</strong>   - Allows you to edit forwarded connections</p>

<p><strong>~R</strong>   - Should be done automatically by current SSH versions anyway.</p>

<p><strong>~V/v</strong> - Change log levels on the fly.</p>

<p><strong>~^Z</strong>  - Suspends the current ssh connection and puts you back into a local shell.
Allows you to return to the ssh session using <code class="language-plaintext highlighter-rouge">fg</code>.</p>

<p><strong>~#</strong>   - Lists all forwarded connections</p>

<p><strong>~&amp;</strong>   - Puts SSH in the background and waits for all processes to exit gracefully.</p>

<p><strong>~?</strong>   - Print the help message you can see above.</p>

<p><strong>~~</strong>   - Allows you to actually send the <code class="language-plaintext highlighter-rouge">~</code> character after a newline.</p>

<p>I am still trying to find a good explanation for <code class="language-plaintext highlighter-rouge">~B</code>.
Let me know if you can point me in the right direction.</p>

<p>These escape characters are described in the <a href="https://man.openbsd.org/ssh#ESCAPE_CHARACTERS">man pages</a> of ssh.
If you live in your terminal, the tricks above pair well with a comfortable local shell — see my <a href="/posts/unix-zshell-reloaded">notes on switching to zsh</a>.</p>]]></content><author><name>cwoebker</name></author><category term="terminal" /><summary type="html"><![CDATA[Practical SSH tricks for keeping sessions alive, tunneling, and speeding up your workflow on remote servers.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cwoebker.com/assets/img/hero/server.jpg" /><media:content medium="image" url="https://cwoebker.com/assets/img/hero/server.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Forming Habits</title><link href="https://cwoebker.com/posts/forming-habits" rel="alternate" type="text/html" title="Forming Habits" /><published>2017-10-08T10:00:00+02:00</published><updated>2017-10-08T10:00:00+02:00</updated><id>https://cwoebker.com/posts/forming-habits</id><content type="html" xml:base="https://cwoebker.com/posts/forming-habits"><![CDATA[<p>What have you done in the last year that has had a truly big impact on your life?
I asked myself that the other day, and after sitting with it for a while I wanted to share the answer with a broader audience.
For me, it was the <strong>habits</strong> I acquired since last year.
A little over a year ago I started becoming extremely organized.
I started following the <a href="http://gettingthingsdone.com">Getting Things Done</a> approach and used <a href="https://www.omnigroup.com/omnifocus">OmniFocus</a> for all my task management. There are great resources on <a href="https://learnomnifocus.com/resources/gtd/">learnomnifocus.com</a>. If there is enough interest, I might write a separate post about the exact task-management setup I use.
On the side, I also added a few simple daily tasks to my list. Things like “plan the next day” or “eat breakfast” (since I would often forget).
As I continued completing my tasks day after day, I realized it has become quite rewarding to complete these simple tasks.</p>

<p><img src="/assets/img/posts/habits.jpg" alt="habits" title="Habits" /></p>

<p>Fast-forward a few weeks, and I decided to try to learn Spanish with Duolingo.
Duolingo has a notable “streak” feature that shows how long you have kept your daily learning goal, day after day.
To make sure I would show up, I added a simple daily task to my list and checked it off.
Since I had made such a habit out of completing all my daily tasks, I always felt the need to actually complete all of them every day. 
My goal is to complete all Duolingo exercises and reach a year-long 365-day streak.
At first, sticking with 10–15 minutes of Spanish every day was not easy, but it became easier with time.
The todo list helps me to divide work into smaller chunks and enables my habits.
Doing something just for a short time <strong>each and every day</strong> can have a more profound impact on your behavior and your life.
Now I use both <a href="https://www.duolingo.com"><strong>Duolingo</strong></a> and another application called <a href="https://ankiweb.net"><strong>Anki</strong></a> and I hope to write another post on my experience of learning a new language with these applications.
With Duolingo, I just hit a 300-day streak today.</p>

<p><img src="/assets/img/posts/duolingo-streak-4.png" alt="streak" title="Duolingo Streak" style="width: 65%;" /></p>

<p>The important thing is to never miss a day of studying.
Of course, there will be times where you cannot make it work, but that should be the rare exception.
If you have an important exam the next day? You keep learning.
If you still have to run tons of errands before tomorrow? You keep learning.
If there is something else on your mind that stops you from staying focused? You keep learning.
The learning needs to become a habit like brushing your teeth or sleeping.
These few minutes every day help tremendously throughout the learning process.
Once you have made it a habit to study every day, it stops feeling like a burden, it does not get in the way of your other work, and you feel more productive overall.</p>

<p>Habits are powerful.
<a href="http://bjfogg.com">BJ Fogg, PhD</a>, Director of the Persuasive Tech Lab at Stanford University, has studied this phenomenon for more than 20 years.
He has found that there are three different things that can change human behavior:</p>

<ul>
  <li>Option <em>A</em> - Have an <strong>epiphany</strong></li>
  <li>Option <em>B</em> - Change your <strong>environment</strong> (what surrounds you)</li>
  <li>Option <em>C</em> - Take <strong>baby steps</strong></li>
</ul>

<p>Option C is the one you can control most easily. You can build habits that add up to small steps and change your own behavior when learning something new.
I can only urge you to try the same.
What areas of your life could you improve with a few minutes a day?</p>]]></content><author><name>cwoebker</name></author><category term="education" /><summary type="html"><![CDATA[How building small daily habits transformed my productivity and focus over the course of a year.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cwoebker.com/assets/img/posts/habits.jpg" /><media:content medium="image" url="https://cwoebker.com/assets/img/posts/habits.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Fast Deployments with Docker</title><link href="https://cwoebker.com/posts/fast-deployments" rel="alternate" type="text/html" title="Fast Deployments with Docker" /><published>2017-04-14T10:00:00+02:00</published><updated>2017-04-14T10:00:00+02:00</updated><id>https://cwoebker.com/posts/fast-deployments</id><content type="html" xml:base="https://cwoebker.com/posts/fast-deployments"><![CDATA[<aside class="post-note" role="note" aria-label="Editor's note">
  <p class="post-note__label">From the archive</p>
  <div class="post-note__body"><p>This post is from 2017. Some tools, links, or commands referenced below have changed since.</p></div>
</aside>

<p>A couple of weeks ago I did an overall upgrade of my server and moved this <a href="/posts/jekyll-blogging">jekyll blog</a> from Heroku’s servers over to my own dedicated machine. During this process I also gave my blog an overhaul and added SSL encryption and made it more efficient by minimizing more resources and adhering to Google’s <a href="https://developers.google.com/speed/docs/insights/about">PageSpeed Best Practices</a>.</p>

<h2 id="simplifying-deployments-with-docker">Simplifying Deployments with Docker</h2>

<p><img class="plain" src="/assets/img/posts/logo_docker.png" alt="docker" title="Docker" style="width: 600px;" /></p>

<p>The new setup is based on the awesome <a href="https://github.com/dokku/dokku">dokku</a>, a docker-powered Platform as a Service (PaaS). Coming from the heroku platform it now allows me to quickly deploy changes of my webpage and host it on my own machine. Furthermore I can run multiple different applications that are isolated from each other (<a href="https://anagram.cwoebker.com">anagram</a>, <a href="https://screen.cwoebker.com">screen</a>, <a href="https://sudoku.cwoebker.com">sudoku</a>). But Docker can provide even <a href="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/7.0_Release_Notes/sect-Red_Hat_Enterprise_Linux-7.0_Release_Notes-Linux_Containers_with_Docker_Format-Advantages_of_Using_Docker.html">more benefits</a>:</p>

<ul>
  <li><strong>Rapid application deployment</strong> – containers include the minimal runtime requirements of the application, reducing their size and allowing them to be deployed quickly.</li>
  <li><strong>Portability across machines</strong> – an application and all its dependencies can be bundled into a single container that is independent from the host version of Linux kernel, platform distribution, or deployment model. This container can be transferred to another machine that runs Docker, and executed there without compatibility issues.</li>
  <li><strong>Version control and component reuse</strong> – you can track successive versions of a container, inspect differences, or roll-back to previous versions. Containers reuse components from the preceding layers, which makes them noticeably lightweight.</li>
  <li><strong>Sharing</strong> – you can use a remote repository to share your container with others. Red Hat provides a registry for this purpose, and it is also possible to configure your own private repository.</li>
  <li><strong>Lightweight footprint and minimal overhead</strong> – Docker images are typically very small, which facilitates rapid delivery and reduces the time to deploy new application containers.</li>
  <li><strong>Simplified maintenance</strong> – Docker reduces effort and risk of problems with application dependencies.</li>
</ul>

<p>To setup an application with dokku I just had to create a simple Dockerfile. It is based on the <a href="https://hub.docker.com/_/ruby/">official ruby image</a> and adds <a href="https://hub.docker.com/_/node/">node and yarn</a> to the mix.</p>

<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="k">FROM</span><span class="s"> ruby</span>

... # install node.js and yarn (see https://github.com/nodejs/docker-node/blob/a82c9dcd3f85ff8055f56c53e6d8f31c5ae28ed7/7.9/Dockerfile)</code></pre></figure>

<p>Afterwards I install all dependencies through yarn, gem and bower.</p>

<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="k">ADD</span><span class="s"> . /app</span>
<span class="k">WORKDIR</span><span class="s"> /app</span>

<span class="k">RUN </span>yarn global add node-gyp
<span class="k">RUN </span>yarn <span class="nb">install</span>
<span class="k">RUN </span>bundle <span class="nb">install</span>
<span class="k">RUN </span>yarn run bower
<span class="k">RUN </span>yarn run gulp</code></pre></figure>

<p>Finally I can build the site with the jekyll command.</p>

<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="k">ENV</span><span class="s"> JEKYLL_ENV production</span>
<span class="k">RUN </span>bundle <span class="nb">exec </span>jekyll build

<span class="k">EXPOSE</span><span class="s"> 5000</span>
<span class="k">CMD</span><span class="s"> ["bundle","exec","unicorn","-p","5000","-c","./unicorn.rb"]</span></code></pre></figure>

<h2 id="docker-caching-issues">Docker Caching Issues</h2>

<p>One major issue I encountered was that changes often took a while to be pushed. Each time I change any small file, e.g. correct a typo on a blog post, docker would reinstall the entire blog with its dependencies. Usually Docker is smart about this and keeps a cache of the different parts of the Dockerfile. But if you added something to the docker context and something changes docker has to restart from there. Since I added my complete project folder at once, any change, as small as it might be, always triggered a complete rebuild of my application.</p>

<h3 id="dependency-jungle">Dependency Jungle</h3>

<p>The steps of the process that took the most time were the dependency installations.
For my blog I use three different commands that take a longer time to execute:</p>

<ul>
  <li>The ruby <strong>gem</strong> command</li>
  <li>The node.js <strong>yarn</strong> package manager</li>
  <li>The <strong>bower</strong> tool for html components</li>
</ul>

<center>
<img class="plain pad" src="/assets/img/posts/logo_ruby.png" alt="ruby" title="Ruby" style="display: inline; width: 30%;" />
<img class="plain pad" src="/assets/img/posts/logo_nodejs.png" alt="node" title="Node" style="display: inline; width: 30%;" />
<img class="plain pad" src="/assets/img/posts/logo_bower.png" alt="bower" title="Bower" style="display: inline; width: 30%;" />
</center>

<p>Ideally I still would like to test my blog under the same conditions as on the server. 
If I would have to reinstall all dependencies every time I make a minor change that would slow me down drastically.
So what do we do about this?</p>

<h2 id="solution">Solution</h2>

<p>To ensure that dependencies are only reinstalled when the corresponding configuration changes we have to selectively add the files to the docker image.</p>

<p>For my blog these files are:</p>

<ul>
  <li>Gemfile (Ruby)</li>
  <li>package.json (Node.js)</li>
  <li>bower.json (bower)</li>
</ul>

<h3 id="dependency-files">Dependency Files</h3>

<p>We have to add these 3 files beforehand. And furthermore install the dependencies in a global or temporary location so that we can add them back to the rest of the application later.</p>

<h4 id="gemfile">Gemfile</h4>

<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="k">ADD</span><span class="s"> Gemfile /tmp/Gemfile</span>
<span class="k">ADD</span><span class="s"> Gemfile.lock /tmp/Gemfile.lock</span>
<span class="k">RUN </span><span class="nb">cd</span> /tmp <span class="o">&amp;&amp;</span> bundle <span class="nb">install</span></code></pre></figure>

<h4 id="packagejson">package.json</h4>

<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="k">RUN </span>yarn global add node-gyp
<span class="k">ADD</span><span class="s"> package.json /tmp/package.json</span>
<span class="k">RUN </span><span class="nb">cd</span> /tmp <span class="o">&amp;&amp;</span> yarn <span class="nb">install</span>
<span class="k">RUN </span><span class="nb">mkdir</span> <span class="nt">-p</span> /app <span class="o">&amp;&amp;</span> <span class="nb">cp</span> <span class="nt">-a</span> /tmp/node_modules /app/</code></pre></figure>

<h4 id="bowerjson">bower.json</h4>

<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="k">ADD</span><span class="s"> bower.json /tmp/bower.json</span>
<span class="k">RUN </span><span class="nb">cd</span> /tmp <span class="o">&amp;&amp;</span> yarn run bower</code></pre></figure>

<h3 id="ordering">Ordering</h3>

<p>Depending on which configuration file changes, all the steps that come afterwards have to be executed again. 
If we want to be smart about our approach, we can order the different installation steps in a more efficient way. In my case this would be:</p>

<ol>
  <li>yarn</li>
  <li>gem</li>
  <li>bower</li>
</ol>

<p>For my application bower dependencies are changed the most frequent, so I install it last. After that I sometimes install new jekyll plugins. And finally comes yarn, where there are mostly just development requirements like gulp that almost never change and I therefore install it right at the beginning.</p>

<h3 id="result">Result</h3>

<p><a href="https://asciinema.org/a/113467"><img src="https://asciinema.org/a/113467.png" alt="asciicast" /></a></p>

<h2 id="final-words">Final Words</h2>

<p>Of course you can use a similar setup for all kinds of dependencies and installation steps that you have. The core idea is to selectively add the files and build your docker image on a step-by-step basis.</p>

<p>Below you can find the final version of my Dockerfile. Don’t hesitate to ask, if you have any questions!</p>

<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="k">FROM</span><span class="s"> ruby</span>

<span class="k">RUN </span>groupadd <span class="nt">--gid</span> 1000 node <span class="se">\
</span>  <span class="o">&amp;&amp;</span> useradd <span class="nt">--uid</span> 1000 <span class="nt">--gid</span> node <span class="nt">--shell</span> /bin/bash <span class="nt">--create-home</span> node

<span class="c"># gpg keys listed at https://github.com/nodejs/node</span>
<span class="k">RUN </span><span class="nb">set</span> <span class="nt">-ex</span> <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="k">for </span>key <span class="k">in</span> <span class="se">\
</span>    9554F04D7259F04124DE6B476D5A82AC7E37093B <span class="se">\
</span>    94AE36675C464D64BAFA68DD7434390BDBE9B9C5 <span class="se">\
</span>    0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 <span class="se">\
</span>    FD3A5288F042B6850C66B31F09FE44734EB7990E <span class="se">\
</span>    71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 <span class="se">\
</span>    DD8F2338BAE7501E3DD5AC78C273792F7D83545D <span class="se">\
</span>    B9AE9905FFD7803F25714661B63B535A4C206CA9 <span class="se">\
</span>    C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 <span class="se">\
</span>    56730D5401028683275BD23C23EFEFE93C4CFFFE <span class="se">\
</span>  <span class="p">;</span> <span class="k">do</span> <span class="se">\
</span>    gpg <span class="nt">--keyserver</span> ha.pool.sks-keyservers.net <span class="nt">--recv-keys</span> <span class="s2">"</span><span class="nv">$key</span><span class="s2">"</span><span class="p">;</span> <span class="se">\
</span>  <span class="k">done</span>

<span class="k">ENV</span><span class="s"> NPM_CONFIG_LOGLEVEL info</span>
<span class="k">ENV</span><span class="s"> NODE_VERSION 7.7.2</span>

<span class="k">RUN </span>curl <span class="nt">-SLO</span> <span class="s2">"https://nodejs.org/dist/v</span><span class="nv">$NODE_VERSION</span><span class="s2">/node-v</span><span class="nv">$NODE_VERSION</span><span class="s2">-linux-x64.tar.xz"</span> <span class="se">\
</span>  <span class="o">&amp;&amp;</span> curl <span class="nt">-SLO</span> <span class="s2">"https://nodejs.org/dist/v</span><span class="nv">$NODE_VERSION</span><span class="s2">/SHASUMS256.txt.asc"</span> <span class="se">\
</span>  <span class="o">&amp;&amp;</span> gpg <span class="nt">--batch</span> <span class="nt">--decrypt</span> <span class="nt">--output</span> SHASUMS256.txt SHASUMS256.txt.asc <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="nb">grep</span> <span class="s2">" node-v</span><span class="nv">$NODE_VERSION</span><span class="s2">-linux-x64.tar.xz</span><span class="se">\$</span><span class="s2">"</span> SHASUMS256.txt | <span class="nb">sha256sum</span> <span class="nt">-c</span> - <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="nb">tar</span> <span class="nt">-xJf</span> <span class="s2">"node-v</span><span class="nv">$NODE_VERSION</span><span class="s2">-linux-x64.tar.xz"</span> <span class="nt">-C</span> /usr/local <span class="nt">--strip-components</span><span class="o">=</span>1 <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="nb">rm</span> <span class="s2">"node-v</span><span class="nv">$NODE_VERSION</span><span class="s2">-linux-x64.tar.xz"</span> SHASUMS256.txt.asc SHASUMS256.txt <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="nb">ln</span> <span class="nt">-s</span> /usr/local/bin/node /usr/local/bin/nodejs

<span class="k">ENV</span><span class="s"> YARN_VERSION 0.21.3</span>

<span class="k">RUN </span><span class="nb">set</span> <span class="nt">-ex</span> <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="k">for </span>key <span class="k">in</span> <span class="se">\
</span>    6A010C5166006599AA17F08146C2130DFD2497F5 <span class="se">\
</span>  <span class="p">;</span> <span class="k">do</span> <span class="se">\
</span>    gpg <span class="nt">--keyserver</span> ha.pool.sks-keyservers.net <span class="nt">--recv-keys</span> <span class="s2">"</span><span class="nv">$key</span><span class="s2">"</span><span class="p">;</span> <span class="se">\
</span>  <span class="k">done</span> <span class="se">\
</span>  <span class="o">&amp;&amp;</span> curl <span class="nt">-fSL</span> <span class="nt">-o</span> yarn.js <span class="s2">"https://yarnpkg.com/downloads/</span><span class="nv">$YARN_VERSION</span><span class="s2">/yarn-legacy-</span><span class="nv">$YARN_VERSION</span><span class="s2">.js"</span> <span class="se">\
</span>  <span class="o">&amp;&amp;</span> curl <span class="nt">-fSL</span> <span class="nt">-o</span> yarn.js.asc <span class="s2">"https://yarnpkg.com/downloads/</span><span class="nv">$YARN_VERSION</span><span class="s2">/yarn-legacy-</span><span class="nv">$YARN_VERSION</span><span class="s2">.js.asc"</span> <span class="se">\
</span>  <span class="o">&amp;&amp;</span> gpg <span class="nt">--batch</span> <span class="nt">--verify</span> yarn.js.asc yarn.js <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="nb">rm </span>yarn.js.asc <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="nb">mv </span>yarn.js /usr/local/bin/yarn <span class="se">\
</span>  <span class="o">&amp;&amp;</span> <span class="nb">chmod</span> +x /usr/local/bin/yarn

<span class="k">RUN </span>yarn global add node-gyp
<span class="k">ADD</span><span class="s"> package.json /tmp/package.json</span>
<span class="k">RUN </span><span class="nb">cd</span> /tmp <span class="o">&amp;&amp;</span> yarn <span class="nb">install</span>
<span class="k">RUN </span><span class="nb">mkdir</span> <span class="nt">-p</span> /app <span class="o">&amp;&amp;</span> <span class="nb">cp</span> <span class="nt">-a</span> /tmp/node_modules /app/

<span class="k">ADD</span><span class="s"> Gemfile /tmp/Gemfile</span>
<span class="k">ADD</span><span class="s"> Gemfile.lock /tmp/Gemfile.lock</span>
<span class="k">RUN </span><span class="nb">cd</span> /tmp <span class="o">&amp;&amp;</span> bundle <span class="nb">install</span>

<span class="k">ADD</span><span class="s"> bower.json /tmp/bower.json</span>
<span class="k">RUN </span><span class="nb">cd</span> /tmp <span class="o">&amp;&amp;</span> yarn run bower

<span class="k">ADD</span><span class="s"> . /app</span>
<span class="k">WORKDIR</span><span class="s"> /app</span>

<span class="k">RUN </span><span class="nb">mv</span> /tmp/bower_components <span class="nb">source</span>/_assets/components
<span class="k">RUN </span>yarn run gulp

<span class="k">ENV</span><span class="s"> JEKYLL_ENV production</span>
<span class="k">RUN </span>bundle <span class="nb">exec </span>jekyll build

<span class="k">EXPOSE</span><span class="s"> 5000</span>
<span class="k">CMD</span><span class="s"> ["bundle","exec","unicorn","-p","5000","-c","./unicorn.rb"]</span></code></pre></figure>]]></content><author><name>cwoebker</name></author><category term="blog" /><category term="devops" /><summary type="html"><![CDATA[A couple of weeks ago I did an overall upgrade of my server and moved this jekyll blog from Heroku's servers over to my own dedicated machine. The new setup is based on the awesome dokku, a docker-powered Platform as a Service (PaaS). Coming from the heroku platform it now allows me to quickly deploy changes of my webpage and host it on my own machine. One major issue I encountered was that changes often took a while to be pushed. Each time I change any small file, e.g. correct a typo on a blog post, docker would reinstall the entire blog with its dependencies. To ensure that dependencies are only reinstalled when the corresponding configuration changes we have to selectively add the files to the docker image.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cwoebker.com/assets/img/posts/logo_docker.png" /><media:content medium="image" url="https://cwoebker.com/assets/img/posts/logo_docker.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">BOINC - Saving The World</title><link href="https://cwoebker.com/posts/saving-the-world" rel="alternate" type="text/html" title="BOINC - Saving The World" /><published>2017-03-25T09:00:00+01:00</published><updated>2017-03-25T09:00:00+01:00</updated><id>https://cwoebker.com/posts/saving-the-world</id><content type="html" xml:base="https://cwoebker.com/posts/saving-the-world"><![CDATA[<p>Back in 2013, I first started using the <a href="https://boinc.berkeley.edu">BOINC</a> software and I signed up for some <a href="https://boinc.berkeley.edu/projects.php">projects</a>. But unfortunately, after just one week, I stopped and focused my time on something else. A couple of weeks ago I realized I was often wasting idle computer time and decided to join again.</p>

<h2 id="what-is-boinc">What is BOINC?</h2>

<p><a href="https://boinc.berkeley.edu">BOINC</a> is an open-source software for volunteer computing that was started at <a href="http://www.berkeley.edu">UC Berkeley</a>. It allows anyone to contribute to scientific advancements simply by using their home computer. Researchers and Scientists can create projects that need a high amount of computing power and ask for people around the world to participate and support their efforts.</p>

<p>In the past BOINC was part of some interesting scientific advancements:</p>

<ul>
  <li>In February 2010 the <a href="https://en.wikipedia.org/wiki/FightAIDS@Home">FightAIDS@Home</a> project scientists announced that they found two compounds that make a completely new class of AIDS-fighting drugs possible.</li>
  <li>In June 2013 the <a href="https://en.wikipedia.org/wiki/Clean_Energy_Project">Clean Energy Project</a> published a database of over 2.3 million organic molecules which have had their properties characterized. Of these, 35,000 molecules have shown the potential to double the efficiency over organic solar cells being produced nowadays.</li>
  <li>In February 2014 the <a href="https://en.wikipedia.org/wiki/Help_Fight_Childhood_Cancer">Help Fight Childhood Cancer</a> project scientists announced the discovery of 7 compounds that destroy neuroblastoma cancer cells without any apparent side effects.</li>
  <li>In July 2015, the Computing for Clean Water project <a href="https://www.worldcommunitygrid.org/about_us/viewNewsArticle.do?articleId=436">announced</a> that a paper had been published on the Nature Nanotechnology journal describing how they have discovered a new way to filter water much faster than previously thought.</li>
</ul>

<h2 id="how-to-setup-boinc">How to setup BOINC</h2>

<p>Setting up the BOINC software is pretty simple. If you are using a desktop computer (Linux, Mac, or Windows) simply download the <a href="https://boinc.berkeley.edu/download_all.php">software</a>. If you have a headless system you can find a tutorial for your operating system <a href="http://boinc.berkeley.edu/w/?search=Installing+BOINC+on&amp;fulltext=Search">here</a>. Afterwards you have to sign up for projects that interest you. I can also recommend using a project manager such as the <a href="https://boincstats.com/en/bam/">BOINC Account Manager (BAM)</a> or <a href="http://www.gridrepublic.org">Grid Republic</a>.</p>

<h2 id="my-boinc-setup">My Boinc Setup</h2>

<p>I have two computers that work on BOINC projects for me. On the one hand I use any spare capacity on my home gaming PC for calculations. You can adapt the BOINC settings so that the CPU is only used while not actively using the computer. On the other hand I use a quarter of the server CPU, where I host this blog, to contribute 24/7.</p>

<h3 id="my-boinc-projects">My Boinc Projects</h3>

<p>So far, I have decided to join the following BOINC projects:</p>

<ol>
  <li><a href="https://www.worldcommunitygrid.org">World Community Grid</a>. Help all kinds of medical research projects.</li>
  <li><a href="http://www.primegrid.com">PrimeGrid</a>. Finding new &amp; large prime numbers.</li>
  <li><a href="https://www.gpugrid.net">GPU Grid</a>. Using your GPU for a distributed computing infrastructure devoted to biomedical research.</li>
</ol>

<h3 id="boinc-statistics">Boinc Statistics</h3>

<p><img src="https://boincstats.com/signature/-1/bam/41331/sig.png" alt="Boinc Stats" /></p>

<h4 id="world-community-grid">World Community Grid</h4>

<center>
<iframe src="https://www.worldcommunitygrid.org/getDynamicImage.do?memberName=v3n0m&amp;mnOn=true&amp;stat=1&amp;imageNum=1&amp;rankOn=true&amp;projectsOn=true&amp;special=false" frameborder="0" name="di" scrolling="no" width="405px" height="190px"></iframe>
</center>

<h2 id="final-words">Final Words</h2>

<p>Let me know in the comments, if I was able to convince you!</p>

<p>Now I can only say: <strong>Come, join me, and save the world.</strong> 😉</p>]]></content><author><name>cwoebker</name></author><category term="science" /><summary type="html"><![CDATA[Back in 2013, I first started using the BOINC software and I signed up for some projects. But unfortunately, after just one week, I stopped and focused my time on something else. A couple of weeks ago I realized I was often wasting idle computer time and decided to join again. BOINC is an open-source software for volunteer computing that was started at UC Berkeley. It allows anyone to contribute to scientific advancements simply by using their home computer. Researchers and Scientists can create projects that need a high amount of computing power and ask for people around the world to participate and support their efforts.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cwoebker.com/assets/img/hero/server.jpg" /><media:content medium="image" url="https://cwoebker.com/assets/img/hero/server.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>