<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://chambers.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://chambers.io/" rel="alternate" type="text/html" /><updated>2026-04-08T15:49:39+00:00</updated><id>https://chambers.io/feed.xml</id><title type="html">chambers.io</title><subtitle>Technical writing and miscellaneous thoughts on software development and devops.</subtitle><author><name>Dakota Chambers</name></author><entry><title type="html">NASA Image Library</title><link href="https://chambers.io/linkblog/2026/04/08/nasa-image-library.html" rel="alternate" type="text/html" title="NASA Image Library" /><published>2026-04-08T00:00:00+00:00</published><updated>2026-04-08T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2026/04/08/nasa-image-library</id><content type="html" xml:base="https://chambers.io/linkblog/2026/04/08/nasa-image-library.html"><![CDATA[<p>Space is amazing.</p>
<p><a href="https://images.nasa.gov/">https://images.nasa.gov/</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[Space is amazing.]]></summary></entry><entry><title type="html">The Git Commands I Run Before Reading Any Code</title><link href="https://chambers.io/linkblog/2026/04/08/the-git-commands-i-run-before-reading-any-code.html" rel="alternate" type="text/html" title="The Git Commands I Run Before Reading Any Code" /><published>2026-04-08T00:00:00+00:00</published><updated>2026-04-08T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2026/04/08/the-git-commands-i-run-before-reading-any-code</id><content type="html" xml:base="https://chambers.io/linkblog/2026/04/08/the-git-commands-i-run-before-reading-any-code.html"><![CDATA[<p><a href="https://piechowski.io/post/git-commands-before-reading-code/">https://piechowski.io/post/git-commands-before-reading-code/</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><category term="git" /><summary type="html"><![CDATA[https://piechowski.io/post/git-commands-before-reading-code/]]></summary></entry><entry><title type="html">How To Fix Sticky Plastics</title><link href="https://chambers.io/linkblog/2026/04/07/how-to-fix-sticky-plastics.html" rel="alternate" type="text/html" title="How To Fix Sticky Plastics" /><published>2026-04-07T00:00:00+00:00</published><updated>2026-04-07T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2026/04/07/how-to-fix-sticky-plastics</id><content type="html" xml:base="https://chambers.io/linkblog/2026/04/07/how-to-fix-sticky-plastics.html"><![CDATA[<p><a href="https://www.ifixit.com/News/93833/ask-ifixit-how-do-i-fix-sticky-plastics">https://www.ifixit.com/News/93833/ask-ifixit-how-do-i-fix-sticky-plastics</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://www.ifixit.com/News/93833/ask-ifixit-how-do-i-fix-sticky-plastics]]></summary></entry><entry><title type="html">NASA on Flickr</title><link href="https://chambers.io/linkblog/2026/04/07/nasa-on-flickr.html" rel="alternate" type="text/html" title="NASA on Flickr" /><published>2026-04-07T00:00:00+00:00</published><updated>2026-04-07T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2026/04/07/nasa-on-flickr</id><content type="html" xml:base="https://chambers.io/linkblog/2026/04/07/nasa-on-flickr.html"><![CDATA[<p><a href="https://www.nasa.gov/mission/artemis-ii/">Artemis II</a> has been incredible.</p>
<p>See also: <a href="/linkblog/2026/04/08/nasa-image-library.html">NASA Image Library</a></p>
<p><a href="https://www.flickr.com/photos/nasa2explore/">https://www.flickr.com/photos/nasa2explore/</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[Artemis II has been incredible.]]></summary></entry><entry><title type="html">The Struggle of Resizing Windows on MacOS Tahoe</title><link href="https://chambers.io/linkblog/2026/01/12/the-struggle-of-resizing-windows-on-macos-tahoe.html" rel="alternate" type="text/html" title="The Struggle of Resizing Windows on MacOS Tahoe" /><published>2026-01-12T00:00:00+00:00</published><updated>2026-01-12T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2026/01/12/the-struggle-of-resizing-windows-on-macos-tahoe</id><content type="html" xml:base="https://chambers.io/linkblog/2026/01/12/the-struggle-of-resizing-windows-on-macos-tahoe.html"><![CDATA[<p><a href="https://noheger.at/blog/2026/01/11/the-struggle-of-resizing-windows-on-macos-tahoe/">https://noheger.at/blog/2026/01/11/the-struggle-of-resizing-windows-on-macos-tahoe/</a></p>
<p>A good example of bad software design.</p>
<p>Please fix this Apple.</p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://noheger.at/blog/2026/01/11/the-struggle-of-resizing-windows-on-macos-tahoe/]]></summary></entry><entry><title type="html">Everyone in Seattle Hates AI</title><link href="https://chambers.io/linkblog/2025/12/03/everyone-in-seattle-hates-ai.html" rel="alternate" type="text/html" title="Everyone in Seattle Hates AI" /><published>2025-12-03T00:00:00+00:00</published><updated>2025-12-03T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/12/03/everyone-in-seattle-hates-ai</id><content type="html" xml:base="https://chambers.io/linkblog/2025/12/03/everyone-in-seattle-hates-ai.html"><![CDATA[<p><a href="https://jonready.com/blog/posts/everyone-in-seattle-hates-ai.html">https://jonready.com/blog/posts/everyone-in-seattle-hates-ai.html</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><category term="AI" /><summary type="html"><![CDATA[https://jonready.com/blog/posts/everyone-in-seattle-hates-ai.html]]></summary></entry><entry><title type="html">Hire Junior Employees</title><link href="https://chambers.io/blog/2025/12/02/junior-employees.html" rel="alternate" type="text/html" title="Hire Junior Employees" /><published>2025-12-02T00:00:00+00:00</published><updated>2025-12-02T00:00:00+00:00</updated><id>https://chambers.io/blog/2025/12/02/junior-employees</id><content type="html" xml:base="https://chambers.io/blog/2025/12/02/junior-employees.html"><![CDATA[<p>Abandoning junior roles in your company is a life-or-death bet that AI will eventually replace ALL roles.</p>
<p>Because those senior employees will <strong>not</strong> be around forever and you have effectively killed your talent development and knowledge transfer pipeline.</p>
<p>If AI developments stall out, if the AI agents that are promised never materialize, if we stop short of AGI and you need to keep humans employeed, your company will die.</p>
<p>Don’t take that risk. Hire juniors. Train them. Pay them what they deserve, and give them meaningful raises to keep them around. Give them an ounce of trust, a bucket of agency, and watch them flourish.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><summary type="html"><![CDATA[Abandoning junior roles in your company is a life-or-death bet that AI will eventually replace ALL roles.]]></summary></entry><entry><title type="html">Warren Buffet’s Final Letter as Berkshire Hathaway’s CEO</title><link href="https://chambers.io/blog/2025/11/20/warren-buffets-final-letter-as-berkshire-hathaways-ceo.html" rel="alternate" type="text/html" title="Warren Buffet’s Final Letter as Berkshire Hathaway’s CEO" /><published>2025-11-20T00:00:00+00:00</published><updated>2025-11-20T00:00:00+00:00</updated><id>https://chambers.io/blog/2025/11/20/warren-buffets-final-letter-as-berkshire-hathaways-ceo</id><content type="html" xml:base="https://chambers.io/blog/2025/11/20/warren-buffets-final-letter-as-berkshire-hathaways-ceo.html"><![CDATA[<p>You must read Warren Buffet’s final letter to shareholders as CEO of Berkshire Hathaway.</p>
<p>Wisdom pours from every paragraph. Buffet is an incredible writer, and I don’t think that’s uncorrelated to his monumental success over the years. In the letter you will find some of his own personal history, what he expects the future may hold for Berkshire Hathaway, an understanding that luck does not strike all of us equally, a reminder that it’s okay to make mistakes, and a beautiful look at one’s own mortality.</p>
<p>Here is <a href="https://www.berkshirehathaway.com/news/nov1025.pdf">a direct link</a> to the letter as shared by Berkshire Hathaway. Here are some of my favorite lines:</p>
<blockquote>
<p>But Lady Luck is fickle and – no other term fits – wildly unfair. In many cases, our leaders and the rich have received far more than their share of luck – which, too often, the recipients prefer not to acknowledge.</p>
</blockquote>
<blockquote>
<p>I was born in 1930 healthy, reasonably intelligent, white, male and in America. Wow! Thank you, Lady Luck.</p>
</blockquote>
<blockquote>
<p>Father Time, to the contrary, now finds me more interesting as I age. And he is undefeated; for him, everyone ends up on his score card as “wins.” When balance, sight, hearing and memory are all on a persistently downward slope, you know Father Time is in the neighborhood.</p>
</blockquote>
<blockquote>
<p>I was late in becoming old – its onset materially varies – but once it appears, it is not to be denied.</p>
</blockquote>
<blockquote>
<p>I have assured my children that they do not need to perform miracles nor fear failures or disappointments. These are inevitable, and I have made my share.</p>
</blockquote>
<blockquote>
<p>Remember Alfred Nobel, later of Nobel Prize fame, who – reportedly – read his own obituary that was mistakenly printed when his brother died and a newspaper got mixed up. He was horrified at what he read and realized he should change his behavior.
Don’t count on a newsroom mix-up: Decide what you would like your obituary to say and live the life to deserve it.</p>
</blockquote>
<blockquote>
<p>Choose your heroes very carefully and then emulate them. You will never be perfect, but you can always be better.</p>
</blockquote>
<p>I could go on and on but I would probably just end up repeating the letter in its entirety. Do not delay further - go and read the letter yourself. You will not regret it.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><summary type="html"><![CDATA[You must read Warren Buffet’s final letter to shareholders as CEO of Berkshire Hathaway.]]></summary></entry><entry><title type="html">The Stars are Aligned: 2026 is the Year of Linux on the Desktop</title><link href="https://chambers.io/blog/2025/11/13/desktop-linux.html" rel="alternate" type="text/html" title="The Stars are Aligned: 2026 is the Year of Linux on the Desktop" /><published>2025-11-13T00:00:00+00:00</published><updated>2025-11-13T00:00:00+00:00</updated><id>https://chambers.io/blog/2025/11/13/desktop-linux</id><content type="html" xml:base="https://chambers.io/blog/2025/11/13/desktop-linux.html"><![CDATA[<p>We’ve been joking about “the year of Linux on the desktop” for three decades now, but it really does feel like the stars are aligned for 2026 to be that year. For it to finally grab a non-niche marketshare in the desktop/laptop computer market.</p>
<p>On the one hand, products from the established big players seem to be growing increasingly hostile to the average consumer.</p>
<ul>
<li>Windows 10 is officially end-of-life. I never loved Windows 10, but it was a decent OS (if you disabled much of the on-by-default telemetry) for the average consumer. And of course, it was pretty much the only serious choice if you wanted to play most PC games.</li>
<li>Windows 11 is <a href="https://www.neowin.net/news/microsoft-confirms-windows-11-is-about-to-change-massively-gets-enormous-backlash/">doubling-down on forced AI integrations</a> and telemetry.</li>
<li>Many devices running Windows 10 are incompatible with Windows 11. Microsoft wants you to throw these away and buy something new.</li>
<li>MacOS 26 (Tahoe) looks and feels like a toy operating system. Performance issues and bugs continue to pile up and undo the incredible work that Apple hardware teams have done with Apple Silicon and the otherwise exceptional Apple hardware.</li>
</ul>
<p>On the other hand, the vibes surrounding desktop Linux seem to be better than ever.</p>
<ul>
<li><a href="https://omarchy.org/">Omarchy Linux</a> has some substantial hype in the developer world.</li>
<li><a href="https://www.valvesoftware.com/en/">Valve</a> is continuing to build on their decade+ effort to make Linux a first-class OS for gaming and they are pushing the boundaries for Linux ease-of-use. The <a href="https://store.steampowered.com/sale/hardware">new hardware</a> from Valve looks to be a great entryway into PC Gaming/Linux for outsiders.</li>
<li><a href="https://frame.work/">Framework</a> is becoming increasingly mainstream and has great options at all price points, including the new super-powerful <a href="https://frame.work/desktop">Framework Desktop</a>. Their repair-friendly approach to hardware is proving to be a bright spot with consumers in an age where tech waste is piling up around us.</li>
</ul>
<p>Will Linux launch into second or first place in PC/laptop marketshare? Of course not. But I think the cards are there for Linux to prove it’s a real, viable, consumer-friendly third option.</p>
<p>If you’re reading this, chances are you’re well aware of Linux and how awesome it can be. It’s up to us nerds to evangelize the platform. Be friendly to newcomers. Linux doesn’t have to be a place exclusively for developers and power-users any more. It really can offer the best of both worlds.</p>
<p>I love my mac hardware and many parts of MacOS, but I will be doubling down on Linux in 2026.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="Linux" /><category term="Gaming" /><summary type="html"><![CDATA[We’ve been joking about “the year of Linux on the desktop” for three decades now, but it really does feel like the stars are aligned for 2026 to be that year. For it to finally grab a non-niche marketshare in the desktop/laptop computer market.]]></summary></entry><entry><title type="html">Raised Panels</title><link href="https://chambers.io/linkblog/2025/11/11/raised-panels.html" rel="alternate" type="text/html" title="Raised Panels" /><published>2025-11-11T00:00:00+00:00</published><updated>2025-11-11T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/11/11/raised-panels</id><content type="html" xml:base="https://chambers.io/linkblog/2025/11/11/raised-panels.html"><![CDATA[<p><a href="https://www.youtube.com/watch?v=M6iIqZY4gvc">https://www.youtube.com/watch?v=M6iIqZY4gvc</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://www.youtube.com/watch?v=M6iIqZY4gvc]]></summary></entry><entry><title type="html">The ‘Toy Story’ You Remember</title><link href="https://chambers.io/linkblog/2025/11/11/the-toy-story-you-remember.html" rel="alternate" type="text/html" title="The ‘Toy Story’ You Remember" /><published>2025-11-11T00:00:00+00:00</published><updated>2025-11-11T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/11/11/the-toy-story-you-remember</id><content type="html" xml:base="https://chambers.io/linkblog/2025/11/11/the-toy-story-you-remember.html"><![CDATA[<p><a href="https://animationobsessive.substack.com/p/the-toy-story-you-remember">https://animationobsessive.substack.com/p/the-toy-story-you-remember</a></p>
<p>A fascinating, if somewhat sad look at how different versions of feature films wind up with different colors and how much that can impact a film.</p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><category term="film" /><summary type="html"><![CDATA[https://animationobsessive.substack.com/p/the-toy-story-you-remember]]></summary></entry><entry><title type="html">SF Parking Cops</title><link href="https://chambers.io/linkblog/2025/09/23/sf-parking-cops.html" rel="alternate" type="text/html" title="SF Parking Cops" /><published>2025-09-23T00:00:00+00:00</published><updated>2025-09-23T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/09/23/sf-parking-cops</id><content type="html" xml:base="https://chambers.io/linkblog/2025/09/23/sf-parking-cops.html"><![CDATA[<p><a href="https://walzr.com/sf-parking/">https://walzr.com/sf-parking/</a></p>
<p><a href="https://walzr.com">Riley Walz</a> has put out a number of incredibly unique projects over the years. This is one of the coolest yet.</p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://walzr.com/sf-parking/]]></summary></entry><entry><title type="html">The Em-Dash Debacle</title><link href="https://chambers.io/blog/2025/09/15/the-em-dash-debacle.html" rel="alternate" type="text/html" title="The Em-Dash Debacle" /><published>2025-09-15T00:00:00+00:00</published><updated>2025-09-15T00:00:00+00:00</updated><id>https://chambers.io/blog/2025/09/15/the-em-dash-debacle</id><content type="html" xml:base="https://chambers.io/blog/2025/09/15/the-em-dash-debacle.html"><![CDATA[<p>If you’ve been anywhere on the internet in the last year or so, you’re probably familiar with what I am calling the “Em-Dash Debacle”.
In case you missed it, the core issue is this: LLMs tend to generate a lot of em-dashes in their text output.
Most people do not write with proper em-dashes these days.
People (at least english speaking people) write with a lot of dashes, but they tend to actually use the hyphen character when doing so.</p>
<p>I am a millennial and I grew up with computers.
I was taught that it was grammatically correct to use dashes, not hyphens.
Microsoft Word (and later, Google Docs) made this trivially easy because you could type two hyphens (–) and it would replace it with an em-dash character.
You never had to memorize a keyboard shortcut for inserting the em-dash character.
I rarely write in Word or Google Docs these days, but when I do, I still do that double-hyphen shortcut.
It’s a habit that I apparently have not forgotten.</p>
<p>So why is em-dash usage suddenly a problem?</p>
<p>I think the main reason people are noticing the em-dash usage now is because most writing has moved away from legacy tools like Word.
“Modern” writing tools like Notion, Obsidian, etc does not not do that charaacter substitution.
Nor do websites like Twitter, where it has become quite obvious when text is being pasted from another place…for example, AI generated content.
If you are writing directly in those apps or websites, the majority of folks are just using a hyphen where they would historically use an em-dash.
These tools are not replacing the hyphens with em-dash characters.
And when people do come across em-dashes in Twitter or whatever, the automatic assumption is that the text is not being written by a real person.</p>
<p>If you do properly use em-dashes in your writing, people assume you are using AI-generated content.
The piling-on in places like Twitter/X has become so bad, that many people are not intentionally avoiding them in order to avoid being called out for sharing “AI slop.”</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="AI" /><category term="LLMs" /><summary type="html"><![CDATA[If you’ve been anywhere on the internet in the last year or so, you’re probably familiar with what I am calling the “Em-Dash Debacle”. In case you missed it, the core issue is this: LLMs tend to generate a lot of em-dashes in their text output. Most people do not write with proper em-dashes these days. People (at least english speaking people) write with a lot of dashes, but they tend to actually use the hyphen character when doing so.]]></summary></entry><entry><title type="html">Hosting a Website on a Disposable Vape</title><link href="https://chambers.io/linkblog/2025/09/15/hosting-a-website-on-a-disposable-vape.html" rel="alternate" type="text/html" title="Hosting a Website on a Disposable Vape" /><published>2025-09-15T00:00:00+00:00</published><updated>2025-09-15T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/09/15/hosting-a-website-on-a-disposable-vape</id><content type="html" xml:base="https://chambers.io/linkblog/2025/09/15/hosting-a-website-on-a-disposable-vape.html"><![CDATA[<p><a href="https://bogdanthegeek.github.io/blog/projects/vapeserver/">https://bogdanthegeek.github.io/blog/projects/vapeserver/</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://bogdanthegeek.github.io/blog/projects/vapeserver/]]></summary></entry><entry><title type="html">Why I Love Obsidian: Hackability</title><link href="https://chambers.io/blog/2025/09/06/obisidian-hackability.html" rel="alternate" type="text/html" title="Why I Love Obsidian: Hackability" /><published>2025-09-06T00:00:00+00:00</published><updated>2025-09-06T00:00:00+00:00</updated><id>https://chambers.io/blog/2025/09/06/obisidian-hackability</id><content type="html" xml:base="https://chambers.io/blog/2025/09/06/obisidian-hackability.html"><![CDATA[<p>I use <a href="https://obsidian.md/">Obsidian</a> as my primary note-taking tool.
There’s so much I love about it:
It’s fast.
It’s local-first.
It’s run by a small team with a focus on being a sustainable business.
It’s got lots of plugins that extend functionality.
But by far the best feature is that it stores all data in plain text files.</p>
<p>This gives you so much power!
You can open your Obsidian notes in other text editors/software if you want.
It also means you can write scripts or use other programs to manipulate your notes.</p>
<p>I use metadata <a href="https://help.obsidian.md/properties">properties</a> extensively in my notes for organization and other things.
I wanted to change a property that I have in many notes from one value to another.
Obsidian has no way to bulk update properties on all notes.
There may be a plugin to do this - but it’s not needed.
Your “Obsidian Vault” is quite literally just plaintext markdown files in a directory on your computer.</p>
<p>There is this great little tool called <a href="https://www.gnu.org/software/sed/manual/sed.html">sed</a>.
You might have heard of it.
It’s really good at one thing - replacing text in a file.
Or better yet, many files.</p>
<p>With a little command line magic following the standard <a href="https://en.wikipedia.org/wiki/Unix_philosophy">Unix philosphy</a> I was able to easily bulk update all of those properties on hundreds of files.</p>
<pre><code>find . -type f -exec sed -i 's/old-property/new-property/g' {} +
</code></pre>
<p><strong>P.S.</strong> if you’re on MacOS - you should install <a href="https://formulae.brew.sh/formula/gnu-sed">gnu-sed</a> and use that instead of the BSD-variant included with MacOS.
It has some quirks and it works slightly differently than GNU sed.
A lot of the <code>sed</code> commands you find online won’t work correctly on MacOS.</p>
<pre><code>brew install gnu-sed
alias sed='gsed'
</code></pre>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><summary type="html"><![CDATA[I use Obsidian as my primary note-taking tool. There’s so much I love about it: It’s fast. It’s local-first. It’s run by a small team with a focus on being a sustainable business. It’s got lots of plugins that extend functionality. But by far the best feature is that it stores all data in plain text files.]]></summary></entry><entry><title type="html">Implementing a Foil Sticker Effect</title><link href="https://chambers.io/linkblog/2025/09/02/foil-sticker-simulation.html" rel="alternate" type="text/html" title="Implementing a Foil Sticker Effect" /><published>2025-09-02T00:00:00+00:00</published><updated>2025-09-02T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/09/02/foil-sticker-simulation</id><content type="html" xml:base="https://chambers.io/linkblog/2025/09/02/foil-sticker-simulation.html"><![CDATA[<p><a href="https://www.4rknova.com/blog/2025/08/30/foil-sticker">https://www.4rknova.com/blog/2025/08/30/foil-sticker</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://www.4rknova.com/blog/2025/08/30/foil-sticker]]></summary></entry><entry><title type="html">Giving Omarchy a Shot</title><link href="https://chambers.io/blog/2025/08/28/omarchy.html" rel="alternate" type="text/html" title="Giving Omarchy a Shot" /><published>2025-08-28T00:00:00+00:00</published><updated>2025-08-28T00:00:00+00:00</updated><id>https://chambers.io/blog/2025/08/28/omarchy</id><content type="html" xml:base="https://chambers.io/blog/2025/08/28/omarchy.html"><![CDATA[<p>If you’re at all involved in the web development, Ruby/Rails, Linux, or general tech community you’ve probably heard of <a href="https://omarchy.org/">Omarchy</a> - a new “opinionated Arch + Hyprland Setup” by <a href="https://dhh.dk/">DHH</a> - CTO at <a href="https://37signals.com/">37 Signals</a> and creator of <a href="https://rubyonrails.org/">Ruby on Rails</a>.</p>
<p>I have been using Linux for the better part of two decades, but these days only as a server operating system. I haven’t really used Linux on the Desktop in nearly ten years - MacOS has just been too good and I haven’t had the time or energy to maintain a Linux desktop environment.</p>
<p>About a year ago DHH released <a href="https://omakub.org/">Omakub</a> - a special configuration of Ubuntu designed for Software Development. I followed the Omakub development and was excited to see people giving Linux on the Desktop some more love, especially people like DHH that evangelized MacOS for decades. But have been too happy with MacOS. The hardware is <strong>too freaking good</strong>. I don’t like the direction Apple has been taking it, but so far everything they have changed I can still “undo” or configure to my liking.</p>
<p>Omakub peaked my interest, but Omarchy has truly captured it. The attention to detail in Omarchy is fantastic and it looks like it provides a refined experience out-of-the-box.</p>
<p>I guess I am technically new to <a href="https://archlinux.org/">Arch</a>. I have been “using” Arch by way of <a href="https://store.steampowered.com/steamos">SteamOS</a> on my Steam Deck for a couple of years, but I have never run mainline Arch Linux. This still feels like Arch on training wheels, but that’s OK. Between parenting, work, running, reading, and <a href="/now">everything else in my life</a> - training wheels sound great right now.</p>
<p>I do <a href="/uses">almost all of my computing on my Macs these days</a>, but I do have a Desktop PC running Windows 10 that I use for playing games. I have been trying to decide what to do with it given the <a href="https://support.microsoft.com/en-us/windows/windows-10-support-ends-on-october-14-2025-2ca8b313-1946-43d3-b55c-2b95b107f281">looming Windows 10 end-of-life</a>. There is no better time than now to give Omarchy an honest try. So I just bought a new SSD (Samsung 990 Pro 2TB) to throw in my Desktop PC that will be dedicated to Omarchy. If I love it, I will wipe the old one with Windows 10 on it.</p>
<p>I’m unhappy with the direction of MacOS. I am unhappy with Windows 11. I have been wanting to try Arch on the desktop for a while. I have been wanting to try Wayland. It’s a perfect storm, and Omarchy is how I am going to ride it out.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="linux" /><category term="omarchy" /><summary type="html"><![CDATA[If you’re at all involved in the web development, Ruby/Rails, Linux, or general tech community you’ve probably heard of Omarchy - a new “opinionated Arch + Hyprland Setup” by DHH - CTO at 37 Signals and creator of Ruby on Rails.]]></summary></entry><entry><title type="html">I spent 6 years building a ridiculous wooden pixel display</title><link href="https://chambers.io/linkblog/2025/08/04/i-spent-6-years-building-a-ridiculous-wooden-pixel-display.html" rel="alternate" type="text/html" title="I spent 6 years building a ridiculous wooden pixel display" /><published>2025-08-04T00:00:00+00:00</published><updated>2025-08-04T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/08/04/i-spent-6-years-building-a-ridiculous-wooden-pixel-display</id><content type="html" xml:base="https://chambers.io/linkblog/2025/08/04/i-spent-6-years-building-a-ridiculous-wooden-pixel-display.html"><![CDATA[]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /></entry><entry><title type="html">Engineered Addictions</title><link href="https://chambers.io/linkblog/2025/07/29/engineered-addictions.html" rel="alternate" type="text/html" title="Engineered Addictions" /><published>2025-07-29T00:00:00+00:00</published><updated>2025-07-29T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/07/29/engineered-addictions</id><content type="html" xml:base="https://chambers.io/linkblog/2025/07/29/engineered-addictions.html"><![CDATA[]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /></entry><entry><title type="html">The Most Dangerous Building in Manhattan</title><link href="https://chambers.io/linkblog/2025/04/28/the-most-dangerous-building-in-manhattan.html" rel="alternate" type="text/html" title="The Most Dangerous Building in Manhattan" /><published>2025-04-28T00:00:00+00:00</published><updated>2025-04-28T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/04/28/the-most-dangerous-building-in-manhattan</id><content type="html" xml:base="https://chambers.io/linkblog/2025/04/28/the-most-dangerous-building-in-manhattan.html"><![CDATA[<p><a href="https://www.youtube.com/watch?v=Q56PMJbCFXQ">https://www.youtube.com/watch?v=Q56PMJbCFXQ</a></p>
<p>I never took an engineering ethics course, but I imagine this is a case study that is talked about in universities around the world.</p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://www.youtube.com/watch?v=Q56PMJbCFXQ]]></summary></entry><entry><title type="html">How to Build an Agent</title><link href="https://chambers.io/linkblog/2025/04/15/how-to-build-an-agent.html" rel="alternate" type="text/html" title="How to Build an Agent" /><published>2025-04-15T00:00:00+00:00</published><updated>2025-04-15T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/04/15/how-to-build-an-agent</id><content type="html" xml:base="https://chambers.io/linkblog/2025/04/15/how-to-build-an-agent.html"><![CDATA[<p><a href="https://ampcode.com/how-to-build-an-agent">https://ampcode.com/how-to-build-an-agent</a></p>
<p>In this phenomonal blog post, <a href="https://thorstenball.com/">Thorsten Ball</a> explains how simple AI Agents are under the hood and how you can build one yourself.</p>
<p>All you really need is an API key for an LLM and a loop.
Agents are not magic.</p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://ampcode.com/how-to-build-an-agent]]></summary></entry><entry><title type="html">Kagi Search Stats</title><link href="https://chambers.io/linkblog/2025/03/27/kagi-search-stats.html" rel="alternate" type="text/html" title="Kagi Search Stats" /><published>2025-03-27T00:00:00+00:00</published><updated>2025-03-27T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/03/27/kagi-search-stats</id><content type="html" xml:base="https://chambers.io/linkblog/2025/03/27/kagi-search-stats.html"><![CDATA[<p><a href="https://kagi.com/stats?stat=leaderboard">https://kagi.com/stats?stat=leaderboard</a></p>
<p>The sites on <a href="https://kagi.com">Kagi</a> that are the most pinned, blocked, raised, or lowered.</p>
<p>Learn what sites Kagi users consider spam. And which sites they always want at the top of their search results.</p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://kagi.com/stats?stat=leaderboard]]></summary></entry><entry><title type="html">Creating a Linkblog</title><link href="https://chambers.io/blog/2025/03/21/creating-a-linkblog.html" rel="alternate" type="text/html" title="Creating a Linkblog" /><published>2025-03-21T00:00:00+00:00</published><updated>2025-03-21T00:00:00+00:00</updated><id>https://chambers.io/blog/2025/03/21/creating-a-linkblog</id><content type="html" xml:base="https://chambers.io/blog/2025/03/21/creating-a-linkblog.html"><![CDATA[<p>I am adding a “Linkblog” to this website. It’s a way for me to share interesting links I find online and maybe share a few thoughts or comments about it.</p>
<p>The links will collate with my own blog posts on the homem page and in the blog archive, but you can browse them separately on the <a href="/linkblog">Linkblog page</a>.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><summary type="html"><![CDATA[I am adding a “Linkblog” to this website. It’s a way for me to share interesting links I find online and maybe share a few thoughts or comments about it.]]></summary></entry><entry><title type="html">git who</title><link href="https://chambers.io/linkblog/2025/03/21/git-who.html" rel="alternate" type="text/html" title="git who" /><published>2025-03-21T00:00:00+00:00</published><updated>2025-03-21T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/03/21/git-who</id><content type="html" xml:base="https://chambers.io/linkblog/2025/03/21/git-who.html"><![CDATA[<p><a href="https://github.com/sinclairtarget/git-who">https://github.com/sinclairtarget/git-who</a></p>
<p>This is a really cool utility, and it’s pretty quick too.
It generates reports for small repositories almost instantly.</p>
<p>For a large Rails monolith that is 18 years old, has 1695 unique committers, and more than 220,000 commits it generates the report in less than three seconds.</p>
<pre><code>time git who
...
real    0m2.885s
user    0m2.711s
sys     0m0.767s
</code></pre>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://github.com/sinclairtarget/git-who]]></summary></entry><entry><title type="html">This Material Gets Bigger When You Squish It</title><link href="https://chambers.io/linkblog/2025/03/21/this-material-gets-bigger-when-you-squish-it.html" rel="alternate" type="text/html" title="This Material Gets Bigger When You Squish It" /><published>2025-03-21T00:00:00+00:00</published><updated>2025-03-21T00:00:00+00:00</updated><id>https://chambers.io/linkblog/2025/03/21/this-material-gets-bigger-when-you-squish-it</id><content type="html" xml:base="https://chambers.io/linkblog/2025/03/21/this-material-gets-bigger-when-you-squish-it.html"><![CDATA[<p><a href="https://youtu.be/Pw3AvKcHeTw?si=Y0MxHxeOUtrlSh0A">https://youtu.be/Pw3AvKcHeTw?si=Y0MxHxeOUtrlSh0A</a></p>]]></content><author><name>Dakota Chambers</name></author><category term="linkblog" /><summary type="html"><![CDATA[https://youtu.be/Pw3AvKcHeTw?si=Y0MxHxeOUtrlSh0A]]></summary></entry><entry><title type="html">Mac Mini Home Server</title><link href="https://chambers.io/blog/2024/11/09/mac-mini-home-server.html" rel="alternate" type="text/html" title="Mac Mini Home Server" /><published>2024-11-09T00:00:00+00:00</published><updated>2024-11-09T00:00:00+00:00</updated><id>https://chambers.io/blog/2024/11/09/mac-mini-home-server</id><content type="html" xml:base="https://chambers.io/blog/2024/11/09/mac-mini-home-server.html"><![CDATA[<p>I just purchased a new <a href="https://www.apple.com/mac-mini/">Mac Mini</a> with the intent of setting it up as a home server.</p>
<p>Despite being a pretty typical nerdy tech guy that works professionally in the DevOps world - I don’t actually have any kind of home lab or real home server set up right now.
I do have an old gaming desktop that I “converted” to a home server a couple of years ago when I built my new desktop PC, but in practice I haven’t used it at all.
Why?
The fans are loud, it’s not cheap to leave running 24/7, and I just haven’t really had much of a desire to build out a home server - until now.</p>
<p>The Mac Minis have always been interesting, and they’ve always been popular - being the cheapest entry into the MacOS ecosystem.
But the migration to M-series Apple Silicon made things…<strong>really</strong> interesting.
Suddenly these small boxes weren’t limited by the low tier Intel chips.</p>
<p>The latest iteration powered by <a href="https://www.apple.com/newsroom/2024/05/apple-introduces-m4-chip/">Apple M4 chips</a> are performance powerhouses.
Even the base model M4 has single-core performance that is among the best in the industry, second only to the M4 Pro/M4 Max.
It’s no slouch with multi-core performance either.
Apple <strong>finally</strong> doubled the RAM in the base model to 16GB.
And it’s packed with Thunderbolt 4 (Thunderbolt 5 in the M4 Pro variant) ports on the back.</p>
<p>In addition, Apple designed an all new, even mini-er case.
It now looks more like a miniature <a href="https://www.apple.com/mac-studio/">Mac Studio</a>.
For a mere $599 ($499 education pricing) you can get a machine with an incredible amount of power packed into a box with a five inch by five inch footprint that sips power - about 5 watts at idle and 20 watts under load.
My gaming desktop idles between 100W-150W and tops out at more than 600W under full load.
Drawing only 5 watts of power - I can run the machine at idle 24/7 for less than five dollars a year.</p>
<p>I opted for the base model - which I think will be perfect for my lower-power home server needs.
And it’s a low-cost entry to the great Mac server experiment.
But if you want, you can spec up the Mini with an M4 Pro and up to 64GB RAM to turn it into a true desktop-grade workstation in a tiny box.
A tiny box that will outperform a $4000 Mac Studio with an M2 Ultra chip from just two years ago.</p>
<p>So why now?
What makes me want to build out a home server now?</p>
<p>I’ve been getting more serious about media preservation and archiving, especially now that we’ve got a mountain of photos and videos of our young kids.
While I do back these up to a cloud service, I would like to have local copies available on network attached storage.
And with <a href="https://tailscale.com/">Tailscale</a>, I can now easily build out a virtual private network with all of our household devices so that network storage can safely be accessed anywhere.</p>
<p>In addition to media management, I plan on setting up some <a href="https://www.reddit.com/r/selfhosted/">self-hosted</a> software for use on the network.
Docker makes it trivially easy to run SaaS-style software at home these days.</p>
<p>I am not quite sure how I will like using MacOS as a “headless” server in the traditional sense.
While I am very experienced managing Linux servers remotely, I know that MacOS doesn’t have quite the same capabilities.
Yes I can still run a SSH server and access it remotely like that, but there are oddities with MacOS.
Apple does have a full remote desktop feature built into the OS, which I am sure I will try out to see how that goes.</p>
<p>For now the Mac will live on top of my Desk next to my docked Macbooks, but I hope to move it into a closet in my office along with a Thunderbolt 4 RAID storage drive.
Hopefully the tiny power draw and low amount of heat means it will happily live in a closet.</p>
<p>The Mac is due for delivery on Monday.
I’ll post an update in a little bit once I start experimenting and settings things up!</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="home-lab" /><summary type="html"><![CDATA[I just purchased a new Mac Mini with the intent of setting it up as a home server.]]></summary></entry><entry><title type="html">My Personal Software Stack - Fall 2024 Edition</title><link href="https://chambers.io/blog/2024/10/01/personal-software-stack-fall-2024.html" rel="alternate" type="text/html" title="My Personal Software Stack - Fall 2024 Edition" /><published>2024-10-01T00:00:00+00:00</published><updated>2024-11-03T00:00:00+00:00</updated><id>https://chambers.io/blog/2024/10/01/personal-software-stack-fall-2024</id><content type="html" xml:base="https://chambers.io/blog/2024/10/01/personal-software-stack-fall-2024.html"><![CDATA[<p>It’s interesting to look at how one’s software usage changes over time.
Some people use the same tools for years or even decades.
Some people change productivity tools every six months.
While I do have a <a href="/uses">/uses</a> page that lists the tools I use to accomplish work and have fun on the computer I figured it would be nice to take a snapshot of the software tools I am using at a particular point in time.</p>
<p>Note that these are tools I use for my own personal projects and productivity, not ones that I use exclusively for my day job (eg Jira).</p>
<h2 id="software">Software</h2>
<ul>
<li>Primary Text Editor: <a href="https://zed.dev/">Zed</a>
<ul>
<li>Alternatives: <a href="https://neovim.io/">Neovim</a>, <a href="https://code.visualstudio.com/">VS Code</a></li>
</ul>
</li>
<li>Terminal: <a href="https://alacritty.org/">Alacritty</a>
- Hoping to switch to <a href="https://mitchellh.com/ghostty">Ghostty</a> soon</li>
<li>Launcher/Everything App: <a href="https://www.raycast.com/">Raycast</a></li>
<li>Passwords: <a href="https://1password.com/">1Password</a></li>
<li>OTP/2FA: <a href="https://getaegis.app/">Aegis</a></li>
<li>Personal Notes: <a href="https://obsidian.md/">Obsidian</a>
<ul>
<li>Plus <a href="https://obsidian.md/sync">Obsidian Sync</a> and <a href="https://publish.obsidian.md/dakota">Obsidian Publish</a></li>
</ul>
</li>
<li>Shared Notes: <a href="https://keep.google.com">Google Keep</a></li>
<li>Todo: <a href="https://ticktick.com/">TickTick</a></li>
<li>Weather: <a href="https://helloweather.com/">Hello Weather</a></li>
<li>Email, Calendar: <a href="https://calendar.google.com/">Google</a>
<ul>
<li>I primarily use the webapp for both, but I also use the <a href="https://www.mowglii.com/itsycal/">Itsycal</a> menu bar app</li>
</ul>
</li>
<li>Docs: <a href="https://docs.google.com/">Google Docs</a></li>
<li>Spreadsheets: <a href="https://sheets.google.com/">Google Sheets</a></li>
<li>Podcasts: <a href="https://antennapod.org/">AntennaPod</a></li>
<li>AI Tools: <a href="https://ollama.com/">Ollama</a>, <a href="https://boltai.com/">BoltAI</a></li>
<li>Screenshots: <a href="https://cleanshot.com/">Cleanshot X</a></li>
<li>MacOS Window Management: <a href="https://rectangleapp.com/">Rectangle</a></li>
<li>API Tool: <a href="https://paw.cloud/">RapidAPI</a>, <a href="https://httpie.io/">httpie</a></li>
</ul>
<h2 id="software-services">Software Services</h2>
<ul>
<li>Cloud File &amp; Photo Storage: <a href="https://one.google.com">Google Drive</a>, <a href="https://dropbox.com/">Dropbox</a>
<ul>
<li><a href="https://maestral.app/">Maestral</a> open source Dropbox client</li>
</ul>
</li>
<li>VPN: Subscribed to <a href="https://www.privateinternetaccess.com/">PIA</a> but I rarely if ever use it. Will drop once subscription ends.
<ul>
<li>Actively working on setting up <a href="https://www.privateinternetaccess.com/">Tailscale</a> for a private VPN</li>
</ul>
</li>
<li>Git Hosting: <a href="https://github.com">GitHub</a></li>
<li>Search: <a href="https://google.com">Google</a> but I am also currently experimenting with <a href="https://kagi.com">Kagi</a></li>
<li>AI: <a href="https://chatgpt.com">ChatGPT</a> (paid account for work, I use the free version personally), <a href="https://gemini.google.com">Gemini</a></li>
<li>Family Chat: <a href="https://www.whatsapp.com/">WhatsApp</a></li>
</ul>
<h2 id="hardware">Hardware</h2>
<ul>
<li>Macbook Air 13” M2/24GB/512GB</li>
<li>Dell U2720Q (27” 4K monitor)</li>
<li>HHKB Professional Hybrid Type-S</li>
<li>Apple Magic Trackpad</li>
<li>Logitech MX Master 3S</li>
<li>Google Pixel 6 Pro</li>
<li>Sony WH1000XM3 Headphones</li>
</ul>
<h3 id="other-hardware">Other Hardware</h3>
<ul>
<li>I have a desktop PC that I build in December 2020 that I only use for playing games.
<ul>
<li>AMD Ryzen 5, Nvidia RTX 3060 Ti, 32GB RAM</li>
</ul>
</li>
<li>Steam Deck (OLED 1TB)</li>
<li>Nintendo Switch</li>
<li>A mountain of mechanical keyboards, but mostly untouched since I got my HHKB.</li>
</ul>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="Apps" /><category term="Software" /><category term="DakotaOS" /><summary type="html"><![CDATA[It’s interesting to look at how one’s software usage changes over time. Some people use the same tools for years or even decades. Some people change productivity tools every six months. While I do have a /uses page that lists the tools I use to accomplish work and have fun on the computer I figured it would be nice to take a snapshot of the software tools I am using at a particular point in time.]]></summary></entry><entry><title type="html">How I Use AI</title><link href="https://chambers.io/blog/2024/07/10/how-i-use-ai.html" rel="alternate" type="text/html" title="How I Use AI" /><published>2024-07-10T00:00:00+00:00</published><updated>2024-07-11T00:00:00+00:00</updated><id>https://chambers.io/blog/2024/07/10/how-i-use-ai</id><content type="html" xml:base="https://chambers.io/blog/2024/07/10/how-i-use-ai.html"><![CDATA[<p>It’s the middle of 2024 and unless you live under a rock you’ve certainly encountered the trend of “AI” infiltrating virtually every piece of software we use. This isn’t necessarily a bad thing, but there are some AI features that are far more valuable than others. Here’s how I use AI in my day-to-day life.</p>
<h2 id="writing">Writing</h2>
<p>I <em>never</em> use AI to help me write. Writing is challenging, but the challenge is what makes it worth it. Think of writing like exercise for the brain. Your brain, like other parts of your body, needs exercise to stay healthy. I enjoy flexing those writing muscles - and you should too!</p>
<p>And I write quite a bit. The nature of working in a mostly-remote company means that a lot of our work is done asynchronously via written communication. I can see how it’s tempting to use AI to help you write, but I think it’s overall more harmful than helpful. Formulating thoughts to the point you can write them down and communicate them clearly is an incredibly valuable process and clearly elevates the quality of your work. Writing well makes you really think about what you want to say and forces you to string together sometimes disjointed thoughts into something concrete.</p>
<h2 id="research">Research</h2>
<p>I do use AI (primarily ChatGPT, but also Gemini) for general Q&amp;A and research, and I think this is one thing it excels at.</p>
<p>You <em>do</em> need to be cautious when using AI tools for research. After all LLMs <strong>cannot actually reason</strong> and simply use mathematical probability to generate one token at a time. LLMs are notorious for “hallucinating” facts precisely because of this. LLMs with better training data will be better at reproducing accurate information, but the generated text can only be as accurate as the training data. And guess what? There’s a lot of inaccurate information out there on the internet.</p>
<p>I like to treat text generated by LLMs like I do other untrusted information on the internet. Trust but verify. Use it as a jumping-off point for future, more in-depth research. I wouldn’t use it to answer a question that I need to 100% verify is correct, but I think it can be an incredibly useful tool to help generate ideas.</p>
<h2 id="coding">Coding</h2>
<p>I do use ChatGPT/Gemini semi-frequently with coding and other technical questions. This could be something as simple as “what does this library do?” to “write a cron schedule that runs every Friday at 2AM”.</p>
<p>I have begun experimenting with GitHub Copilot when writing code, but I don’t use it all that much yet. I feel like when I try to use it I am constantly trying to write code according to what the AI is expecting. For some reason it prevents me from getting into the “flow state” and it doesn’t encourage me to approach problems holistically.</p>
<h2 id="other-generative-ai">Other Generative AI</h2>
<p>I don’t currently use any kind of image, video, or audio generative AI. I don’t have a need to, and I personally prefer art made by actual people.</p>
<h2 id="chambersioai">chambers.io/ai</h2>
<p>It’s important to set personal limits on how we approach and use AI tools as they becomes more prevalent throughout our society. I have created a new permanent page on my website (<a href="https://chambers.io/ai">https://chambers.io/ai</a>) that I will keep updated (inspired by <a href="https://sive.rs/ai">Dever Sivers</a> and <a href="https://www.bydamo.la/p/ai-manifesto">Damola Morenikeji</a>) with how I personally use AI to <em>add value to my life</em> in a sustainable way.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="AI" /><category term="LLMs" /><summary type="html"><![CDATA[It’s the middle of 2024 and unless you live under a rock you’ve certainly encountered the trend of “AI” infiltrating virtually every piece of software we use. This isn’t necessarily a bad thing, but there are some AI features that are far more valuable than others. Here’s how I use AI in my day-to-day life.]]></summary></entry><entry><title type="html">Social Media Diet</title><link href="https://chambers.io/blog/2024/02/20/social-media-diet.html" rel="alternate" type="text/html" title="Social Media Diet" /><published>2024-02-20T00:00:00+00:00</published><updated>2024-02-20T00:00:00+00:00</updated><id>https://chambers.io/blog/2024/02/20/social-media-diet</id><content type="html" xml:base="https://chambers.io/blog/2024/02/20/social-media-diet.html"><![CDATA[<p>Stop me if you’ve been there before.</p>
<p>You just left a stressful Zoom call.
You lean back in your chair, take a deep breath, and your phone finds its way into your hands.
Twitter is open.
You’re scrolling.</p>
<p>You blink, look at the tiny numbers in the corner of your phone screen displaying the time and immediately sit upright, shocked.
Thirty minutes of your life have evaporated, never to be seen again.
You didn’t even read anything worth remembering, and you have nothing to show for it.</p>
<p>…</p>
<p>You finally got the kids down for bedtime after winning tonights battle against the many bedtime complaints.
“I’m not tired,” “I need water,” and “I have to pee!”
You pull your phone out of your pocket and tell yourself you need just a few minutes to decompress, then you’re going to brew a cup of tea, sit down and read a chapter in the book you were so excited to read.
But Instagram has its hooks in you.
Or TikTok.
Or YouTube Shorts.</p>
<p>You scroll, and you scroll, and you scroll some more.
Some of the videos make you smile.
None make you laugh.
You send others to friends.
All the while, you are telling yourself <em>this is a waste of time</em> but the dopamine hits hard and your brain craves more.
No video is good enough to give you that final, lasting high but each one is good enough to keep you thinking <em>the next one is the last one, it’s got to be</em>.</p>
<p>You scroll some more.</p>
<p>…</p>
<p>It’s a tale as old as time.</p>
<p>I wish I could tell you I had a solution to the above.
The obvious answer is “just stop using social media” - but I believe certain types of social media <em>do</em> have value.
How can I extract that value while escaping the time-sucking, attention-sucking, fun-sucking trap that is the rest of social media?</p>
<p>Lately I found myself falling into the above traps all too often.
Rather than lay down every night disappointed with myself, I made a conscious decision to go on a social media diet.</p>
<p>Not a social media ban, but a <em>diet</em>.
And well, like all good diets, that includes some outright bans on some things and moderate amounts of others.
Like food, not all social media is created equal.</p>
<p>Here is my diet plan:</p>
<ul>
<li>Remove <strong>all</strong> social media apps from my phone.
<ul>
<li>This includes Twitter, Mastodon, Facebook, Instagram, Reddit, etc. YouTube stays…for now.</li>
<li>I exclude Snapchat (not because of their <a href="https://newsroom.snap.com/less-social-media-more-**snapchat**">“We’re not social media” campaign</a>, but because it’s the primary way I send photos and videos of our kids to family members)</li>
</ul>
</li>
<li><strong>Zero tolerance ban</strong> on Tiktok-style endless video content. I don’t use TikTok, but for me this includes Instagram Reels and YouTube Shorts.
<ul>
<li>YouTube makes this difficult because there is no way to hide shorts from the platform. As such, this means no opening up YouTube to “browse” - but only using it for specific purposes.</li>
</ul>
</li>
<li>Log out of all social media websites on my phone and computers.
<ul>
<li>If I decide I <em>need</em> to use social media, I need to log in first. When I am done, I log out.</li>
</ul>
</li>
<li>Allow myself a dedicated five minutes per morning and per evening to check in on the above social media, only on my computer, and primarily as a way to see if I have any pending messages or “notifications” that I actually need to see. <strong>No scrolling feeds allowed.</strong></li>
<li>Allow myself to <em>post</em> some content on an as-need basis. I don’t believe social media is inherently evil, and for many people it’s an incredibly useful tool. But I do believe our little monkey brains are not equipped to handle the fast-paced, instant-gratification treadmill we have created. The primary goal is to slow down the <em>consumption</em> of “nutrition-less” social media content.</li>
<li>Allow usage of “small web” social media. Reading blogs via RSS feed, updating a “status” on <a href="https://status.lol">https://status.lol</a>, writing my own blog posts and sharing them widely.</li>
<li>Undecided: Hacker News. It’s not truly social media, but its social enough. I do find it far more valuable than many of the other social media products I use, especially for my work. For now I will restrict my HN usage to computer only.</li>
</ul>
<p>Here’s a handy metaphor:</p>
<p>Processed, sugar-filled “junk” food is bad, and for the most part we all know that, but some of us still like to bake and share cakes and tasty baked sweets with friends.
I will let myself bake as many cakes as I want, and consume handmade cakes from other people I know and care about, but I won’t be eating any prepackaged cake or sweets from the grocery store.</p>
<p>In this metaphor - I will allow myself to create content and share it online (making my cake), browse content on the small web (eat cake from friends), but I won’t waste any time scrolling the feeds (eating prepackaged garbage from the store).</p>
<p>I’m going to give this a go for a month and see how it goes.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="social-media" /><summary type="html"><![CDATA[Stop me if you’ve been there before.]]></summary></entry><entry><title type="html">2023 Year In Review</title><link href="https://chambers.io/blog/2023/12/31/2023-year-in-review.html" rel="alternate" type="text/html" title="2023 Year In Review" /><published>2023-12-31T00:00:00+00:00</published><updated>2023-12-31T00:00:00+00:00</updated><id>https://chambers.io/blog/2023/12/31/2023-year-in-review</id><content type="html" xml:base="https://chambers.io/blog/2023/12/31/2023-year-in-review.html"><![CDATA[<p>It’s 10:38 AM.
I’m sitting at the kitchen table and the house is a warzone of opened presents and to-be-put-away special dishware and decorations from Christmas.
I’ve got three loaves of sourdough that are halfway finished fermenting.
One child is running around the house with a candy cane and sticky hands (my nightmare).
But the youngest is napping so it’s going to be now or never.
I’ve tried to sit down and write this blog post for a week straight now, but life is just a wee bit busy these days.</p>
<h2 id="recap">2023 Recap</h2>
<p>So How did 2023 go? Let’s do a quick recap of my resolutions and goals I set in December of 2022.</p>
<h3 id="resolution">Resolution</h3>
<blockquote>
<p>Consume less, create more.</p>
</blockquote>
<p>This was a mixed bag.</p>
<p>My main goal in “consuming less” was to spend less time scrolling/swiping on Instagram, Twitter, etc.
I went through phases where I did well with this (eg when I uninstalled them from my phone), but ultimately would fall back into old patterns.
Maybe I need to permanently remove these apps from my phone and force myself to use less convenient methods.</p>
<p>Create more: I hoped to have a finished app/project launched but I did not achieve this goal.
I did spent a lot of time making sourdough bread, and I am happy with that.
I did do more writing this year than last year, and I am proud of that as well.</p>
<h3 id="goals">Goals</h3>
<ul>
<li>Run 500 miles
<ul>
<li>According to Strava I ran 455 miles this year.
I was on track to pass 500 but a wicked bout of back-to-back sicknesses in December destroyed that reality.
Sometimes, that’s what life with kids gets you.
Still very proud of the running I did this year, and I even set a “modern” (eg post-Dad life) personal best for a 10K race, finishing in under 50 minutes.</li>
</ul>
</li>
<li>Read 5 books
<ul>
<li>I finished 3, and am about 75% of the way through a fourth (Alexander Hamilton). Not great, not bad.</li>
</ul>
</li>
<li>Complete 3 video games
<ul>
<li>I only truly “finished” one game, but have really enjoyed playing several this year (namely <em>The Legend of Zelda - Tears of the Kingdom</em> and <em>Dave the Diver</em>.)</li>
</ul>
</li>
<li>Write 5 Blog Posts
<ul>
<li>This is number 5/5!</li>
</ul>
</li>
</ul>
<h3 id="highlights">Highlights</h3>
<ul>
<li><strong>The true highlight of the year, our second chld - Emma Ann - was born in April!</strong>
She’s a wonderfully happy and healthy baby and we could not ask for anything more.</li>
<li><strong>I attented KubeCon 2023 in Chicago.</strong>
This was my first post-COVID conference and to say I was excited is an understatement.
I had a fantastic time attending with some of my co-workers, learned a lot, and caught up with some colleagues across the industry.</li>
<li><strong>Paid off the last of my student loans.</strong>
This one stings a bit because, as a Pell grant recipient in college, I was eligible for $20,000 in loan forgiveness under Biden’s plan that was ultimately canceled by the Supreme Court.
That’s $20,000 that would have been nice to use on improving the house or putting into college funds for our kids.
Oh well!
Happy to have this weight off of my shoulders finally gone.</li>
<li><strong>I got my open water scuba diving cerification!</strong>
This was a lifelong goal that I just never got around to doing.
I was able to find some time to do it while on paternity leave this summer.
We have an upcoming Cruise planned in 2024 with some diving opportunities in Cozumel, and I really wanted to be able to dive with that trip.
With the rate the oceans are changing, there’s really no knowing how much time there is left to see the amazing ocean reefs of the world.
If this is something that interests you, go out and do it <em>now</em>.</li>
<li><strong>I lost about 35 pounds.</strong>
I have a complicated history with my weight and health.
Turns out I’m very good at losing weight, but bad at keeping it off.
I’ve gone through 3-4 cycles of losing (and slowly re-gaining) not insignificant amounts of weight.
Outside of my weight, I’m actually quite healthy.
Vitals are all good, I run and excercise frequently.
But I have family history of both heart conditions and diabetes - and now that I have two young kids this is omething I feel like I need to address permanently.</li>
</ul>
<h3 id="what-challenged-me">What Challenged Me</h3>
<p>I struggled at times finding a balance between being a Dad, taking care of responsibilities around the house, and getting a full day of work in.
Working from home 3-4 days a week both helps and hurts this!
It means less time spent commuting, which saves about an hour each day.
But it also means that its easier to get distracted by things around the house that need to get done, or more often, kids getting home from daycare and me feeling guilty for not immediately coming out of my office to play with them.</p>
<p>One of my major goals for 2024 is to be more intentional with my time.
I need to make sure I am not wasting time during the day so that when my kids get home I can go play with them without leaving work unfinished.
This also means fewer late nights getting stuff done (another con of having work available in the other room is its easy to “go finish something quick” and wind up working until well after bedtime).</p>
<h2 id="looking-forward-to-2024">Looking Forward to 2024</h2>
<h3 id="goals-for-2024">Goals for 2024</h3>
<p>This year I decided to split my goals into four categories:</p>
<h4 id="personal">Personal</h4>
<ul>
<li>Finish the Chicago Marathon in under four hours.</li>
<li>Read six books.</li>
<li>Launch at least one side project as an app/service for sale.</li>
<li>Maintain a weight under 180lb.</li>
</ul>
<h4 id="family">Family</h4>
<ul>
<li>Travel and enjoy new experiences with the kids (we already have two vacations booked!)</li>
<li>Don’t be afraid to eat out at restaurants with the kids.
<ul>
<li>If there was one thing that we did way too much of in 2023, it was carryout food.</li>
</ul>
</li>
</ul>
<h4 id="financial">Financial</h4>
<ul>
<li>Pick a date and dollar amount for retirement.
Re-evaluate current retirement investments and formulate new plan based on set date.</li>
<li>Eliminate/rotate through streaming and entertainment services.
<ul>
<li>There’s simply no need to subscribe to 6+ streaming services at the same time.
There’s not enough time to watch a fraction of the content available.
Costs have gotten out of control.</li>
</ul>
</li>
</ul>
<h4 id="career">Career</h4>
<ul>
<li>Achieve or be on track (eg feel confident it will happen in 2025) for promotion to Staff Software Engineer.</li>
<li>Submit a proposal to speak at a tech conference.</li>
</ul>
<h3 id="what-i-want-to-avoid-in-2024">What I Want to Avoid in 2024</h3>
<ul>
<li>Less “mindless” screen time (Instagram/Twitter/Hacker News scrolling mainly).</li>
<li>Less fast food.</li>
<li>Avoid letting clutter acumulate.
<ul>
<li>If it takes less than 5 minutes to finish/clean/put away, just do it right away.</li>
</ul>
</li>
</ul>
<h3 id="resolution-1">2024 Resolution</h3>
<ul>
<li>Be more intentional with my time!</li>
</ul>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="year-in-review" /><summary type="html"><![CDATA[It’s 10:38 AM. I’m sitting at the kitchen table and the house is a warzone of opened presents and to-be-put-away special dishware and decorations from Christmas. I’ve got three loaves of sourdough that are halfway finished fermenting. One child is running around the house with a candy cane and sticky hands (my nightmare). But the youngest is napping so it’s going to be now or never. I’ve tried to sit down and write this blog post for a week straight now, but life is just a wee bit busy these days.]]></summary></entry><entry><title type="html">Fighter Jets Can’t Go To Space</title><link href="https://chambers.io/blog/2023/11/14/fighter-jets-cant-go-to-space.html" rel="alternate" type="text/html" title="Fighter Jets Can’t Go To Space" /><published>2023-11-14T00:00:00+00:00</published><updated>2023-11-20T00:00:00+00:00</updated><id>https://chambers.io/blog/2023/11/14/fighter-jets-cant-go-to-space</id><content type="html" xml:base="https://chambers.io/blog/2023/11/14/fighter-jets-cant-go-to-space.html"><![CDATA[<p>Fighter jets are a technological marvel. Capable of traveling at several times the speed of sound and flying miles above the surface of the earth. From our spot on the ground, it’s easy to look up and blown away by the power and speed on display and think ‘Wow, that thing is unstoppable.’</p>
<p>But no matter how much you upgrade it, no matter what you do to make it faster and more powerful, that fighter jet is never going to reach escape velocity and travel to space. It is impossible. Fighter jets need oxygen to burn fuel and they need air under their wings to provide lift. Neither of those exist in or near the edge of space. We can keep pushing that fighter jet higher and faster but eventually it’s going to reach the limit of it’s technological capabilities, well before it’s on the way to Mars. It’s fundamentally not the right tool for the job.</p>
<p>LLMs are that fighter jet, and space travel is AGI (Artificial General Intelligence). You can make them more powerful and faster, capable of “remembering” information in larger contexts, but fundamentally the technology is never going to be more than a LLM. As time goes on and we put more power into them, each improvement will get smaller and smaller until we hit that limit where they can go no further. It has been proven that LLMs are incredible tools and we absolutely should be making use of the technology to better our lives and be more productive.</p>
<p>But if our goal is to go to space, fighter jets aren’t going to get us there.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="AI" /><category term="OpenAI" /><category term="AGI" /><category term="LLMs" /><summary type="html"><![CDATA[Fighter jets are a technological marvel. Capable of traveling at several times the speed of sound and flying miles above the surface of the earth. From our spot on the ground, it’s easy to look up and blown away by the power and speed on display and think ‘Wow, that thing is unstoppable.’]]></summary></entry><entry><title type="html">Back to Forums</title><link href="https://chambers.io/blog/2023/06/11/back-to-forums.html" rel="alternate" type="text/html" title="Back to Forums" /><published>2023-06-11T00:00:00+00:00</published><updated>2023-06-11T00:00:00+00:00</updated><id>https://chambers.io/blog/2023/06/11/back-to-forums</id><content type="html" xml:base="https://chambers.io/blog/2023/06/11/back-to-forums.html"><![CDATA[<p>In case you’ve been living under a rock the past couple of weeks, <a href="https://www.theverge.com/2023/6/10/23756476/reddit-protest-api-changes-apollo-third-party-apps">people are kind of mad at Reddit</a>.</p>
<p>This all started because Reddit decided to start charging for its data API, which has been free until this point.
This comes just a couple of months after Twitter, under new leadership, made a similar decision which made its data API prohibitively expensive, effectively killing third-party apps and tools for interacting with Twitter data.
The reddit API price increase also effectively <a href="https://www.reddit.com/r/apolloapp/comments/144f6xm/apollo_will_close_down_on_june_30th_reddits/">kills third party applications</a> such as Apollo, Reddit Sync, Reddit is Fun, and more.</p>
<p>After <a href="https://www.reddit.com/r/reddit/comments/145bram/addressing_the_community_about_changes_to_our_api/">a disastrous AMA</a> from current reddit CEO Steve Huffman, many subreddits are going dark indefinitely until Reddit agrees to backtrack or re-evaluate the changes they are making.</p>
<p>Reddit has problems for sure, but despite that it is home to some of the most interesting and niche communities on the modern web.
I have discovered so many cool hobbies and fun things thanks to reddit.
I am proud that moderators and users are standing together with these developers in order to push for change, but a bit of me is sad that these communities may whither and die - or maybe even worse, hide behind closed doors such as Discord.
In some cases, users are already using scripts to “shred” their reddit comment and post history, tearing holes in the knowledge graphs that make up these small communities.
Enough holes and those communities lose real value.</p>
<p>I don’t use reddit for the “default” subs or many very large one.
Some of my favorites and most-visited are small subreddits with a small but vibrant community.
It won’t matter in the slightest to me if something like <code>r/funny</code> or <code>r/pics</code> dies.
Those are largely a waste of time (albeit a fun waste of time for many).
The small subs are the ones I worry about the most.
Moving a community like that is very challenging, if not impossible.</p>
<p>There’s something to be asked about the relationships between these web companies, the data the have, and the users.
In the case of reddit and twitter, the content is all user generated.
Who really owns this data?</p>
<p>I believe it is within Reddit’s right to charge for accessing and using that data.
Storage, bandwidth, electricity, and engineering hours aren’t free.
But I also think that Reddit (and other social media companies) should do everything they can to make that data reasonably available.
Getting rid of third party applications and tools tends to disproportionately affect the users that provide the most value to your site.
Maybe not the value that advertisers recognize, but the value in actually creating content that makes a site worth visiting.</p>
<p>Anyway, I think I’m going to poke around some forums again.
I never truly gave up on forums when I started using Reddit in 2010, but I certainly stopped visting most of them over time.
I wonder if many…any…of them are still alive.
And I wonder if there are new ones out there that I have missed over the last few years.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="reddit" /><category term="forums" /><category term="web" /><category term="web culture" /><summary type="html"><![CDATA[In case you’ve been living under a rock the past couple of weeks, people are kind of mad at Reddit.]]></summary></entry><entry><title type="html">AI Pessimism</title><link href="https://chambers.io/blog/2023/03/20/ai-pessimism.html" rel="alternate" type="text/html" title="AI Pessimism" /><published>2023-03-20T00:00:00+00:00</published><updated>2023-03-20T00:00:00+00:00</updated><id>https://chambers.io/blog/2023/03/20/ai-pessimism</id><content type="html" xml:base="https://chambers.io/blog/2023/03/20/ai-pessimism.html"><![CDATA[<p>There has been a lot written about AI lately.
Particularly large language models such as OpenAI’s ChatGPT and GPT-4.
Yet despite my best efforts, I find myself in a constant state of pessimism about LLMs and generative AIs and what they mean for humanity.</p>
<p>This past weekend on Twitter I came across one post stating “people once had to be convinced of the usefulness of electricity, too” and I can’t help but think just how poorly that translates to today’s situation with the looming AI takeover of many (most?) knowledge worker jobs.
When electricity was introduced, whose jobs were immediately threatened?
Lamplighters…and…well, that’s about it I guess.</p>
<p>And how many new types of jobs were possible because of electricity?
Thousands.
Millions.
Countless.</p>
<p>In stark contrast, so much of the online conversation about AI has been focused on who will lose their jobs.
What careers are basically dead.
Photography, illustration, copywriting, screenwriting, customer service, accounting, teaching, programming.
The list goes on and on - even the role of CEO isn’t safe (see: <a href="https://twitter.com/jacksonfall/status/1636107218859745286?s=20">HustleGPT</a>).
The two themes I see online are that 1) companies will save so much money by not having to hire people to write things or draw things any more and 2) people that did these things are all S.O.L.</p>
<p>I can’t imagine that the salesmen of early electrical companies in the world focused on just how many people would lose their jobs as they pushed the technology onto people.
So my question is, when will we start learning what new jobs and opportunities AI will unlock for us?
Why am I having such a hard time seeing a bright future?</p>
<p>It’s obvious that AI can be an incredibly useful tool that is going to remove a lot of menial work.
But I cannot help but be scared that most companies, with short sighted visions that seek to only make shareholders happy from one financial quarter to the next, will simply rejoice at this cost cutting opportunity without truly realizing the potential of what lies before us.</p>
<p>I know there has to be a wave of new opportunities emerging for us knowledge workers soon to be deemed too expensive to continue to employ.</p>
<p>When do these new opportunities become apparent?
The valley of despair is deep and dark, and I miss seeing the light of opportunity.</p>
<hr />
<p>P.S. I asked ChatGPT about this topic after I had already written this blog post, and this is what it had to say.
Keep your friends close and your enemies closer, as they say.</p>
<pre><code>Who lost their jobs when electricity was popularized in the late 1800s?
</code></pre>
<blockquote>
<p>The widespread adoption of electricity in the late 1800s led to significant changes in the labor market, particularly in industries that were dependent on steam or water power.
Jobs that involved manual labor, such as stokers who fed fuel to steam engines, were some of the first to be affected.
Additionally, workers in the gas lighting industry, who had been employed to light streets and buildings with gas lamps, also saw their jobs disappear as electric lighting became more prevalent.</p>
<p>Other jobs that were affected by the adoption of electricity included factory workers who operated machinery powered by steam or water, as electric-powered machines replaced older ones.
However, it’s worth noting that while some jobs were lost, many new jobs were also created in industries related to electricity production, distribution, and maintenance.
Overall, the transition to electricity led to significant changes in the labor market, but it also paved the way for new technologies and industries that created new jobs and economic opportunities.</p>
</blockquote>
<pre><code>Who will lose their jobs because of AI?
</code></pre>
<blockquote>
<p>The impact of artificial intelligence (AI) on jobs is a complex and often debated topic, and there is no simple answer to who will lose their jobs because of AI.</p>
<p>While AI has the potential to automate many tasks and jobs that are currently done by humans, it also has the potential to create new jobs and industries.
In general, jobs that involve routine and repetitive tasks are more likely to be automated by AI, while jobs that require creativity, critical thinking, and human interaction are less likely to be affected.</p>
<p>Some examples of jobs that could be impacted by AI in the future include:</p>
<ul>
<li>Jobs in manufacturing, where robots and automated systems can perform repetitive tasks more efficiently and accurately than humans.</li>
<li>Jobs in transportation, where autonomous vehicles and drones could replace human drivers and pilots.</li>
<li>Jobs in customer service, where chatbots and other AI-powered systems could handle simple customer inquiries and support.</li>
<li>Jobs in finance and accounting, where AI can perform tasks such as data entry, fraud detection, and financial analysis.</li>
<li>Jobs in healthcare, where AI can assist with tasks such as medical diagnosis, drug discovery, and patient monitoring.</li>
</ul>
<p>However, it’s important to note that the impact of AI on jobs will depend on many factors, including the specific technologies developed, the pace of adoption, and the ability of workers to adapt to changing job requirements.
It’s also worth noting that while some jobs may be automated, new jobs and industries may emerge as a result of advances in AI and related technologies.</p>
</blockquote>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="technology" /><category term="AI" /><summary type="html"><![CDATA[There has been a lot written about AI lately. Particularly large language models such as OpenAI’s ChatGPT and GPT-4. Yet despite my best efforts, I find myself in a constant state of pessimism about LLMs and generative AIs and what they mean for humanity.]]></summary></entry><entry><title type="html">Enabling Comments</title><link href="https://chambers.io/blog/2023/03/20/comments.html" rel="alternate" type="text/html" title="Enabling Comments" /><published>2023-03-20T00:00:00+00:00</published><updated>2023-03-20T00:00:00+00:00</updated><id>https://chambers.io/blog/2023/03/20/comments</id><content type="html" xml:base="https://chambers.io/blog/2023/03/20/comments.html"><![CDATA[<p>Quick update - I have enabled comments for blog posts on <a href="https://chambers.io">chambers.io</a>.
Scroll to the bottom of the page to check it out!</p>
<p>Comments use the <a href="https://giscus.app/">giscus</a> commenting system.
The system uses GitHub Discussions as a database for comments.
Comments are then loaded by the page using the GitHub API.</p>
<p>It does require a github account to comment, but given that this blog is mostly technical that’s probably not a barrier for most people.
Don’t have an account yet? GitHub accounts are free and open to anyone, even if you don’t write code (yet!?).
Learn more at <a href="http://github.com/">github.com</a></p>
<p>Lastly, you can view all comment threads in the Discussion tab for this blog’s <a href="https://github.com/dcchambers/dcchambers.github.io/discussions/categories/blog-comments">github repo</a>.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><summary type="html"><![CDATA[Quick update - I have enabled comments for blog posts on chambers.io. Scroll to the bottom of the page to check it out!]]></summary></entry><entry><title type="html">2022 Year In Review</title><link href="https://chambers.io/blog/2022/12/31/2022-year-in-review.html" rel="alternate" type="text/html" title="2022 Year In Review" /><published>2022-12-31T00:00:00+00:00</published><updated>2022-12-31T00:00:00+00:00</updated><id>https://chambers.io/blog/2022/12/31/2022-year-in-review</id><content type="html" xml:base="https://chambers.io/blog/2022/12/31/2022-year-in-review.html"><![CDATA[<h2 id="highlights">Highlights</h2>
<ul>
<li>We bought a new house and moved!</li>
</ul>
<h2 id="resolutions">Resolutions</h2>
<ul>
<li>Conquer <a href="https://en.wikipedia.org/wiki/Fear_of_missing_out">FOMO</a>
<ul>
<li>Status: Mostly successful.</li>
</ul>
</li>
</ul>
<h2 id="goals">Goals</h2>
<p>There were my goals in 2022. How did I do?</p>
<ul>
<li>Run 500 miles.
<ul>
<li>Status: 👎 74.2/500</li>
</ul>
</li>
<li>Read 10 books.
<ul>
<li>Status: 🆗 5/10</li>
</ul>
</li>
<li>Write 10 blog posts.
<ul>
<li>Status: 👎 1/10</li>
</ul>
</li>
<li>Complete 3 video games.
<ul>
<li>Status: ❓ I played a lot but didn’t play many single-player/campaign focused games.</li>
</ul>
</li>
<li>Launch (1) self-sustaining project/website/app.<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>
<ul>
<li>Status: 🟡 In progress, but still in “stealth” mode/not launched publicly.</li>
</ul>
</li>
</ul>
<h2 id="books-i-read">Books I Read</h2>
<ul>
<li>The Nightingale - Kristin Hannah</li>
<li>The Lean Startup - Eric Ries</li>
<li>Digital Minimalism - Cal Newport</li>
<li>The Lord of the Rings: The Fellowship of the Ring - J.R.R. Tolkien</li>
<li>Tartine Bread - Chad Robertson<sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup></li>
</ul>
<h2 id="fitness">Fitness</h2>
<p>I biked and walked quite a bit in 2022, but I only ran 74 miles - well short of my 500 mile goal.</p>
<section class="footnotes">
<ol>
<li id="fn1">
<p>Generate enough revenue to offset costs. <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
<li id="fn2">
<p>I have been used his excellent sourdough process/recipes for a while but I finally read through the entire book. <a href="#fnref2" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="year-in-review" /><summary type="html"><![CDATA[Highlights]]></summary></entry><entry><title type="html">Heroku: Worth Reading About</title><link href="https://chambers.io/blog/2022/05/15/heroku.html" rel="alternate" type="text/html" title="Heroku: Worth Reading About" /><published>2022-05-15T00:00:00+00:00</published><updated>2022-05-18T00:00:00+00:00</updated><id>https://chambers.io/blog/2022/05/15/heroku</id><content type="html" xml:base="https://chambers.io/blog/2022/05/15/heroku.html"><![CDATA[<p>If you are not familiar with Heroku, it’s a platform-as-a-service for deploying and running software applications. That sounds so simple, but Heroku was actually one of the first companies to do it, and do it well. Heroku started as a humble tool for building, deploying, and running ruby-on-rails websites, but grew to be so much more. At a time when most people were still deploying their applications by manually copying updated files to a remote server using scp/ftp, Heroku kicked off a generational leap in deployment capabilities for many developers and companies around the world.</p>
<p>For years, Heroku was <em>the</em> industry-standard. The perfect balance between ease-of-use and power for deploying and serving web applications. Their developer experience was (is) second-to-none, and to this day there are many new platforms that claim to be the “Heroku for X.”</p>
<p>Recently, Heroku has been in the news because of a security incident which has prevented a major part of their tool from working for a month now.<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup></p>
<p>This isn’t a blog post about the demise of Heroku. I still envy the company and think their core product is basically flawless (if a bit expensive). Professionally, I work on deployment and development tools. I love what they’ve done and always strive to achieve that balance of power and simple elagance in my own work.</p>
<p>There’s been a lot of very interesting stories, twitter threads, and blog posts written about Heroku lately due to this incident and the perceived fall-from-grace the product has had over the last few years. Many of these words come from past and current Heroku employees, some of whom I believe are some of the smartest engineers in the industry. This is a collection of those stories. Stories worth reading.</p>
<ul>
<li><a href="https://brandur.org/nanoglyphs/033-heroku">Heroku: Core Impact (brandur.org)</a>
<ul>
<li><a href="https://news.ycombinator.com/item?id=31391272">Discussion on Hacker News</a></li>
</ul>
</li>
<li><a href="https://christine.website/blog/heroku-devex-2022-05-12">I Miss Heroku’s DevEx (christine.website)</a>
<ul>
<li><a href="https://news.ycombinator.com/item?id=31348529">Discussion on Hacker News</a></li>
</ul>
</li>
<li><a href="https://christine.website/blog/fly.io-heroku-replacement">Fly.io: the Reclaimer of Heroku’s Magic (christine.website)</a>
<ul>
<li><a href="https://news.ycombinator.com/item?id=31390506">Discussion on Hacker News</a></li>
</ul>
</li>
<li><a href="https://matt-rickard.com/why-did-heroku-fail/">Why Did Heroku Fail? (matt-rickard.com)</a><sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup>
<ul>
<li><a href="https://news.ycombinator.com/item?id=31372675">Discussion on Hacker News</a></li>
</ul>
</li>
<li><a href="https://news.ycombinator.com/item?id=31313779">Ask HN: Is Heroku Being Sunset? (Hacker News)</a></li>
<li><a href="https://twitter.com/yongfook/status/1519275363032961024">Any Heroku Alternatives? (Jon Yongfook - Twitter)</a></li>
<li><a href="https://amyunger.com/blog/2020/09/10/staff-engineer-at-heroku.html">How I operated as a Staff engineer at Heroku (amyunger.com)</a><sup class="footnote-ref"><a href="#fn3" id="fnref3">3</a></sup></li>
</ul>
<p><em>Added 18 May 2022</em>:</p>
<ul>
<li><a href="https://www.craigkerstiens.com/2022/05/18/unfinished-business-with-postgres/">Unfinished Business with Postgres (craigkerstiens.com)</a><sup class="footnote-ref"><a href="#fn4" id="fnref4">4</a></sup></li>
</ul>
<section class="footnotes">
<ol>
<li id="fn1">
<p><a href="https://status.heroku.com/incidents/2413">https://status.heroku.com/incidents/2413</a> <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
<li id="fn2">
<p>Warning: Clickbait title <a href="#fnref2" class="footnote-backref">↩</a></p>
</li>
<li id="fn3">
<p>This post is from 2020 and predates the current incident, but it’s still a great read. <a href="#fnref3" class="footnote-backref">↩</a></p>
</li>
<li id="fn4">
<p>Technically a blog post about Postgres, but contains tons of good details about early database work at Heroku. <a href="#fnref4" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="technology" /><category term="devops" /><category term="heroku" /><summary type="html"><![CDATA[If you are not familiar with Heroku, it’s a platform-as-a-service for deploying and running software applications. That sounds so simple, but Heroku was actually one of the first companies to do it, and do it well. Heroku started as a humble tool for building, deploying, and running ruby-on-rails websites, but grew to be so much more. At a time when most people were still deploying their applications by manually copying updated files to a remote server using scp/ftp, Heroku kicked off a generational leap in deployment capabilities for many developers and companies around the world.]]></summary></entry><entry><title type="html">2021 Year In Review</title><link href="https://chambers.io/blog/2021/12/31/2021-year-in-review.html" rel="alternate" type="text/html" title="2021 Year In Review" /><published>2021-12-31T00:00:00+00:00</published><updated>2021-12-31T00:00:00+00:00</updated><id>https://chambers.io/blog/2021/12/31/2021-year-in-review</id><content type="html" xml:base="https://chambers.io/blog/2021/12/31/2021-year-in-review.html"><![CDATA[<h2 id="highlights">Highlights</h2>
<ul>
<li>We had a baby! Oliver Avery Chambers was born on February 17, 2021.</li>
<li>I got promoted to Senior Software Engineer!</li>
</ul>
<h2 id="book-books-i-read">:book: Books I Read</h2>
<ol>
<li><a href="https://www.goodreads.com/book/show/54493401-project-hail-mary">Project Hail Mary - Andy Weir</a></li>
<li><a href="https://www.goodreads.com/book/show/34912895-the-great-alone">The Great Alone - Kristin Hannah</a></li>
<li><a href="https://www.goodreads.com/book/show/10396652-a-storm-of-swords">A Storm of Swords - George R. R. Martin</a></li>
<li><a href="https://www.goodreads.com/book/show/38814138-one-flew-over-the-cuckoo-s-nest">One Flew Over the Cuckoo’s Nest - Ken Kesey</a></li>
<li><a href="https://www.goodreads.com/book/show/13414492-flour-water-salt-yeast">Flour Water Salt Yeast - Ken Forkish</a><sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup></li>
<li><a href="https://www.goodreads.com/book/show/44767458-dune">Dune - Frank Herbert</a></li>
<li><a href="https://www.goodreads.com/book/show/1898.Into_Thin_Air">Into Thin Air - Jon Krakaur</a></li>
</ol>
<h2 id="videogame-games-i-played">:video_game: Games I played</h2>
<ul>
<li>Super Mario 3D World (Switch)</li>
<li>Monster Hunter Rise (Switch)</li>
<li>The Legend of Zelda: Breath of the Wild (Switch)<sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup></li>
</ul>
<h2 id="fitness">Fitness</h2>
<p>Mileage was down quite a bit from 2020. I was dealing with some leg/knee injuries, and a newborn makes running a bit harder (lack of time and, mostly, lack of energy).</p>
<p>According to <a href="https://www.strava.com/athletes/30402150">Strava</a> I ran 295 miles and biked 224 miles in 2021. Excludes some indoor cycling.</p>
<!-- refs -->
<section class="footnotes">
<ol>
<li id="fn1">
<p>I’ve actually used the recipes in this for a while, but I finally read the whole thing. <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
<li id="fn2">
<p>Finally finished this game, years later. Definitely an all-time favorite! <a href="#fnref2" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="year-in-review" /><summary type="html"><![CDATA[Highlights]]></summary></entry><entry><title type="html">2020 Year In Review</title><link href="https://chambers.io/blog/2020/12/31/2020-year-in-review.html" rel="alternate" type="text/html" title="2020 Year In Review" /><published>2020-12-31T00:00:00+00:00</published><updated>2020-12-31T00:00:00+00:00</updated><id>https://chambers.io/blog/2020/12/31/2020-year-in-review</id><content type="html" xml:base="https://chambers.io/blog/2020/12/31/2020-year-in-review.html"><![CDATA[<h2 id="book-books-i-read">:book: Books I Read</h2>
<ol>
<li><a href="https://www.goodreads.com/book/show/8664353-unbroken">Unbroken - Laura Hillenbrand</a></li>
<li><a href="https://www.goodreads.com/book/show/653135.The_Secret_History">The Secret History - Donna Tartt</a></li>
<li><a href="https://www.goodreads.com/book/show/22826126-seveneves">Seveneves - Neal Stephenson</a></li>
<li><a href="https://www.goodreads.com/book/show/35133922-educated">Educated - Tara Westover</a></li>
<li><a href="https://www.goodreads.com/book/show/70535.2001">2001: A Space Odyssey - Arthur C. Clarke</a></li>
<li><a href="https://www.goodreads.com/book/show/34217486-murder-on-the-orient-express">Murder on the Orient Express - Agatha Christie</a></li>
<li><a href="https://www.goodreads.com/book/show/37976541-bad-blood">Bad Blood: Secrets and Lies in a Silicon Valley Startup - John Carreuyrou</a></li>
<li><a href="https://www.goodreads.com/book/show/3758.Casino_Royale">Casino Royale - Ian Fleming</a></li>
<li><a href="https://www.goodreads.com/book/show/36809135-where-the-crawdads-sing">Where the Crawdads Sing - Delia Owens</a></li>
</ol>
<p>Started, but not finished:</p>
<ul>
<li><a href="https://www.goodreads.com/book/show/10396652-a-storm-of-swords">A Storm of Swords (A Song of Ice and Fire #3) - George R. R. Martin</a></li>
<li><a href="https://www.goodreads.com/book/show/34013922-kubernetes-in-action">Kubernetes in Action - Marko Luksa</a></li>
</ul>
<p><a href="https://www.goodreads.com/review/list/44353038-dakota-chambers?shelf=2020-reading-list">See my complete 2020 reading list (Goodreads)</a> or check out my personal <a href="/library">library</a>.</p>
<h2 id="videogame-games-i-played">:video_game: Games I played</h2>
<p>A selection of games I enjoyed throughout the year.</p>
<ul>
<li>Fall Guys (PC)</li>
<li>Animal Crossing: New Horizons (Switch)</li>
<li>The Witcher (PC)</li>
<li>Luigi’s Mansion 3 (Switch)</li>
<li>Stardew Valley (Switch &amp; PC)</li>
<li>Paper Mario: The Origami King (Switch)</li>
<li>Xenoblade Chronicles: Definitive Edition (Switch)</li>
</ul>
<h2 id="fitness">Fitness</h2>
<h3 id="running-running">:running: Running</h3>
<p>By my calculation, I ran 704 miles in 2020.</p>
<ul>
<li>January: ??? Miles</li>
<li>February: 18.5 Miles</li>
<li>March: 24.1 Miles</li>
<li>April: 55.1 Miles</li>
<li>May: 68.1 Miles</li>
<li>June: 64.9 Miles</li>
<li>July: 79.7 Miles</li>
<li>August: 94.6 Miles</li>
<li>September: 101.7 Miles</li>
<li>October: 71.8 Miles</li>
<li>November: 47.9 Miles</li>
<li>December: 77.9 Miles</li>
</ul>
<p>See <a href="https://www.strava.com/athletes/30402150">Strava</a> for more details.</p>
<h3 id="bike-biking">:bike: Biking</h3>
<p>According to <a href="https://www.strava.com/athletes/30402150">Strava</a> I biked 773 miles in 2020.</p>
<h2 id="scorecard">Scorecard</h2>
<table>
<thead>
<tr>
<th>Books Read</th>
<th>Games Beaten</th>
<th>Miles Run</th>
<th>Bones Broken</th>
</tr>
</thead>
<tbody>
<tr>
<td>9/25</td>
<td>0/10</td>
<td>:star: 704/500</td>
<td>:star: 0/0</td>
</tr>
</tbody>
</table>
<!-- References/Links -->
<!-- books -->
<!-- fitness -->]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="year-in-review" /><summary type="html"><![CDATA[:book: Books I Read]]></summary></entry><entry><title type="html">vb4c - The Road to 1.0</title><link href="https://chambers.io/blog/2020/04/15/vb4c.html" rel="alternate" type="text/html" title="vb4c - The Road to 1.0" /><published>2020-04-15T00:00:00+00:00</published><updated>2020-04-15T00:00:00+00:00</updated><id>https://chambers.io/blog/2020/04/15/vb4c</id><content type="html" xml:base="https://chambers.io/blog/2020/04/15/vb4c.html"><![CDATA[<p>Introducing vb4c - Vim Bindings for Chrome!</p>
<p><img src="/assets/images/vb4c-promo-title.png" alt="" /></p>
<hr />
<p>This is a blog post that I have needed to write for a couple of months now but
a certain <a href="https://www.cdc.gov/coronavirus/2019-ncov/index.html">global health
situation</a>
distracted me. But I’m settling into a life of self-isolation and am ready to
get back to working on this.</p>
<h3 id="tldr">TL;DR</h3>
<p><a href="https://github.com/dcchambers/vb4c">vb4c</a> is a fork of the popular but sadly
abandoned Chrome extension, cVim. cVim brings vim-like bindings to chrome. It
work(ed) really well, but recent changes to chrome broke some core
functionality. A replacement was needed, so I decided to create a fork.</p>
<h3 id="the-road-to-10">The Road to 1.0</h3>
<p><strong>vb4c</strong> needs a lot of work. The codebase is pretty old. In case you aren’t
aware, the javascript world moves along pretty quickly. Most of the code is
4+ years old. Or about 15 javascript years.</p>
<p>All jokes aside, I need to finish a deep-dive into the code base in order to
fully understand how this extension works. The chrome architecture is new to
me. I have worked with javascript quite a bit but I am <em>not</em> a JS developer, so
many of the intricacies are lost on me.</p>
<p>I do not imagine v1.0 will be a major re-write, but we will see what happens as
I continue to learn how the extension functions.</p>
<h4 id="how-were-getting-there">How We’re Getting There</h4>
<p>I have created a <a href="https://github.com/dcchambers/vb4c/projects/1">project
board</a> in the GitHub repo. I
am going to need help with this, so I want to do all the work in the open.</p>
<h4 id="critical-bug-fixes">Critical Bug Fixes</h4>
<p>I have already merged in a few changes to fix bugs that broke core
functionality. Now that those changes are done, the extension is fully
useable again and can be manually installed. With that complete my next task is
to get this extension approved and listed on the chrome web store for simple
one-click installation.</p>
<h4 id="chrome-web-store">Chrome Web Store</h4>
<p>After merging the changes I quickly listed the extension for distribution in
the Chrome web store and was rejected. I am working to rectify the issues Google
had with the extension.</p>
<p>The reason for denial was requesting too many user permissions. I did not
request any more than the original extension, cVim, but I may have done a bad
job justifying why this extension needs those permissions. I am currently
working to better understand what the extension does with every permission it
requests.</p>
<h4 id="goals-of-10-release">Goals of 1.0 Release</h4>
<ul>
<li>Fix critical, feature-breaking bugs.</li>
<li>Get the extension approved and listed in the Chrome web store.</li>
<li>Understand and document the code.</li>
<li>Add CI tests.</li>
<li>Make it easy for other to contribute to the code base.</li>
<li>Improve logo/branding.</li>
</ul>
<h3 id="faq">FAQ</h3>
<p>Q: Why was a fork needed?
A: See above.</p>
<p>Q: Why not use a well-maintained and feature-complete extension like Surfing Keys?
A: You certainly can! I liked the way cVim worked and wanted to keep using it,
but with the major bugs fixed.</p>
<p>Q: But you’re not a javascript developer!
A: I’m not! And I will need help maintaining this. If you are a JS dev and want
to contribute to a cool open source project, please reach out to me.</p>
<p>Q: Why would you want to bring vim-like keyboard bindings to chrome? I thought
the mouse was the future?
A: Get off my lawn! Just kidding. Serious answer: you can be more productive if
you never take your hands off the keyboard. Also it makes you feel like a 1337
hacker.</p>
<p>Q: OK you’ve convinced me, how do I get vb4c?
A: I am working on getting this into the chrome web store. You can install it
manually following <a href="https://github.com/dcchambers/vb4c#install">these
instructions</a>.</p>
<p>Q: How can I contribute?
A: Check out the <a href="https://github.com/dcchambers/vb4c">repo</a>, fork it, open a
PR, or reach out to me directly.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="vb4c" /><category term="technology" /><summary type="html"><![CDATA[Introducing vb4c - Vim Bindings for Chrome!]]></summary></entry><entry><title type="html">2019 Year In Review</title><link href="https://chambers.io/blog/2019/12/31/2019-year-in-review.html" rel="alternate" type="text/html" title="2019 Year In Review" /><published>2019-12-31T00:00:00+00:00</published><updated>2019-12-31T00:00:00+00:00</updated><id>https://chambers.io/blog/2019/12/31/2019-year-in-review</id><content type="html" xml:base="https://chambers.io/blog/2019/12/31/2019-year-in-review.html"><![CDATA[<h2 id="highlights">Highlights</h2>
<ul>
<li>I broke my leg :frowning:</li>
<li>I started a new job at <a href="https://zendesk.com">Zendesk</a>! :tada:</li>
</ul>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="year-in-review" /><summary type="html"><![CDATA[Highlights]]></summary></entry><entry><title type="html">New Adventures Ahead</title><link href="https://chambers.io/blog/2019/08/11/zendesk.html" rel="alternate" type="text/html" title="New Adventures Ahead" /><published>2019-08-11T00:00:00+00:00</published><updated>2019-08-11T00:00:00+00:00</updated><id>https://chambers.io/blog/2019/08/11/zendesk</id><content type="html" xml:base="https://chambers.io/blog/2019/08/11/zendesk.html"><![CDATA[<p>I’m joining <a href="https://www.zendesk.com/">Zendesk</a>!</p>
<p>Quick update with some exciting news. I am joining Zendesk as a software engineer on the Engineering Productivity team right here in beautiful Madison, WI.</p>
<p>So what does that mean? I could post the job description but that’s boring. I am sure I will write lots about my experience over the next few weeks/months/years, but essentially I will be working with a team that supports the entire engineering staff at Zendesk. We create internal tools that are used by the entire staff to create amazing software that helps make Zendesk so great.</p>
<p>This is a pretty big change from my current role, but I am thrilled for the opportunity and the challenges that await.</p>
<p>Look forward to more updates soon!</p>
<p><em>(P.S. you can subscribe for email updates!)</em></p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="zendesk" /><category term="work" /><summary type="html"><![CDATA[I’m joining Zendesk!]]></summary></entry><entry><title type="html">Email</title><link href="https://chambers.io/blog/2019/06/15/email.html" rel="alternate" type="text/html" title="Email" /><published>2019-06-15T00:00:00+00:00</published><updated>2019-06-15T00:00:00+00:00</updated><id>https://chambers.io/blog/2019/06/15/email</id><content type="html" xml:base="https://chambers.io/blog/2019/06/15/email.html"><![CDATA[<p>We use it for everything, and most of us have no control. It’s kind of insane.</p>
<p>Take a few seconds and think about all of the accounts you’ve got linked to your email account. Social Media, Messaging, Entertainment, Video Games, Credit Cards, Bills, Rent, Banking, Taxes. The list is endless for most. Email has ingrained itself in every part of our day-to-day lives. Most of us check our email inboxes regularly. Many of us get a vibrating notification in our pocket or on our wrist the second a message comes in. Despite the rise of a new generation of instant messaging clients like Slack, it is still the de-facto form of communicating with people professionally, and has long replaced 🐌 “snail-mail” for most things in our lives.</p>
<p>Let me stress that I don’t want to call out email as the enemy. Quite the contrary. I love email! The near-instant, but still asynchronous<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>, communication has permanently altered the way that professionals, friends, and family alike talk to each other around the world.</p>
<p>My fear is founded in the fact that most of us have email addresses that <em>we do not control</em>.</p>
<p>I’ve used the same primary email address, a Gmail address, for a little over 10 years. The thought of having to change it is horrifying. I cannot fathom the hours required to log into each service I use, each site I have an account on, and try to change my email address. Some simply won’t let you change a primary email address. Some make you call a customer service representative. For others, I have long since forgotten my password, and the only recourse is to have a temporary password sent…to my email account!</p>
<p>Most of us could lose access to our email account in an instant. Years of history - gone. Access to all of your important accounts becomes that much harder. Fear-mongering? Maybe. But you read the horror stories online all the time. Every email provider has <a href="https://www.businessinsider.com/deloitte-study-91-percent-agree-terms-of-service-without-reading-2017-11">a list of rules which you agreed to and probably didn’t read</a>. Violating any one of those rules could be cause for instant termination of your account with no recourse.</p>
<p>So, what do we do about it?</p>
<p>I don’t think there is a one-size-fits-all solution. In a best-case world, each of us would have our own email address at our own domain, and run our own email servers on hardware that we control. But that’s not in the least bit realistic. Services like Gmail, Outlook, Yahoo Mail, Proton Mail…whatever you use - they are amazing <em>because</em> they let us use the magic of email without having to manage all of the tricky bits. Email servers are complicated, and I say that as an engineer hacking on UNIX/Linux systems every day. I am glad we have the option to use these different email hosts. Yes, even <a href="https://status.cloud.google.com/incident/cloud-networking/19009_">Gmail has outages</a>. Yet they have an infrastructure that is far more robust than you or I could put together, and have an uptime far better than most of us can do on our own. That’s just the reality of keeping hardware running. Could you do better? Maybe, if you ran a resilient cluster of your own email servers, replicated across multiple cloud providers around the world, on top of your own hardware churning away in your garage. You would still be subject to the whims of global network issues that these massive cloud providers face.</p>
<p>I don’t have a proposal to fix the situation. I do have a proposal to help alleviate some of my concerns.</p>
<p>My proposal has three basic tiers:</p>
<ol>
<li>
<p>Easy difficulty: <strong>Export and keep local backups of email. Create a secondary email with another provider and add it to all the services that let you</strong>. First and foremost, this is to preserve your email history. It has an immense value that you should fight to protect. This is simple and anyone can do it. I won’t bother going into the details of how to save local backups of your email. <a href="https://www.google.com/search?q=save+local+copies+of+gmail&amp;oq=save+local+copies+of+gmail&amp;aqs=chrome..69i57j0.5354j0j7&amp;sourceid=chrome&amp;ie=UTF-8">Enough has been written on that already.</a> You might not even need to manually export data from your provider - just using an email client on your machine with IMAP may be enough. The second step is to create a secondary free email address with another provider, and add that as a backup to as many accounts and services as you can. You gain some peace-of-mind in case you do ever lose access to your primary account.</p>
</li>
<li>
<p>Medium difficulty: <strong>Set up your own email address with a free hosted provider such as Gmail</strong>. In this case, you will own your email address. For example, <code>dakota@somecoolwebsite.com</code> will be mine. Google can never take that from me. Many email providers, such as Gmail, will let you use a custom email address with their services. You are still subject to their terms and conditions, but if you ever lose access to your account their, you won’t actually lose access to your email. Again, I won’t go over the details of how to do this, but there are <a href="https://www.google.com/search?q=use+your+own+email+with+gmail&amp;oq=use+your+own+email+with+gmail&amp;aqs=chrome.0.0l4.2587j0j7&amp;sourceid=chrome&amp;ie=UTF-8">plenty of guides available</a>. If you followed step 1 and maintain local, offline backups of your email, then there isn’t really much risk of ever <em>losing</em> access to your email account or losing your history. There is a small cost required: the annual cost of owning a domain, but even those can be had very cheap. In my opinion, this offers the best of both worlds. You have more control over your email address, but you get the benefits of a cloud-hosted email provider.</p>
</li>
<li>
<p>Hard difficulty: <strong>Host your own email server</strong>. I don’t recommend this for most people. I’ve thought about it, and overall the effort doesn’t seem worth it to me. But for those of you that want to truly take control of your email, the only option is to host your own server. If you go this route, I would still recommend using a cloud provider for a VM. A simple VPS will be enough for most people, and there are many cheap options available. If you choose to run your server on your own local hardware, keep in mind the energy costs, the other (mental, physical) costs associated with keeping hardware running 24/7, and the networking details you’ll have to work out with your internet provider. There are some modern attempts at <a href="https://mailinabox.email/">all-in-one solutions</a> that I have never tried. Otherwise, Linode has <a href="https://www.linode.com/docs/email/running-a-mail-server/">a good guide</a> on running a mail server. It’s actually a great exercise in Linux system administration and networking, but it’s not something I would recommend unless you enjoy troubleshooting technical problems.</p>
</li>
</ol>
<p>Myself? I prefer option number 2. It has a small cost and a small degree of difficulty, but overall it’s the right choice for a balance of controlling your own email, and taking advantage of what email hosts can give you. Regardless of what you choose, keep in mind that you probably don’t have any control over your email, and that’s worth being concerned about.</p>
<p><strong>Want to say hi?</strong> I’d love to hear from you! Shoot me a message at <a href="mailto:hello@chambers.io">hello@chambers.io</a></p>
<section class="footnotes">
<ol>
<li id="fn1">
<p>It’s important to remember that Email, while virtually instant, is asynchronous in nature. It is non-blocking, and allows all members of an email correspondence to read and respond in an offline manor. This is an important distinction between email and instant messaging solutions. <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="technology" /><summary type="html"><![CDATA[We use it for everything, and most of us have no control. It’s kind of insane.]]></summary></entry><entry><title type="html">Linux &amp;amp; Unix Command Line Essentials</title><link href="https://chambers.io/blog/2019/03/02/command-line-essentials.html" rel="alternate" type="text/html" title="Linux &amp;amp; Unix Command Line Essentials" /><published>2019-03-02T00:00:00+00:00</published><updated>2019-03-02T00:00:00+00:00</updated><id>https://chambers.io/blog/2019/03/02/command-line-essentials</id><content type="html" xml:base="https://chambers.io/blog/2019/03/02/command-line-essentials.html"><![CDATA[<p>When I got my first SysAdmin job (as a Student with the <a href="http://chtc.cs.wisc.edu">Center for High Throughput Computing</a>)
my Linux/Unix knowledge was passable but not great. I started to keep a list of commands I regularly used for my own education
and technical improvement.</p>
<p>The list has grown considerably over the years. It is expressive but still succint. It is <em>not</em> an exhaustive list of
all Linux/Unix programs and commands one should know. I do think it’s a pretty good list of <strong>essential commands you should be aware of</strong>
if you want to work with Linux (as a System Administrator, Systems/DevOps Engineer, or Software Developer).</p>
<p>You do not have to know exactly how they work or know every <code>--flag</code>, but these are commands that will be very useful in maintaining
a Linux/Unix system.</p>
<p>I migrated the list to a <a href="https://gist.github.com/dcchambers/482bb55e0b20c55435a5c4658adde8c0">GitHub Gist</a> a while back and just
now made it public. Feel free to make a suggestion/contribution if you think it’s missing something.</p>
<p>Cheers!</p>
<p>Posted in full:</p>
&lt;script src="https://gist.github.com/dcchambers/482bb55e0b20c55435a5c4658adde8c0.js"></script>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="linux/unix" /><category term="command line" /><summary type="html"><![CDATA[When I got my first SysAdmin job (as a Student with the Center for High Throughput Computing) my Linux/Unix knowledge was passable but not great. I started to keep a list of commands I regularly used for my own education and technical improvement.]]></summary></entry><entry><title type="html">Rest Easy - You’re Now Browsing With HTTPS</title><link href="https://chambers.io/blog/2019/02/26/rest-easy-were-secure.html" rel="alternate" type="text/html" title="Rest Easy - You’re Now Browsing With HTTPS" /><published>2019-02-26T00:00:00+00:00</published><updated>2019-02-26T00:00:00+00:00</updated><id>https://chambers.io/blog/2019/02/26/rest-easy-were-secure</id><content type="html" xml:base="https://chambers.io/blog/2019/02/26/rest-easy-were-secure.html"><![CDATA[<p>As of today <code>chambers.io</code> is officially served up over <code>HTTPS</code>.</p>
<p><img src="/assets/images/chambers-io-https.png" alt="" /></p>
<p>If you’ve read any of my previous posts - you might know that this blog is created with
<a href="https://jekyllrb.com">Jekyll</a> and it’s hosted on <a href="https://pages.github.com">Github Pages</a>.</p>
<p>Before, <code>HTTPS</code> was possible with GitHub Pages but it was kind of a pain to set up (well, not really
a pain, it just took more time than I had to spare).</p>
<p>Recently…this past summer…okay not all that recently after all…GitHub made <code>HTTPS</code> easily
available for sites hosted on GitHub Pages that use custom domains. They also made it
easy to enforce <code>HTTPS</code> (redirect regular ’ol <code>HTTP</code> requests to <code>HTTPS</code>).</p>
<p>As an added bonus, this change also places my site behind a CDN - so it should load faster
for folks all over the world! ¡ɐᴉlɐɹʇsn∀ ollǝH</p>
<p>Check out the <a href="https://github.blog/2018-05-01-github-pages-custom-domains-https/">GitHub Blog</a> for more information.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><summary type="html"><![CDATA[As of today chambers.io is officially served up over HTTPS.]]></summary></entry><entry><title type="html">Celebrate Valentine’s Day with Bash!</title><link href="https://chambers.io/blog/2019/02/14/valentines-bash-prompt.html" rel="alternate" type="text/html" title="Celebrate Valentine’s Day with Bash!" /><published>2019-02-14T00:00:00+00:00</published><updated>2019-02-14T00:00:00+00:00</updated><id>https://chambers.io/blog/2019/02/14/valentines-bash-prompt</id><content type="html" xml:base="https://chambers.io/blog/2019/02/14/valentines-bash-prompt.html"><![CDATA[<p>If you’re using a modern terminal emulator with unicode support
(for example, the default Gnome terminal shipped with Ubuntu)
you can add Emoji to your bash prompt.</p>
<p>If you’ve never changed your bash prompt, it probably looks something like this:</p>
<ul>
<li><code>username@hostname ~ $</code></li>
</ul>
<p>You can customize your prompt within your <code>.bashrc</code> file!</p>
<p>Feeling lonely today? Can’t wait to get home to a loved one? Add a <a href="https://emojipedia.org/heavy-black-heart/">heart</a>
:heart: emoji to your bash prompt for a cheerful reminder.</p>
<h2 id="change-your-bash-prompt">Change your Bash Prompt</h2>
<p>Your bash prompt is set with the <code>$PS1</code> variable in your <code>.bashrc</code> file.</p>
<ol>
<li>Open up <code>~/.bashrc</code> with your favorite editor.</li>
<li>Comment out the existing <code>PS1=...</code> line</li>
<li>Add the following: <code>PS1='\[\e[35m\]❤\[\e[m\]  \w $ '</code></li>
</ol>
<ul>
<li>The <code>\[\e[35m\] ... \[\e[m\]</code> text sets the color to magenta/pink.</li>
</ul>
<ol start="4">
<li>Reload your bash profile with the command: <code>$ source ~/.bashrc</code></li>
<li>Your prompt should now have a colorful heart! Hurray!
<img src="/assets/images/bash-heart.png" alt="" /></li>
</ol>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="linux/unix" /><category term="command line" /><summary type="html"><![CDATA[If you’re using a modern terminal emulator with unicode support (for example, the default Gnome terminal shipped with Ubuntu) you can add Emoji to your bash prompt.]]></summary></entry><entry><title type="html">What the Hell is a Shell?</title><link href="https://chambers.io/blog/2018/11/29/what-the-hell-is-a-shell.html" rel="alternate" type="text/html" title="What the Hell is a Shell?" /><published>2018-11-29T00:00:00+00:00</published><updated>2018-11-29T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/11/29/what-the-hell-is-a-shell</id><content type="html" xml:base="https://chambers.io/blog/2018/11/29/what-the-hell-is-a-shell.html"><![CDATA[<p>You see the term ‘Shell’ tossed around a lot these days. The Bourne Shell (sh),
Bash (Bourne Again Shell), Powershell, etc. What actually is a “shell”?</p>
<blockquote>
<p>Put simply, a shell is an interface that lets a user interact with the Operating
System. A shell could be a command-line interface or a graphical user interface.</p>
</blockquote>
<p>For the purpose of this post, we’ll be looking at command-line interface shells.
I wanted to do a couple of posts about the Linux/Unix Command Line and thought
it would be good to dive right in and explore a Unix (or Unix-like) Shell.</p>
<p>Many people will often times use words like terminal, command-line, shell, or
bash interchangeably - but it’s important to note the difference. Let’s start
with some terminology.</p>
<hr />
<p>Terminology:</p>
<ul>
<li><strong>Terminal</strong> - the actual window filled with text. When most people say “terminal”
they actually mean “terminal emulator” - and it does just that. It <em>emulates</em> an
old school video or text terminal within your operating system.
<ul>
<li>Most Unix or Unix-like operating systems ship with a default terminal
emulator, but you can install others without issue.</li>
</ul>
</li>
<li><strong>Command Line</strong> - the actual place where you enter your commands. Letters appear
here when you type on your keyboard. Usually has a blinking cursor.</li>
<li><strong>Shell</strong> - the software that runs inside the terminal window and sends your
commands to the operating system. Some examples:
<ul>
<li>Bourne Shell and Bash</li>
<li>Powershell</li>
<li>Zsh</li>
<li>Fish Shell</li>
<li>…and many more!</li>
</ul>
</li>
</ul>
<hr />
<h2 id="how-the-shell-works">How the Shell Works</h2>
<h2 id="scripting">Scripting</h2>
<h2 id="popular-shells">Popular Shells</h2>
<h3 id="bash">Bash</h3>
<h3 id="zsh">Zsh</h3>
<h3 id="fish-shell">Fish Shell</h3>
<h3 id="git">git</h3>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="command line" /><summary type="html"><![CDATA[You see the term ‘Shell’ tossed around a lot these days. The Bourne Shell (sh), Bash (Bourne Again Shell), Powershell, etc. What actually is a “shell”?]]></summary></entry><entry><title type="html">Don’t Fear the Command Line</title><link href="https://chambers.io/blog/2018/09/26/dont-fear-the-command-line.html" rel="alternate" type="text/html" title="Don’t Fear the Command Line" /><published>2018-09-26T00:00:00+00:00</published><updated>2018-09-26T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/09/26/dont-fear-the-command-line</id><content type="html" xml:base="https://chambers.io/blog/2018/09/26/dont-fear-the-command-line.html"><![CDATA[<p><img src="/assets/gif/terminal_gif.gif" alt="" /></p>
<p>Someone made a funny remark at work the other day. Before I begin, here’s a
little background.</p>
<p>At one point in time, long before my own computing years, a command line prompt
and terminal window was the the primary - often only - way of interacting
with a computer. Today, the thought of using a command line is alien to many. I
was brought up in a GUI world, and I love every thing about it. Yet it is hard
to deny the (beautiful, brutalist) utility of the command line. It shows you
only what you need, it doesn’t try to make things very pretty
(although <a href="https://www.reddit.com/r/unixporn/">it can be</a>), it’s stupid fast,
and incredibly powerful.</p>
<p>I remember the first time I saw a true <em>Command Line Wizard</em> - my supervisor at
my first job as a student working for the Center for High Throughput Computing
at UW. I had used Linux before, sure. We used RedHat in the CS labs. I had
Ubuntu on my Laptop and I had installed a few applications using <em>apt-get</em> and I
had used vim and a shell to run simple bash scripts in some of my CS classes,
but I had never really <em>used</em> a command line until that job. My first day on the
job I saw down in his office and immediately noticed his screen was nothing but
a full screen terminal window. It was all I could do to keep my jaw from dropping
as I watched his fingers dance over the keys in an aggressive but deliberate
flurry of activity as he configured my account and showed me what I would do in
my new position. My first real introduction to the (Linux) command line was a
whirlwind, but I was instantly hooked.</p>
<p>I was lucky. My first real, technical job forced me to use Linux and the command
line. Often the best way to learn something is to throw yourself into it. The
situation for me was quite literally sink or swim. I floundered in the water for
a bit but I did manage to tread water, and eventually take some slow strokes
into what would eventually blossom into a job and career for me. I am now lucky
enough to work in an environment where I get to use the command line every day.</p>
<p>Fast-forward to the other day at work. While we use the Linux or Mac OS terminal
daily in the UW Radiology development team that primarily work with, the
Infrastructure/Server team at UW Health that I also work with is mostly
comprised of Windows administrators. It was at a meeting with members of the
server team that someone, reporting on a product they had just learned about at
a conference, said “…and the enterprise edition includes a graphical
interface, since the command line is intimidating.”</p>
<p>Intimidating? How can something so simple be intimidating? Yet as I was sitting
in that meeting, all I could think about the rash of “enterprise-grade” tools I have to
use where I sift through a clunky web-app desperately searching for a way to do
something and wishing I could access a command line, knowing there’s got to be a
simple flag to set this option. I’m not bashing GUIs or web interfaces. They are
awesome 90% of the time. However, it’s that 10% of the time where 90% of the
work gets done that really counts. I love building interfaces and new ways for
people to interact with the computer on the web. But the command line will
always be one of the most powerful, simple, and elegant ways to interact with
a computer. It was all I could do to not stand up and yell ‘blasphemy!’ I wanted
to sit my co-worker down and show him the magic of the command line, right then
and there, and force him to see my point of view…no matter if I was right or
wrong.</p>
<p>I once feared the command line, but there really isn’t any reason to.
Unsurprisingly, humans are pretty good with text. Using a written language is
second-nature to us. Computers work <em>really good</em> with text. It makes sense to
interact using written language.</p>
<p>It’s undeniable that touch input, much like the mouse before it, has taken the
world by storm since <em>about</em> 2007, and that method of human/computer interaction
has opened up a whole world of new possibilities. There will probably be a new
way of interacting with a computer in the future. But I think there will always
be a place for a keyboard, a simple terminal window, and a blinking cursor.</p>
<p>Don’t fear the command line - use it.</p>
<hr />
<p>This silly post previews my next upcoming series of blog posts all about the
command line, including <em>Cool Terminal Applications I Use Every Day</em> and
<em>What the Hell is a Shell?</em> Check back soon to read more!</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="linux/unix" /><category term="command line" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">On Keeping Notes</title><link href="https://chambers.io/blog/2018/08/01/note-keeper.html" rel="alternate" type="text/html" title="On Keeping Notes" /><published>2018-08-01T00:00:00+00:00</published><updated>2018-08-01T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/08/01/note-keeper</id><content type="html" xml:base="https://chambers.io/blog/2018/08/01/note-keeper.html"><![CDATA[<p>I made a tiny script for keeping simple text-based notes.
You might find it useful too.<br />
Introducing: <a href="https://github.com/dcchambers/note-keeper">Note Keeper</a></p>
<hr />
<p>I am a devout member of the <a href="http://bulletjournal.com/">bullet journal</a> cult.
But I tend to be picky about what I write down in my journal and, let’s be
honest, it’s often faster to type than to write, especially when you’re already
sitting in front of a keyboard or you have to copy/paste a long string of
nonsensical characters.</p>
<p>I’ve gone through a couple of iterations of note taking processes when working.
I work almost exclusively in Linux these days and am regularly working from the
command line. My work-flow is pretty much a shell + tmux + a hundred different
command line applications.</p>
<h3 id="this-is-how-i-used-to-keep-notes">This is how I used to keep notes:</h3>
<ul>
<li>Keep a master notebook at ~/notebook.md</li>
<li>Switch to my NOTES window in tmux.</li>
<li>Open up the notebook with vim.</li>
<li>Write whatever I need.</li>
<li>Switch back to my working window in tmux.</li>
</ul>
<p><a href="https://asciinema.org/a/194447"><img src="https://asciinema.org/a/194447.png" alt="asciicast" /></a></p>
<h3 id="and-this-is-how-i-keep-notes-now">And this is how I keep notes now:</h3>
<ul>
<li>Use my <code>note</code> script to open up a new note at ~/notes/year/month/day.md.</li>
</ul>
<p><a href="https://asciinema.org/a/194428"><img src="https://asciinema.org/a/194428.png" alt="asciicast" /></a></p>
<hr />
<h2 id="note-keeper">Note Keeper</h2>
<p>Originally, I had simply aliased the <code>note</code> command to create and edit a new
markdown note in a certain location. I decided to expand upon that idea…</p>
<p>That became <a href="https://github.com/dcchambers/note-keeper">Note Keeper</a> - a tiny
shell script for keeping notes. It’s pretty basic right now.
You can:</p>
<ul>
<li>Create notes</li>
<li>Edit notes</li>
<li>Print a note</li>
<li>Print information about a note</li>
</ul>
<p>Planned additions:</p>
<ul>
<li>Destroy a note</li>
<li>Encrypt a secret note</li>
<li>Directly/immediately append a string to the end of a note</li>
</ul>
<hr />
<p>Use <em>Note Keeper</em> to make TODO lists, create ASCII art, write poems, or as a
copy/paste clipboard.</p>
<ul>
<li>Note Keeper will automatically create a <code>$day.md</code> markdown note for you</li>
<li>It will organize it in a sane way (in the directory <code>~/notes/$year/$month/</code>)</li>
<li>It will open the note up for editing in Vim.</li>
<li>Simply install the script and type <code>note</code> on your command line.</li>
<li>Probably<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup> compatible with Mac OS and most Linux distributions.</li>
<li>As of <a href="https://github.com/dcchambers/note-keeper/releases/tag/v0.1.1"><code>v0.1.1</code></a>
<em>Note Keeper</em> now opens vim in <code>insert</code> mode and puts the cursor at the end of
the file for even more rapid note taking.
<ul>
<li>Simply type <code>note</code> and start writing!</li>
</ul>
</li>
</ul>
<p>Check out the source code on :octocat: <a href="https://github.com/dcchambers/note-keeper">Github.</a><br />
Currently <a href="https://github.com/dcchambers/note-keeper/releases/tag/v0.2.1"><code>v0.2.1</code></a> :tada: :wink:</p>
<section class="footnotes">
<ol>
<li id="fn1">
<p>Tested on Mac OS High Sierra and Ubuntu 16.04 LTS. <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="linux/unix" /><category term="command line" /><summary type="html"><![CDATA[I made a tiny script for keeping simple text-based notes. You might find it useful too. Introducing: Note Keeper]]></summary></entry><entry><title type="html">Radiology Tech Stack</title><link href="https://chambers.io/blog/2018/05/11/radiology-tech-stack.html" rel="alternate" type="text/html" title="Radiology Tech Stack" /><published>2018-05-11T00:00:00+00:00</published><updated>2018-06-11T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/05/11/radiology-tech-stack</id><content type="html" xml:base="https://chambers.io/blog/2018/05/11/radiology-tech-stack.html"><![CDATA[<p><img src="/assets/images/wisc-radiology.png" alt="" /></p>
<p>In January of 2018 I started a new job with the Department of Radiology in
the University of Wisconsin’s School of Medicine and Public Health. Phew, that
was a mouthful. From here on out, I’ll just refer to it as “Radiology.”</p>
<p>Our department is dual-purpose. We support both academic research in the
School of Medicine and we build and support clinical applications that are
used every day by doctors and staff in the UW Hospital and Clinics.
We’re a pretty small team. Our core team is just five people -
four developers and me, the dev/ops engineer guy. We also work closely
with our media team for graphics work, content updates, and some
design/front-end work. We also work with the Server Team at UW Health for our
infrastructure needs.</p>
<p>So, what does the tech stack for a unique group like ours? I could just go ahead
and list a bunch of tools without explaining <em>how</em> we use them - but my guess is
you’re here to see <em>how and why</em> we use certain tools. It’s easy enough to head
to a website like <a href="https://stackshare.io">stackshare</a> and have a bunch of
technologies thrown at you without any indication of how they’re used. Instead,
I think it will be more fun to explore how we use different technologies.</p>
<h2 id="what-we-do">What We Do</h2>
<p>So what does a development team in a Radiology department do? Radiology is a
medical specialty that uses medical imaging to diagnose and help treat issues
within the body.</p>
<p>Medical imaging covers everything from X-Rays to MRI (Magnetic Resonance
Imaging) to CT (Computed Tomography) to PET (Positron Emission Tomography)
scans to Ultrasound. Radiology is involved in pretty much every aspect of
healthcare. Break a bone? A radiologist will read the X-ray. Have a traumatic
brain injury or stroke? A radiologist will read the CT scan or look for an
aneurysm (and even place the stent to fix it!). Searching for cancer cells?
A radiologist will help with that too.</p>
<p>Radiology has long been a pioneer of technological advances in healthcare, and
a lot of the focus is on improving these technologies through various means. We
work closely with the informatics group to analyze large data sets. We work with
medical physics to improve scanners and develop new technologies to see inside
the body.</p>
<p>As a development team, a lot of our work is improving the workflow and
efficiency of Radiologists and other staff members. We work directly with
stakeholders within the department, most of them medical doctors, to create
tools that will help them in the field. Because we work at a teaching hospital,
we also develop tools to help foster communication and learning between med
students, residents, and attending physicians.</p>
<h2 id="legacy-applications">Legacy applications</h2>
<h3 id="lamp-stack">LAMP Stack</h3>
<p>Many of our existing legacy applications are regular good ’ol LAMP stack
applications. The (L)inux (A)pache (M)ysql (P)HP stack is battle-tested for
sure. Most of the stuff we do is database-driven, and PHP and MySQL pair
together like a fine red wine and a ribeye steak.</p>
<p>Some of these applications are simple web dashboards written in PHP that
display relevant data from our MySQL database. For example, we’ve got one app
that allows staff to view statistics about our CT scanners and filter results.</p>
<p>Some of our these applications are “CRUD” apps that interact with our database.
CRUD stands for “Create, Read, Update, and Delete.” For example, physicians
earn merit and are paid based on different achievements and activities
throughout the year. We’ve developed a PHP application that allows the admin
staff to enter activities throughout the year. These are then added to a
database and ultimately a score is computed to help evaluate performance and
compensation.</p>
<p>We’ve got an application to request time and see availability on a particular
image scanner.</p>
<p>We’ve got a small application used for annual staff reviews.</p>
<p>These are just a few examples of our typical in-house PHP applications.</p>
<h3 id="mobile-applications">Mobile Applications</h3>
<p>Currently we only have one mobile application, but there are plans for more down
the line. It’s an
<a href="https://itunes.apple.com/us/app/gadcalc/id1051070769?mt=8">iOS app to calculate Gadolinum dosages</a>.
It’s written in Swift. It is used daily in the Hospital but we aren’t currently
working on new features, only on maintenance. Porting the application to Android
is on our Summer road-map.</p>
<h3 id="java-and-groovy-grails">Java and Groovy Grails</h3>
<p>Finally, we’ve got a couple of legacy applications that are built in Java and
Apache’s Groovy/Grails. At this point we have stopped all active development of
Java and Groovy/Grails applications outside of bug-fixes and regular
maintenance. The long-term plan is to port (update and re-write) these legacy
applications in our new unified tech-stack…<strong>Ruby-on-Rails</strong>.</p>
<h2 id="new-applications">New applications</h2>
<p>Ultimately, the nature of our department means we get a very wide range of
requests. Some ‘application’ requests are simple web-pages that have a dashboard
that displays data in some database. Other requests are more involved - like a
mobile app for calculating gadolinium dosages or an application that allows
Residents to compare their radiology reading room preliminary examinations to
an attending physician’s final exam.</p>
<p>Going forward, the department has decided to simplify and unify our tech stack.
<strong>Ruby-on-Rails</strong> is our web framework of choice.</p>
<p><img src="/assets/images/ruby-rails.png" alt="" /></p>
<p>Why Ruby/Rails?</p>
<ul>
<li>Building new applications is wicked fast.</li>
<li>It’s suited to rapid agile development and other modern development practices.</li>
<li>Code is highly readable, which is good when trying to hire and keep talented
development staff.</li>
<li>Rails has a strong developer community.</li>
<li>It’s open source.</li>
</ul>
<h3 id="philipsai-bridge-platform">(Philips)/AI Bridge Platform</h3>
<p><a href="https://www.analytical.info/developers/">Analytical Informatics</a> (now owned by
Philips) provides a centralized platform for easily working with delicate
healthcare data. The <a href="https://developer-docs.analytical.info/">Bridge</a> platform
is built on top of the Ruby-on-Rails framework (technically <a href="http://jruby.org/">jRuby</a>,
but let’s not be pedantic).</p>
<p>By teaming up with the Philips/AI team, we can create applications that
interface with HL7 (Healthcare data standard) and DICOM (imaging standard) data
faster than ever.</p>
<p><img src="/assets/images/analytical-info.png" alt="" />{:width=“300px”} <img src="/assets/images/philips.png" alt="" />{:width=“100px”}</p>
<p>Why is working on the Philips/AI Bridge platform so great? Here’s a couple
reasons.</p>
<ul>
<li><strong>Real-Time Normalized Database.</strong> We work with a lot of data from a lot of
different sources. They aggregate that data, validate it, and let us access it
with stupid simple queries.</li>
<li><strong>HIPAA Audit Logging.</strong> HIPAA isn’t anything to mess with. A single failure can
cost your company/hospital/university millions. Writing code to log everything
for future potential audits isn’t so fun either.</li>
<li><strong>Authentication.</strong> They tap into our Active Directory for Single Sign On and
also allow integration with PACS and other clinical applications.</li>
<li><strong>Share with others.</strong> We can tap into applications that other groups have
built on the Bridge platform and use/extend them as we need. We can also share
what we have done with others! Sharing is caring! :wave:</li>
</ul>
<p><em>TL;DR - they take care of the boring stuff and let us ship apps in record time!</em></p>
<p>Ruby on Rails! <em>In 2018?!</em> Of course :wink: I’m sure I’ll write more on this later.</p>
<h3 id="wordpress">Wordpress</h3>
<p><img src="/assets/images/wordpress.png" alt="" /></p>
<p><a href="https://radiology.wisc.edu">Our website</a> is a Wordpress website that follows
the conventions and uses the theming provided by the University of Wisconsin.
However it is developed and supported by our dev team. Most content updates are
done by the media/communication team, student employees, or specific
stakeholders.</p>
<h2 id="infrastructure">Infrastructure</h2>
<p>Ahha! Now we get to the fun stuff. :smirk: My job as a dev/ops admin is to help
the other developers not worry about the infrastructure at all. I have to make
sure the application runs the same on our server(s) as it does on their local
development machine.</p>
<p>The infrastructure team at UW Health provides IaaS (Infrastructure as a Service)
to various teams within UW Health and the UW School of Medicine. They host all
of our VMs in highly reliable, distributed data-centers that are designed for
maximum uptime.</p>
<h3 id="servers">Servers</h3>
<p>All of our servers run some flavor of Linux. Most of what we’ve got deployed
right now is RHEL7/CentOS7, with some CentOS6 and Ubuntu 16.04 Server boxes in
the mix.</p>
<h3 id="docker">Docker</h3>
<p><img src="/assets/images/docker.png" alt="" /></p>
<p>Containerize all the things! If you don’t know what
<a href="https://www.docker.com/">Docker</a> or
<a href="https://www.redhat.com/en/topics/containers">containers</a> are - you’re really
missing out. We have all of our applications “dockerized.” In practice, this
means we use docker-compose to build and run the application environment.</p>
<p>Perhaps the best advantage to working in a Docker
environment is that everything is highly portable. If it runs docker, it should
be able to run your application without issue - no matter what kind of
dependency hell you’ve created or what strange version of Ruby or MySQL you
need to get your application working.</p>
<h3 id="deployment">Deployment</h3>
<p><img src="/assets/images/jenkins.png" alt="" /></p>
<p>We use <a href="https://jenkins.io/">Jenkins</a> to manage our application building and to
automate deployment to development, testing, and production environments. I get
to spend a good chunk of my time working with Docker and Jenkins!</p>
<h3 id="database">Database</h3>
<p>Our primary database is MySQL, which works great with the web-focused
tools and applications we create.</p>
<p>The Philips/AI database is PostgreSQL.</p>
<h3 id="everything-else">Everything Else</h3>
<h4 id="nginx">Nginx</h4>
<p>We use Nginx as a <a href="https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/">reverse proxy</a>.</p>
<h4 id="apache">Apache</h4>
<p>Many of our legacy applications use the Apache web server.</p>
<h4 id="ldap">LDAP</h4>
<p>We support a number of login methods, including non-domain accounts and
integration with UW Health’s Active Directory domain using LDAP.</p>
<h4 id="version-control">Version Control</h4>
<p><img src="/assets/images/github.png" alt="" /></p>
<p>Our legacy applications are set up in Mercurial Repos using
<a href="http://help.fogcreek.com/kiln">Kiln</a>.</p>
<p>We use Git for current and future applications, and have a self-hosted
<a href="https://enterprise.github.com/home">Github Enterprise</a> account. We also keep
all of our docker/container configuration in Git. Not using Git?
<a href="http://chambers.io/2018/04/09/git-101.html">You should be.</a></p>
<hr />
<p>And that’s just about everything. As you can see, we use a ton of different
technologies and get to work on a wide range of applications. It can get a
little crazy at times, but it’s awesome that we get to learn so many cool
tools/technologies and see many projects through from start-to-finish. There
aren’t many jobs where you get to meet with primary stakeholders and go through
the entire development process from start to finish. It’s also nice knowing that
the stuff we work on is being used to directly improve both patient healthcare
and medical research.</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="work" /><category term="linux/unix" /><category term="healthcare" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Git vs. The Competition</title><link href="https://chambers.io/blog/2018/04/17/git-vs-the-competition.html" rel="alternate" type="text/html" title="Git vs. The Competition" /><published>2018-04-17T00:00:00+00:00</published><updated>2018-04-18T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/04/17/git-vs-the-competition</id><content type="html" xml:base="https://chambers.io/blog/2018/04/17/git-vs-the-competition.html"><![CDATA[<p>If you have been following along during <a href="/2018/04/07/git-week.html">Git Week 2018</a>,
you know that Git isn’t your only choice for version control. There are plenty of
other options out there. Are they worth looking at? Git has a few features that
set it apart from many other version control systems. In the final article for
Git Week 2018 (a little late - sorry! :frowning:), we’ll look at how Git is
different and how it stacks up to the competition.</p>
<h2 id="git-is-distributed">Git is Distributed</h2>
<p>One of the most important things about Git is that it is a <strong>distributed</strong>
version control system. Today, that doesn’t make it very unique. Any VCS I would
recommend using is a dVCS. At the time of Git’s inception, though, distributed
version control systems were not all too common.</p>
<p>CVS (Concurrent Versions System) and SVN (Subversion) are two older and at one
time, very common <em>centralized</em> version control systems. In this model, the
systems use a centralized client-server model where a team of developers use a
single shared repository on a remote server.</p>
<p>Distributed version control systems like Git are better than centralized version
control systems for a couple of reasons.</p>
<ul>
<li>When a developer <em>clones</em> the repository, they have a copy of the entire project
including every file and the complete history on their local machine.
<ul>
<li>This allows Git to work fast for most actions because everything Git needs
is already available on the local machine - it doesn’t need to contact a
remote server.</li>
<li>Allows developers to safely work offline, making branches and commits without
ever needing to contact a remote server until you want to push or pull.</li>
<li>It also provides a convenient distributed back-up system for your source
code. Git <strong>is not</strong> a proper back-up system, which you should still implement,
but it’s better than nothing.
The only real disadvantage to a distributed system is that repos with lots of
large (binary) files can take a long time to download and will consume a large
amount of disk space. However, disk and bandwidth are dirt cheap compared to the
potential costs of <em>not</em> using a dVCS.</li>
</ul>
</li>
</ul>
<h2 id="git-is-safe">Git is Safe</h2>
<p>We learned in <a href="/2018/04/15/how-git-works.html">How Git Works</a> that Git stores
all of its objects (commits, etc) in a simple hashed key-value database. This
means that the data in these objects is <em>immutable</em>. In other words, it can’t
be changed. Because of this, Git history is very safe! Even if you think you’ve
accidentally deleted a commit, it’s probably stilled stored in the <em>reflog</em>. The
reflog is the Reference Log - and it keeps track of every single Git reference
you’ve made. Thanks to the reflog it’s hard to accidentally destroy data in Git.</p>
<p>:bulb: You can use <code>git reflog</code> similar to the <code>log</code> command to look at a
history of your actions in a repository.</p>
<h3 id="rewriting-history">Rewriting History</h3>
<p>One of the most powerful things Git lets you do is rewrite history. You can
change the order of commits, change commit messages, combine commits or split
one into multiple commits, and even remove commits completely. The distributed
nature of Git allows you to do this locally before pushing your commits and
sharing them with others. And because Git is built to be safe, even when
re-writing history its hard to truly destroy any data.</p>
<ul>
<li>Modify the most recent commit with <code>$ git commit --amend</code>.
<ul>
<li>Forget to add a file in a commit? Make your change, add it with <code>$ git add</code>,
and then <code>git commit --amend --no-edit</code>. The <code>--no-edit</code> flag tells Git to not
change the commit message.</li>
<li>:warning: Again, because Git is picky about protecting the history, amended
commits are actually <em>new</em> commits. Be careful about amending a commit others
might be working from.</li>
</ul>
</li>
<li><code>$ git rebase</code> is perhaps one of the best features of Git when compared to other
dVCS (such as Mercurial). <code>rebase</code> allows you to move commits around. Use the
<code>-i</code> flag to run <code>rebase</code> in interactive mode to selectively decide what history
to edit.</li>
</ul>
<p>:star: Thanks to the wonder that is <strong>reflog</strong>, you can edit git history without
fear. Reflog contains information about the old states of branches, even after
“rewriting” history - and allows you to go back to those states if desired.</p>
<h2 id="social-coding">Social Coding</h2>
<p>It’s impossible to understate the impact that <em>social coding</em> sites like Github
and Gitlab have had on modern software development. Open Source projects are
more popular than ever, and these platforms allow people to collaborate in ways
never thought possible only a few years ago. The best part? Almost all of them
use Git. Github is by far the most popular, but the other big players in the
field, including Gitlab and Bitbucket, all support Git as the primary VCS.</p>
<p>There are also more tools than ever, both for enterprise and personal use, to
enhance your software development experience using Git. There are awesome GUI
tools for interacting with your Git repo, including favorites like
<a href="https://www.gitkraken.com/">Kraken</a> and <a href="https://www.git-tower.com/mac/">Tower</a>.
Integrate your Github account to your <a href="https://blog.trello.com/github-and-trello-integrate-your-commits">Trello task boards</a>.
Work with your Gitlab repo directly in <a href="https://docs.gitlab.com/ee/user/project/integrations/gitlab_slack_application.html">Slack</a>.
Do <a href="https://github.com/features/code-review">code reviews</a>,
<a href="https://guides.github.com/features/issues/">track issues</a>,
<a href="https://help.github.com/articles/creating-releases/">manage releases</a>,
<a href="https://github.com/features">and more, directly in Github.</a> Gitlab, Bitbucket,
and the other guys all have similar options.</p>
<h2 id="the-competition">The Competition</h2>
<p>There are many version control systems, but only a few I would consider as a
realistic alternative to Git.</p>
<h3 id="mercurial">Mercurial</h3>
<p>Mercurial (hg) is probably the most well-known and popular Git alternative. Like
Git, it is a distributed VCS. Also like Git, it was created as an answer to
Bitkeeper removing its free license in 2005. While the Linux Kernel project
ultimately went with Git, Mercurial has proved to be a capable and popular VCS
on its own.</p>
<ul>
<li>
<p>While Git history is safe, Mercurial history is sacred. Mercurial treats its
history as unchangeable, and that offers a sense of security to some developers.</p>
</li>
<li>
<p>Mercurial also has first-class Windows support and operates virtually the same
in every environment you can run it.</p>
</li>
<li>
<p>Mercurial’s command line tools are pretty damn sleek. Git’s commands are
powerful and open ended - allowing you to do a lot but being less obvious about
how to get stuff done right away. Mercurial’s commands are the opposite - they
do one thing, but they do it well.</p>
</li>
<li>
<p>Mercurial is significantly slower than Git, and repos are considerably less
efficient with storage concerns. Not a problem for many people, but potentially
problematic for large projects.</p>
</li>
<li>
<p>Mercurial’s inability to rewrite history can be limiting when cleaning up a
messy history (after a night of testing the
<a href="https://xkcd.com/323/">Balmer Peak Hypothesis</a>, maybe?) or doing other work
typical in a Git workflow.</p>
</li>
</ul>
<p>If for some reason you couldn’t use Git, Mercurial is the first (and possibly
only) alternative I would recommend.</p>
<h3 id="team-foundation-server">Team Foundation Server</h3>
<p>Team Foundation Server isn’t actually a VCS - it’s Microsoft’s all-in-one
solution for the software development life cycle. It does have the ability to
use Git for version control, but Microsoft would prefer you use the included
<a href="https://docs.microsoft.com/en-us/vsts/tfvc/overview?view=vsts">Team Foundation Version Control (TFVC)</a>.</p>
<p>TFVC is a centralized version control system, similar to Apache’s Subversion. As
a result, it doesn’t have any benefits of using a dVCS. Developers only have
one version of a file on their machine at a time, and project history is stored
only on the remote server. As a result, offline work is limited.</p>
<p>I might recommend TFS if you’re developing on the Windows platform or using
Visual Studio. Use Git if you can - it’s got so many advantages over TFVC.</p>
<h3 id="bazaar">Bazaar</h3>
<p><a href="http://bazaar.canonical.com/en/">Bazaar</a> is Canonical’s dVCS solution. It has
all the usual advantages of a dVCS that both Git and Mercurial have. Bazaar does
have one feature that makes it unique - <em>bound branches</em>. A bound branch checks
that you’re up-to-date with a remote repo <em>before</em> making a commit. This can
prevent issues like merge conflicts. A useful, but ultimately not <em>entirely
necessary</em> feature. Like Mercurial, Bazaar also runs natively on Windows.</p>
<p>While Bazaar has some neat features, I don’t think it has enough extra going on
for it to recommend it over Git or Mercurial for most people. Especially since
development has slowed to a crawl - the last major stable release was over two
years ago in February of 2016.</p>
<h3 id="everything-else">Everything Else</h3>
<p>As I mentioned - there are a lot of different version control systems. Far more
than I have experience with or could even name. We can’t discuss them all, but
here’s a couple of the most commonly sought-after alternatives.</p>
<h4 id="the-old-guard">The Old Guard</h4>
<p>CVS and SVN had their time in the sun - and that time is gone. Distributed
version control simply has too many advantages to continue to use these
dinosaurs of the VCS world.</p>
<h4 id="fossil">Fossil</h4>
<p>I don’t have any experience with Fossil - but it seems to be gaining a small
resurgence of popularity lately. It does seem to have some
<a href="https://www.fossil-scm.org/xfer/doc/trunk/www/fossil-v-git.wiki">neat features</a>.
It’s distributed, open-source, and in active development. Might be worth looking
at!</p>
<h4 id="perforce-helix-core">Perforce (Helix Core)</h4>
<p>Perforce is ten years older than Git and still has a strong following in certain
enterprise industries. The kicker: it’s not free. For <em>most</em> people, I can’t
recommend Perforce/Helix Core. It might be looking into if you’ve got a
particularly large repo or want good Enterprise Windows support. It’s also got
better GUI support out-of-the box and natively supports Windows. I suspect most
teams would be able to switch to Git/Mercurial without issue, though.</p>
<hr />
<p>Well, that sums up Git vs. the Competition. Ultimately, there’s a ton of choices
out there. Git is my VCS of choice, but I use Mercurial at work in addition to
Git (damn you legacy projects!), and it serves us well. If you’re trying to
decide on a tool, do your research to learn the benefits of each. In general,
I think Git has just about everything most teams need to be successful.</p>
<p>This wraps up my <a href="/2018/04/07/git-week.html">miniseries on Git</a>. I hope you’ve enjoyed reading
about one of the most influential software development tools of the 21st Century!
If you’re getting tired of Git-related posts, thanks for sticking with me. I’ve
got some fresh content in the pipeline!</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="git" /><summary type="html"><![CDATA[If you have been following along during Git Week 2018, you know that Git isn’t your only choice for version control. There are plenty of other options out there. Are they worth looking at? Git has a few features that set it apart from many other version control systems. In the final article for Git Week 2018 (a little late - sorry! :frowning:), we’ll look at how Git is different and how it stacks up to the competition.]]></summary></entry><entry><title type="html">How Git Works</title><link href="https://chambers.io/blog/2018/04/15/how-git-works.html" rel="alternate" type="text/html" title="How Git Works" /><published>2018-04-15T00:00:00+00:00</published><updated>2018-04-16T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/04/15/how-git-works</id><content type="html" xml:base="https://chambers.io/blog/2018/04/15/how-git-works.html"><![CDATA[<p>So far this week we’ve talked about what Git is and how to use it. If you’re
anything like me, you want to know how things work under the hood. When you first
learn Git it can seem like magic…but it also seems like something that can
easily break. Or something that works by pure <em>demonic byte voodoo</em>. One of the
best things Git does is allow you to write code with confidence - fear not about
breaking things or losing files. They’re always recoverable. To feel confident,
it helps to know how things work.</p>
<p>This <a href="https://xkcd.com/1597/">XKCD comic</a> perfectly summarizes how most people
use Git.
<img src="/assets/images/xkcd_git.png" alt="" />
I hope by the end of this post you feel a little more confident. :smile:</p>
<p>Git works differently than most other version control systems. As a result, it
runs freakishly fast and has some killer features that elevate it above the
competition. We’ll cover some basic VCS principles and look at some of the cogs
that make the Git machine tick.</p>
<h2 id="understanding-diff">Understanding Diff</h2>
<p>You have to know what a <em>diff</em> is to understand how version control systems work.
A <em>diff</em> is essentially just a difference between two things. In the case of Git
and many other version control systems, a <em>diff</em> is the difference between two
files. Linux actually has a <em>diff</em> utility that can tell you the difference
between two files. It works by examining each <em>line</em> individually. Here’s a
quick example.</p>
<p>Let’s assume that file1 contains:</p>
<pre><code>This is a file!
Hello world!
End of file.
</code></pre>
<p>and file2 contains:</p>
<pre><code>This is a file!
Goodbye, world.
End of file.
</code></pre>
<p>If you run <code>$ diff file1 file2</code> you will get a result that looks like:</p>
<pre><code>2c2
&lt; Hello world!
---
&gt; Goodbye, world.
</code></pre>
<p>Here’s what that means:</p>
<ul>
<li>The first line, <code>2c2</code>, gives us an overview of what happened.
<ul>
<li>The <code>c</code> means that a line was <em>changed</em>.</li>
<li>The number before the <code>c</code>, a <code>2</code> in this case, is the line in the <em>first
file</em> that corresponds to the change.</li>
<li>The number after the <code>c</code>, also a <code>2</code>, is the line in the <em>second file</em> that
has changed.</li>
</ul>
</li>
<li>The <code>&lt;</code> denotes the line(s) in the first file.</li>
<li>The <code>&gt;</code> denotes the line(s) in the second file.</li>
<li>the <code>---</code> separates the contents from the first and second files.</li>
</ul>
<p>If we were to delete line 2 in the second file, so that it’s contents just look
like:</p>
<pre><code>This is a file!
End of file.
</code></pre>
<p>the diff would look like this:</p>
<pre><code>2d1
&lt; Hello world!
</code></pre>
<ul>
<li>Again, the first line <code>2d1</code> gives us a snapshot of the difference.
<ul>
<li>The <code>d</code> means a line was deleted.</li>
<li>the <code>2</code> means line number 2 in file1 was the edited (deleted) file.</li>
<li>The <code>1</code> means that in file2, the change happened after line number 1. Or,
after deletion, the line counter went back to line number 1.</li>
</ul>
</li>
<li>The <code>&lt; Hello world!</code> is the line from file1 that was deleted.</li>
<li>Nothing was changed or added in <code>file2</code>, so there are no <code>---</code> and <code>&gt;</code> markings.</li>
</ul>
<p>:warning: The first part, <code>2c2</code>, <code>2d1</code>, etc can often times be ignored - these are
mostly intended for use by the linux tool <code>patch</code>.</p>
<hr />
<p><code>git-diff</code> works a little bit differently than the <code>diff</code> tool and the output is
different, but the basic idea of a <em>diff</em> is the same. Here’s an example from
two different commits in this repository. We’re going to look at the difference
between commit <code>d8ee32d55db5ba04456d7ac214e7f02d3151081c</code> and commit
<code>f7fababd22ea85dba012c69aebac0067769b1208</code>. Here’s the output from <code>git-log</code>
so you can see what we’re working with.</p>
<pre><code>$ git log
commit f7fababd22ea85dba012c69aebac0067769b1208
Author: Dakota Chambers &lt;dakotachambers@gmail.com&gt;
Date:   Sat Apr 14 14:47:02 2018 -0500

    Change grammar in 'Understanding Diff' section.

commit d8ee32d55db5ba04456d7ac214e7f02d3151081c
Author: Dakota Chambers &lt;dakotachambers@gmail.com&gt;
Date:   Sat Apr 14 14:46:08 2018 -0500

    Start writing how-git-works post.
</code></pre>
<p>To see what change I made between those commits, I can use <code>$ git diff</code>!
:bulb: when working with the uniquely identifying SHA-1 HASH of each commit, you
don’t have to use the whole thing. Often times the first 6 characters of each
HASH value is enough.</p>
<pre><code>$ git diff d8ee32 f7faba
diff --git a/_posts/2018-04-14-how-git-works.md b/_posts/2018-04-14-how-git-works.md
index 49076cc..633c386 100644
--- a/_posts/2018-04-14-how-git-works.md
+++ b/_posts/2018-04-14-how-git-works.md
@@ -14,7 +14,7 @@ files. Linux actually has a *diff* utility that can tell you the difference
 between two files. It works by examining each *line* individually. Here's a
 quick example.

-Let's assume file1 contains:
+Let's assume that file1 contains:
 ` ` `
 This is a file!
 Hello world!
</code></pre>
<p>Normally, your git-diff will be color coded for easier reading. It will look
something like this:
<img src="/assets/images/git-diff-screenshot.png" alt="" /></p>
<p>Whoa, this looks a lot scarier! Let’s break it down…there’s only a few things
we care about for this example. The first part</p>
<pre><code>--- a/_posts/2018-04-14-how-git-works.md
+++ b/_posts/2018-04-14-how-git-works.md
</code></pre>
<p>is basically a unified diff header. Essentially, the <code>---</code> is the old file and
the <code>+++</code> is the new file. The next part</p>
<pre><code>@@ -14,7 +14,7 @@
</code></pre>
<p>gives us information about what lines were changes and what the diff is showing.
You can ignore the @ signs, those are just markers.</p>
<ul>
<li><code>-14,7</code> is short hand for representing the changes in the first file. In the
file, the diff starts on line 14, and it is 7 lines long. The actual <em>diff</em> isn’t
7 lines long, but it’s showing 7 lines from the file.</li>
<li><code>+14,7</code> is short hand that represents the changes to the second file. Again,
the diff is showing a “chunk” that starts on line 14 and is 7 lines long.</li>
</ul>
<p>The most important part what comes after that section. It is showing the contents
of both files. Anything without a <code>-</code> or <code>+</code> in front of it is the same in both
files, while any line with those markers present is a line that was changed.
The <code>-</code> is a line that was removed from the first file, and the <code>+</code> is a line that
was added in the second file.</p>
<pre><code>-Let's assume file1 contains:
+Let's assume that file1 contains:
</code></pre>
<p>Because diff works on a line-by-line basis, it views these two lines as totally
different even though I only added a single word. So this is saying that I deleted
a line containing <code>Let's assume file1 contains:</code> and aded a line that contains
<code>Let's assume that file1 contains:</code>. The words below the <code>-</code>/<code>+</code> section are just
some more contents of the file to help give context.</p>
<p>And that’s how <code>diff</code> works! The first step in understanding Git/version control
is to know that they operate by tracking changes in files.</p>
<h3 id="snapshots-not-differences">Snapshots, not Differences</h3>
<p>If you look at the <a href="https://git-scm.com/book/en/v2/Getting-Started-Git-Basics">the official documentation</a>,
you’ll see that Git doesn’t actually work by tracking diffs. Instead, Git keeps a <em>snapshot</em> of
the current state of a directory. Haha, you’ve been fooled! You learned the magic
of <em>diff</em> for nothing! Fret not - it’s still important to know what a <em>diff</em> is
to understand why Git is different. Git still uses diffs to know when a file has
been changed. Some version control systems, like CVS, Subversion, Bazaar, etc
work by tracking diffs. This is called <em>delta-based version control</em>.</p>
<p>Git works a little differently. Every time you make a <em>commit</em>, Git takes a
snapshot of all the files, and then creates a reference to those files in there
exact form at that moment in time. If you change a file and make another commit,
Git takes another snapshot and creates another reference. At a glance this seems
horribly inefficient - you would think that your repo would rapidly increase in
size with every commit you make if it keeps a copy of every file in every commit,
right? Luckily, Git is smart about taking snapshots! If a file hasn’t changed
from a previous version when you make a commit, it doesn’t actually save another
copy of that file. Instead, it just saves a link to the previous (identical)
version of that file. You can imagine it similar to how a <em>symlink</em> works in a
Unix-like operating system.</p>
<p>This distinction actually allows Git to do a lot of the cool things that other
version control systems cannot. For example, Git has an incredibly powerful
branching model due to the nature of how it works that many other VCS can not
compete with.</p>
<p>All right. Diffs, snapshots…apples, oranges, you get it. Moving on!</p>
<h2 id="three-states">Three States</h2>
<p>Files in a Git repository have three states they can be in: <strong>modified</strong>,
<strong>staged</strong>, and <strong>committed</strong>.</p>
<ul>
<li>When you make a change to a file and save that change, it is marked as
<strong>modified</strong>. At this stage, Git has <strong>not</strong> recorded the changes. If you were
to delete the file, you would not be able to recover it with those changes
present.</li>
<li>Once your have edited your file and area ready to commit it, you need to use
<code>git add</code> to stage the file. This marks the file as <strong>staged</strong>. It updates the
<em>snapshot</em> (index) to the contents of the file in the current working directory.
Staging a file tells Git you are ready to add it to the next commit.</li>
<li>Finally, you can use <code>git commit</code> to mark a file as <strong>committed</strong>. In this
stage, the file is backed up in the Git ‘database’. At this point, it’s virtually
impossible to <em>accidentally</em> make a file non-recoverable.
This image from the
<a href="https://git-scm.com/book/en/v2/Getting-Started-Git-Basics">Git Documentation</a>
describes the stages pretty well:
<img src="/assets/images/git-states.png" alt="" /></li>
</ul>
<h2 id="the-git-directory">The .git directory</h2>
<p>When you create a new Git repo with <code>git init</code> or <code>git clone</code> an existing repo,
you’ll notice that Git creates a .git directory within your repo. The .git
directory contains all the goodies that make Git work. Try using <code>tree</code> to
inspect the contents of that directory.</p>
<pre><code>$ tree .git -L 2
.git
├── COMMIT_EDITMSG
├── FETCH_HEAD
├── HEAD
├── ORIG_HEAD
├── branches
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
├── objects
│   ├── 00
│   ├── info
│   └── pack
├── packed-refs
└── refs
    ├── heads
    ├── remotes
    └── tags

</code></pre>
<p>Let’s break down what we see here.</p>
<ul>
<li><code>COMMIT_EDITMSG</code> is simply the message from your last commit.</li>
<li><code>FETCH_HEAD</code> is the SHA-1 Hash of the remote/branch that was updated the last
time you ran <code>git fetch</code> or <code>git pull</code>.</li>
<li><code>HEAD</code> is the current <em>ref</em> (commit reference) you’re looking at.</li>
<li><code>ORIG_HEAD</code> is the SHA-1 Hash of the branch you are merging <em>into</em> when doing
<code>git merge</code></li>
<li><code>MERGE_HEAD</code> (not listed above) is the SHA-1 Hash of a branch you’re merging
<em>from</em> with <code>git merge</code>. (e.g. this is the branch that gets merged into the
branch that the ORIG_HEAD SHA-1 Hash points to).</li>
<li><code>branches</code> is a directory that is ‘A slightly deprecated way to store
shorthands to be used to specify a URL to git fetch, git pull and git push.’
according to the official documentation. You can consider this deprecated - you
won’t have to worry about it.</li>
<li><code>config</code> contains repository settings.</li>
<li><code>description</code> is used only by the GitWeb program - you can safely ignore it.</li>
<li><code>hooks</code> is a directory that contains scripts that can run automatically when
you do certain git actions (e.g. push to a branch). <em>Hooks</em> are an incredibly
powerful way to interact with Git. There are many tools that you can tie into
Git using hooks to automate certain actions. For example, you can use a hook
with <a href="https://jenkins.io/">Jenkins</a> to automate a build and deployment after
commiting to a certain branch. For more information about hooks, check out the
<a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">documentation</a>.</li>
<li><code>index</code> is a file that contains all kind of information about the
current <em>snapshot</em> of the repository.</li>
<li><code>info</code> is a directory that contains some additional information about the repo.
<ul>
<li><code>exclude</code> is a file that contains an exclude pattern list. Many people will
find using the regular <code>.gitignore</code> is fine.</li>
</ul>
</li>
<li><code>logs</code> is a directory that contains a log from various branches.
<ul>
<li><code>HEAD</code> shows the log of the HEAD ref.</li>
<li><code>refs</code> is a directory that contains logs of other refs.</li>
</ul>
</li>
<li><code>objects</code> is a directory that contains blobs of data that Git stores. This
directory will grow over time.</li>
<li><code>packed-refs</code> contains the same information as the <code>refs</code> directory in a more
efficient way.</li>
<li><code>refs</code> is a directory that contains all of the <em>references</em> of the repository.</li>
</ul>
<p>The <em>core parts</em> of Git are the <code>HEAD</code>, <code>index</code>, <code>objects</code> directory, and <code>refs</code>
directory. Git uses a bunch of low-level commands to manipulate data within
these files/directories.</p>
<h2 id="plumbing-vs-porcelain">Plumbing vs. Porcelain</h2>
<p>Git was originally created as a toolkit for other version control systems, not
as a stand-alone version control system. As a result, there are a number of
low-level “plumbing” commands that are designed to be strung together and
executed by scripts. The user-facing commands, such as <code>checkout</code> or <code>commit</code>
are sometimes referred to as “porcelain” commands. When working directly with
Git from the command line, you’ll rarely ever have to use the “plumbing”
commands. In fact, most of the “porcelain” commands you are familiar with
actually use a bunch of “plumbing” commands.</p>
<p>I’m not going to dig too far into the Git plumbing commands - that’s enough
material for a whole book. If you want to learn more, check out the
<a href="https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain">documentation</a>.</p>
<h2 id="objects-and-references">Objects and References</h2>
<p>Objects and References (Refs) are the core of what makes git work.</p>
<h3 id="objects">Objects</h3>
<p>Git is a content-addressable filesystem, or simply put, Git uses a
<a href="https://en.wikipedia.org/wiki/Key-value_database">key-value data store</a>. This
is a concept most programmers learn early into their education. A key-value data
store means that you can add any type of file to a Git repository, and Git will
generate a unique key for that object. Key-value data stores have become somewhat
popular lately due to their speed and scalability. Some common database examples
are <a href="https://redis.io/">Redis</a> and <a href="https://aws.amazon.com/dynamodb/">DynamoDB</a>.</p>
<p>We’ve already learned that Git uses Hash functions to refer to specific commits
and branches. Git uses Hashes to refer to objects as well. For example, the
plumbing command <code>git hash-object</code> takes some file, stores the data in the
<code>.git/objects directory</code>, and returns the hash value that it stored the data at.</p>
<p>Commits are stored as Objects too! Ever wonder why Git is so damned fast? It’s
largely due to the key-value data model it uses.</p>
<h4 id="trees-and-blobs">Trees and Blobs</h4>
<p>All objects that Git stores are either a blob or a tree. A <em>blob</em> is just a fancy
way of referring to a binary file. A tree object is used to store filenames and
groups of files. A single tree object can contain other tree objects, and SHA-1
Hash values that point to a blob of data or other subtrees. Basically, Git stores
data similar to a regular Unix-like filesystem.</p>
<h3 id="references">References</h3>
<p>References (Refs) are the yin to the Git Object’s yang. While everything is stored
in Git as a blob referenced by SHA-1 Hashes, <em>References</em> allow you to refer to
that data without having to use hash values. <code>HEAD</code> for example, is a reference
that points to the SHA-1 Hash’d commit object of the most recent commit.</p>
<p>A <em>branch</em> is a reference to a certain commit, and all of the history that
commit includes.</p>
<h4 id="tags">Tags</h4>
<p>A <em>tag</em> is a handy way of referring to a specific commit. It’s kind of like a
branch reference, except it does not ‘move’ as you make more commits in that
branch. <em>Tags</em> are useful for doing release-management with Git.</p>
<h4 id="remotes">Remotes</h4>
<p>A <em>remote</em> is a reference that points to a remote git server. For example, when
you clone a repo from Github it creates a <em>remote</em> named <code>origin</code>. Once you’ve
added a remote and pushed to it with <code>git push</code>, Git stores the value you last
pushed in the <code>.git/refs/remotes</code> directory. You can always reference this
directory to see what a branch looked like the last time you pushed it to the
remote server. A remote is different than a branch in that Git considers it
“read only.” This is why your commits don’t write directly to the remote repo.
The HEAD never points to a remote, but to a local branch/commit.</p>
<h2 id="putting-it-all-together">Putting It All Together</h2>
<p>Okay, we’ve look at some of the things that make Git work behind the scenes.
Let’s take a minute to re-cap and put all the pieces together.</p>
<ul>
<li>Typical version control systems work by tracking changes to files. Git, however,
is not a delta-based VCS. Git takes a <em>snapshot</em> of the directory when you make
a <em>commit</em>.</li>
<li>Every file in a Git Repository can be in one of three states:
<ul>
<li>Modified</li>
<li>Staged</li>
<li>committed</li>
</ul>
</li>
<li>Every Git repository has a .git directory that contains pretty much everything
needed for Git to work.</li>
<li>Git has two types of commands, <em>plumbing</em> and <em>porcelain</em>.
<ul>
<li>Porcelain commands are what a user types into a terminal to perform regular
Git operations.</li>
<li>Plumbing commands are low-level commands used by Git and other scripts to
actually manipulate data, objects, and references.</li>
</ul>
</li>
<li>Objects and References make the world go ’round.
<ul>
<li>Everything in Git is stored as an <em>object</em> in a key-value data store.
<ul>
<li>Git uses an SHA-1 hashing algorithm to store data as blobs.</li>
</ul>
</li>
<li>References are nice ways to refer to SHA-1 hashes so we don’t have to
memorize and type 40-digit hexadecimal hash values.</li>
</ul>
</li>
</ul>
<p>And that’s the basics of how Git works!</p>
<hr />
<p>Thanks for reading! This post (and <a href="/2018/04/09/git-101.html">Git 101</a>) ended up
taking a lot more time writing than I originally anticipated. As a result, I’m
pushing back the upcoming “Git vs. the Competition” post to early next week to
wrap up “Git Week 2018.” For those of you that are getting tired of Git - new
content is coming too! Thanks for sticking it out this far. :smile:</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="git" /><summary type="html"><![CDATA[So far this week we’ve talked about what Git is and how to use it. If you’re anything like me, you want to know how things work under the hood. When you first learn Git it can seem like magic…but it also seems like something that can easily break. Or something that works by pure demonic byte voodoo. One of the best things Git does is allow you to write code with confidence - fear not about breaking things or losing files. They’re always recoverable. To feel confident, it helps to know how things work.]]></summary></entry><entry><title type="html">Git for Sysadmins</title><link href="https://chambers.io/blog/2018/04/12/git-for-sysadmins.html" rel="alternate" type="text/html" title="Git for Sysadmins" /><published>2018-04-12T00:00:00+00:00</published><updated>2018-04-16T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/04/12/git-for-sysadmins</id><content type="html" xml:base="https://chambers.io/blog/2018/04/12/git-for-sysadmins.html"><![CDATA[<p>Congratulations! You survived <a href="/2018/04/09/git-101.html">Git 101</a>. :tada: :tada:</p>
<p>I’m sure you noticed that it focused on using Git from the perspective of a
software developer. A common problem with most Git documentation and online tutorials
is that they are often written with one audience in mind: developers. Most of the
documentation aimed at System Administrators is focused around <em>administrating
a Git server</em>, not about actually <em>using Git</em> for system administration tasks. This
post is going to focus on <strong>practical ways you can use Git with System
Administration tasks.</strong></p>
<p>It turns out that Git and other version control systems can be just as useful
for System Administrators as they are for Developers. My background is in Linux
System Administration - so my knowledge and advice is focused on that area. I am
sure that many principles could easily apply to Windows administration as well.
If you had to distill sysadmin tasks to a bare minimum, a lot of the work that
is done is creating, editing, and maintaining various <em>plain-text</em> configuration
files and scripts.</p>
<p>What system works great with plain-text files? <em>Git, of course!</em></p>
<h2 id="practical-sysadmin-uses-for-git">Practical Sysadmin Uses for Git</h2>
<h3 id="puppetsaltansiblechef-configuration">Puppet/Salt/Ansible/Chef Configuration</h3>
<p>Automation is essential for survival in modern enterprise. There are simply too
many tasks to be done manually and too many servers to manage individually.
Configuration Management tools allow us to stay on top of an ever-growing list
of responsibilities and manage hundreds or thousands of servers with a
relatively small technical team. As companies move to <em>the cloud</em> and fully
embrace the <em>software-defined data center</em>, configuration management tools
become even more important. As we start to treat servers like cattle and less
like pets, we need a way to rapidly provision and configure new servers. It’s
great that we don’t have to care about keeping a specific physical server alive
any more - but all this virtualization and shuffling around data means that we
need to be able to spin up servers and configure them faster than ever.</p>
<p><img src="/assets/images/puppet_logo.png" alt="" /></p>
<p>When I was still working as a Linux System Administrator at the
<a href="http://chtc.cs.wisc.edu/">Center for High Throughput Computing</a> at the
University of Wisconsin, we used <a href="https://puppet.com/">Puppet</a> for our server
configuration management. Traditionally, Puppet uses a standard master and agent
method for configuring servers. You have a master Puppet server that holds all
of your Puppet code, and you push that out to Puppet agents running on
all of your other servers. In the “old school” Puppet model, you would compile
the puppet code on the master server with every change and to be sent out to
every server. This leads to one major bottleneck and point of failure in your
entire server management system - the Puppet master. This server can easily become
overloaded when managing thousands of agent servers, and serves as a single
breaking point.</p>
<p>It turns out, Git can be used with a tool like Puppet to add both speed and
reliability to your Puppet (or other CM tool) configuration! I won’t go into the
details, but you can set up a <em>masterless Puppet</em> system using Git!
<a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-masterless-puppet-environment-on-ubuntu-14-04">Here’s</a>
a great article from Digital Ocean that goes into more details about that. It’s
a little dated - targeting Ubuntu 14.04, but the basic idea and workflow will
work for any system. We used a self-hosted <a href="http://gitolite.com/gitolite/">Gitolite</a>
server, but just about any modern Git setup will do. The basic idea behind a
“masterless” Puppet system is to keep all of your Puppet code in your git
repository, and then have each server checkout the code and compile it on the
server itself. This prevents your master server from getting overloaded when
handling requests from thousands of servers at a time, and reduces the dependence
on a single server. Yes, you’re still reliant on a Git server, but it’s easier
to support and scale that Git server than a high-traffic Puppet master server.
The distributed nature of Git makes backups and restores easier as well.</p>
<p>Another reason to keep your Configuration Management files in a Git repository
is for easy testing and contributions from multiple administrators. If you want
to test a new configuration, in a few keystrokes you can create a new branch,
modify the code you want, and push that specific branch to a server. There’s no
need to include special language in the configuration code itself about only
modifying a certain server - because only the server you choose will update from
your test branch. Additionally, you can let multiple admins run wild writing
configuration code without worry about impacting or breaking the work others
have done. Just one of the many benefits of working in a distributed Git
environment! :smile:</p>
<h3 id="power-up-your-scripts">Power-Up your Scripts</h3>
<p>Scripts are the super-weapons of any System Administrator worth his or her salt.
Whether it’s Python, Bash, PowerShell, Perl, or whatever else you crazy kids are
using these days, there’s no reason to not keep your scripts in a Git repository.
Why?</p>
<p><img src="/assets/images/python_logo.png" alt="" /></p>
<ul>
<li>(Unofficial) distributed back-ups.
<ul>
<li>A remote Git server is <strong>not</strong> a perfect back-up system, but it’s a hell of
a lot better than nothing. Keep everything you write pushed to a remote Git
server on a daily basis and the day your laptop spontaneously combusts won’t be
<em>quite</em> as bad any more. You put a lot of work into writing scripts - store
them properly!</li>
</ul>
</li>
<li>Facilitate re-use.
<ul>
<li>Keeping your scripts in a Git repository means you can easily pull them down
to multiple Git servers and re-use something you have written. It’s also an
easy way to let other administrators on your team make use of the awesome work
you have done. It’s possible they are trying to solve the same problem as you
and could make good use of your existing work.</li>
</ul>
</li>
<li>Facilitate cooperation and community.
<ul>
<li>One of the greatest unintended rewards from the Git movement is how
it facilitates a strong sense of community. Use a Git platform with good
community features like <a href="https://enterprise.github.com/home">Github</a> or
<a href="https://about.gitlab.com/">Gitlab</a> and you can start working together in ways
you’ve never previously imagined!</li>
</ul>
</li>
<li>Versioning, branches, and diffs.
<ul>
<li>As I pointed out in <a href="/2018/04/09/git-101.html">Git 101</a>, one of the primary
uses of Git is versioning and revision control. You can use Git to keep
multiple versions of a script, whether it be for testing, for different
servers, or even for different operating systems. Additionally,
being able to “go back in time” and view your script at different points in
its history can help you understand what is happening or why you did something
a certain way. Commit messages are another way of adding readability to your code.
Look at the diff between different commits to see what you changed and why!
Need to change the script but also keep a working version? Create a test
branch!</li>
</ul>
</li>
<li>Make things easy for the new guy.
<ul>
<li>Handing off ‘the keys’ to the new guy is rarely a fun or easy thing. The
reality is that most people will change jobs/companies every couple of years.
If you’re a good administrator, you will keep everything well documented for a
smooth handoff when you leave and someone new comes in. Having all of your
configuration files and scripts in a remote Git repository makes that process
remarkably better. You don’t have to worry about giving them a USB drive full
of random files and scripts with no real documentation or explanation.</li>
</ul>
</li>
</ul>
<h3 id="documentation">Documentation</h3>
<p>I am <em>sure</em> you read my post on <a href="/2018/04/03/why-markdown.html">writing in Markdown</a>.
If you do choose to keep notes and documentation in Markdown, you can readily
store those files in a Git repository. I’ve got some pretty opinionated thoughts
on technical documentation that I’ll have to get to in another post, but I firmly
believe the key to good documentation is that the contents is properly indexed
and searchable. If you use a Git service like Github, your entire repository is
indexed for easy searching. Huzzah! There are many choices for documentation:
from wiki pages to directories full of spreadsheets and MS Word documents…and
some are much better choices than others.</p>
<p>I’m not sure if writing a bunch of documents and storing them in a Git repo is
the best choice for documentation, but it’s certainly not the worst, and it’s
absolutely better than keeping no documentation at all! I’m in favor of wiki-style
centralized documentation sources. A self-hosted <a href="https://www.mediawiki.org/wiki/MediaWiki">Mediawiki</a>
site is a great choice if you’re strapped for cash. Thanks to <a href="https://www.docker.com/">Docker</a>
you can get a <a href="https://hub.docker.com/r/_/mediawiki/">Mediawiki instance</a> running
over your lunch break. On the enterprise-y side of things, I really like
<a href="https://www.atlassian.com/software/confluence/why-wiki-collaboration-software">Atlassian’s Confuence Wiki</a>.</p>
<p>I don’t have any experience with it, but there’s a pretty slick wiki called
<a href="https://github.com/jgm/gitit">Gitit</a> that uses Git + Markdown files to manage
knowledge! This is an awesome approach for a lightweight Wiki because it doesn’t
require running a full PHP/SQL setup like Mediawiki, and it doesn’t have the
costs of an enterprise setup like Confluence.</p>
<p>You can also write documentation (or textbooks, guides, etc) with
<a href="https://www.gitbook.com/">Gitbook</a>! You can tie Gitbook into a Github account
and write documentation in Markdown. This is one model that allows a team to
collaborate and for write simple, elegant documentation, that is also easy to
share with others.</p>
<h3 id="prototyping-and-data-visualizations">Prototyping and Data Visualizations</h3>
<p>As a system administrator you might find yourself tasked with quickly deploying
prototypes of various applications or websites. You can use tools like Jekyll,
Markdown, and Git to build simple websites and dashboards. Need to throw
together a small presentation to argue for a larger department budget? Aggregate
your data in a git repository and use a number of tools to help visualize that
data.</p>
<p>Monitoring and logging have become essential tasks for system administrators.
There are many tools for the job these days, including some personal favorites
like <a href="https://grafana.com/">Grafana</a> and <a href="https://www.icinga.com/">Icinga</a>. These
tools are great for tapping into live applications and services to monitor different
metrics. With a little bit of work, there’s a massive number of tools available for
<a href="https://github.com/topics/data-visualization">visualizing data</a>. A Git
repository is a great natural place to store this data - especially if it’s in
a plaintext form like CSV. Using a Git repo allows you to view changes in data
over time.</p>
<hr />
<p>And there you have it. Just as promised, a couple of practical uses for Git as a system
administrator.</p>
<p>Coming up next, we’ll open up the hood of our favorite tool and get our hands
dirty as we dig into some technical details to find out how Git really works. :wrench:</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="git" /><category term="sysadmin" /><summary type="html"><![CDATA[Congratulations! You survived Git 101. :tada: :tada:]]></summary></entry><entry><title type="html">Git 101</title><link href="https://chambers.io/blog/2018/04/09/git-101.html" rel="alternate" type="text/html" title="Git 101" /><published>2018-04-09T00:00:00+00:00</published><updated>2018-10-31T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/04/09/git-101</id><content type="html" xml:base="https://chambers.io/blog/2018/04/09/git-101.html"><![CDATA[<p>Welcome to Git 101! This pico-course is going to take you from zero-to-hero with
one of the greatest technologies of the last 20 years. We’ll explore a brief
history of Version Control, look at all the Git essentials, and finally, you’ll
learn a practical Git workflow to immediately improve your quality-of-life.
If you feel like you’ve wandered here in error, note that Zoology 319:
<em>Searching for Sasquatch</em> has been moved down the hall to room 210.</p>
<h3 id="why-is-this-course-needed">Why is This Course Needed?</h3>
<p><a href="https://git-scm.com/">Git</a> is an awesome technology that has become the
de-facto standard for version control in the software development industry.
It is also a technology that most people never properly learn. Few University
Computer Science programs cover it. Most new graduates and junior developers
will teach themselves Git or other version control software as needed. You will
be hard pressed finding a development job today that doesn’t require you to
learn and use Git in some manor, and I’d argue that it’s impossible to find a
development job worth keeping if they don’t use some kind of version control
(and yes, they do exist).</p>
<p>Git is an essential tool of the modern developer. A tool they will use as often
as a good text editor or noise-canceling headphones in an open office. Yet it
remains a tool that is often brought up as an afterthought in a developer
interview. Git is to developers what a good hammer is to a carpenter. Can you
drive a nail into a board without it? Sure. But you sure as hell wouldn’t want
to.</p>
<h2 id="what-is-version-control">What is Version Control?</h2>
<p>I’m not going to give you a history less on Version Control. If you want that,
just check out the
<a href="https://en.wikipedia.org/wiki/Version_control">Wikipedia article</a>.</p>
<p>Here’s a TL;DR of that page: Version control is an essential component of software
development that tracks changes to source code files over the life of a project.
As the name implies, version control software lets you keep different versions
of the same source code files and permanently track changes to those files.
It allows you to easily deploy an application to different environments (like
testing or production) and it allows erroneous updates to be gracefully rolled
back if needed. Perhaps most importantly, modern VCS (Version Control Systems)
allow multiple people to independently contribute to a project in a (mostly)
headache-free way.</p>
<p>Are you tired of your source code directories looking like this</p>
<pre><code>$ ls
index.php                    index-new.php     index-new2.php
index-final.php              index-final2.php  index-final2-edited.php
index-final2.edited.php.bak  index-actually-final!.php
</code></pre>
<p>after a long days work?</p>
<p>Tired of using FTP to transfer individual files and constantly making
and copying backups by hand?</p>
<p>Look no further! With proper version control, those
are all relics of the past.</p>
<h2 id="git-a-brief-history">Git: A Brief history</h2>
<p>Git was first released on April 7, 2005, following an incident with the source
control management (SCM) software BitKeeper and Linux Kernel development.
<a href="https://en.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a>, perhaps best
known for <a href="https://groups.google.com/forum/#!msg/comp.os.minix/dlNtH7RRrGA/SwRavCzVE7gJ">developing a little OS (Kernel) named Linux</a>,
created Git as a result of BitKeeper removing free use of their product. Failing
to find a free product that worked similar to BitKeeper and met the requirements
for developing the Linux Kernel, Torvalds decided to create his own SCM software,
and Git was born.</p>
<p>The primary design goals for Git was something that:</p>
<ul>
<li>Ran stupidly fast, due to the demanding nature of patching the Linux Kernel.</li>
<li>Prevented data corruption.</li>
<li>Allowed for distributed workflows.</li>
</ul>
<p>Within a couple of weeks Torvalds had managed to achieve all of this, and
version control as we know it was changed forever. Git was 100% free software,
arguably better than everything else on the market, and was compatible with
existing SCM workflows.</p>
<h2 id="git-basics">Git Basics</h2>
<h3 id="before-we-begin">Before we Begin</h3>
<h4 id="visualizing-git">Visualizing Git</h4>
<p>It’s best to image a Git repository like a tree. It starts growing from the
ground up. When a tree is new, it might only consist of a single branch (AKA
the trunk). In most git repositories (and by default) this trunk is called
<code>master</code>. The oldest bits of the tree will be near the base of the tree, and
the newest bits will be at the top. Over time, the tree will grow. It will
grow taller. It will grow branches. Those branches will grow branches.
When trying to understand how a Git repository is laid out, imagine
a picture of a tree where the oldest stuff is at the bottom, and the newest
stuff is spread far out on branches or at the very top.</p>
<h4 id="terminology">Terminology</h4>
<p>I’m going to throw around a lot of terminology in this course, and some of it is
not going to be explained in detail. If a term confuses you, just look it up on
Google. At some point I might add a  proper glossary. Until then, here’s a few
important definitions. Also check out the official
<a href="https://git-scm.com/docs/gitglossary">Git Glossary</a>.</p>
<ul>
<li>repository (repo) - A directory that contains all the files associated with a
particular Git project.</li>
<li>HEAD - A reference to the currently checked out commit. Basically, the files
that you see.</li>
</ul>
<p><strong>Disclaimer</strong>: All of the Git commands we’re going to learn today are for the
command-line. By nature, Git works best via a command-line interface. Although
there are many awesome GUI tools for working with git, it is essential to learn
the basics via the command-line. This guide assumes that you know how to do
basic operations from the command line in a Unix-like environment.</p>
<p>There are a couple of <em>basic Git commands</em> you must know in order to
effectively use the tool. While the total number of git commands and options
far exceeds the basics, knowing these will allow you to do most things you will
ever need to.</p>
<p><strong>The big five</strong>: <code>clone</code>, <code>pull</code>, <code>push</code>, <code>add</code>, <code>commit</code>. Learn these and you
can start working with git. Of <em>the big five</em>, none is more important than the
others, because you need all of them in order for Git to work.</p>
<p><strong>The essential two:</strong> <code>status</code>, <code>log</code>. While knowing <em>the big five</em> commands above
is the bare minimum to get you started with Git, you’ll also want to learn these
<em>essential two</em> commands.</p>
<p>Before we dig into the commands, let’s look at a simple workflow for working on
a software project. Let’s imagine you are working on a simple application and
the source code is hosted on a server managed by your operations team. You need
to make a copy of that source code on your local development machine, make a
change to a file, and then upload that file to the server.</p>
<h3 id="the-big-five">The Big Five</h3>
<ol start="0">
<li>Make sure git is installed on your machine, and make sure you have done the
<a href="https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup">first-time setup</a>
by setting your Username and Email:</li>
</ol>
<ul>
<li><code>$ git config --global user.name &quot;&lt;Your Name&gt;&quot;</code></li>
<li><code>$ git config --global user.email &lt;Your Email&gt;</code></li>
</ul>
<ol>
<li>Use the <code>clone</code> command to copy source code from a remote server to your machine.</li>
</ol>
<ul>
<li>Change into the directory you want to work in (eg ~/Projects)</li>
<li>Copy the source code with: <code>$ git clone &lt;URL-of-remote-git-repository&gt;</code>
<ul>
<li>:warning: A git repository URL will end in <code>.git</code>.</li>
</ul>
</li>
<li>This will copy the entire source code repository onto your local machine
in the location you specified above. (eg ~/Projects/repo-name)
<ul>
<li>Not only does this copy the source code files, but it copies every
branch and the history of every file to your computer.</li>
<li>By default, you will be viewing the <code>master</code> branch. We’ll look at what
a branch is more in the next section.</li>
</ul>
</li>
<li>Some people will be upset that I started with <code>clone</code> instead of <code>init</code>. Most people that use
Git these days work with a remote repository (GitHub, GitLab, etc).
<ul>
<li>If you don’t have a remote repository and want to create a git repo, you can use <code>$ git init</code>
instead to create a new git repository in your current working directory.</li>
</ul>
</li>
</ul>
<ol start="2">
<li>Great, now you’ve got the source code, edited the file you needed to, and
you’re ready to send that change back to the remote server. First, you’ll need
to <code>commit</code> your changes.</li>
</ol>
<ul>
<li>Before you can <code>commit</code> your changes, you need to <code>add</code> them. These two
commands go together like peanut-butter and jelly.</li>
<li>Use the <code>add</code> command to add all files you have created or modified to the
staging area.
<ul>
<li><code>$ git add &lt;list-files-delimited-by-spaces&gt;</code></li>
<li>You can also use a catch-all like <code>git add *</code></li>
</ul>
</li>
<li>Use the <code>commit</code> command to record your change in the Git repository. No
change you make is recorded in the Git history until you make a commit.
<ul>
<li><code>$ git commit</code>
<ul>
<li>:warning: You have to create a message for every commit you make. Just
typing <code>git commit</code> will open up your default text editor for you to
write a commit message.</li>
<li>You can short-hand this by using the <code>-m</code> flag.
<ul>
<li><code>$ git commit -m &quot;A commit message&quot;</code>
<ul>
<li>This is useful but it is good practice to write proper commit
messages. A proper commit message will have a single line of
72 characters or less that summarizes the changes. Below that,
you can write a more detailed explanation of what the changes in
the commit do. It’s also good practice to write commit messages
in the imperative form (eg “Fix Bug” not “Fixed a Bug”).
<ul>
<li>Here’s an example:</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>Update database references

We've decided to switch from SQLite to MySQL for our web application.
This commit changes all of the variable references from the SQLite DB
to the new MySQL DB.
</code></pre>
<ol start="3">
<li>Okay, you’ve got your changes made and committed. Congratulations - only you
can see those changes on your local machine. You need to <code>push</code> these changes
to the remote server.</li>
</ol>
<ul>
<li>Use the <code>push</code> command to publish your changes on the remote server.</li>
<li><code>$ git push &lt;Remote-repository-name&gt; &lt;Branch-name&gt;</code>
<ul>
<li>For this example, you can use something like: <code>$ git push origin master</code>
<ul>
<li>The remote repository is named <code>origin</code> by default.</li>
<li>We haven’t yet taught you about branching, so you’ll likely still
be on the <code>master</code> branch.</li>
</ul>
</li>
</ul>
</li>
<li>Your changes are now live on the remote server! :tada:</li>
</ul>
<ol start="4">
<li>Now, let’s imagine another developer has been making changes and you want to
update your local copy of the source code with those changes. You could blow
away the entire directory and re-clone it, but that seems like a lot of work and
wasted bandwidth. Let’s use the <code>pull</code> command instead.</li>
</ol>
<ul>
<li>Run: <code>$ git pull</code></li>
<li>This will <code>fetch</code> those changes from the remote server and <code>merge</code>
those changes with your local copy. What’s this? <code>fetch</code> and <code>merge</code>? You
told me there were only five commands I had to know?! Well, we’re doing a
little bit of <em>git magic</em> here. The <code>pull</code> command is actually equivalent
to running both <code>git fetch</code> followed immediately by <code>git merge &lt;Fetch-head&gt;</code>
<ul>
<li>Ulimately, you’ll want to learn both <code>git fetch</code> and <code>git merge</code> on their
own. For now, just knowing <code>git pull</code> will let you get by.</li>
</ul>
</li>
</ul>
<p>:tada: Congratulations! With these five commands, you can <em>start</em> working with
Git. Let’s go home and have some beer :beer:, right? Wrong! There’s a lot more
to Git than just pulls, commits, and pushes.</p>
<p>In particular, there are two commands you will find <em>essential</em> when using git.</p>
<h3 id="the-essential-two">The Essential Two</h3>
<p>The commands I outlined above will let you start working with git, but they
sure don’t provide a lot of information. While the following two commands are not
<em>technically</em> required to use Git, they are all but <em>essential</em> for using Git
effectively. Trying to do anything without them would be like trying to
perfectly mount a frame on a wall without a level.</p>
<ul>
<li>
<p><code>git status</code> - The status command, exactly as you would imagine, tells you
the status of your current working tree.</p>
<ul>
<li>It tells you what files have been created or modified.</li>
<li>It tells you if new/modified files have already been added to the current
working index with <code>git add</code>.</li>
<li>It tells you what branch you are working on.</li>
<li>It tells you if your current working branch is “ahead” or “behind”
the branch you started from.</li>
</ul>
</li>
<li>
<p><code>git log</code> - The git log command prints out a log (history) of all commits
made in a repository.</p>
<ul>
<li>At a glance, this lets you take a brief but detailed look at the changes
to a project over time.</li>
<li>By default, git log will print a little basic information about
each commit in reverse chronological order (most recent changes are listed
first). Each bit of information contains:
<ul>
<li>The commit hash (A SHA-1 checksum, a 40-digit hexadecimal string you can
use to uniquely identify a particular commit).</li>
<li>The commit author.</li>
<li>The commit date.</li>
<li>The commit summary.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="beyond-the-basics">Beyond the Basics</h2>
<p>Each of the commands I outlined above has about a million options. It would be
well worth your time to check out the
<a href="https://git-scm.com/docs">official documentation</a> or to read some more advanced
tutorials. I will give a couple of examples of “advanced” commands in this Course,
but this is <em>Git 101</em> after all. Maybe some day I’ll be able to make a <em>Git 201</em>
. :smile:</p>
<h3 id="branches">Branches</h3>
<p>Remember how I told you to visualize a Git repository as a tree? What kind of
tree doesn’t have branches? Branches are an essential part of Git or any modern
version control system and Git’s branching model is particularly awesome.</p>
<p>In practice, you don’t want to be making your changes directly to the <code>master</code>
branch of a repository. Let’s look at some commands to help you create your own
branch or work with branches other than <code>master</code>.</p>
<ul>
<li>
<p><code>branch</code></p>
<ul>
<li>Use the <code>branch</code> command to list, create, or delete branches.</li>
<li><code>$ git branch</code> - This command with no flags will list all branches you have
on your local machine, and designates your current working branch with an
asterisk (*).</li>
<li><code>$ git branch -r</code> The -r flag shows all branches in the remote repository.</li>
<li><code>$ git branch &lt;New-Branch-Name&gt;</code> will create a new branch based off of your
current working branch.</li>
</ul>
</li>
<li>
<p><code>checkout</code></p>
<ul>
<li>Use the <code>checkout</code> command to switch between branches.</li>
<li><code>$ git checkout &lt;Branch-name&gt;</code> immediately switches you to the desired branch.</li>
<li><code>$ git checkout -b &lt;New-Branch-Name&gt;</code> will create a new branch and switch to it.</li>
</ul>
</li>
<li>
<p><code>merge</code></p>
<ul>
<li>When working between multiple branches, at some point you will probably copy
the changes from one branch into another. You can accomplish this with the
<code>merge</code> command.</li>
<li><code>$ git merge &lt;Branch-name&gt;</code> will merge the branch (Branch-name) into your
<em>current</em> branch. This is best explained with an example:
<ul>
<li>Let’s imagine that you have been working on a branch named “fix-bug” and
you are ready to merge your changes back into the master branch.</li>
<li>The “tree” might look like this, where each letter is a commit:</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>      E---F---G    &lt;-- fix-bug
     /
A---B---C---D      &lt;-- master
</code></pre>
<ul>
<li>To merge the <code>fix-bug</code> branch into <code>master</code>, first, checkout the <code>master</code>
branch with <code>$ git checkout master</code> and then merge with <code>git merge fix-bug</code>.</li>
<li>If all goes well, the changes you made in <code>fix-bug</code> will now appear in
<code>master</code> and the “tree” will look like this:</li>
</ul>
<pre><code>      E---F---G     &lt;-- fix-bug
     /         \
A---B---C---D---H   &lt;-- master
</code></pre>
<ul>
<li>It is important to note that the <code>fix-bug</code> branch still exists, and you
can still work on it independently from <code>master</code> or any other branches
if you want to.</li>
</ul>
<h4 id="solving-a-merge-conflict">Solving a Merge Conflict</h4>
<p>Inevitably you’re going to try to merge two branches together and see the
dreaded words: <strong>merge conflict.</strong> This sounds a lot scarier than it is.</p>
<p>What is a merge conflict? A merge conflict occurs when git unable to
automatically merge two files together. This typically occurs when a particular
line or a file has been changed in two different branches. Git is unsure of which
change you want to keep, so you will have to decide which change stays and which
change gets deleted. In reality, merge conflicts are a regular part of using Git.</p>
<ul>
<li>Run <code>$ git status</code> to see which file has the merge conflict.</li>
<li>Open that file with whatever text editor you prefer.</li>
<li>Inside the file, Git marks where the merge conflict happens. Here’s an example
of what you will see.</li>
</ul>
<pre><code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
some text
=======
text other text
&gt;&gt;&gt;&gt;&gt;&gt;&gt; BRANCH-NAME
</code></pre>
<ul>
<li>In this example, <code>some text</code> between <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD</code> and <code>=======</code> is the source
code in the HEAD or current base branch.</li>
<li><code>some other text</code> between <code>=======</code> and <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; BRANCH-NAME</code> is the source code
in the <code>BRANCH-NAME</code> branch.</li>
<li>Simply delete whatever version you want to get rid of, leaving the version that
you want to merge in. Also delete the conflict markers (<code>&lt;&lt;&lt;</code>, <code>===</code>, <code>&gt;&gt;&gt;</code>) and
associated text that Git inserted into the file.
<ul>
<li><code>commit</code> the file that you fixed, and <code>push</code> it as necessary!</li>
</ul>
</li>
</ul>
<p>See, that’s not so scary! :ghost:</p>
<h3 id="a-few-more-things">A Few More Things…</h3>
<p>Here’s a couple more useful git tricks to get you started!</p>
<ul>
<li><code>rebase</code>
<ul>
<li>Use <code>$ git rebase &lt;Branch-to-Rebase-Onto&gt;</code> to <em>move</em> a commit, or set of
commits, from one base commit to another.</li>
<li>Picture the Git tree we’ve talked about. Imagine if you could cut off a branch,
and then seemly glue it back on somewhere else on the trunk. That is rebasing!</li>
<li>Visualy, it looks like this:</li>
</ul>
</li>
</ul>
<pre><code>      E---F---G    &lt;-- fix-bug
     /
A---B---C---D      &lt;-- master
</code></pre>
<ul>
<li>Run <code>$ git rebase master fix-bug</code> and it will now look like:</li>
</ul>
<pre><code>              E---F---G    &lt;-- fix-bug
             /
A---B---C---D      &lt;-- master
</code></pre>
<ul>
<li>
<p><code>stash</code></p>
<ul>
<li>Working on something and suddenly realize you have to switch branches to
quickly fix a bug? You can quickly save your changes with <code>$ git stash</code>
<ul>
<li>This will store the current state of the repository, along with your file
changes, and revert back to the HEAD commit. You can always re-apply these
changes with <code>$ git stash apply</code>.</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Use <code>git diff</code> to view changes in a commit.</p>
<ul>
<li>Want to quickly see what files were changed from one commit to another?
Use <code>git diff</code>!</li>
<li><code>$ git diff &lt;HASH1&gt; &lt;HASH2&gt;</code>
<ul>
<li>HASH1 is the SHA-1 hash of the earlier commit, and HASH2 is the SHA-2 hash
of the later commit. It will show you all of the changes in every file in
classic diff style.</li>
</ul>
</li>
</ul>
</li>
<li>
<p><code>.gitignore</code></p>
<ul>
<li>Don’t forget your <code>.gitignore</code> file! Use this to tell Git to ignore certain
file types. This is useful for configuration files specific to your machine.</li>
<li>Create a <code>.gitignore</code> file with whatever text editor you want.
<ul>
<li>Simply list out the file extensions of whatever files you want to ignore.</li>
<li>You can also list specific files.</li>
</ul>
</li>
<li>For example, a <code>.gitignore</code> file that contains <code>.log</code> will ignore every file
in your repository that ends with <code>.log</code>.</li>
</ul>
</li>
</ul>
<h2 id="practical-git-workflow">Practical Git Workflow</h2>
<p>Okay, now you know the basics. I promised you a no-nonsense method to use these
tools to bring the best of Git to your life. Here goes! This is a basic Git
workflow that will let you work both independently and with multiple people on
projects that have source code hosted on a remote repository
(e.g. <a href="https://github.com">Github</a>).</p>
<p>This is a <em>basic</em> git Workflow. It incorporates most of what you just learned.</p>
<ol>
<li>Clone the master repository onto your local machine.</li>
</ol>
<ul>
<li><code>$ git clone [url]</code></li>
</ul>
<ol start="2">
<li>Create a new branch on your local machine to work on a feature.</li>
</ol>
<ul>
<li><code>$ git checkout -b [new_branch_name]</code></li>
</ul>
<ol start="3">
<li>Push the branch to the remote server.</li>
</ol>
<ul>
<li><code> $ git push origin [new_branch_name]</code></li>
</ul>
<ol start="4">
<li>Add a remote for your branch.</li>
</ol>
<ul>
<li><code>$ git remote add [new_remote_name] [git url]</code></li>
</ul>
<ol start="5">
<li>Make changes to local files.</li>
<li>Stage the changes you want to commit.</li>
</ol>
<ul>
<li><code>$ git add [file_name]</code></li>
</ul>
<ol start="7">
<li>Commit the changes.</li>
</ol>
<ul>
<li><code> $ git commit</code></li>
</ul>
<ol start="8">
<li>Push the commit to your branch.</li>
</ol>
<ul>
<li><code>$ git push origin [new_branch_name/new_remote_name]</code></li>
</ul>
<ol start="9">
<li>Depending on your team organization, you have a couple options for merging
these changes into the <code>master</code> branch.</li>
</ol>
<ul>
<li>If you’re using github, submit a <a href="https://help.github.com/articles/about-pull-requests/">pull request</a></li>
<li>Optionally, merge these into a staging/testing branch, or use a tool like Jenkins
to automate the testing and deployment process.</li>
</ul>
<ol start="10">
<li>Once your changes have been accepted and you are done with this branch, you can delete it.</li>
<li>Switch back to the master branch.</li>
</ol>
<ul>
<li><code>$ git checkout master</code></li>
</ul>
<ol start="12">
<li>Update your local master with the changes from the repository.</li>
</ol>
<ul>
<li><code>$ git pull</code></li>
</ul>
<ol start="13">
<li>Delete the branch you created.</li>
</ol>
<ul>
<li><code>$ git branch -d [new_branch_name]</code></li>
</ul>
<ol start="14">
<li>Delete the branch on the remote github repository.</li>
</ol>
<ul>
<li><code>$ git push origin :[new_branch_name]</code></li>
</ul>
<p>This has gotten quite a bit longer than I originally intended. Looks like I’ll
have to make a Git 201 pico-course some time soon to cover even more fun stuff
you can do with Git.</p>
<p>That’s all for now! I hope you’ve learned a lot and you feel ready to start using
Git with your own projects! Feel free to drop me a message
<a href="https://twitter.com/DakotaChambers">on Twitter </a> if you’ve got any
questions or feedback. Thanks!</p>
<p>P.S. This is part of a <a href="/2018/04/07/git-week.html">week-long miniseries on Git</a>.
Make sure to check out the other articles!</p>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="git" /><summary type="html"><![CDATA[Welcome to Git 101! This pico-course is going to take you from zero-to-hero with one of the greatest technologies of the last 20 years. We’ll explore a brief history of Version Control, look at all the Git essentials, and finally, you’ll learn a practical Git workflow to immediately improve your quality-of-life. If you feel like you’ve wandered here in error, note that Zoology 319: Searching for Sasquatch has been moved down the hall to room 210.]]></summary></entry><entry><title type="html">Happy Birthday, Git!</title><link href="https://chambers.io/blog/2018/04/07/git-week.html" rel="alternate" type="text/html" title="Happy Birthday, Git!" /><published>2018-04-07T00:00:00+00:00</published><updated>2018-04-18T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/04/07/git-week</id><content type="html" xml:base="https://chambers.io/blog/2018/04/07/git-week.html"><![CDATA[<p><img src="/assets/images/git-logo.png" alt="" /></p>
<p>Git turns 13 today…which means it is officially in its angsty teenage years!
To celebrate, I’m doing a week-long miniseries on Git.</p>
<p>Here’s a preview of what’s coming up:</p>
<ul>
<li>
<p><a href="/2018/04/09/git-101.html">Monday: Git 101</a></p>
<ul>
<li>Have you heard all the cool kids talking about this magical thing called
Git? Want to know what all the fuss is about but not sure where to start?
Applying for a job fresh out of college? This is the lesson for you! Tune in
Monday, April 9th for Git 101. I’ll take you through a brief history of Git
and version control, why it’s important, and cover all the git basics so that
you are ready to <em>commit with confidence</em>.</li>
</ul>
</li>
<li>
<p><a href="/2018/04/12/git-for-sysadmins.html"><del>Wednesday</del> Thursday: Git for Sysadmins</a></p>
<ul>
<li>Most Git tutorials and lessons focus on using Git from a developer
perspective. I’m going to tell you why and how you should learn git as a
System Administrator.</li>
</ul>
</li>
<li>
<p><a href="/2018/04/15/how-git-works.html"><del>Friday</del> Sunday: How Git Works</a></p>
<ul>
<li>A brief look at how Git Works under the hood. What the hell is a <em>diff</em> and
why should I care? How is it so fast? What is so great about distributed
version control?</li>
</ul>
</li>
<li>
<p><a href="/2018/04/17/git-vs-the-competition.html"><del>Saturday</del> Next Week: Git vs. the Competition</a></p>
<ul>
<li>Git isn’t the only (distributed) version control system…are the others
worth looking at? We will take a brief tour of the history of version control
systems to see how we ended up where we are today, and compare Git to the
other options.</li>
</ul>
</li>
</ul>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="git" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Why You Should Write in Markdown</title><link href="https://chambers.io/blog/2018/04/03/why-markdown.html" rel="alternate" type="text/html" title="Why You Should Write in Markdown" /><published>2018-04-03T00:00:00+00:00</published><updated>2018-04-04T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/04/03/why-markdown</id><content type="html" xml:base="https://chambers.io/blog/2018/04/03/why-markdown.html"><![CDATA[<blockquote>
<p><em>What is this Markdown nonsense and why should I care? I’ll give up .doc when
you pry it from my cold, dead hands.</em></p>
</blockquote>
<p>- An actual quote I made up just for this blog post.</p>
<p>John Gruber, of <a href="https://daringfireball.net">Daring Fireball</a> fame, had a
problem. After years of writing and reading HTML, he found himself sporadically
inserting HTML tags into his everyday writing. His WYSIWYG text editor wasn’t
responding to his creative desires. His emails were boring, unformatted text
blobs. Yet he was able to get by.</p>
<p>That was, at least, until <em>the incident</em>. One day John stumbled upon an ancient
HTML document…a document that contained
<a href="https://en.wikipedia.org/wiki/P_versus_NP_problem">a secret</a> every computer
scientist, mathematician, and amateur programmed wants to know. But this
document was marred by thousands of now obsolete HTML tags and other garbage
associated with the ancient language.</p>
<p>Parsing the contents proved challenging, but he began to uncover the secrets
until he made a critical mistake. Due to something we now call <em>tag fatigue</em>,
John unknowingly skipped over a small line and missed a crucial sentence
explaining the timed self-destructing nature of the document. He was exhausted
from a day of decrypting the ancient language and went to sleep, only to return
the next morning and find the entire file wiped from existence. Had John not
suffered that <em>tag fatigue</em> he might have hurriedly copied the file, snapped a
photo, or pushed on into the wee hours of the night.</p>
<p>In a fit of rage John cried out, cursing the Computer Gods. The Gods answered,
and told John the path to true righteousness was through a language he would
create. On what we now call the First Day, John named his creation Markdown.</p>
<p>At least that’s how I imagined it happened.</p>
<h2 id="so-what-is-markdown">So, What is Markdown?</h2>
<p><img src="/assets/images/markdown_logo.png" alt="" /></p>
<p>From the creator himself, <em>“The idea for Markdown is to make it easy to read,
write, and edit prose. HTML is a publishing format; Markdown is a writing
format.”</em><sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup></p>
<p>Let’s take a look at this simple example. The first is valid HTML and the
second is valid Markdown. The generated content is identical.</p>
<pre><code>A &lt;i&gt;quick&lt;/i&gt; brown fox &lt;del&gt;hopped&lt;/del&gt; jumped over the &lt;b&gt;lazy&lt;/b&gt; dog.
</code></pre><pre><code>A *quick* brown fox ~~hopped~~ jumped over the **lazy** dog.
</code></pre>
<p>A <em>quick</em> brown fox <del>hopped</del> jumped over the <strong>lazy</strong> dog.</p>
<ul>
<li>The HTML Markup takes 25% more characters (75 vs. 60) to represent the same
content.</li>
<li>The markdown is (subjectively) easier to read because there are no jarring
brackets/tags.</li>
<li>The displayed content is identical because Markdown is converted to HTML when
viewed in a web browser. That said, this proves you don’t have to write/read
boring old HTML when writing and reading prose.</li>
</ul>
<p>In essence, Markdown is a lightweight markup language that can be converted to
many other languages. It is a tool to create rich text content using plain text.
And you should be using it for all<sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup> of your writing. Here’s why.</p>
<h2 id="plain-text-is-king">Plain Text is King.</h2>
<p>Perhaps the most important feature of Markdown is that it is written in simple
plain text format. This means the characters that appear on your screen are
exactly the characters that your computer writes to the file on your hard
drive.<sup class="footnote-ref"><a href="#fn3" id="fnref3">3</a></sup> Here’s why that matters:</p>
<ul>
<li>Take your Words with you - no Vendor Lock-In!
<ul>
<li>If you find yourself writing important documents in .doc or some other
proprietary format, you will find yourself <em>locked in</em> to that text editing
environment. If you try to open that document with anything other than the
supported, often non-free editor, it will look like gibberish. Anyone that
wants to view or edit your file is going to need to use their software, and
you will always need to if you want to open or edit your own file long into
the future.</li>
</ul>
</li>
<li>Use Version Control for Back-Ups, Versioning, and Editing.
<ul>
<li>I’m sure you already know how amazing Git is. If not you’ll have to wait for
me to explain that in another blog post. The beauty of plain text is that it
allows your files to work properly with version control. Version control works
by looking at the <em>diffs</em> of various verions of a file. It’s nearly impossible
to track a file diff in a proprietary or binary format, but it’s pretty simple
with plain text documents! This means you can version control your documents
the same way you would code.
<ul>
<li>You can use version control like Git as a distributed back up system.</li>
<li>As the name implies, use version control to create and maintain different
versions of your writing. Want to start rewriting something while keeping an
unchanged copy of the original? Easy! Just make a new branch and make your
changes, while your original is always there for reference.</li>
<li>Version control is also great for editing. Let anyone view/edit your files
without affecting the original by using a
<a href="http://nvie.com/posts/a-successful-git-branching-model/">git branching model.</a></li>
</ul>
</li>
</ul>
</li>
<li>Convert to Other Formats.
<ul>
<li>Markdown can be converted to pretty much any relevant format these days.
While you write in plain text, there’s no reason you have to read it that way!
Convert your Markdown document to PDF, LaTeX, HTML, etc. There’s a plethora of
tools available, but one of my favorites is <a href="https://pandoc.org/">Pandoc</a>.</li>
</ul>
</li>
<li>Focus on the Content, not the Styling.
<ul>
<li>As I pointed out in my <sup>totally non-fiction</sup> account of the creation
of Markdown earlier, the real beauty of Markdown and plain text is that it
allows you, the writer, to focus on the content itself. Markdown lets you do
simple but powerful styling without getting in your way. <strong>Emphasize text</strong> in
a way that makes sense, not with tiresome HTML tags or the need to take your
hands off the keys and click on the “bold” button in a WYSIWYG editor. To <strong>bold</strong>
text in Markdown, simply surround the word(s) in a pair of asterisks. It looks
great when formatted and it’s easy to read as plain text.</li>
<li>Markdown supports a number of powerful styling tools, like Headers, text
styling, images, automatic URLs, lines, tables, indented lists, and more. The
best part is, because Markdown support in-line HTML, you can always add anything
that it doesn’t natively support (like <sup>superscripts</sup>) by throwing in
the occasional HTML tag.</li>
</ul>
</li>
<li>Your Choice of Editor.
<ul>
<li>Write anything, anywhere, with virtually any tool. Use a classic editor like
<a href="https://www.vim.org/">Vim</a> or <a href="https://www.gnu.org/software/emacs/">Emacs</a>.
Use a simple tool like Notepad. Use a modern editor such as
<a href="https://atom.io/">Atom</a> or <a href="https://code.visualstudio.com/">VS Code</a>. Use a
full-blown IDE like <a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a>. Write
directly on <a href="https://tobloef.com/markant/">the web</a>.
<a href="https://teletype.atom.io/">Collaborate in real-time</a>.
Do <strong>what you want</strong> because this is <strong>your content</strong>. Many editors have
plugins or native support for previewing Markdown. There are also many powerful
plugins to help you write better content. Spell-checking, tab completion, :smile:
emoji support, and more.</li>
</ul>
</li>
</ul>
<h2 id="create-beautiful-web-content-no-html-needed">Create Beautiful Web Content, no HTML Needed.</h2>
<p>This blog post is written in Markdown. You can even view the
<a href="https://github.com/dcchambers/dcchambers.github.io/blob/master/_posts/2018-04-03-why-markdown.md">source code</a>. This website was created using a static site generator called <a href="https://jekyllrb.com/">Jekyll</a>.
It turns a couple of YAML (<em>plain text</em> configuration files) and Markdown files
into a full-blown HTML website. There’s a massive number of themes available,
and the capabilities are pretty much limited to the scope of your imagination.
The best part? Because the pages you create are written in Markdown, you still
have access to awesome content styling but retain the readability of plain text.</p>
<p>With tools Jekyll I can easily take a paper written in Markdown and convert it
into a responsive web page, ready for popular consumption by anyone with an
<a href="https://en.wikipedia.org/wiki/Global_Internet_usage">internet-connected device</a>.
I can then use a tool like Pandoc to convert my Markdown paper to PDF, print it,
and distribute it as I wish in hard-copy format.</p>
<h2 id="latex-without-latex">LaTeX without LaTeX.</h2>
<p>LaTeX is awesome. LaTeX is also the worst thing on earth. It’s an incredibly
powerful typesetting tool that’s also incredibly hard to read and write with a
learning curve so steep it makes Lombard Street look as flat as a pancake. It’s
most commonly and famously used as the standard for writing academic papers.
Where LaTeX really shines is in creating complex mathematical formulas.</p>
<p>Why am I mentioning this in a paper on Markdown? Well, many Markdown interpreters
have in-line LaTeX support. This means you can use LaTeX to add math and other
complex items to your Markdown document!</p>
<p>For example, I’ve selected <a href="https://kramdown.gettalong.org/index.html">kramdown</a>
as the Markdown “version” in this document. (Kramdown isn’t actually a Markdown
“version” but rather a Ruby library for parsing and converting a superset of
Markdown, but that’s pedantic. :wink:) Kramdown, along with many other Markdown
varients, support LaTeX-like typesetting. Take a look at
<a href="http://www.gastonsanchez.com/visually-enforced/opinion/2014/02/16/Mathjax-with-jekyll/">this excellent post</a>
for how to use LaTeX within Markdown via the <a href="https://www.mathjax.org/">MathJax</a>
JS library.</p>
<p>That begs the question - why not just write everything in LaTeX?</p>
<ul>
<li>While LaTeX is ultimately more powerful for formatting and styling, the best
feature of Markdown is that it gets out of your way and lets you focus on writing.
Combine your Markdown document with a little in-line HTML and LaTeX, and you’ve
basically got content creation super powers!</li>
</ul>
<h2 id="use-cases-for-markdown">Use Cases for Markdown</h2>
<p>Most people are familiar with Markdown from GitHub README files. It’s awesome
that GitHub has chosen this as the default format for README files in Github
repositories, but it’s a shame most people don’t think to use Markdown for
anything more than that.</p>
<p>Here are some things you could use Markdown for:</p>
<ul>
<li>Personal Notes</li>
<li>To-Do Lists</li>
<li>Organized Lists/Outlines</li>
<li>Static Web Pages</li>
<li>Blog Posts</li>
<li>Documentation</li>
<li>Academic Papers<sup class="footnote-ref"><a href="#fn4" id="fnref4">4</a></sup></li>
<li>Long-Form Journalism</li>
<li>Technical Writing</li>
<li>Fiction</li>
<li>Emails</li>
<li>And yes, awesomely-formatted README files.
<br><br></li>
</ul>
<section class="footnotes">
<ol>
<li id="fn1">
<p><a href="https://daringfireball.net/projects/markdown/syntax">Daring Fireball</a> <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
<li id="fn2">
<p>Okay, there’s a time and a place for everything. <a href="#fnref2" class="footnote-backref">↩</a></p>
</li>
<li id="fn3">
<p>Well, not <em>exactly</em>, per say. But let’s pretend the computer writes unicode characters instead of 0s and 1s. <a href="#fnref3" class="footnote-backref">↩</a></p>
</li>
<li id="fn4">
<p>When you solve P vs. NP you better write your paper in Markdown, lest you suffer the same fate as John. :smile: <a href="#fnref4" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><category term="markdown" /><summary type="html"><![CDATA[What is this Markdown nonsense and why should I care? I’ll give up .doc when you pry it from my cold, dead hands.]]></summary></entry><entry><title type="html">What’s Up, World?</title><link href="https://chambers.io/blog/2018/03/24/whats-up-world.html" rel="alternate" type="text/html" title="What’s Up, World?" /><published>2018-03-24T00:00:00+00:00</published><updated>2018-03-27T00:00:00+00:00</updated><id>https://chambers.io/blog/2018/03/24/whats-up-world</id><content type="html" xml:base="https://chambers.io/blog/2018/03/24/whats-up-world.html"><![CDATA[<p>Because <code>Hello, World!</code> is <em>sooo</em> 1976.</p>
<p>This is a technical blog.<br />
Let’s get some <em>technical details</em> out of the way.</p>
<ul>
<li>The content is written in <a href="http://commonmark.org/help/"><code>markdown</code></a></li>
<li>The site is built with <a href="https://jekyllrb.com/">Jekyll</a>.</li>
<li>It’s hosted on <a href="https://pages.github.com">Github Pages</a>.</li>
<li>You can view even view the <a href="https://github.com/dcchambers/dcchambers.github.io">source code</a>.</li>
</ul>
<h2 id="why-am-i-writing-this">Why am I writing this?</h2>
<p>One of my resolutions for :calendar: 2018 is to improve my writing.<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup><sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup> It
turns out that in order to write <em>better</em>, you have to write <em>more</em>. I’ve been
<a href="http://bulletjournal.com/">Bullet Journaling</a> for a while now - but that
doesn’t really let me flex my creative writing muscles. I have already started
writing a regular journal, but I’ve been wanting to start a technical blog for a
while. There are a number of tech/programming/ops blogs I read religiously.
<a href="https://jvns.ca/">Julia Evans</a>,
<a href="http://rachelbythebay.com/w/">Rachel by the Bay</a>,
<a href="https://www.joelonsoftware.com/">Joel on Software</a>,
<a href="http://danluu.com/">Dan Luu</a>, etc. You know the drill.
Incredibly smart people writing incredibly well about incredibly cool<sup>and
some incredibly mundane</sup> things.<sup class="footnote-ref"><a href="#fn3" id="fnref3">3</a></sup> I don’t imagine my technical rants
will ever be seen in the same light as some of those talented individuals, but
maybe someone desperately scouring the internet for a weird Docker error will
stumble upon a post here and <del>fix their problem</del> become even more confused.</p>
<h2 id="about-me">About Me</h2>
<p>I’m currently doing fun dev/ops stuff with the University of Wisconsin’s
Department of Radiology. I help the dev team build and deploy their applications
using tools like Docker and Jenkins. We write mostly web-based applications and
manage everything from the <a href="https://radiology.wisc.edu">Radiology Website</a> to
clinical applications that are used every day in the UW Hospital. We’re teamed
up with the awesome folks at <a href="https://uwhealth.org">UW Health</a> to provide
remarkable healthcare and do amazing research.</p>
<p>Before this I worked as a Linux system administrator at the UW
<a href="http://chtc.cs.wisc.edu/">Center for High Throughput Computing</a> and at the
<a href="https://morgridge.org/">Morgridge Institure for Research</a>.</p>
<p>Outside of work, I like building silly applications and websites that rarely
ever get finished. I also enjoy dabbling in pixel art and drawing/animating with
CSS/HTML and SVG.</p>
<h2 id="what-to-expect">What to Expect</h2>
<p>Honestly, I’m not sure yet. I’m going to try <em>like really, really hard</em> to post
content regularly. I expect I will write about what I’m working on both
professionally and personally. I’ll write about the interesting problems we
encounter and (hopefully) the solutions to those problems. I might write a
hands-on guide to implementing a technology or some long-form essays. I might
even write some fiction or share a joke.</p>
<p>It’s time to sign off, though. This post is dated 2018-03-24 and I see the clock
has just ticked past midnight. My first post and I’m already breaking the rules.
:wink:</p>
<section class="footnotes">
<ol>
<li id="fn1">
<p>I just realized the Calendar emoji :calendar: doesn’t show the current date and for some reason that really bothers me. <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
<li id="fn2">
<p>I also just realized you can create footnotes in Markdown. Awesome. <a href="#fnref2" class="footnote-backref">↩</a></p>
</li>
<li id="fn3">
<p>Maybe I can expand my vocabulary :book: a bit, too? :wink: <a href="#fnref3" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content><author><name>Dakota Chambers</name></author><category term="blog" /><summary type="html"><![CDATA[Because Hello, World! is sooo 1976.]]></summary></entry></feed>