<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>The Ops Community ⚙️: Natalie Lunbeck</title>
    <description>The latest articles on The Ops Community ⚙️ by Natalie Lunbeck (@nlunbeck).</description>
    <link>https://community.ops.io/nlunbeck</link>
    <image>
      <url>https://community.ops.io/images/rVGk2HkdzJFCcDZ_yarLGebbGiXl576J7asaXm9rDX8/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL3Vz/ZXIvcHJvZmlsZV9p/bWFnZS8yOTk4LzRk/NjhhNWFlLTYyMzMt/NDc3OS05N2Q5LTRl/NzZmOTAwM2Y0Zi5q/cGVn</url>
      <title>The Ops Community ⚙️: Natalie Lunbeck</title>
      <link>https://community.ops.io/nlunbeck</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://community.ops.io/feed/nlunbeck"/>
    <language>en</language>
    <item>
      <title>How to Containerize Your Docusaurus (And Why You Should)</title>
      <dc:creator>Natalie Lunbeck</dc:creator>
      <pubDate>Thu, 25 Jan 2024 19:28:48 +0000</pubDate>
      <link>https://community.ops.io/nlunbeck/how-to-containerize-your-docusaurus-and-why-you-should-3gie</link>
      <guid>https://community.ops.io/nlunbeck/how-to-containerize-your-docusaurus-and-why-you-should-3gie</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://shipyard.build/blog/containerize-your-docs/"&gt;This post was originally published on the Shipyard Blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Containerizing your project’s documentation might be one of the easiest ways you can remove friction from iterating. Your docs are also probably one of the easiest things you can containerize. Here’s how you can get your docs up and running with Docker Compose in just a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should I containerize my docs?
&lt;/h2&gt;

&lt;p&gt;Simply put, containerizing your docs lets you hit the ground running when writing documentation.&lt;/p&gt;

&lt;p&gt;Here are a few QoL improvements that come with doing this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No need to install/update/manage dependencies&lt;/li&gt;
&lt;li&gt;Work with the same development environment across machines&lt;/li&gt;
&lt;li&gt;Start developing with just a single command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, it’s just easier. You don’t have to think about building and running the dev server, you can just open your terminal and your IDE, then start writing. When writing docs, you’re likely iterating often and adding small chunks at a time, so it makes sense to optimize your local dev environment to spin up as efficiently as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Containerizing your Docusaurus build
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://shipyard.build"&gt;Shipyard&lt;/a&gt;, we’re big fans of &lt;a href="https://docusaurus.io"&gt;Docusaurus&lt;/a&gt;. We’ve been using it to write our &lt;a href="https://docs.shipyard.build/docs"&gt;public documentation&lt;/a&gt; for three years. We’ve also been using &lt;a href="https://docs.docker.com/compose/"&gt;Docker Compose&lt;/a&gt; for local docs development just as long. A lesson we've learned is that sometimes the best tools are the ones we're already using. We were using Docker Compose for everything else, why not extend it to our docs?&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing the Dockerfile
&lt;/h3&gt;

&lt;p&gt;Since Docusaurus is &lt;a href="https://nodejs.org/en"&gt;Node&lt;/a&gt;-based, the Dockerfile is pretty standard. You might need to swap in your docs’ custom run commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:16-alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  This Dockerfile Explained
&lt;/h4&gt;

&lt;p&gt;If you’re newer to &lt;a href="https://docs.docker.com"&gt;Docker&lt;/a&gt;, here’s a line-by-line rundown of what this Dockerfile is doing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with a Node base image&lt;/li&gt;
&lt;li&gt;Create and set the working directory within the container&lt;/li&gt;
&lt;li&gt;Copy the Node dependencies to the working directory&lt;/li&gt;
&lt;li&gt;Install dependencies within container&lt;/li&gt;
&lt;li&gt;Copy the rest of the repo’s contents to the working directory&lt;/li&gt;
&lt;li&gt;Run the Node project’s start command&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Setting the host
&lt;/h3&gt;

&lt;p&gt;In order to make the application accessible from outside the container (e.g. from your web browser), you’ll want to set the &lt;code&gt;--host&lt;/code&gt; option to &lt;code&gt;0.0.0.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This can be done from your &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"docusaurus"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docusaurus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docusaurus start --host 0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or in your Dockerfile as an argument to your project’s start command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start", “--host”, “0.0.0.0”]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Writing the Docker Compose file
&lt;/h3&gt;

