<?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>DEV Community: Graeme Fawcett</title>
    <description>The latest articles on DEV Community by Graeme Fawcett (@graeme_fawcett_ed0cbe79de).</description>
    <link>https://dev.to/graeme_fawcett_ed0cbe79de</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3558395%2F76aceae5-63b8-4d3e-ab94-bb8164b5eb44.png</url>
      <title>DEV Community: Graeme Fawcett</title>
      <link>https://dev.to/graeme_fawcett_ed0cbe79de</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/graeme_fawcett_ed0cbe79de"/>
    <language>en</language>
    <item>
      <title>Factories Without Belts #2 - It Began as a Trickle</title>
      <dc:creator>Graeme Fawcett</dc:creator>
      <pubDate>Thu, 19 Mar 2026 18:46:41 +0000</pubDate>
      <link>https://dev.to/graeme_fawcett_ed0cbe79de/it-began-as-a-trickle-opl</link>
      <guid>https://dev.to/graeme_fawcett_ed0cbe79de/it-began-as-a-trickle-opl</guid>
      <description>&lt;h2&gt;
  
  
  Satiated and Ready for a Nap
&lt;/h2&gt;

&lt;p&gt;Nita returned to her cube after lunch, already regretting having eaten.  Two tacos were probably one and a half too many, but they were delicious.&lt;/p&gt;

&lt;p&gt;She logged into her laptop again and saw her editor still open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;To be continued&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pressing &lt;code&gt;dd&lt;/code&gt; to erase her screen, she reviewed her notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] setup a build environment with the correct JDK&lt;/li&gt;
&lt;li&gt;[x] build and run the application&lt;/li&gt;
&lt;li&gt;[x] perform a simple smoke test&lt;/li&gt;
&lt;li&gt;[x] determine the runtime environment (networking, monitoring)&lt;/li&gt;
&lt;li&gt;[x] determine the runtime orchestrator&lt;/li&gt;
&lt;li&gt;[x] create a service definition&lt;/li&gt;
&lt;li&gt;[x] smoke test the service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Earlier that day, she had followed the standard steps that she always followed when she'd been given an embryonic bit of software to deploy.&lt;/p&gt;

&lt;p&gt;First, build the thing to make sure it's even possible.&lt;/p&gt;

&lt;p&gt;Then work through the basic steps of packaging and runtime configuration.  Make sure everything works as best as possible locally before setting out to build any automation.  She knew that the feedback loops were much tighter locally and she'd save a bunch of time if there was anything wrong with the code itself.&lt;/p&gt;

&lt;p&gt;Finally, with the understanding gained from having done the thing, automate it so it's repeatable and reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Stage Right
&lt;/h2&gt;

&lt;p&gt;Feeling confident that her exploration that morning had found that the application was stable enough to be operationalized, she turned her thoughts towards automation.  She knew that her manual process was fine to test things out, but anything that required manual input was a surface area that invited errors to form and she was eager to make a good first impression, even though she still wasn't sure where any of her co-workers actually were.&lt;/p&gt;

&lt;p&gt;At her former company, the developer platform was a massive thing that had grown over a decade of Jira tickets and deskside drive-bys.  She knew she wasn't going to be able to achieve that in a single go, but she also knew she didn't want to manually have to build every Docker image that her team was tasked with deploying.  She remembered that the Peregrine platform she was used to using had been based around the concept of Actors, so she started to sketch out a minimally viable platform using the same concept.&lt;/p&gt;

&lt;p&gt;The actor pattern was something she'd learned at her old job.  There the build system called "Peregrine" required developers to configure an actor for each stage of the pipeline - things like a &lt;code&gt;gradle&lt;/code&gt; actor in the &lt;code&gt;build&lt;/code&gt; stage or the &lt;code&gt;ecsService&lt;/code&gt; version found down in &lt;code&gt;deploy&lt;/code&gt;.  In Peregrine's world, each stage fulfilled a contract - the set of properties that defined a stage were expressed as "what went in" and "what came out".  Her boss had always been making jokes about the "Yoneda Lemon", as he called it.  It was a term from Category Theory, a branch of mathematics that had been developed because a couple of guys kept saying "Yo, you know that thing is just one of these right?" and no one believed them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An object X is completely determined by the collection of all morphisms pointing into it from every other object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;--- The Yoneda Lemma [category theory]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;She thought back to their old wiki, on some system called &lt;code&gt;nightingale&lt;/code&gt; where her old boss dumped all of his thoughts and the one he'd left on why they should care about his 🍋.&lt;/p&gt;

