<?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: Core Trail Labs</title>
    <description>The latest articles on DEV Community by Core Trail Labs (coretraillabs).</description>
    <link>https://dev.to/coretraillabs</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.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F15389%2F1aa60c56-883b-4b9a-aae2-86b2dcc2a804.png</url>
      <title>DEV Community: Core Trail Labs</title>
      <link>https://dev.to/coretraillabs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/coretraillabs"/>
    <language>en</language>
    <item>
      <title>A Running Container Doesn't Mean a Healthy Service</title>
      <dc:creator>Gökhan Koç</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:42:01 +0000</pubDate>
      <link>https://dev.to/coretraillabs/a-running-container-doesnt-mean-a-healthy-service-5a16</link>
      <guid>https://dev.to/coretraillabs/a-running-container-doesnt-mean-a-healthy-service-5a16</guid>
      <description>&lt;p&gt;A container is running. A health check is failing. A worker has exited.&lt;/p&gt;

&lt;p&gt;Those observations answer different questions. Treating them as interchangeable makes an investigation harder, especially when several services change state close together.&lt;/p&gt;

&lt;p&gt;I'm Gökhan, one of the developers behind CoreTrailKit at Core Trail Labs. This is a technical note from a controlled local Docker test we used while developing the app—not a customer incident or a production outage.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test: several failures, not one proven chain
&lt;/h2&gt;

&lt;p&gt;The environment contained three demo repositories and 14 real Docker services. We deliberately introduced several failure conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;order-worker&lt;/code&gt; exceeded its memory limit and was OOM-killed.&lt;/li&gt;
&lt;li&gt;Selected health checks were made to fail, with explanatory output supplied by the demo fixtures.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;shipping-api&lt;/code&gt; process stopped with exit code 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These were controlled inputs. In particular, a health-check message mentioning an unavailable dependency was part of the fixture; it was not independent proof that the worker's memory failure caused every other symptom.&lt;/p&gt;

&lt;p&gt;That distinction matters when reading a convincing-looking dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process state and health are separate observations
&lt;/h2&gt;

&lt;p&gt;Docker gives a container with a configured health check a health status in addition to its normal container status. A process can remain running while its health check fails. Docker's &lt;a href="https://docs.docker.com/reference/dockerfile/#healthcheck" rel="noopener noreferrer"&gt;HEALTHCHECK reference&lt;/a&gt; explains that distinction.&lt;/p&gt;

&lt;p&gt;The reverse deserves caution too: passing a particular probe does not establish that every user-facing operation works. It tells us that the configured probe passed.&lt;/p&gt;

&lt;p&gt;For an existing container, a useful starting point is to inspect its state and recent application output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace CONTAINER_ID with the actual container name or ID.&lt;/span&gt;
docker inspect &lt;span class="nt"&gt;--type&lt;/span&gt; container &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'{{json .State}}'&lt;/span&gt; CONTAINER_ID
docker logs &lt;span class="nt"&gt;--timestamps&lt;/span&gt; &lt;span class="nt"&gt;--since&lt;/span&gt; 10m CONTAINER_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are inspection examples, not captured output from the screenshots. The Docker references for &lt;a href="https://docs.docker.com/reference/cli/docker/inspect/" rel="noopener noreferrer"&gt;inspect&lt;/a&gt; and &lt;a href="https://docs.docker.com/reference/cli/docker/container/logs/" rel="noopener noreferrer"&gt;logs&lt;/a&gt; describe the commands and options.&lt;/p&gt;

&lt;p&gt;Keep the questions separate: is the process running, what does the probe report, and what does the application say? Do not combine three partial answers into a stronger conclusion than the evidence supports.&lt;/p&gt;

&lt;h2&gt;
  
  
  An alarm should identify the evidence, not invent the explanation
&lt;/h2&gt;

&lt;p&gt;Here is the actual alarm screen from our test:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fviul79j4soq8fg1s6r0i.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fviul79j4soq8fg1s6r0i.webp" alt="CoreTrailKit alarm screen from a controlled local Docker test, showing an out-of-memory worker, failing health checks, and a stopped service." width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Real application screenshot from the controlled demo. The health-check explanations were supplied by the fixtures.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the worker, the Docker connector checks the reported &lt;code&gt;OOMKilled&lt;/code&gt; flag rather than treating any exit as a memory failure. The stopped shipping service is a different observation: exit code 1 does not explain the underlying application bug.&lt;/p&gt;

&lt;p&gt;Likewise, a failing health check is evidence of a failed probe. Its output can be a useful lead, but the text itself may still need verification against the application and its dependencies.&lt;/p&gt;

&lt;p&gt;The next investigation step should follow the evidence available—not the most plausible story we can tell about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A timeline preserves context, not causality
&lt;/h2&gt;

&lt;p&gt;The timeline captured changes observed during the watch session:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8x66ht1wi84cg2it7nc.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8x66ht1wi84cg2it7nc.webp" alt="CoreTrailKit timeline for the orders-engine demo repository, with recorded health and process-state observations." width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Several visible entries share the same displayed minute. Their position on the screen is not proof of a precise causal order.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This view is useful for asking what was observed around the time a problem appeared. It does not establish that the first visible entry caused the next one, or that every underlying transition was captured.&lt;/p&gt;

&lt;p&gt;To investigate a suspected dependency failure, I would look for more specific evidence: timestamped application output, matching request identifiers, or records from both sides of the interaction. A nearby timestamp is a reason to investigate, not a completed diagnosis.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to capture before restarting
&lt;/h2&gt;

&lt;p&gt;The practical takeaway does not require a particular dashboard. Before changing the failing environment, capture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The affected container's identity and current state.&lt;/li&gt;
&lt;li&gt;Health-check status and available probe output.&lt;/li&gt;
&lt;li&gt;Exit information and any explicit OOM indication.&lt;/li&gt;
&lt;li&gt;Relevant timestamped application logs.&lt;/li&gt;
&lt;li&gt;What you changed yourself, and when.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be careful when sharing that material: logs and probe output can contain credentials or personal data.&lt;/p&gt;

&lt;p&gt;In our test, we knew how the failures had been introduced. In a real investigation, we often do not. Keeping observations, fixture-supplied explanations, and causal conclusions separate is what makes the record useful later.&lt;/p&gt;

&lt;p&gt;When a local service fails, what context do you most often discover you should have captured before restarting it?&lt;/p&gt;

</description>
      <category>docker</category>
      <category>debugging</category>
      <category>observability</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