&lt;p&gt;Now that we have the Dockerfile, we can write a single-service Compose file to leverage it. Here, we’ll specify any Docker config options (so we don’t need to remember them for complex &lt;code&gt;docker build&lt;/code&gt; and &lt;code&gt;docker run&lt;/code&gt; commands).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;docusaurus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3000:3000'&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./docs:/app/docs'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./src:/app/src'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./static:/app/static'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./docusaurus.config.js:/app/docusaurus.config.js'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./sidebars.js:/app/sidebars.js'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because we’re optimizing this Compose file for local development, we’ll want to define bind mounts from any files and directories that we plan to edit. This way, any local changes will be reflected in the Docker container.&lt;/p&gt;

&lt;p&gt;In this example, I have a few bind mounts defined under the volumes option. The syntax for this involves specifying the local path (relative to the build context), followed by a colon, then followed by the corresponding location in the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: Writing the .dockerignore
&lt;/h3&gt;

&lt;p&gt;Docker images tend to run pretty large, so writing a &lt;code&gt;.dockerignore&lt;/code&gt; can help slim them down by weeding out any files irrelevant to your Docker build.&lt;/p&gt;

&lt;p&gt;To exclude any Markdown files in the root directory (e.g. your &lt;code&gt;README.md&lt;/code&gt; and &lt;code&gt;LICENSE.md&lt;/code&gt;, but not your &lt;em&gt;actual&lt;/em&gt; Markdown doc pages), you can use this glob pattern in the &lt;code&gt;.dockerignore&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="o"&gt;/*&lt;/span&gt;&lt;span class="n"&gt;.md&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Docker build also doesn’t need to include the Dockerfile or the Compose file. These glob patterns will match most naming conventions for those:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;compose&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Dockerfile&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also exclude &lt;code&gt;node_modules&lt;/code&gt; (likely the biggest bloat culprit):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight r"&gt;&lt;code&gt;&lt;span class="n"&gt;node_modules&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Docs that work right out of the box
&lt;/h3&gt;

&lt;p&gt;Now that you’ve containerized your Docusaurus docs, you can spin them up locally with &lt;code&gt;docker compose up&lt;/code&gt; and start editing.&lt;/p&gt;

&lt;p&gt;Thanks for reading! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you enjoyed this Docker Compose tutorial, &lt;a href="https://shipyard.build/blog/react-wordle-with-docker-compose/"&gt;check out this post I made a few months ago on how to write a Compose file for a Wordle clone&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>help</category>
      <category>tutorials</category>
    </item>
    <item>
      <title>Why won't Docker install on my older Mac? Your macOS is probably too old</title>
      <dc:creator>Natalie Lunbeck</dc:creator>
      <pubDate>Tue, 16 Jan 2024 21:15:41 +0000</pubDate>
      <link>https://community.ops.io/nlunbeck/why-wont-docker-install-on-my-older-mac-your-macos-is-probably-too-old-1hn4</link>
      <guid>https://community.ops.io/nlunbeck/why-wont-docker-install-on-my-older-mac-your-macos-is-probably-too-old-1hn4</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://shipyard.build/blog/installing-docker-on-older-mac/"&gt;This post was originally published on the Shipyard blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;A few days ago, I tried manually upgrading Docker Desktop on my personal 2015 MacBook Pro (running macOS Mojave 10.14.6). I went to &lt;a href="https://docs.docker.com/get-docker/"&gt;Docker’s website&lt;/a&gt; and downloaded the newest image for my Intel-based Mac, only to find an unhelpful and misleading message from macOS:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Warning: Docker DMG file is corrupt.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/__yg2cmXuu8AZ9VYdy7WJMkToLLyDnwf2a1HVRNGwkg/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9kZXYt/dG8tdXBsb2Fkcy5z/My5hbWF6b25hd3Mu/Y29tL3VwbG9hZHMv/YXJ0aWNsZXMvZ21j/Zm1kenBlZGt0ZGp1/dGZqd3QucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/__yg2cmXuu8AZ9VYdy7WJMkToLLyDnwf2a1HVRNGwkg/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9kZXYt/dG8tdXBsb2Fkcy5z/My5hbWF6b25hd3Mu/Y29tL3VwbG9hZHMv/YXJ0aWNsZXMvZ21j/Zm1kenBlZGt0ZGp1/dGZqd3QucG5n" alt="Docker.dmg is corrupt on macOS" width="736" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course I went back to make sure I didn't click on the ARM version and downloaded a brand new copy, but again, the “corrupt image” warning. A few panicked minutes of thinking I got MITM'd later, I realized it wasn't a corrupt image at all: my macOS was too old to install the latest and greatest version of Docker.  &lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://docs.docker.com/desktop/install/mac-install/#system-requirements"&gt;Docker's macOS System Requirements&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker supports Docker Desktop on the most recent versions of macOS. 
That is, the current release of macOS and the previous two releases. 
As new major versions of macOS are made generally available, 
Docker stops supporting the oldest version and supports the newest 
version of macOS (in addition to the previous two releases).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current version of Docker (4.26.0 as of January 2024) supports macOS Sonoma, Ventura, and Monterey. Mac users on Big Sur or an earlier OS will need to find an alternate solution.&lt;/p&gt;

&lt;p&gt;I did some digging and found a few different approaches to getting Docker working on my Mac.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 (Obvious and scary): Upgrade macOS
&lt;/h3&gt;

&lt;p&gt;It’s important to consider whether your Docker use case warrants an entire OS upgrade. You might already be avoiding an upgrade for a myriad of reasons. For a few key reasons to think twice before upgrading, check out &lt;a href="https://www.howtogeek.com/842706/should-you-wait-to-upgrade-to-the-latest-version-of-macos/"&gt;this article from How-To Geek&lt;/a&gt;. Remember, you have other software that might break because of the upgrade, and OS upgrades have been known to slow down older hardware.&lt;/p&gt;

&lt;p&gt;These upgrades can take a good chunk of time and are a pretty big commitment if you are just trying to test out a new feature in &lt;a href="https://www.docker.com/blog/new-docker-compose-v2-and-v1-deprecation/"&gt;Compose…&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before upgrading, you might also want to check that your Mac hardware can run Docker’s required macOS version. &lt;a href="https://www.macworld.com/article/673697/what-version-of-macos-can-my-mac-run.html"&gt;This article from Macworld&lt;/a&gt; lists the Macs supported by each macOS release since OS X Mountain Lion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2 (Quick and easy): Find an old supported version of Docker
&lt;/h3&gt;

&lt;p&gt;Many users, myself included, choose to stay on an older version of macOS on older hardware for performance and/or compatibility reasons. Users with machines that are over four or five years old have no option to upgrade to the latest macOS version (by legitimate means, at least).&lt;/p&gt;

&lt;p&gt;If you’d prefer to keep your current OS, you can simply install an older version of Docker. These aren’t listed alongside current downloads on the Docker website, but the links are still live.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/franklinyu/5e0bb9d6c0d873f33c78415dd2ea4138"&gt;This (unofficial) Gist&lt;/a&gt; includes the download links to previous Docker versions, expanded by &lt;a href="https://gist.github.com/FranklinYu/5e0bb9d6c0d873f33c78415dd2ea4138?permalink_comment_id=4724306#gistcomment-4724306"&gt;this recent comment&lt;/a&gt;. For versions 4.18.0 and up, you can grab a download link directly from the &lt;a href="https://docs.docker.com/desktop/release-notes/"&gt;release notes&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;When choosing a previous Docker version, cross reference with the release notes. This way, you can find a version that works with your current OS and includes the features and bug fixes that you need for your use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 3 (Fun and complex): Running a Linux VM
&lt;/h3&gt;

&lt;p&gt;If you’re unable to upgrade macOS and need the latest version of Docker, there’s a last resort: you can run a Linux distro in a VM (via VirtualBox or QEMB) and install Docker there. This will allow you to use the same version of Docker on your Mac (Docker on macOS runs in a LinuxKit VM), however it’ll be much less optimized and will require more config since you won’t be running it natively.&lt;/p&gt;

&lt;p&gt;Docker &lt;a href="https://docs.docker.com/desktop/install/linux-install/#supported-platforms"&gt;supports Ubuntu, Debian, and Fedora-based distros&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Docker for your Mac
&lt;/h2&gt;

&lt;p&gt;The swap from Intel to Apple Silicon added complexity to third-party software releases, and three years in, &lt;a href="https://www.lifewire.com/the-end-of-intel-macs-7569716"&gt;we’re seeing shorter support lifespans for Intel Macs&lt;/a&gt;. If an OS upgrade isn’t in the cards for you, it’s nice to know that Docker still hosts its older DMGs and that there’s support for mainstream Linux distros.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to automate your Docker builds in your CI? Check out this post I did a few months back on &lt;a href="https://shipyard.build/blog/gha-recipes-build-and-push-container-registry/"&gt;using GitHub Actions to build and push Docker images to a container registry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>tutorials</category>
      <category>help</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