&lt;h3&gt;
  
  
  On Middleware as Morphisms
&lt;/h3&gt;

&lt;p&gt;Data at rest has the potential to be interesting, but it's just a storage mechanism.&lt;/p&gt;

&lt;p&gt;Data in motion is a system that's doing work, and watching it work is how you understand it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Storage&lt;/th&gt;
&lt;th&gt;Understanding&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Database row&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API response&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline stage&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Middleware transform&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge activity&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A typical delivery pipeline has a number of inputs; a PR triggers the pipeline containing a repository URL and a hash to be built, configuration management and IaC configurations pitch in to help shape the final output, a test case or two if we're lucky help verify intent; but none of them achieve anything on their own.&lt;/p&gt;

&lt;p&gt;The git commit is just a bit of metadata until something comes along and builds it.  Gradle and JUnit are constantly conspiring to teach us why we shouldn't use the compiler as spell chekc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Selenium test failure by itself is generally noise.  A Selenium test failure that was successful yesterday is worth notifying someone about.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In category theory, the Yoneda Lemma states that we only need to know the relationships between objects, the collection of its effects on the world, to describe the object.  In platform engineering, we define objects as artifacts produced, and the relationships between them become the contracts that we are going to watch Nita establish.&lt;/p&gt;

&lt;p&gt;What they do is their own business, each a black box to be known by its effects on the system - the complete set of capabilities and constraints it brings.&lt;/p&gt;

&lt;p&gt;In category theory, the relationships between objects are called morphisms.&lt;/p&gt;

&lt;p&gt;In platform engineering, we just call it middleware and it's everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 1 :: Know Your Lines
&lt;/h2&gt;

&lt;p&gt;Nita drew on that memory as started to sketch out her requirements for her pipeline.&lt;/p&gt;

&lt;p&gt;"I'm going to need something to represent an actor", she thought.  She remembered back to what she'd learned before, complexity should come from composition.  Each individual component of her system should be designed for a single operation, "Combinatorics are a harsh mistress" was a mantra she'd had drilled into her each time she'd presented a design that tried to cram too many features into a small surface area.&lt;/p&gt;

&lt;p&gt;The objects in the universe of her new pipeline were simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;source&lt;/strong&gt; enters the universe in the form on a repository with a specific hash to be built&lt;/li&gt;
&lt;li&gt;an &lt;strong&gt;application artifact&lt;/strong&gt; in the form of a JAR&lt;/li&gt;
&lt;li&gt;an &lt;strong&gt;image artifact&lt;/strong&gt; in the form of an OCI image&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;web service&lt;/strong&gt; responding to HTTP requests&lt;/li&gt;
&lt;li&gt;a set of &lt;strong&gt;test results&lt;/strong&gt; that verify that the deployment was completed successfully&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple relationship that described the transitions between the objects could be written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. source 

[compiles to]

2. application artifact

[is packaged in]

3. image artifact

[is deployed as]

4. web service

[is verified by]

5. test results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This mean that her pipeline was going to require four relationships to be defined:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;compiles to&lt;/strong&gt; could be implemented with a wrapper around &lt;code&gt;mvn&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;is packaged in&lt;/strong&gt; could be implemented with &lt;code&gt;docker build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;is deployed as&lt;/strong&gt; could be implemented with &lt;code&gt;docker compose up&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;is verified by&lt;/strong&gt; could be implemented by a wrapper around &lt;code&gt;Net::HTTP&lt;/code&gt; that captured the results in the context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;She decided to sketch a simple actor class with a single &lt;code&gt;#execute&lt;/code&gt; method to start.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;module Kremis
  class Actor
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nb"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;context&lt;span class="p"&gt;)&lt;/span&gt;
      raise NotImplementedError&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"#{self.class}#execute must be implemented"&lt;/span&gt;
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Act 2 :: Tension Builds
&lt;/h2&gt;

&lt;p&gt;For this pipeline, she decided that she would be safe to just hardcode some of the build metadata as long as she designed her actor appropriately.  Data driven design had been drilled into her head, her old boss really hated having to crack code open to make what he felt should have been a configuration change.  She knew that she'd eventually need to build an attribute loader, but she also knew to only engineer for the problem you have and not the one you want to solve.&lt;/p&gt;

&lt;p&gt;Normally, she thought to herself, she'd want to separate the build and image stages in a larger application as often having access to the application artifacts outside of their final home can be useful for debugging, but at this point she didn't feel that the &lt;code&gt;infinite-money&lt;/code&gt; necessitated the extra work that would entail, so she made a decision to compress two of the relationships in her sketched pipeline into a single actor.  Her multi-stage Dockerfile was already designed to support this model.&lt;/p&gt;

&lt;p&gt;She cracked open another terminal and converted the manual build steps she had executed before into a form that her &lt;code&gt;Kremis::Actor&lt;/code&gt; could run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;require_relative &lt;span class="s2"&gt;"../../lib/kremis"&lt;/span&gt;

module Actors
  class Build &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; Kremis&lt;span class="p"&gt;::&lt;/span&gt;Actor
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nb"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;context&lt;span class="p"&gt;)&lt;/span&gt;
      app_dir &lt;span class="p"&gt;=&lt;/span&gt; File&lt;span class="p"&gt;.&lt;/span&gt;expand_path&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"../../../app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; __dir__&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"infinity-service:#{context[:commit]}"&lt;/span&gt;

      puts &lt;span class="s2"&gt;"    docker build -t #{tag} #{app_dir}"&lt;/span&gt;
      result &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"docker build -t #{tag} #{app_dir}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      raise &lt;span class="s2"&gt;"Docker build failed"&lt;/span&gt; unless result

      context&lt;span class="p"&gt;.&lt;/span&gt;merge&lt;span class="p"&gt;(&lt;/span&gt;image_tag&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    end
  end
end

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"There", she thought, expertly typing &lt;code&gt;:wq&lt;/code&gt; to save her work and close her editor, "that will do for now".&lt;/p&gt;

&lt;p&gt;She reviewed her work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;her final build script would need to be co-located with the application being deployed and Alice had left her code in an &lt;code&gt;app&lt;/code&gt; directory, so she'd be ok to use relative paths.  She hoped her boss was back soon so she could inquire about Infinity Co's artifact repository, she'd used Nexus in the past and was eager to get her new gem package deployed somewhere the build servers could access it.  She didn't want to leave the deployment code packaged with the application any longer than she needed to&lt;/li&gt;
&lt;li&gt;the only requirement that her boss had given her in her brief orientation was that she capture the specific hash of any comit contributing to the build for tracking purposes.  Infinity Co were big on numbers he'd implied and really liked to track things.  She'd decided that it would be ok to use the commit has as an input to her pipeline for now, as it was generally available in most CI systems environments.  This would enter the build actor as part of the global context&lt;/li&gt;
&lt;li&gt;as this was an internal system in use for one application with a fully deterministic configuration, she felt safe combining string concatenation with a &lt;code&gt;#system&lt;/code&gt; call&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that bit of work complete, she prepared to shutdown her workstation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git add .&lt;span class="p"&gt;;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; save your files 💾 - tom dibblee&lt;span class="p"&gt;;&lt;/span&gt; git push
&lt;span class="go"&gt;[ticket-001 924d48a] save your files 💾 - tom dibblee
 1 file changed, 1 insertion(+)
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 733 bytes | 733.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
To git.sr.ht:~graemefawcett/sprout
&lt;/span&gt;&lt;span class="gp"&gt;   bb441f3..924d48a  ticket-001 -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ticket-001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before she left for the day, she reviewed her build list.  Happy that she'd satisified the criteria she'd set for herself, she checked off the first item and closed the lid to her laptop.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] A build actor that can wrap Docker and execute multi-stage Dockerfiles to combine the &lt;code&gt;build&lt;/code&gt; and &lt;code&gt;image&lt;/code&gt; stages that her old build system separated&lt;/li&gt;
&lt;li&gt;[ ] A deploy actor that could automatically update and deploy a Docker compose service definition with an updated image&lt;/li&gt;
&lt;li&gt;[ ] A simple verification actor that can perform a post-deployment validation&lt;/li&gt;
&lt;li&gt;[ ] A simple engine to chain them together and manage shared context&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>programming</category>
      <category>sre</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Factories Without Belts</title>
      <dc:creator>Graeme Fawcett</dc:creator>
      <pubDate>Thu, 19 Mar 2026 18:40:39 +0000</pubDate>
      <link>https://dev.to/graeme_fawcett_ed0cbe79de/factories-without-belts-4c4e</link>
      <guid>https://dev.to/graeme_fawcett_ed0cbe79de/factories-without-belts-4c4e</guid>
      <description>&lt;h2&gt;
  
  
  It's Like Mario Up in Here
&lt;/h2&gt;

&lt;p&gt;I met my first pipeline about 25 years ago.  It was shaped like a conveyor belt and it was responsible for sorting all of the Norah Jones and Kidz Bop CDs that didn't sell at Wal-Mart that month back into boxes so we could get a refund.&lt;/p&gt;

&lt;p&gt;At the time, I was working for a category manager and supplier of music entertainment products as a lead in their returns centre, responsible for maintaining that conveyor belt of a pipeline and the people and systems that fed it.  Not much has changed in the last 25 years, I'm still building systems to manage pipelines though now they're more apt to deliver digital products and infrastructure than the physical kind.&lt;/p&gt;

&lt;p&gt;I'm still supporting people too, as best I can.  Experience gained is wasted, if not shared.  Through this series of posts I'm hoping to share with you, the reader and assumed enjoyer of pipelines and flow, how I go about things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Belts and Suspenders
&lt;/h2&gt;

&lt;p&gt;By now, everyone that has worked in the software is familiar with the idea of a pipeline.  The backend people have had them for years, BPEL workflows &amp;amp; ESBs last time I did backend work.  The data guys got into the act with their drag and drop, code generating ETL tools a decade ago.  They fed directly into the ML guys who do the same thing, but at scale.&lt;/p&gt;

&lt;p&gt;Anyone who's been doing DevOps/Platform Engineering work in the last decade or so should be familiar with them too.  Chained Jenkins jobs begat Jenkinsfiles.  Github's Actions and Gitlab's auto-DevOps moved orchestration to the cloud.  Tools like Argo pull in the deployment environment and make the end-to-end flow a matter of configuring a YAML template.&lt;/p&gt;

&lt;p&gt;In technical terms, these tools are all generally based on some form of a Direct Acyclic Graph (DAG) which is just a fancy way of saying a sequence of steps that can branch and contract, but can never cycle.  In practical terms, this generally means that a set of steps that are provided in a structured format (YAML is common) to an engine that executes them in the order provided.  In more concrete terms, a "context accumulating DAG" is often implemented, which is just another way of saying "as the thing runs, keep track of what it's doing and write notes".&lt;/p&gt;

&lt;p&gt;To demonstrate, we're going to build one.  Or rather, we're going to watch one be built.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show, Then Tell
&lt;/h2&gt;

&lt;p&gt;Meet Nita.&lt;/p&gt;

&lt;p&gt;Nita is a platform engineer at Infinity Co (a division of Zero Industries Ltd).  It's her first day.&lt;/p&gt;

&lt;p&gt;Nita's not sure what a platform engineer is, I'm not sure any of us really are.  She has done some automation in previous positions and really loves Ruby for some reason.&lt;/p&gt;

&lt;p&gt;Infinity Co is just getting setup.  Nita is part of a brand new team and her manager has told her she's free to solve the problems in her tickets her way, as long as she keeps their customers happy.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Wild Customer Appears
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;** KRM-1 : Deployment Pipeline Needed **

Submitted By: probably.ai@infinity.co
Assigned To: nita@infinity.co
Ticket #: KRM-1


I've got an app that need to be in production tomorrow and I've almost got it working.  

Can you setup a deployment pipeline for me?  It's Java 8 on Springboot.  

I've been told it should be Docker or something... 
I don't know about any of that stuff, I normally just push the play button in Eclipse and it works.

Can you try to have it ready for the end of the day?  
I'd like to get this deployment done first thing in the morning before everyone gets in.  

I hate when people are around, it makes me nervous.

Best Regards,

Alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  In the Beginning
&lt;/h3&gt;

&lt;p&gt;Nita finishes reading Alice's ticket and looks around for her boss.  Monitor's on but no one's home, as usual.  And he's not in his chair either.  "Guess I'll figure this out on my own then", she thinks to herself as she gets started.&lt;/p&gt;

&lt;p&gt;"First, lets see if we can even build this thing", she says to herself as she pulls the code onto her laptop&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tree
&lt;span class="c"&gt;.
&lt;/span&gt;&lt;span class="go"&gt;├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── infinity
        │           ├── Application.java
        │           └── DivisionController.java
        └── resources
            └── application.properties
7 directories, 4 files
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Here goes", she thought as she typed &lt;code&gt;mise use java@8; mvn package&lt;/code&gt; into her terminal and started to relax as the package resolution details scrolled by.  She always enjoyed this part.&lt;/p&gt;

&lt;p&gt;"Invalid engine version", she mumbled reading the error on the screen.  She knew it wasn't going to be Java 8.  It was 2025, she had at least /hoped/ it wasn't going to be Java 8.  She was unsure how Alice had managed to coax Eclipse into running her application, she assumed the work of an LLM was involved somewhere.  &lt;code&gt;mise use java@17; mvn package&lt;/code&gt; she typed again.&lt;/p&gt;

&lt;p&gt;A few moments, and many, many MB later, the build completed and she reviewed what she'd been given:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tree
&lt;span class="c"&gt;.
&lt;/span&gt;&lt;span class="go"&gt;├── mise.toml
├── pom.xml
├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── infinity
│       │           ├── Application.java
│       │           └── DivisionController.java
│       └── resources
│           └── application.properties
└── target
    ├── classes
    │   ├── application.properties
    │   └── com
    │       └── infinity
    │           ├── Application.class
    │           └── DivisionController.class
    ├── generated-sources
    │   └── annotations
    ├── infinity-service-0.0.1.jar
    ├── infinity-service-0.0.1.jar.original
    ├── maven-archiver
    │   └── pom.properties
    └── maven-status
        └── maven-compiler-plugin
            └── compile
                └── default-compile
                    ├── createdFiles.lst
                    └── inputFiles.lst
17 directories, 14 files
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;She was never sure exactly what Springboot needed all that nonsense for, but it had at least finished what it was doing without errors.  "Let's see what we're dealing with", she said to her self as she spawned another terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;java &lt;span class="nt"&gt;-XX&lt;/span&gt;:-UseContainerSupport &lt;span class="nt"&gt;-jar&lt;/span&gt; target/infinity-service-0.0.1.jar &amp;amp;
&lt;span class="go"&gt;  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.3)
2026-03-10T10:54:12.923-04:00  INFO 16692 --- [           main] com.infinity.Application                 : Starting Application v0.0.1 using Java 17.0.2 with PID 16692 (/home/gfawcett/working/sprout/app/target/infinity-service-0.0.1.jar started by gfawcett in /home/gfawcett/working/sprout/app)
2026-03-10T10:54:12.927-04:00  INFO 16692 --- [           main] com.infinity.Application                 : No active profile set, falling back to 1 default profile: "default"
2026-03-10T10:54:14.653-04:00  INFO 16692 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 9999 (http)
2026-03-10T10:54:14.672-04:00  INFO 16692 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2026-03-10T10:54:14.672-04:00  INFO 16692 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.19]
2026-03-10T10:54:14.725-04:00  INFO 16692 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2026-03-10T10:54:14.727-04:00  INFO 16692 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1649 ms
2026-03-10T10:54:15.434-04:00  INFO 16692 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint(s) beneath base path '/actuator'
2026-03-10T10:54:15.522-04:00  INFO 16692 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 9999 (http) with context path ''
2026-03-10T10:54:15.548-04:00  INFO 16692 --- [           main] com.infinity.Application                 : Started Application in 3.322 seconds (process running for 3.995)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the service up, she cleared her terminal and tested the two endpoints she'd dug out of the code base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;http :9999/health
&lt;span class="go"&gt;HTTP/1.1 200
Connection: keep-alive
Content-Length: 2
&lt;/span&gt;&lt;span class="gp"&gt;Content-Type: text/plain;&lt;/span&gt;&lt;span class="nv"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UTF-8
&lt;span class="go"&gt;Date: Tue, 10 Mar 2026 14:55:17 GMT
Keep-Alive: timeout=60

OK
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The health check seemed ok.  "Now", she thought, "let's see what all the fuss is about".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;http :9999/divide?a&lt;span class="o"&gt;=&lt;/span&gt;1&amp;amp;b&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="go"&gt;HTTP/1.1 200
Connection: keep-alive
Content-Length: 54

&lt;/span&gt;&lt;span class="gp"&gt;Content-Type: text/plain;&lt;/span&gt;&lt;span class="nv"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UTF-8
&lt;span class="go"&gt;Date: Tue, 10 Mar 2026 14:55:38 GMT
Keep-Alive: timeout=60

Infinity. You divided by zero. Welcome to the company.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nita tried not to ask too many questions about what her company did to make money.&lt;/p&gt;

&lt;p&gt;With that settled, she closed that terminal and turned to the the next step, packaging.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Package Was Left on or Around Your Front Porch
&lt;/h3&gt;

&lt;p&gt;"Where is he?", she thought again looking over at her boss' still empty chair.  His monitor was still glowing away at the end of the line of cubes, for some reason now showing an animated collage of pictures of his toaster oven.  "Oh well", she continued feeling the pressure of the ticket bleeding through, "I guess I'll just figure this out too".&lt;/p&gt;

&lt;p&gt;She hadn't been given any orientation when she started and there was never anyone else in the row of cubicles that her team had been assigned.  Come to think of it, she'd never actually seen all of her team  in one place at one time.  "I suppose I'll just get on with it, there's a deployment to complete", the motto of the well seasoned platform engineer escaping her lips.&lt;/p&gt;

&lt;p&gt;Given the time constraints, and her love of not over complicating things unnecessarily, she decided a simple two stage Docker build would suffice and would save her the trouble of getting &lt;code&gt;mise&lt;/code&gt; configured on the build server, wherever that was.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;FROM maven&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;eclipse&lt;span class="p"&gt;-&lt;/span&gt;temurin&lt;span class="m"&gt;-17&lt;/span&gt; AS build
WORKDIR /app
COPY pom&lt;span class="p"&gt;.&lt;/span&gt;xml &lt;span class="p"&gt;.&lt;/span&gt;
RUN mvn dependency&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;offline &lt;span class="p"&gt;-&lt;/span&gt;B
COPY &lt;span class="k"&gt;src&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;/&lt;span class="k"&gt;src&lt;/span&gt;
RUN mvn package &lt;span class="p"&gt;-&lt;/span&gt;DskipTests &lt;span class="p"&gt;-&lt;/span&gt;B

FROM eclipse&lt;span class="p"&gt;-&lt;/span&gt;temurin&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;jre
WORKDIR /app
COPY &lt;span class="p"&gt;--&lt;/span&gt;from&lt;span class="p"&gt;=&lt;/span&gt;build &lt;span class="sr"&gt;/app/&lt;/span&gt;target/*&lt;span class="p"&gt;.&lt;/span&gt;jar app&lt;span class="p"&gt;.&lt;/span&gt;jar
EXPOSE &lt;span class="m"&gt;9999&lt;/span&gt;
ENTRYPOINT &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"java"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"-jar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"app.jar"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"There", she thought, "nice and simple".  The first stage represented the minimal requirements to get a jar produced and then she'd discard all of the excess and pluck the jar out into its deployment wrapper.&lt;/p&gt;

&lt;p&gt;Alice hadn't provided any direction for configuration her application, so Nita had been forced to dig through the code to find what she needed in the &lt;code&gt;application.properties&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;server&lt;span class="p"&gt;.&lt;/span&gt;port&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;9999&lt;/span&gt;
management&lt;span class="p"&gt;.&lt;/span&gt;endpoints&lt;span class="p"&gt;.&lt;/span&gt;web&lt;span class="p"&gt;.&lt;/span&gt;exposure&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Here we go", she thought as she pressed enter on her keyboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; infinity-service:test
&lt;span class="go"&gt;DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
            Install the buildx component to build images with BuildKit:
            https://docs.docker.com/go/buildx/
Sending build context to Docker daemon   22.3MB
Step 1/11 : FROM maven:3.9-eclipse-temurin-17 AS build
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;c73f8f3a9e50
&lt;span class="go"&gt;Step 2/11 : WORKDIR /app
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Using cache
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;79e8ac138dfc
&lt;span class="go"&gt;Step 3/11 : COPY pom.xml .
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Using cache
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;bd0c3f2cf589
&lt;span class="go"&gt;Step 4/11 : RUN mvn dependency:go-offline -B
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Using cache
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;5be4346e1b1e
&lt;span class="go"&gt;Step 5/11 : COPY src ./src
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;b9b32cd1ed75
&lt;span class="go"&gt;Step 6/11 : RUN mvn package -DskipTests -B
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Running &lt;span class="k"&gt;in &lt;/span&gt;21e31b085197
&lt;span class="c"&gt; ...
 ...
 ...
&lt;/span&gt;&lt;span class="go"&gt; INFO] --- spring-boot:3.2.3:repackage (repackage) @ infinity-service ---
[INFO] Replacing main artifact /app/target/infinity-service-0.0.1.jar with repackaged archive, adding nested dependencies in BOOT-INF/.
[INFO] The original artifact has been renamed to /app/target/infinity-service-0.0.1.jar.original
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.929 s
[INFO] Finished at: 2026-03-10T15:25:12Z
[INFO] ------------------------------------------------------------------------
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Removed intermediate container 21e31b085197
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;0272ee24ac4c
&lt;span class="go"&gt;Step 7/11 : FROM eclipse-temurin:17-jre
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ff692acf8725
&lt;span class="go"&gt;Step 8/11 : WORKDIR /app
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Using cache
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;e53a22d40ef0
&lt;span class="go"&gt;Step 9/11 : COPY --from=build /app/target/*.jar app.jar
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;230b4b03cb4b
&lt;span class="go"&gt;Step 10/11 : EXPOSE 9999
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Running &lt;span class="k"&gt;in &lt;/span&gt;21247500458a
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Removed intermediate container 21247500458a
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;1be013450fd2
&lt;span class="go"&gt;Step 11/11 : ENTRYPOINT ["java", "-jar", "app.jar"]
&lt;/span&gt;&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Running &lt;span class="k"&gt;in &lt;/span&gt;98b67c550707
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Removed intermediate container 98b67c550707
&lt;span class="gp"&gt; ---&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;1cfa22fed259
&lt;span class="go"&gt;Successfully built 1cfa22fed259
Successfully tagged infinity-servce:test
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having built Alice's jar up front, she wasn't surprised that it built again inside of her Dockerfile.  She was pleasantly surprised that she hadn't made any typos though.  Before she started thinking about deployment models, she ran one final local test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 9999:9999 infinity-service:test
&lt;span class="go"&gt;26c0a30762ffa58836167f4b12792d9a685c5661e66f6b45e4f10290f6e65ba7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker ps
&lt;span class="go"&gt;CONTAINER ID   IMAGE                   COMMAND               CREATED         STATUS         PORTS                                         NAMES
&lt;/span&gt;&lt;span class="gp"&gt;26c0a30762ff   infinity-service:test   "java -jar app.jar"   6 seconds ago   Up 5 seconds   0.0.0.0:9999-&amp;gt;&lt;/span&gt;9999/tcp, &lt;span class="o"&gt;[&lt;/span&gt;::]:9999-&amp;gt;9999/tcp   nervous_kepler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;http :9999/divide?a&lt;span class="o"&gt;=&lt;/span&gt;1&amp;amp;b&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="go"&gt;HTTP/1.1 200
Connection: keep-alive
Content-Length: 54
&lt;/span&gt;&lt;span class="gp"&gt;Content-Type: text/plain;&lt;/span&gt;&lt;span class="nv"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UTF-8
&lt;span class="go"&gt;Date: Tue, 10 Mar 2026 15:31:56 GMT
Keep-Alive: timeout=60

Infinity. You divided by zero. Welcome to the company.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Onwards, Upwards, Deploywards
&lt;/h3&gt;

&lt;p&gt;At her old job, Nita had used something called Peregrine.  It was an in house platform built by some dude that had been there forever, "and it did all of this for me" she thought as she looked for her boss again.  She wanted to ask what server she should be deploying this to.  Her old job had used Amazon's Elastic Container Service, at home she used Nomad from Hashicorp and for something like this she'd normally just knock out a quick compose file.&lt;/p&gt;

&lt;p&gt;The one and only question that she had asked when it was her turn during her interview was "Do you use k8s?".  She couldn't recall ever having been so glad to hear the word "No" in her life.  "Horrible technology", she thought to no one in particular, "abstractions are supposed to simplify, not obscure".&lt;/p&gt;

&lt;p&gt;She opened up another terminal and typed &lt;code&gt;nvim docker-compose.yml&lt;/code&gt; and got to work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;services&lt;span class="p"&gt;:&lt;/span&gt;
  infinity&lt;span class="p"&gt;-&lt;/span&gt;service&lt;span class="p"&gt;:&lt;/span&gt;
    image&lt;span class="p"&gt;:&lt;/span&gt; infinity&lt;span class="p"&gt;-&lt;/span&gt;service&lt;span class="p"&gt;:&lt;/span&gt;test
    ports&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"9999:9999"&lt;/span&gt;
    restart&lt;span class="p"&gt;:&lt;/span&gt; unless&lt;span class="p"&gt;-&lt;/span&gt;stopped
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"That should do", she thought, "lets run &lt;code&gt;docker compose up&lt;/code&gt; and make sure it works", somehow managing to preformat her thoughts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;nita@infinity:~/work/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;docker compose up
&lt;span class="gp"&gt;~/w/infinite-money &amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ticket-001 &lt;span class="k"&gt;*&lt;/span&gt;… &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; app &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; docker compose up                     Tue 10 Mar 2026 12:20:16 PM EDT
&lt;span class="go"&gt;Attaching to infinity-service-1
infinity-service-1  |
infinity-service-1  |   .   ____          _            __ _ _
infinity-service-1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
infinity-service-1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
infinity-service-1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
infinity-service-1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
infinity-service-1  |  =========|_|==============|___/=/_/_/_/
infinity-service-1  |  :: Spring Boot ::                (v3.2.3)
infinity-service-1  |
infinity-service-1  | 2026-03-10T16:20:19.965Z  INFO 1 --- [           main] com.infinity.Application                 : Starting Application v0.0.1 using Java 17.0.18 with PID 1 (/app/app.jar started by root in /app)
infinity-service-1  | 2026-03-10T16:20:19.974Z  INFO 1 --- [           main] com.infinity.Application                 : No active profile set, falling back to 1 default profile: "default"
infinity-service-1  | 2026-03-10T16:20:21.773Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 9999 (http)
infinity-service-1  | 2026-03-10T16:20:21.791Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
infinity-service-1  | 2026-03-10T16:20:21.791Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.19]
infinity-service-1  | 2026-03-10T16:20:21.844Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
infinity-service-1  | 2026-03-10T16:20:21.846Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1715 ms
infinity-service-1  | 2026-03-10T16:20:22.518Z  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint(s) beneath base path '/actuator'
infinity-service-1  | 2026-03-10T16:20:22.595Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 9999 (http) with context path ''
infinity-service-1  | 2026-03-10T16:20:22.619Z  INFO 1 --- [           main] com.infinity.Application                 : Started Application in 3.321 seconds (process running for 3.988)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A Moment, as to Reflect
&lt;/h3&gt;

&lt;p&gt;It was 11:30am and Nita had been sitting in her cube all morning, not a co-worker nor a hint of management in sight.  She stopped to check what she'd accomplished so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] setup a build environment with the correct JDK&lt;/li&gt;
&lt;li&gt;[x] build and run the application&lt;/li&gt;
&lt;li&gt;[x] perform a simple smoke test&lt;/li&gt;
&lt;li&gt;[x] determine the runtime environment (networking, monitoring)&lt;/li&gt;
&lt;li&gt;[x] determine the runtime orchestrator&lt;/li&gt;
&lt;li&gt;[x] create a service definition&lt;/li&gt;
&lt;li&gt;[x] smoke test the service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ticket from Alice had only requested that it be ready for tomorrow.  Her boss had implied during her orientation that there was a platform that she was supposed to be engineering, but it so far was as absent as the rest of her team.  She decided to do what she'd been taught during her last role, if she had a problem to solve, why not build a tool?&lt;/p&gt;

&lt;h3&gt;
  
  
  It's Hammers All the Way Down Til the Turtle Layer
&lt;/h3&gt;

&lt;p&gt;fired up &lt;code&gt;nvim&lt;/code&gt; again, this time excited by the chance to create.  "But first", she thought, "time for lunch".  She quickly typed a note into her editor, before locking her laptop and grabbing her purse.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;To be continued&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devops</category>
      <category>programming</category>
      <category>sre</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
