<?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: Sreekanth Kuruba</title>
    <description>The latest articles on DEV Community by Sreekanth Kuruba (@sreekanth_kuruba_91721e5d).</description>
    <link>https://dev.to/sreekanth_kuruba_91721e5d</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%2Fuser%2Fprofile_image%2F3286476%2Fc7a306ec-1c67-4d33-901a-1148effc29ce.jpg</url>
      <title>DEV Community: Sreekanth Kuruba</title>
      <link>https://dev.to/sreekanth_kuruba_91721e5d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sreekanth_kuruba_91721e5d"/>
    <language>en</language>
    <item>
      <title>From Docker to Kubernetes: When Docker Stops Being Enough</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 06 Oct 2026 03:15:33 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/from-docker-to-kubernetes-when-docker-stops-being-enough-a35</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/from-docker-to-kubernetes-when-docker-stops-being-enough-a35</guid>
      <description>&lt;p&gt;You learned how to build an image.&lt;/p&gt;

&lt;p&gt;You can start a container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can inspect it, read its logs, attach volumes, configure networks, set resource limits, add health checks, and harden its security.&lt;/p&gt;

&lt;p&gt;Then Docker Compose helps you run several services together.&lt;/p&gt;

&lt;p&gt;So why does Kubernetes exist?&lt;/p&gt;

&lt;p&gt;If Docker already does a good job of running containers, &lt;strong&gt;what problem is Kubernetes actually solving?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer becomes clearer when one container becomes hundreds.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Start With One Container
&lt;/h2&gt;

&lt;p&gt;Imagine a simple web application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
 │
 ▼
Web Container
 │
 ▼
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running it is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing complicated yet.&lt;/p&gt;

&lt;p&gt;Now traffic increases.&lt;/p&gt;

&lt;p&gt;You need several application instances.&lt;/p&gt;

&lt;p&gt;Then the application itself grows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend&lt;/li&gt;
&lt;li&gt;API&lt;/li&gt;
&lt;li&gt;Database&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;Background workers&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;li&gt;Logging components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker Compose can describe and run these services together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For development and many single-host environments, that's extremely useful.&lt;/p&gt;

&lt;p&gt;But then another requirement appears:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The application can no longer live on one machine.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. When One Server Becomes Ten
&lt;/h2&gt;

&lt;p&gt;Imagine you now have 100 containers that need to run across 10 machines.&lt;/p&gt;

&lt;p&gt;Suddenly, &lt;code&gt;docker run&lt;/code&gt; isn't the difficult part.&lt;/p&gt;

&lt;p&gt;The difficult questions are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which machine should run each container?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if that machine fails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if one container crashes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if traffic suddenly triples?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do applications find containers that are constantly being replaced?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you update 50 instances without taking everything offline?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At this point, the problem has changed.&lt;/p&gt;

&lt;p&gt;You're no longer dealing primarily with a &lt;strong&gt;container problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You're dealing with an &lt;strong&gt;orchestration problem&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. This Is Where Kubernetes Enters
&lt;/h2&gt;

&lt;p&gt;A useful simplified progression is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvn61s1xsju1q729lwh07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvn61s1xsju1q729lwh07.png" alt="Docker-compose-k8s" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This doesn't mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Docker = beginner&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Kubernetes = advanced Docker&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They're solving different layers of the problem.&lt;/p&gt;

&lt;p&gt;Docker gives you tools to &lt;strong&gt;build and run containers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Kubernetes gives you a system for &lt;strong&gt;coordinating containerized workloads across infrastructure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that changes the question you're asking.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Kubernetes Changes the Question
&lt;/h2&gt;

&lt;p&gt;With Docker, you might say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're directly telling the system what action to perform.&lt;/p&gt;

&lt;p&gt;Kubernetes encourages a different model.&lt;/p&gt;

&lt;p&gt;You describe the state you want.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want three instances of this application running.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Conceptually:&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;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kubernetes continually works to make reality match that desired state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Desired State
     │
     ▼
3 replicas should exist
     │
     ▼
Kubernetes observes reality
     │
     ▼
Only 2 exist?
     │
     ▼
Create another
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That idea — &lt;strong&gt;desired state and reconciliation&lt;/strong&gt; — is one of the biggest mental shifts from manually operating containers.&lt;/p&gt;

&lt;p&gt;You stop thinking only about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Start this container."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And start thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Keep my application in this state."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. What Happens When Things Fail?
&lt;/h2&gt;

&lt;p&gt;Suppose your application should have three instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App 1    App 2    App 3
  ✓        ✓        ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then one fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App 1    App 2    App 3
  ✓        ✗        ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't want someone to discover the failure and manually create a replacement.&lt;/p&gt;

&lt;p&gt;Kubernetes controllers continuously compare the current state with the desired state.&lt;/p&gt;

&lt;p&gt;If three replicas should exist but only two remain, Kubernetes can work to restore the desired number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Desired: 3
Actual: 2

     ↓

Create replacement

     ↓

Actual: 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But containers aren't the only things that fail.&lt;/p&gt;

&lt;p&gt;Machines fail too.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node 1
 ├─ App
 └─ Worker

Node 2
 ├─ App
 └─ API

Node 3
 ├─ App
 └─ Worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Node 2 becomes unavailable, several workloads may disappear at once.&lt;/p&gt;

&lt;p&gt;Now another question appears:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where should the replacements run?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kubernetes can schedule replacement workloads onto available nodes according to the workload configuration and cluster conditions.&lt;/p&gt;

&lt;p&gt;Failure has moved from being something you manually react to into something the platform continuously observes and responds to.&lt;/p&gt;

&lt;p&gt;That's a major reason orchestration exists.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. From Containers to Scheduled Pods
&lt;/h2&gt;

&lt;p&gt;Kubernetes doesn't normally manage an individual container as its smallest deployable unit.&lt;/p&gt;

&lt;p&gt;It manages a &lt;strong&gt;Pod&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pod
 │
 ├── Application Container
 │
 └── Optional Supporting Container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Pod can contain one or more tightly coupled containers that share certain resources such as networking.&lt;/p&gt;

&lt;p&gt;Most commonly, you'll still encounter one main application container per Pod.&lt;/p&gt;

&lt;p&gt;Containers haven't disappeared.&lt;/p&gt;

&lt;p&gt;Kubernetes has added a management layer around them.&lt;/p&gt;

&lt;p&gt;But now we have another problem.&lt;/p&gt;

&lt;p&gt;Suppose the cluster contains several nodes with different available resources.&lt;/p&gt;

&lt;p&gt;Where should a new Pod run?&lt;/p&gt;

&lt;p&gt;Doing this manually for hundreds of workloads would quickly become difficult.&lt;/p&gt;

&lt;p&gt;Kubernetes uses its &lt;strong&gt;scheduler&lt;/strong&gt; to select an appropriate node based on factors such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resource requirements&lt;/li&gt;
&lt;li&gt;Scheduling constraints&lt;/li&gt;
&lt;li&gt;Node conditions&lt;/li&gt;
&lt;li&gt;Affinity rules&lt;/li&gt;
&lt;li&gt;Taints and tolerations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important change is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Placement becomes a cluster decision instead of a human manually choosing a server.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. Scaling Creates Another Problem
&lt;/h2&gt;

&lt;p&gt;Suppose three application instances normally handle your traffic.&lt;/p&gt;

&lt;p&gt;Then traffic increases dramatically.&lt;/p&gt;

&lt;p&gt;You need six.&lt;/p&gt;

&lt;p&gt;Docker can certainly start more containers.&lt;/p&gt;

&lt;p&gt;But in a larger environment, you also need a system that understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many instances should exist&lt;/li&gt;
&lt;li&gt;Where they should run&lt;/li&gt;
&lt;li&gt;Whether enough resources are available&lt;/li&gt;
&lt;li&gt;What should happen when instances fail&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kubernetes workloads can be scaled manually, and Kubernetes also supports automatic scaling based on configured metrics and policies.&lt;/p&gt;

&lt;p&gt;But creating more instances introduces another problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does anything reliably find them?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Replaceable Pods Need Stable Networking
&lt;/h2&gt;

&lt;p&gt;Pods are designed to be replaceable.&lt;/p&gt;

&lt;p&gt;Suppose an API Pod has this IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.1.7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It disappears.&lt;/p&gt;

&lt;p&gt;A replacement appears with a different IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.3.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your frontend depends directly on the old address, it now points at something that no longer exists.&lt;/p&gt;

&lt;p&gt;Kubernetes solves this problem with &lt;strong&gt;Services&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        Frontend
            │
            ▼
       API Service
            │
      ┌─────┼─────┐
      ▼     ▼     ▼
    Pod A Pod B Pod C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pods can come and go.&lt;/p&gt;

&lt;p&gt;The Service provides a stable way to reach the workload.&lt;/p&gt;

&lt;p&gt;That reveals another important Kubernetes idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The individual instance is temporary. The application identity should remain stable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Docker Concepts Don't Disappear
&lt;/h2&gt;

&lt;p&gt;This is where learning Docker first starts paying off.&lt;/p&gt;

&lt;p&gt;Many of the problems you've already encountered still exist in Kubernetes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Docker concept&lt;/th&gt;
&lt;th&gt;Kubernetes world&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Container&lt;/td&gt;
&lt;td&gt;Container inside a Pod&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image&lt;/td&gt;
&lt;td&gt;Container image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource limits&lt;/td&gt;
&lt;td&gt;Requests and limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Health checks&lt;/td&gt;
&lt;td&gt;Liveness, readiness, and startup probes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Networking&lt;/td&gt;
&lt;td&gt;Pod and Service networking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistent data&lt;/td&gt;
&lt;td&gt;Persistent Volumes / Claims&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Environment/config&lt;/td&gt;
&lt;td&gt;ConfigMaps and Secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restart/recovery thinking&lt;/td&gt;
&lt;td&gt;Controllers and reconciliation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Kubernetes doesn't make Docker knowledge useless.&lt;/p&gt;

&lt;p&gt;It builds on many of the same container fundamentals while adding orchestration around them.&lt;/p&gt;

&lt;p&gt;Take health checks as an example.&lt;/p&gt;

&lt;p&gt;With Docker, we learned:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Running doesn't necessarily mean healthy.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kubernetes makes the distinction even more useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Liveness Probe
&lt;/h3&gt;

&lt;p&gt;Roughly asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this container functioning, or should Kubernetes restart it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Readiness Probe
&lt;/h3&gt;

&lt;p&gt;Asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this Pod currently ready to receive traffic?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Startup Probe
&lt;/h3&gt;

&lt;p&gt;Helps protect slow-starting applications from liveness checks being applied too early.&lt;/p&gt;

&lt;p&gt;An application can therefore be alive without being ready to serve users.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Alive ≠ Ready&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The underlying problem hasn't disappeared.&lt;/p&gt;

&lt;p&gt;The orchestration layer simply has more ways to respond to it.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Updating One Container Is Easy. Updating Fifty Isn't.
&lt;/h2&gt;

&lt;p&gt;Replacing one Docker container is straightforward.&lt;/p&gt;

&lt;p&gt;But imagine updating 50 application instances.&lt;/p&gt;

&lt;p&gt;Stopping all of them at once could create downtime.&lt;/p&gt;

&lt;p&gt;Instead, you'd prefer something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Old Old Old Old

      ↓

New Old Old Old

      ↓

New New Old Old

      ↓

New New New Old

      ↓

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

&lt;/div&gt;



&lt;p&gt;Kubernetes Deployments support controlled rolling updates.&lt;/p&gt;

&lt;p&gt;If something goes wrong, rollout history and rollback mechanisms can help return the workload to an earlier revision.&lt;/p&gt;

&lt;p&gt;Again, Kubernetes isn't making the individual container smarter.&lt;/p&gt;

&lt;p&gt;It's coordinating &lt;strong&gt;how a group of containerized instances changes over time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's the pattern throughout this article.&lt;/p&gt;

&lt;p&gt;The container isn't necessarily the difficult part anymore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coordinating all the containers is.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Kubernetes Didn't Simply Replace Docker
&lt;/h2&gt;

&lt;p&gt;This is one of the most common misconceptions.&lt;/p&gt;

&lt;p&gt;You may have heard:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Kubernetes stopped using Docker."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That can make it sound as though Docker images somehow stopped working with Kubernetes.&lt;/p&gt;

&lt;p&gt;They didn't.&lt;/p&gt;

&lt;p&gt;Kubernetes needs a &lt;strong&gt;container runtime&lt;/strong&gt; to actually run containers.&lt;/p&gt;

&lt;p&gt;Modern Kubernetes communicates with container runtimes through the &lt;strong&gt;Container Runtime Interface (CRI)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Common examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;containerd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CRI-O&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kubernetes removed its old Docker-specific integration layer, known as &lt;strong&gt;dockershim&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But that doesn't mean Docker-built container images became unusable.&lt;/p&gt;

&lt;p&gt;The important takeaway is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Docker images didn't stop working with Kubernetes. Kubernetes changed how it communicates with container runtimes.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A simplified model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build Container Image
        │
        ▼
Store in Registry
        │
        ▼
Kubernetes
        │
        ▼
Container Runtime
        │
        ▼
Run Containers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the choice isn't simply:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker OR Kubernetes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Different tools are operating at different layers.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. So When Does Docker Stop Being Enough?
&lt;/h2&gt;

&lt;p&gt;Not every application needs Kubernetes.&lt;/p&gt;

&lt;p&gt;That's important.&lt;/p&gt;

&lt;p&gt;If you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A few containers&lt;/li&gt;
&lt;li&gt;One server&lt;/li&gt;
&lt;li&gt;Predictable traffic&lt;/li&gt;
&lt;li&gt;Simple deployments&lt;/li&gt;
&lt;li&gt;Limited scaling requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker or Docker Compose may be completely sufficient.&lt;/p&gt;

&lt;p&gt;Adding Kubernetes could simply introduce complexity you don't need.&lt;/p&gt;

&lt;p&gt;Kubernetes starts becoming more useful when the problems themselves change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many workloads&lt;/li&gt;
&lt;li&gt;Multiple machines&lt;/li&gt;
&lt;li&gt;Automated scheduling&lt;/li&gt;
&lt;li&gt;Failure recovery&lt;/li&gt;
&lt;li&gt;Service discovery&lt;/li&gt;
&lt;li&gt;Horizontal scaling&lt;/li&gt;
&lt;li&gt;Rolling deployments&lt;/li&gt;
&lt;li&gt;High availability&lt;/li&gt;
&lt;li&gt;Cluster-wide resource management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So perhaps the wrong question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"When should I graduate from Docker to Kubernetes?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Do I actually have an orchestration problem?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is no, Kubernetes may be solving a problem you don't have.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Journey From &lt;code&gt;docker run&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This series started with a deceptively simple command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we went underneath it.&lt;/p&gt;

&lt;p&gt;We explored:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker internals&lt;/li&gt;
&lt;li&gt;Image builds&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Container security&lt;/li&gt;
&lt;li&gt;Docker Compose&lt;/li&gt;
&lt;li&gt;Production reliability&lt;/li&gt;
&lt;li&gt;Rootless Docker and advanced security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And something interesting happened.&lt;/p&gt;

&lt;p&gt;The deeper we went, the less Docker looked like simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A tool that runs containers."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We started seeing the Linux kernel.&lt;/p&gt;

&lt;p&gt;Namespaces.&lt;/p&gt;

&lt;p&gt;cgroups.&lt;/p&gt;

&lt;p&gt;Filesystems.&lt;/p&gt;

&lt;p&gt;Networks.&lt;/p&gt;

&lt;p&gt;Security boundaries.&lt;/p&gt;

&lt;p&gt;Resource management.&lt;/p&gt;

&lt;p&gt;Application lifecycle.&lt;/p&gt;

&lt;p&gt;Eventually, the question changed.&lt;/p&gt;

&lt;p&gt;It was no longer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How do I run this container?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It became:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How do I reliably operate large numbers of containers across multiple machines?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's where the container problem becomes an orchestration problem.&lt;/p&gt;

&lt;p&gt;And that's where Kubernetes begins.&lt;/p&gt;

&lt;p&gt;Docker is surprisingly easy to start with.&lt;/p&gt;

&lt;p&gt;That's one of its greatest strengths.&lt;/p&gt;

&lt;p&gt;But underneath that simple experience is a much deeper system.&lt;/p&gt;

&lt;p&gt;You don't need to master every Docker internal before learning Kubernetes.&lt;/p&gt;

&lt;p&gt;But understanding the foundation makes Kubernetes feel much less mysterious.&lt;/p&gt;

&lt;p&gt;Because eventually you realize:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes isn't where containers begin.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's what becomes useful when operating containers becomes the bigger problem.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Question for You
&lt;/h2&gt;

&lt;p&gt;When did Kubernetes start making sense to you — while learning Pods and Deployments, or only after understanding the problems orchestration is trying to solve?&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>containers</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>Rootless Docker &amp; Advanced Security: Which Root Are We Actually Talking About?</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Thu, 24 Sep 2026 03:31:18 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/rootless-docker-advanced-security-which-root-are-we-actually-talking-about-1f8p</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/rootless-docker-advanced-security-which-root-are-we-actually-talking-about-1f8p</guid>
      <description>&lt;p&gt;You run a container as root.&lt;/p&gt;

&lt;p&gt;That sounds dangerous.&lt;/p&gt;

&lt;p&gt;But here's a more interesting question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which root?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Root inside the container?&lt;/p&gt;

&lt;p&gt;Root on the host?&lt;/p&gt;

&lt;p&gt;Or the root user running the Docker daemon?&lt;/p&gt;

&lt;p&gt;They aren't necessarily the same thing.&lt;/p&gt;

&lt;p&gt;And understanding that difference changes how you think about Docker security.&lt;/p&gt;

&lt;p&gt;We've already seen that containers rely on namespaces, capabilities, seccomp, and other Linux mechanisms for isolation.&lt;/p&gt;

&lt;p&gt;Now let's go one level deeper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if Docker itself didn't need root privileges in the first place?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's where Rootless Docker enters the picture.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Why Docker Has So Much Power
&lt;/h2&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the Docker CLI isn't creating the container by itself.&lt;/p&gt;

&lt;p&gt;A simplified flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
 │
 ▼
Docker CLI
 │
 ▼
Docker Daemon
 │
 ▼
Container Runtime
 │
 ▼
Linux Kernel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a traditional Docker installation, the Docker daemon normally runs with &lt;strong&gt;root privileges&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's powerful because container management involves operations around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Namespaces&lt;/li&gt;
&lt;li&gt;cgroups&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;li&gt;Filesystems&lt;/li&gt;
&lt;li&gt;Processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But that power creates an important security boundary.&lt;/p&gt;

&lt;p&gt;If someone gains unrestricted control over a rootful Docker daemon, they may gain extremely powerful access to the host.&lt;/p&gt;

&lt;p&gt;So Docker security isn't only about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Is my application running as root?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You also need to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Who controls Docker itself?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. The Docker Socket Is a Security Boundary
&lt;/h2&gt;

&lt;p&gt;You've probably seen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/run/docker.sock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Docker CLI commonly communicates with the Docker daemon through this Unix socket.&lt;/p&gt;

&lt;p&gt;That makes access to the socket much more powerful than it might initially appear.&lt;/p&gt;

&lt;p&gt;Someone with sufficient Docker access could potentially create highly privileged containers or expose sensitive host resources inside them.&lt;/p&gt;

&lt;p&gt;That's why blindly doing this is dangerous:&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="nt"&gt;-v&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might look like you're simply giving a container access to Docker.&lt;/p&gt;

&lt;p&gt;In reality, you're exposing a &lt;strong&gt;highly privileged control interface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A useful mental model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Protect access to the Docker daemon like you protect administrative access to the host.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And this leads to the next question.&lt;/p&gt;

&lt;p&gt;If the daemon itself is so powerful, &lt;strong&gt;does it always need to run as root?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Container Root ≠ Host Root
&lt;/h2&gt;

&lt;p&gt;Before answering that, we need to clarify what &lt;strong&gt;root&lt;/strong&gt; actually means.&lt;/p&gt;

&lt;p&gt;Suppose a process inside a container reports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uid=0(root)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's root inside that environment.&lt;/p&gt;

&lt;p&gt;But that doesn't necessarily mean it must have the same identity or privileges as UID 0 on the host.&lt;/p&gt;

&lt;p&gt;Linux &lt;strong&gt;user namespaces&lt;/strong&gt; can map identities inside one namespace to different identities outside it.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Container                  Host

UID 0 (root)   ────────▶   UID 100000
UID 1          ────────▶   UID 100001
UID 2          ────────▶   UID 100002
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UID 0 = root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the host's perspective, that identity can correspond to an unprivileged UID.&lt;/p&gt;

&lt;p&gt;This creates an important distinction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Root inside a user namespace doesn't necessarily mean root on the host.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's one of the ideas Rootless Docker builds upon.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. So What Is Rootless Docker?
&lt;/h2&gt;

&lt;p&gt;Traditional Docker commonly looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal User
     │
     ▼
Docker CLI
     │
     ▼
Docker Daemon
   (root)
     │
     ▼
Containers
     │
     ▼
Linux Kernel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rootless Docker changes the privilege model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal User
     │
     ▼
Docker CLI
     │
     ▼
Docker Daemon
 (non-root)
     │
     ▼
User Namespace
     │
     ▼
Containers
     │
     ▼
Linux Kernel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Docker daemon runs without host-root privileges, while user namespaces and other Linux mechanisms allow container operations to happen from an unprivileged user context.&lt;/p&gt;

&lt;p&gt;A process may still appear as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uid=0(root)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;inside its user namespace.&lt;/p&gt;

&lt;p&gt;But that identity can be mapped to an unprivileged identity on the host.&lt;/p&gt;

&lt;p&gt;Why does that matter?&lt;/p&gt;

&lt;p&gt;Because if something compromises the daemon or a container, the attack begins from a &lt;strong&gt;less privileged position&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's the real value of Rootless Docker.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Rootless Docker doesn't make compromise impossible. It reduces what a compromise starts with.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Rootful vs Rootless: What Actually Changes?
&lt;/h2&gt;

&lt;p&gt;Here's the simpler mental model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Rootful Docker&lt;/th&gt;
&lt;th&gt;Rootless Docker&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker daemon&lt;/td&gt;
&lt;td&gt;Runs as root&lt;/td&gt;
&lt;td&gt;Runs as a normal user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User namespaces&lt;/td&gt;
&lt;td&gt;Not inherently required for the daemon's privilege model&lt;/td&gt;
&lt;td&gt;Fundamental to the rootless model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Host privilege exposure&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;td&gt;Reduced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low-level host access&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;td&gt;More restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compatibility&lt;/td&gt;
&lt;td&gt;Broad&lt;/td&gt;
&lt;td&gt;Some limitations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security posture&lt;/td&gt;
&lt;td&gt;Requires careful privilege management&lt;/td&gt;
&lt;td&gt;Reduces daemon privileges by design&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Rootless doesn't eliminate Docker security concerns.&lt;/p&gt;

&lt;p&gt;It changes the &lt;strong&gt;starting privilege level&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that's important.&lt;/p&gt;

&lt;p&gt;But there's another trap here.&lt;/p&gt;

&lt;p&gt;It's tempting to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Docker is rootless now. Problem solved."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not quite.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Rootless Is Only One Security Layer
&lt;/h2&gt;

&lt;p&gt;A container can still have more access than the application actually needs.&lt;/p&gt;

&lt;p&gt;Rootless Docker answers one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How much host privilege does Docker itself start with?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It doesn't answer every other security question.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which privileged operations can the application perform?&lt;/li&gt;
&lt;li&gt;Can it gain additional privileges?&lt;/li&gt;
&lt;li&gt;Can it modify its filesystem?&lt;/li&gt;
&lt;li&gt;Which system calls can it make?&lt;/li&gt;
&lt;li&gt;Which host resources can it access?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's why container security works better as layers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2qptlv595445z9bc32k6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2qptlv595445z9bc32k6.png" alt="Application → Non-root → Capabilities → no-new-privileges → Read-only → seccomp → AppArmor/SELinux → User Namespace → Kernel" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each layer removes a different kind of unnecessary power.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security isn't one wall.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's a series of boundaries an attacker has to cross.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Reduce What the Container Can Do
&lt;/h2&gt;

&lt;p&gt;Linux traditionally gives root enormous power.&lt;/p&gt;

&lt;p&gt;Capabilities split many privileged operations into smaller units.&lt;/p&gt;

&lt;p&gt;Docker already starts containers with a reduced set of Linux capabilities.&lt;/p&gt;

&lt;p&gt;But for workloads that allow it, you can go further.&lt;/p&gt;

&lt;p&gt;Start by dropping all capabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cap-drop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ALL &lt;span class="se"&gt;\&lt;/span&gt;
  nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add back only what the workload genuinely requires.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cap-drop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ALL &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cap-add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;NET_BIND_SERVICE &lt;span class="se"&gt;\&lt;/span&gt;
  nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The principle is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Start with less privilege. Add privilege only when the workload proves it needs it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's another question:&lt;/p&gt;

&lt;p&gt;What if the process starts with limited privileges but later finds a way to gain more?&lt;/p&gt;

&lt;p&gt;Docker provides another useful control:&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="nt"&gt;--security-opt&lt;/span&gt; no-new-privileges&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--security-opt&lt;/span&gt; no-new-privileges&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells the kernel that processes in the container should not gain additional privileges through mechanisms such as setuid or setgid binaries.&lt;/p&gt;

&lt;p&gt;So these controls answer two different questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What privileged operations can this process perform?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;no-new-privileges&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can this process gain more privilege later?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a much stronger model than simply asking whether the process is called &lt;code&gt;root&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Reduce What the Container Can Change
&lt;/h2&gt;

&lt;p&gt;Now suppose an attacker compromises the application.&lt;/p&gt;

&lt;p&gt;Even with reduced privileges, another question matters:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What can the process modify?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many applications don't need to write to their entire container filesystem.&lt;/p&gt;

&lt;p&gt;If yours doesn't, Docker can make the root filesystem read-only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--read-only&lt;/span&gt; nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That reduces the places where a compromised process can modify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application files&lt;/li&gt;
&lt;li&gt;Binaries&lt;/li&gt;
&lt;li&gt;Configuration&lt;/li&gt;
&lt;li&gt;Other filesystem content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some applications still need writable locations for temporary files or runtime data.&lt;/p&gt;

&lt;p&gt;Those can be provided separately.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--read-only&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tmpfs&lt;/span&gt; /tmp &lt;span class="se"&gt;\&lt;/span&gt;
  nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The security principle is straightforward:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If something doesn't need write access, don't give it write access.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Reduce What the Container Can Reach
&lt;/h2&gt;

&lt;p&gt;Containers share the host's Linux kernel.&lt;/p&gt;

&lt;p&gt;That makes the kernel interface another important boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  seccomp
&lt;/h3&gt;

&lt;p&gt;Applications interact with the kernel using &lt;strong&gt;system calls&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Docker's default seccomp profile blocks many system calls that typical containers don't require.&lt;/p&gt;

&lt;p&gt;For many workloads, keeping Docker's default profile is a sensible starting point.&lt;/p&gt;

&lt;p&gt;More sensitive environments can use more restrictive workload-specific profiles.&lt;/p&gt;

&lt;p&gt;The principle remains the same:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Allow what is required. Reduce everything else.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  AppArmor and SELinux
&lt;/h3&gt;

&lt;p&gt;Normal Unix permissions aren't the only way Linux can control access.&lt;/p&gt;

&lt;p&gt;Mandatory Access Control systems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AppArmor&lt;/li&gt;
&lt;li&gt;SELinux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can enforce additional policies around what processes are allowed to access.&lt;/p&gt;

&lt;p&gt;Think of ordinary permissions as asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Does this user normally have permission?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mandatory Access Control adds another question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Even if normal permissions allow it, does security policy allow it?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These controls don't replace Rootless Docker.&lt;/p&gt;

&lt;p&gt;And Rootless Docker doesn't replace them.&lt;/p&gt;

&lt;p&gt;They protect different boundaries.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Where Rootless Docker Doesn't Fit
&lt;/h2&gt;

&lt;p&gt;At this point Rootless Docker might sound like something that should simply be enabled everywhere.&lt;/p&gt;

&lt;p&gt;But security controls come with trade-offs.&lt;/p&gt;

&lt;p&gt;Depending on the environment, Rootless Docker can have differences or limitations involving areas such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;li&gt;Privileged ports&lt;/li&gt;
&lt;li&gt;cgroup behavior or configuration&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Host integration&lt;/li&gt;
&lt;li&gt;Certain low-level workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some workloads genuinely require deeper host access that doesn't fit well with a rootless environment.&lt;/p&gt;

&lt;p&gt;So the goal isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Rootless everywhere at any cost."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The better principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Use the least privilege that still allows the workload to function correctly."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rootless Docker is especially worth evaluating where reducing daemon privilege is valuable and the workload doesn't require functionality incompatible with the rootless model.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Putting the Layers Together
&lt;/h2&gt;

&lt;p&gt;Now the individual controls start making more sense.&lt;/p&gt;

&lt;p&gt;Instead of simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a more restricted workload might look conceptually like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--read-only&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cap-drop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ALL &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cap-add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;NET_BIND_SERVICE &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--security-opt&lt;/span&gt; no-new-privileges&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;512m &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cpus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.0 &lt;span class="se"&gt;\&lt;/span&gt;
  nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not every application will work with exactly this configuration.&lt;/p&gt;

&lt;p&gt;And that's actually the important part.&lt;/p&gt;

&lt;p&gt;Hardening forces you to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What does this application actually need?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What can I give it so it definitely works?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those are very different security mindsets.&lt;/p&gt;

&lt;p&gt;A practical review might ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the application run as a non-root user?&lt;/li&gt;
&lt;li&gt;Can Docker itself run rootless?&lt;/li&gt;
&lt;li&gt;Which capabilities does the workload actually require?&lt;/li&gt;
&lt;li&gt;Can &lt;code&gt;no-new-privileges&lt;/code&gt; be enabled?&lt;/li&gt;
&lt;li&gt;Can the root filesystem be read-only?&lt;/li&gt;
&lt;li&gt;Is seccomp protection active?&lt;/li&gt;
&lt;li&gt;Is AppArmor or SELinux available?&lt;/li&gt;
&lt;li&gt;Is Docker socket access tightly controlled?&lt;/li&gt;
&lt;li&gt;Are resource limits configured?&lt;/li&gt;
&lt;li&gt;Is &lt;code&gt;--privileged&lt;/code&gt; being avoided unless there is a specific requirement?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to enable every option blindly.&lt;/p&gt;

&lt;p&gt;It's to understand &lt;strong&gt;why each privilege exists&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Docker security becomes easier to understand when you stop thinking of &lt;strong&gt;root&lt;/strong&gt; as one universal identity.&lt;/p&gt;

&lt;p&gt;There is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user running Docker&lt;/li&gt;
&lt;li&gt;The Docker daemon&lt;/li&gt;
&lt;li&gt;The process inside the container&lt;/li&gt;
&lt;li&gt;The user namespace&lt;/li&gt;
&lt;li&gt;The host kernel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those identities and privilege boundaries interact.&lt;/p&gt;

&lt;p&gt;That's why:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Root inside a container doesn't automatically mean root on the host.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it's why Rootless Docker matters.&lt;/p&gt;

&lt;p&gt;But Rootless Docker is only one part of the larger idea.&lt;/p&gt;

&lt;p&gt;Capabilities reduce what a process can do.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;no-new-privileges&lt;/code&gt; limits privilege escalation.&lt;/p&gt;

&lt;p&gt;Read-only filesystems reduce what can be changed.&lt;/p&gt;

&lt;p&gt;seccomp reduces unnecessary kernel access.&lt;/p&gt;

&lt;p&gt;AppArmor and SELinux add additional policy boundaries.&lt;/p&gt;

&lt;p&gt;User namespaces change what identities mean outside the container.&lt;/p&gt;

&lt;p&gt;The strongest container isn't necessarily the one with the most security features enabled.&lt;/p&gt;

&lt;p&gt;It's the one that has &lt;strong&gt;only the privileges it actually needs.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Question for You
&lt;/h2&gt;

&lt;p&gt;If your application works perfectly with fewer privileges, &lt;strong&gt;what reason is there to give it more?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you tried Rootless Docker in a development or production environment?&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>containers</category>
      <category>security</category>
    </item>
    <item>
      <title>Docker in Production: What Changes When Containers Meet Reality?</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Wed, 26 Aug 2026 12:25:33 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/docker-in-production-what-changes-when-containers-meet-reality-1bmm</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/docker-in-production-what-changes-when-containers-meet-reality-1bmm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;post 8:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You run a container.&lt;/p&gt;

&lt;p&gt;It starts successfully.&lt;/p&gt;

&lt;p&gt;The application works.&lt;/p&gt;

&lt;p&gt;So… is it production-ready?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not necessarily.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The real test of a production container isn't what happens when everything works.&lt;/p&gt;

&lt;p&gt;It's what happens when something goes wrong.&lt;/p&gt;

&lt;p&gt;What happens when the application consumes all available memory?&lt;/p&gt;

&lt;p&gt;What happens when the process crashes?&lt;/p&gt;

&lt;p&gt;What happens when the application is running, but isn't actually healthy?&lt;/p&gt;

&lt;p&gt;Where do the logs go?&lt;/p&gt;

&lt;p&gt;How do you know something is wrong before users tell you?&lt;/p&gt;

&lt;p&gt;And when the container fails, how do you find the actual cause?&lt;/p&gt;

&lt;p&gt;Running Docker in production isn't just about starting containers.&lt;/p&gt;

&lt;p&gt;It's about making them &lt;strong&gt;reliable, observable, manageable, and recoverable.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1. Production Starts With Boundaries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A container that works perfectly on a developer's laptop can behave very differently under production load.&lt;/p&gt;

&lt;p&gt;Development often prioritizes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed&lt;/li&gt;
&lt;li&gt;Convenience&lt;/li&gt;
&lt;li&gt;Easy debugging&lt;/li&gt;
&lt;li&gt;Frequent changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Production prioritizes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliability&lt;/li&gt;
&lt;li&gt;Predictability&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Recovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the first production questions is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What happens if this container consumes more resources than expected?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's where resource limits come in.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2. Resource Limits – Don't Let One Container Consume Everything&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without appropriate resource limits, a container can consume more host resources than intended.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;512m &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cpus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.0 &lt;span class="se"&gt;\&lt;/span&gt;
  nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This limits the container to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;512 MB memory&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1 CPU&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why does this matter?&lt;/p&gt;

&lt;p&gt;Imagine one application suddenly starts consuming several gigabytes of memory.&lt;/p&gt;

&lt;p&gt;Without appropriate limits, it could affect other workloads running on the same host.&lt;/p&gt;

&lt;p&gt;Resource limits create boundaries between workloads.&lt;/p&gt;

&lt;p&gt;But remember:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A resource limit doesn't fix a memory leak.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It only limits how much damage that container can cause to the host.&lt;/p&gt;

&lt;p&gt;So now we have another question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What if the container is running, but the application inside it is broken?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;3. Health Checks – Running Doesn't Mean Healthy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most important production concepts is the difference between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container is running&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application is healthy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A container can be running while the application inside is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hung&lt;/li&gt;
&lt;li&gt;Unable to connect to a database&lt;/li&gt;
&lt;li&gt;Returning errors&lt;/li&gt;
&lt;li&gt;Failing internal checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker supports health checks.&lt;/p&gt;

&lt;p&gt;For example:&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;HEALTHCHECK&lt;/span&gt;&lt;span class="s"&gt; --interval=30s --timeout=5s \&lt;/span&gt;
  CMD curl -f http://localhost:8080/health || exit 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Docker can track the application's health status.&lt;/p&gt;

&lt;p&gt;The important idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Process alive ≠ application healthy&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A health check only reports the container's health status. Docker does &lt;strong&gt;not&lt;/strong&gt; automatically restart a container simply because it becomes &lt;code&gt;unhealthy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An orchestrator or external health-monitoring tool is needed to take further action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Health vs. Recovery
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Process exits&lt;/td&gt;
&lt;td&gt;A restart policy can restart the container&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Health check becomes &lt;code&gt;unhealthy&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Docker reports the status; it doesn't automatically restart the container&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container repeatedly crashes&lt;/td&gt;
&lt;td&gt;A restart policy may keep retrying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application is unhealthy but still running&lt;/td&gt;
&lt;td&gt;Monitoring or orchestration is needed to take further action&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So what happens when the application actually &lt;strong&gt;crashes and exits&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;That's where restart policies come in.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4. Restart Policies – What Happens After a Crash?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Applications crash.&lt;/p&gt;

&lt;p&gt;Processes exit unexpectedly.&lt;/p&gt;

&lt;p&gt;Production systems need a recovery strategy.&lt;/p&gt;

&lt;p&gt;Docker provides restart policies such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;unless-stopped nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common policies include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;no&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;on-failure&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;always&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unless-stopped&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&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="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;on-failure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tells Docker to restart the container when it exits with a failure.&lt;/p&gt;

&lt;p&gt;Notice the distinction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Health check → reports health&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart policy → reacts to container exits&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A restart policy doesn't automatically fix an application that is alive but unhealthy.&lt;/p&gt;

&lt;p&gt;And if an application crashes repeatedly, restarting it doesn't solve the underlying problem.&lt;/p&gt;

&lt;p&gt;It simply keeps trying to recover.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recovery and diagnosis are two different problems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Which leads to another question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When something fails, where is the evidence?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;5. Logging – Keep the Evidence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When something fails in production, logs are often your first source of evidence.&lt;/p&gt;

&lt;p&gt;Docker captures container output from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stdout
stderr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can inspect it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &amp;lt;container&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow logs in real time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; &amp;lt;container&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And limit the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &lt;span class="nt"&gt;--tail&lt;/span&gt; 100 &amp;lt;container&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But don't treat &lt;code&gt;docker logs&lt;/code&gt; as your complete production logging strategy.&lt;/p&gt;

&lt;p&gt;Docker's default &lt;code&gt;json-file&lt;/code&gt; logging driver can grow over time and consume host disk space if log rotation isn't configured.&lt;/p&gt;

&lt;p&gt;Production environments should consider log rotation using options such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;max-size
max-file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For high-volume applications, a non-blocking logging mode can also help prevent logging from affecting application performance.&lt;/p&gt;

&lt;p&gt;Larger environments may also send logs to a centralized logging system for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log retention&lt;/li&gt;
&lt;li&gt;Search and filtering&lt;/li&gt;
&lt;li&gt;Centralized access&lt;/li&gt;
&lt;li&gt;Alerting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Logs are your first witness. Treat them like evidence, not decoration.&lt;/p&gt;

&lt;p&gt;They tell you what happened. But what if you want to know what is happening right now?&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;6. Monitoring – Know Before Users Tell You&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Logs tell you what happened.&lt;/p&gt;

&lt;p&gt;Metrics help you understand &lt;strong&gt;what is happening&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At minimum, monitor things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage&lt;/li&gt;
&lt;li&gt;Memory usage&lt;/li&gt;
&lt;li&gt;Network activity&lt;/li&gt;
&lt;li&gt;Container restarts&lt;/li&gt;
&lt;li&gt;Disk usage&lt;/li&gt;
&lt;li&gt;Application response time&lt;/li&gt;
&lt;li&gt;Error rates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker provides a simple starting point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stats
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you a live view of container resource consumption.&lt;/p&gt;

&lt;p&gt;But production monitoring usually goes further.&lt;/p&gt;

&lt;p&gt;You want to know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Is the application healthy before customers start reporting that it is broken?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's where metrics, dashboards, and alerts become important.&lt;/p&gt;

&lt;p&gt;But even with monitoring, failures will happen.&lt;/p&gt;

&lt;p&gt;The next skill is knowing how to investigate them.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;7. Troubleshooting – Don't Just Restart Everything&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a container isn't working, don't randomly restart everything.&lt;/p&gt;

&lt;p&gt;Use a systematic approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Check the container status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exited containers&lt;/li&gt;
&lt;li&gt;Restarting containers&lt;/li&gt;
&lt;li&gt;Unexpectedly stopped services&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Check the logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &amp;lt;container&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application errors&lt;/li&gt;
&lt;li&gt;Configuration problems&lt;/li&gt;
&lt;li&gt;Connection failures&lt;/li&gt;
&lt;li&gt;Permission issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Inspect the container
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker inspect &amp;lt;container&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Environment variables&lt;/li&gt;
&lt;li&gt;Mounts&lt;/li&gt;
&lt;li&gt;Networks&lt;/li&gt;
&lt;li&gt;Restart policies&lt;/li&gt;
&lt;li&gt;Health status&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Check resource usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stats
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High CPU&lt;/li&gt;
&lt;li&gt;High memory&lt;/li&gt;
&lt;li&gt;Unusual resource consumption&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: Check networking
&lt;/h3&gt;

&lt;p&gt;If the application cannot reach another service, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network configuration&lt;/li&gt;
&lt;li&gt;Service/container name&lt;/li&gt;
&lt;li&gt;Ports&lt;/li&gt;
&lt;li&gt;DNS resolution&lt;/li&gt;
&lt;li&gt;Connectivity between containers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Check the image
&lt;/h3&gt;

&lt;p&gt;Sometimes the problem isn't the container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's the image.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image version&lt;/li&gt;
&lt;li&gt;Recent changes&lt;/li&gt;
&lt;li&gt;Application dependencies&lt;/li&gt;
&lt;li&gt;Base image updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to move from:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“The container isn't working.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“This specific component is failing for this specific reason.”&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;8. Image Versions – Know What You're Running&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider:&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; nginx:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks convenient.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;latest&lt;/code&gt; can change over time.&lt;/p&gt;

&lt;p&gt;The same Dockerfile may produce different results later because the underlying image changed.&lt;/p&gt;

&lt;p&gt;Using a known version gives you more predictable deployments:&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; nginx:1.29&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Production environments can go even further by using carefully controlled image versions or immutable image references.&lt;/p&gt;

&lt;p&gt;The principle is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Know exactly what you're deploying.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;9. Smaller Images – Reduce What You Ship&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Production images should contain only what the application needs.&lt;/p&gt;

&lt;p&gt;Smaller images can provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster image pulls&lt;/li&gt;
&lt;li&gt;Faster deployments&lt;/li&gt;
&lt;li&gt;Smaller attack surface&lt;/li&gt;
&lt;li&gt;Less unnecessary software&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multi-stage builds can help.&lt;/p&gt;

&lt;p&gt;For example:&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="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:22&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&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; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:alpine&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build environment doesn't need to be included in the final runtime image.&lt;/p&gt;

&lt;p&gt;This separates:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;from&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Runtime environment&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;10. Make Containers Replaceable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's another important production mindset:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Containers should be replaceable, not precious.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't rely on manually changing files inside a running container as a permanent fix.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;container&amp;gt; bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be useful for troubleshooting.&lt;/p&gt;

&lt;p&gt;But manually editing application files inside the container creates a change that disappears when the container is replaced.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change the configuration or code&lt;/li&gt;
&lt;li&gt;Build a new image&lt;/li&gt;
&lt;li&gt;Test it&lt;/li&gt;
&lt;li&gt;Deploy the new version&lt;/li&gt;
&lt;li&gt;Replace the old container&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes deployments predictable and repeatable.&lt;/p&gt;

&lt;p&gt;And this raises another important question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What happens to data when the container disappears?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;11. Separate Application Lifecycle From Data Lifecycle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Containers are usually treated as disposable.&lt;/p&gt;

&lt;p&gt;Application data may not be.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database data&lt;/li&gt;
&lt;li&gt;Uploaded files&lt;/li&gt;
&lt;li&gt;Application-generated persistent data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's where Docker volumes or external storage come in.&lt;/p&gt;

&lt;p&gt;The container can be replaced while the data remains.&lt;/p&gt;

&lt;p&gt;This separation is important:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application lifecycle ≠ Data lifecycle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The application can change.&lt;/p&gt;

&lt;p&gt;The container can disappear.&lt;/p&gt;

&lt;p&gt;The data should survive when it needs to.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;12. Security Still Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Production reliability doesn't replace security.&lt;/p&gt;

&lt;p&gt;The security principles from the previous article still apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't run applications as root when unnecessary&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;--privileged&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use appropriate capabilities&lt;/li&gt;
&lt;li&gt;Keep images updated&lt;/li&gt;
&lt;li&gt;Use seccomp and other security controls&lt;/li&gt;
&lt;li&gt;Scan images&lt;/li&gt;
&lt;li&gt;Limit container resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A production container isn't secure simply because it is running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reliability, security, and observability have to work together.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;13. A Practical Production Checklist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before running a container in production, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Is the image version controlled?&lt;/li&gt;
&lt;li&gt;[ ] Is the container running as a non-root user where possible?&lt;/li&gt;
&lt;li&gt;[ ] Are CPU and memory limits defined?&lt;/li&gt;
&lt;li&gt;[ ] Is a health check configured?&lt;/li&gt;
&lt;li&gt;[ ] Is an appropriate restart policy configured?&lt;/li&gt;
&lt;li&gt;[ ] Is log rotation configured?&lt;/li&gt;
&lt;li&gt;[ ] Are important metrics being monitored?&lt;/li&gt;
&lt;li&gt;[ ] Are alerts configured for critical failures?&lt;/li&gt;
&lt;li&gt;[ ] Is persistent data stored outside the container filesystem?&lt;/li&gt;
&lt;li&gt;[ ] Can the container be safely replaced?&lt;/li&gt;
&lt;li&gt;[ ] Is the image regularly updated and scanned?&lt;/li&gt;
&lt;li&gt;[ ] Is there a documented troubleshooting process?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need every advanced platform feature on day one.&lt;/p&gt;

&lt;p&gt;But you should know &lt;strong&gt;what happens when something goes wrong.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Running Docker in production isn't simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's about designing for what happens &lt;strong&gt;after&lt;/strong&gt; the container starts.&lt;/p&gt;

&lt;p&gt;You need to think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt; → How much can the container consume?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health&lt;/strong&gt; → Is the application actually working?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recovery&lt;/strong&gt; → What happens when it crashes?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logs&lt;/strong&gt; → Where is the evidence?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt; → How do we know something is wrong?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Troubleshooting&lt;/strong&gt; → How do we find the cause?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images&lt;/strong&gt; → Do we know exactly what we're deploying?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data&lt;/strong&gt; → What survives when the container disappears?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; → What privileges does the workload actually need?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A container that runs successfully is only the beginning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Production readiness starts when you ask what happens when things go wrong.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Question for You&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the first thing you check when a Docker container fails in production — logs, resources, health status, or something else?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Next Topic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rootless Docker &amp;amp; Advanced Security: Running Containers With Fewer Privileges&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>sysadmin</category>
      <category>containers</category>
    </item>
    <item>
      <title>Think `docker compose up` just starts containers?

There’s more happening behind the scenes.

And one common assumption about `depends_on` can cause real problems.

I break down what Compose actually does—and what it doesn’t.</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 18 Aug 2026 08:10:23 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/think-docker-compose-up-just-starts-containers-theres-more-happening-behind-the-scenes-50d7</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/think-docker-compose-up-just-starts-containers-theres-more-happening-behind-the-scenes-50d7</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/sreekanth_kuruba_91721e5d/docker-compose-isnt-what-i-thought-it-was-1pjg" class="crayons-story__hidden-navigation-link"&gt;Docker Compose Isn't What I Thought It Was&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/sreekanth_kuruba_91721e5d" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3286476%2Fc7a306ec-1c67-4d33-901a-1148effc29ce.jpg" alt="sreekanth_kuruba_91721e5d profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/sreekanth_kuruba_91721e5d" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Sreekanth Kuruba
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Sreekanth Kuruba
                
                
              
              &lt;div id="story-author-preview-content-4044392" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/sreekanth_kuruba_91721e5d" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3286476%2Fc7a306ec-1c67-4d33-901a-1148effc29ce.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Sreekanth Kuruba&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/sreekanth_kuruba_91721e5d/docker-compose-isnt-what-i-thought-it-was-1pjg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 18&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/sreekanth_kuruba_91721e5d/docker-compose-isnt-what-i-thought-it-was-1pjg" id="article-link-4044392"&gt;
          Docker Compose Isn't What I Thought It Was
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/containerization"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;containerization&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cloudnative"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cloudnative&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/sreekanth_kuruba_91721e5d/docker-compose-isnt-what-i-thought-it-was-1pjg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/sreekanth_kuruba_91721e5d/docker-compose-isnt-what-i-thought-it-was-1pjg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Docker Compose Isn't What I Thought It Was</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 18 Aug 2026 03:21:36 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/docker-compose-isnt-what-i-thought-it-was-1pjg</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/docker-compose-isnt-what-i-thought-it-was-1pjg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;post 7:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;A practical guide to understanding Docker Compose—what it is, how it works, and the misconceptions that catch most beginners.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You've mastered single containers.&lt;/p&gt;

&lt;p&gt;Now it's time to build a real application.&lt;/p&gt;

&lt;p&gt;A frontend.&lt;br&gt;
A backend.&lt;br&gt;
A database.&lt;br&gt;
A Redis cache.&lt;/p&gt;

&lt;p&gt;Suddenly you're juggling multiple &lt;code&gt;docker run&lt;/code&gt; commands.&lt;/p&gt;

&lt;p&gt;Ports.&lt;br&gt;
Networks.&lt;br&gt;
Volumes.&lt;br&gt;
Environment variables.&lt;/p&gt;

&lt;p&gt;Chaos.&lt;/p&gt;

&lt;p&gt;Then someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Just use Docker Compose."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It works beautifully.&lt;/p&gt;

&lt;p&gt;But here's the twist most people never realize…&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Why Docker Compose Exists&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine starting an application like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend&lt;/li&gt;
&lt;li&gt;Backend&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running each container manually quickly becomes repetitive and error-prone.&lt;/p&gt;

&lt;p&gt;Docker Compose lets you describe your entire application in a single YAML file and start everything with one command.&lt;/p&gt;

&lt;p&gt;Instead of remembering dozens of commands, you define your infrastructure once.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;What Docker Compose Actually Is&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker Compose is &lt;strong&gt;not a container orchestrator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Docker Compose is a tool that reads your Compose YAML file and uses the Docker Engine to create and manage the resources defined in it.”&lt;/p&gt;

&lt;p&gt;Modern Docker uses &lt;strong&gt;Compose V2&lt;/strong&gt;, which runs as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of the older:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compose runs only when you execute a command.&lt;/p&gt;

&lt;p&gt;It creates the required Docker resources, starts the containers, and then exits.&lt;/p&gt;

&lt;p&gt;This makes it ideal for &lt;strong&gt;development, testing, and single-host deployments&lt;/strong&gt;, but it doesn't provide orchestration features like automatic scheduling, self-healing, or multi-node management.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A Simple docker-compose.yml&lt;/strong&gt;&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&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="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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB_HOST=db&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;

  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:15&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="s"&gt;postgres_data:/var/lib/postgresql/data&lt;/span&gt;

  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:alpine&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;YAML Quick Reference&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;services&lt;/td&gt;
&lt;td&gt;Defines containers (web, db, redis)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;build&lt;/td&gt;
&lt;td&gt;Builds an image from a Dockerfile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;image&lt;/td&gt;
&lt;td&gt;Uses an existing image from a registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ports&lt;/td&gt;
&lt;td&gt;Maps host ports to container ports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;environment&lt;/td&gt;
&lt;td&gt;Sets environment variables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;depends_on&lt;/td&gt;
&lt;td&gt;Controls startup order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;volumes&lt;/td&gt;
&lt;td&gt;Stores persistent data&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;What Happens When You Run docker compose up?&lt;/strong&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-compose.yml
        ↓
Compose reads the YAML
        ↓
Creates networks
        ↓
Creates volumes
        ↓
Builds images (if needed)
        ↓
Starts containers
        ↓
Application is running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command replaces many manual &lt;code&gt;docker run&lt;/code&gt; commands.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Modern Compose Features&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Profiles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Profiles let you enable optional services only when needed.&lt;/p&gt;

&lt;p&gt;For example, if your Compose file has a service assigned to the cache profile:&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;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:alpine&lt;/span&gt;
  &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cache&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can start it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="nt"&gt;--profile&lt;/span&gt; cache up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Development-only services&lt;/li&gt;
&lt;li&gt;Optional tools&lt;/li&gt;
&lt;li&gt;Testing environments&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;2. Watch (Compose V2)&lt;/strong&gt;&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;develop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sync&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./src&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app/src&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compose automatically syncs file changes without rebuilding the container.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Available in recent Docker Compose V2 releases.)&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Biggest Gotcha&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many beginners believe this:&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;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The database is ready."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It doesn't.&lt;/p&gt;

&lt;p&gt;It only means&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The database container has started."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The application inside may still be initializing.&lt;/p&gt;

&lt;p&gt;A better approach is to combine startup ordering with &lt;strong&gt;health checks&lt;/strong&gt; or design your application to retry connections until dependencies are available.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Common Expectations vs Reality&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expectation&lt;/th&gt;
&lt;th&gt;Reality&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compose is a production orchestrator&lt;/td&gt;
&lt;td&gt;It's primarily a development and single-host deployment tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;depends_on&lt;/code&gt; waits for the application&lt;/td&gt;
&lt;td&gt;It only waits for the container to start&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic scaling&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-healing&lt;/td&gt;
&lt;td&gt;Not provided&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-node orchestration&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hot reload&lt;/td&gt;
&lt;td&gt;Supported with &lt;code&gt;docker compose watch&lt;/code&gt; (Compose V2)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;Simple Mental Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of Docker Compose as a &lt;strong&gt;project manager&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of starting every container one by one, Compose reads a blueprint and launches everything in the correct configuration.&lt;/p&gt;

&lt;p&gt;It doesn't replace Docker.&lt;/p&gt;

&lt;p&gt;It simply coordinates Docker for you.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this guide you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why Docker Compose exists&lt;/li&gt;
&lt;li&gt;What Compose actually is&lt;/li&gt;
&lt;li&gt;Compose V2 vs the old Compose V1&lt;/li&gt;
&lt;li&gt;Understanding &lt;code&gt;services&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, &lt;code&gt;image&lt;/code&gt;, &lt;code&gt;ports&lt;/code&gt;, &lt;code&gt;environment&lt;/code&gt;, &lt;code&gt;depends_on&lt;/code&gt;, &lt;code&gt;profiles&lt;/code&gt;, &lt;code&gt;networks&lt;/code&gt;, and &lt;code&gt;volumes&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;What happens during &lt;code&gt;docker compose up&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Modern features like Profiles and Watch&lt;/li&gt;
&lt;li&gt;Common misconceptions about Compose&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Why This Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker Compose is one of the most valuable tools for local development.&lt;/p&gt;

&lt;p&gt;It lets developers spin up complete applications with a single command, making multi-container development simple and repeatable.&lt;/p&gt;

&lt;p&gt;As applications grow across multiple servers and require features like automatic scaling, self-healing, and high availability, orchestration platforms such as Kubernetes become the next step.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Question for You&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What's the biggest misconception you had about Docker Compose?&lt;/p&gt;

&lt;p&gt;Or what's one feature you wish you had discovered sooner?&lt;/p&gt;




</description>
      <category>docker</category>
      <category>devops</category>
      <category>containerization</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>Docker Security Internals: How Safe Are Your Containers Really?</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 11 Aug 2026 07:27:40 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/docker-security-internals-how-safe-are-your-containers-really-281e</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/docker-security-internals-how-safe-are-your-containers-really-281e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;post 6:&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You run containers every day.&lt;/p&gt;

&lt;p&gt;But have you ever asked yourself this uncomfortable question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If one container gets compromised… can it break out and take down the entire host?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most people assume containers are “secure by default.”&lt;/p&gt;

&lt;p&gt;They’re not.&lt;/p&gt;

&lt;p&gt;They’re &lt;strong&gt;isolated by default&lt;/strong&gt; — and isolation is not the same as security.&lt;/p&gt;

&lt;p&gt;This post explains how Docker security actually works under the hood, what the real risks are, and how to harden your containers properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Foundation: Linux Kernel Features
&lt;/h2&gt;

&lt;p&gt;Docker doesn’t invent its own security model.&lt;/p&gt;

&lt;p&gt;It relies heavily on existing Linux kernel features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Namespaces&lt;/strong&gt; → Isolation of processes, network, filesystem, and more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cgroups&lt;/strong&gt; → Resource limits for CPU, memory, and I/O&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capabilities&lt;/strong&gt; → Fine-grained control over root privileges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;seccomp&lt;/strong&gt; → Filtering of potentially dangerous system calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AppArmor / SELinux&lt;/strong&gt; → Mandatory Access Control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding these layers is the key to understanding container security.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Namespaces – Isolation, Not Security
&lt;/h2&gt;

&lt;p&gt;Namespaces give each container its own private view of the system.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PID namespace&lt;/strong&gt; → Container processes are isolated from host processes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network namespace&lt;/strong&gt; → Container gets its own network stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mount namespace&lt;/strong&gt; → Container gets its own filesystem view&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User namespace&lt;/strong&gt; → Container users can be mapped to unprivileged users on the host&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isolation is powerful — but it isn't perfect.&lt;/p&gt;

&lt;p&gt;All containers still share the &lt;strong&gt;same Linux kernel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means a serious kernel vulnerability could potentially affect the host and other containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Namespaces provide isolation, not complete security.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. cgroups – Preventing Resource Exhaustion
&lt;/h2&gt;

&lt;p&gt;Namespaces control &lt;strong&gt;what a container can see&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cgroups control how much of the host's resources it can consume.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without resource limits, a single container could potentially:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consume excessive CPU&lt;/li&gt;
&lt;li&gt;Exhaust available memory&lt;/li&gt;
&lt;li&gt;Generate excessive disk I/O&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;512m &lt;span class="nt"&gt;--cpus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.0 nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--memory=512m&lt;/code&gt; limits memory usage&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--cpus=1.0&lt;/code&gt; limits CPU usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps prevent one container from consuming an unreasonable amount of the host's resources.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Root Problem – Still Real
&lt;/h2&gt;

&lt;p&gt;By default, many containers run as &lt;strong&gt;root (UID 0) inside the container&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, Docker starts containers with a &lt;strong&gt;reduced set of Linux capabilities&lt;/strong&gt;, limiting what that root process can do.&lt;/p&gt;

&lt;p&gt;This significantly reduces the attack surface.&lt;/p&gt;

&lt;p&gt;But container root is still something to take seriously.&lt;/p&gt;

&lt;p&gt;If an application is compromised and has excessive privileges, combined with a kernel or runtime vulnerability, an attacker could potentially attempt a &lt;strong&gt;container escape&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A good practice is to run applications as a non-root user whenever possible.&lt;/p&gt;

&lt;p&gt;For example, in a Dockerfile:&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; nginx:alpine&lt;/span&gt;

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; 1000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also avoid using:&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="nt"&gt;--privileged&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;unless there is a specific, well-understood requirement.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--privileged&lt;/code&gt; option grants a container significantly more access to the host and disables or weakens several isolation protections.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. seccomp – Blocking Dangerous System Calls
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;seccomp (Secure Computing Mode)&lt;/strong&gt; is another important Docker security layer.&lt;/p&gt;

&lt;p&gt;Applications interact with the Linux kernel through &lt;strong&gt;system calls&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A compromised application could potentially try to use unusual or dangerous system calls to interact with the kernel.&lt;/p&gt;

&lt;p&gt;Docker provides a &lt;strong&gt;default seccomp profile&lt;/strong&gt; that blocks many system calls that containers typically don't need.&lt;/p&gt;

&lt;p&gt;You can also apply a custom, stricter profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--security-opt&lt;/span&gt; &lt;span class="nv"&gt;seccomp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/custom-profile.json &lt;span class="se"&gt;\&lt;/span&gt;
  nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can further reduce the container's attack surface.&lt;/p&gt;

&lt;p&gt;The key idea is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If an application doesn't need a system call, don't give it access to that system call.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Rootless Docker – Reducing Host-Level Risk
&lt;/h2&gt;

&lt;p&gt;Traditional Docker deployments commonly use a Docker daemon that requires root privileges.&lt;/p&gt;

&lt;p&gt;This creates an important security consideration because access to the Docker daemon can provide powerful control over containers and, depending on configuration, the host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rootless Docker&lt;/strong&gt; allows the Docker daemon and containers to operate without requiring root privileges.&lt;/p&gt;

&lt;p&gt;Container root can be mapped to an unprivileged user on the host.&lt;/p&gt;

&lt;p&gt;This reduces the potential impact of certain container or daemon compromises.&lt;/p&gt;

&lt;p&gt;Rootless Docker is particularly useful in environments where reducing host-level privileges is important, although it can have some feature and compatibility limitations.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Practical Docker Hardening Checklist
&lt;/h2&gt;

&lt;p&gt;Here are some practical steps you can apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Run containers as a non-root user&lt;/strong&gt; whenever possible&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use official and regularly updated base images&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable Rootless Docker&lt;/strong&gt; when it fits your environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;--read-only&lt;/code&gt;&lt;/strong&gt; for the container filesystem when the application allows it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set resource limits&lt;/strong&gt; such as &lt;code&gt;--memory&lt;/code&gt; and &lt;code&gt;--cpus&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep Docker's default seccomp profile&lt;/strong&gt; unless you have a reason to change it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use AppArmor or SELinux&lt;/strong&gt; where appropriate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scan images regularly&lt;/strong&gt; with tools such as Trivy or Docker Scout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid &lt;code&gt;--privileged&lt;/code&gt;&lt;/strong&gt; unless there is a specific requirement&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep Docker Engine and container images updated&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security is not achieved by using just one of these controls.&lt;/p&gt;

&lt;p&gt;It comes from &lt;strong&gt;multiple layers working together&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Docker security is &lt;strong&gt;not magic&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is a combination of multiple Linux and Docker security mechanisms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Namespaces&lt;/strong&gt; → Process and resource isolation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cgroups&lt;/strong&gt; → Resource control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capabilities&lt;/strong&gt; → Privilege reduction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;seccomp&lt;/strong&gt; → System call filtering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AppArmor / SELinux&lt;/strong&gt; → Mandatory Access Control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rootless Docker&lt;/strong&gt; → Reduced host-level privileges&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Default Docker settings provide a useful level of isolation, but production environments often require &lt;strong&gt;deliberate security hardening&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The important thing to remember is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Containers are isolated, but isolation alone does not make them secure.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Understanding what happens underneath Docker helps you move from:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“It works.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“It works — and it’s properly secured.”&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Next Topic
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Docker Compose Internals – How It Orchestrates Multi-Container Applications&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>linux</category>
      <category>containers</category>
    </item>
    <item>
      <title>Linux Troubleshooting Workflow for Beginners: A Step-by-Step Guide</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 04 Aug 2026 06:18:32 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/linux-troubleshooting-workflow-for-beginners-a-step-by-step-guide-427c</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/linux-troubleshooting-workflow-for-beginners-a-step-by-step-guide-427c</guid>
      <description>&lt;p&gt;Most Linux problems aren't actually difficult.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They're difficult because they're often debugged in the wrong order.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many beginners immediately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restart services randomly&lt;/li&gt;
&lt;li&gt;Run commands without a plan&lt;/li&gt;
&lt;li&gt;Change configurations before understanding the problem&lt;/li&gt;
&lt;li&gt;Guess instead of observing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Experienced engineers do something different.&lt;/p&gt;

&lt;p&gt;They follow a structured troubleshooting process.&lt;/p&gt;

&lt;p&gt;This article isn't about learning new Linux commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's about knowing when and why to use the commands you've already learned throughout this Linux Beginner Series.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of it as putting everything together into one practical troubleshooting workflow that's used in real Linux and DevOps environments.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Quick Troubleshooting Workflow&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Observe
   ↓
Check System Health
   ↓
Identify Problem Type
   ↓
Read Logs
   ↓
Verify Service
   ↓
Check Network
   ↓
Check Disk
   ↓
Recent Changes
   ↓
Find the Root Cause
   ↓
Apply the Fix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep this workflow in mind as you read through the guide.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 0: Observe Before You Change Anything&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before running a single command, pause for a moment.&lt;/p&gt;

&lt;p&gt;Ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What exactly is broken?&lt;/li&gt;
&lt;li&gt;When did the issue start?&lt;/li&gt;
&lt;li&gt;Is everyone affected or only some users?&lt;/li&gt;
&lt;li&gt;Is the problem constant or intermittent?&lt;/li&gt;
&lt;li&gt;What changed recently?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many troubleshooting sessions become longer because people try to fix the problem before they understand it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good troubleshooting begins with observation, not commands.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 1: Check Overall System Health&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your first goal is to understand the overall health of the system—not to fix anything yet.&lt;/p&gt;

&lt;p&gt;Useful commands:&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="nb"&gt;uptime
&lt;/span&gt;free &lt;span class="nt"&gt;-h&lt;/span&gt;
top
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High load average&lt;/li&gt;
&lt;li&gt;High CPU usage&lt;/li&gt;
&lt;li&gt;Low available memory&lt;/li&gt;
&lt;li&gt;Signs that the server is under heavy load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, you're only gathering evidence.&lt;/p&gt;

&lt;p&gt;A quick system health check often tells you where to investigate next.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 2: Identify the Type of Problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before diving deeper, classify the issue.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem Type&lt;/th&gt;
&lt;th&gt;Common Symptoms&lt;/th&gt;
&lt;th&gt;First Commands to Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td&gt;Slow system, high CPU usage&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;top&lt;/code&gt;, &lt;code&gt;htop&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Applications crashing, OOM kills&lt;/td&gt;
&lt;td&gt;&lt;code&gt;free -h&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disk&lt;/td&gt;
&lt;td&gt;"No space left on device"&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;df -h&lt;/code&gt;, &lt;code&gt;du -sh&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;Connection failures&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ping&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;ip a&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;td&gt;Service unavailable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application&lt;/td&gt;
&lt;td&gt;Errors or exceptions&lt;/td&gt;
&lt;td&gt;Application logs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Classification narrows your investigation instead of jumping between unrelated commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A well-classified problem is already half solved.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 3: Read the Logs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Logs are usually the most reliable source of information during troubleshooting.&lt;/p&gt;

&lt;p&gt;System logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-xe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specific service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traditional log files:&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="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/error.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search for errors:&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="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; error /var/log/syslog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For large log files, use &lt;strong&gt;less&lt;/strong&gt; to navigate comfortably instead of opening the entire file at once.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; Replace &lt;code&gt;nginx&lt;/code&gt; with the service you're troubleshooting, such as &lt;code&gt;sshd&lt;/code&gt;, &lt;code&gt;docker&lt;/code&gt;, or &lt;code&gt;apache2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Logs often tell you &lt;strong&gt;what&lt;/strong&gt; failed.&lt;/p&gt;

&lt;p&gt;Your job is to discover &lt;strong&gt;why&lt;/strong&gt; it failed.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 4: Verify the Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Never assume a service is healthy just because the application isn't responding.&lt;/p&gt;

&lt;p&gt;Check the service status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the running process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A service can be running while still failing to serve requests correctly.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The process may be running.&lt;/li&gt;
&lt;li&gt;The application may have failed during startup.&lt;/li&gt;
&lt;li&gt;The service may be unable to connect to its database.&lt;/li&gt;
&lt;li&gt;Configuration errors may prevent it from serving requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always verify the service before moving on to other areas.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 5: Check the Network&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the service looks healthy, verify connectivity.&lt;/p&gt;

&lt;p&gt;Useful commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping &amp;lt;host&amp;gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:8080
ip a
ss &lt;span class="nt"&gt;-tuln&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands help answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the server reach other systems?&lt;/li&gt;
&lt;li&gt;Is the application listening on the expected port?&lt;/li&gt;
&lt;li&gt;Is the network interface configured correctly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many "application issues" are actually network or DNS problems.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 6: Check Disk Space and Inodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Disk-related problems are among the most common causes of Linux issues.&lt;/p&gt;

&lt;p&gt;Check disk usage:&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="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check inode usage:&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="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find large directories:&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="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&lt;/span&gt; /&lt;span class="k"&gt;*&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-hr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A full disk—or exhausted inodes—can prevent applications from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing log files&lt;/li&gt;
&lt;li&gt;Creating temporary files&lt;/li&gt;
&lt;li&gt;Saving uploaded data&lt;/li&gt;
&lt;li&gt;Starting correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if CPU and memory look healthy, disk issues can bring an application down.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 7: Look for Recent Changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many production issues are caused by something that recently changed.&lt;/p&gt;

&lt;p&gt;Review recent logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 hour ago"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check recent logins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;last &lt;span class="nt"&gt;-10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Was there a recent deployment?&lt;/li&gt;
&lt;li&gt;Was a configuration changed?&lt;/li&gt;
&lt;li&gt;Was a package updated?&lt;/li&gt;
&lt;li&gt;Did anyone restart the service?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need to locate a configuration file, use tools like &lt;strong&gt;find&lt;/strong&gt; or &lt;strong&gt;whereis&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before making major configuration changes, consider creating a backup with &lt;strong&gt;tar&lt;/strong&gt; so you can easily restore the original if needed.&lt;/p&gt;

&lt;p&gt;Looking for recent changes often shortens the investigation dramatically.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 8: Find the Root Cause, Not Just the Symptom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finding an error doesn't always mean you've found the real problem.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;A web application crashes.&lt;/p&gt;

&lt;p&gt;The logs show write failures.&lt;/p&gt;

&lt;p&gt;You check the disk.&lt;/p&gt;

&lt;p&gt;The disk is full.&lt;/p&gt;

&lt;p&gt;The application wasn't the real problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The full disk was.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always ask yourself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Is this the root cause, or just another symptom?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This habit separates troubleshooting from guessing.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A Simple Troubleshooting Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever something breaks, follow the same sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Observe the problem
        ↓
Check system health
        ↓
Identify the problem type
        ↓
Read the logs
        ↓
Verify the service
        ↓
Check the network
        ↓
Check disk space
        ↓
Look for recent changes
        ↓
Find the root cause
        ↓
Apply the fix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following the same workflow every time reduces guesswork and speeds up troubleshooting.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A Real-World Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine a user reports:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"The website is down."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of restarting Nginx immediately:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check whether the service is running.&lt;/li&gt;
&lt;li&gt;Read the service logs.&lt;/li&gt;
&lt;li&gt;Notice repeated &lt;strong&gt;"No space left on device"&lt;/strong&gt; errors.&lt;/li&gt;
&lt;li&gt;Run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Discover the disk is full.&lt;/li&gt;
&lt;li&gt;Free up disk space.&lt;/li&gt;
&lt;li&gt;Restart the service if necessary.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The restart wasn't the solution. Finding the root cause was.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Common Beginner Mistakes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Avoid these habits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restarting services without checking logs&lt;/li&gt;
&lt;li&gt;Ignoring CPU, memory, or disk usage&lt;/li&gt;
&lt;li&gt;Running random commands without a plan&lt;/li&gt;
&lt;li&gt;Assuming the first error is the real cause&lt;/li&gt;
&lt;li&gt;Skipping recent changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good troubleshooting isn't about memorizing commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's about following a consistent process.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Linux troubleshooting isn't about knowing hundreds of commands.&lt;/p&gt;

&lt;p&gt;It's about asking the right questions in the right order.&lt;/p&gt;

&lt;p&gt;Commands help you collect evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A structured process helps you solve the problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The faster you narrow down the problem, the faster you'll reach the root cause.&lt;/p&gt;

&lt;p&gt;That's the mindset experienced engineers develop over time.&lt;/p&gt;

&lt;p&gt;Start with a simple process.&lt;/p&gt;

&lt;p&gt;Practice it consistently.&lt;/p&gt;

&lt;p&gt;You'll spend less time guessing and more time solving problems.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you've followed this Linux Beginner Series from the beginning, you've built a solid foundation in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux basics&lt;/li&gt;
&lt;li&gt;Filesystem structure&lt;/li&gt;
&lt;li&gt;Users &amp;amp; Permissions&lt;/li&gt;
&lt;li&gt;Processes&lt;/li&gt;
&lt;li&gt;Disk usage&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;li&gt;Logs&lt;/li&gt;
&lt;li&gt;Package management&lt;/li&gt;
&lt;li&gt;Finding files &amp;amp; text&lt;/li&gt;
&lt;li&gt;Viewing files efficiently&lt;/li&gt;
&lt;li&gt;File compression&lt;/li&gt;
&lt;li&gt;Troubleshooting workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's no longer just a collection of Linux commands.&lt;/p&gt;

&lt;p&gt;It's a practical foundation for understanding how Linux systems work and how to troubleshoot them with confidence.&lt;/p&gt;

&lt;p&gt;Remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good engineers don't memorize every command.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They know how to investigate problems, gather evidence, and find the root cause.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The best way to improve at troubleshooting is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break things in a safe environment.&lt;/li&gt;
&lt;li&gt;Fix them.&lt;/li&gt;
&lt;li&gt;Learn from them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's where real learning happens.&lt;/p&gt;

&lt;p&gt;Thank you for following this Linux Beginner Series!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Your Turn&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What's one Linux troubleshooting lesson you learned the hard way?&lt;/p&gt;

&lt;p&gt;Share your experience in the comments—your story might help another beginner avoid the same mistake.&lt;/p&gt;

&lt;p&gt;Happy learning! &lt;/p&gt;

</description>
      <category>linux</category>
      <category>sysadmin</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>File Compression in Linux Explained Simply (tar, gzip, zip &amp; unzip)</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Thu, 30 Jul 2026 06:44:14 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/file-compression-in-linux-explained-simply-tar-gzip-zip-unzip-2a1m</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/file-compression-in-linux-explained-simply-tar-gzip-zip-unzip-2a1m</guid>
      <description>&lt;p&gt;Working with files in Linux isn't just about creating and editing them.&lt;/p&gt;

&lt;p&gt;Sometimes you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Archive multiple files into one&lt;/li&gt;
&lt;li&gt;Compress files to save disk space&lt;/li&gt;
&lt;li&gt;Share files with others&lt;/li&gt;
&lt;li&gt;Create backups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linux provides several tools for this, each with a different purpose.&lt;/p&gt;

&lt;p&gt;Let's simplify them.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What is File Compression?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;File compression reduces the size of a file.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saves disk space&lt;/li&gt;
&lt;li&gt;Faster file transfers&lt;/li&gt;
&lt;li&gt;Easier backups&lt;/li&gt;
&lt;li&gt;Reduces bandwidth usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;A 100 MB log file might become a much smaller compressed file, depending on its contents.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Archive vs Compression&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many beginners think they're the same.&lt;/p&gt;

&lt;p&gt;They are not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Archive&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Combines multiple files into a single file.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;photos/
docs/
notes.txt

↓

backup.tar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Compression&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reduces the size of a file.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;backup.tar

↓

backup.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 &lt;strong&gt;tar archives files. gzip compresses them.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1. Create an Archive with tar&lt;/strong&gt;&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="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-cvf&lt;/span&gt; backup.tar Documents/    &lt;span class="c"&gt;#Create an archive&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-tvf&lt;/span&gt; backup.tar               &lt;span class="c"&gt;#View archive contents&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xvf&lt;/span&gt; backup.tar               &lt;span class="c"&gt;#Extract an archive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt; → Create&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;v&lt;/code&gt; → Verbose (show progress)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;f&lt;/code&gt; → File name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; → Extract&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backups&lt;/li&gt;
&lt;li&gt;Bundling multiple files&lt;/li&gt;
&lt;li&gt;Moving folders&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;2. Compress with gzip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Compress a file:&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="nb"&gt;gzip &lt;/span&gt;file.txt          &lt;span class="c"&gt;# Creates file.txt.gz&lt;/span&gt;
&lt;span class="c"&gt;# Result&lt;/span&gt;
file.txt.gz
&lt;span class="nb"&gt;gunzip &lt;/span&gt;file.txt.gz     &lt;span class="c"&gt;# decompress&lt;/span&gt;
&lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; file.txt       &lt;span class="c"&gt;# Keep original file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log files&lt;/li&gt;
&lt;li&gt;Large text files&lt;/li&gt;
&lt;li&gt;Saving disk space&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;3. Archive and Compress Together&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most common command:&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;# Create compressed archive&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-czvf&lt;/span&gt; backup.tar.gz Documents/
&lt;span class="c"&gt;# Extract&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzvf&lt;/span&gt; backup.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;z&lt;/code&gt; → Use gzip compression&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This is one of the most common backup commands in Linux.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4. Working with ZIP Files&lt;/strong&gt;&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;# Create ZIP&lt;/span&gt;
zip &lt;span class="nt"&gt;-r&lt;/span&gt; project.zip project/
&lt;span class="c"&gt;# Extract&lt;/span&gt;
unzip project.zip
&lt;span class="c"&gt;# List contents&lt;/span&gt;
unzip &lt;span class="nt"&gt;-l&lt;/span&gt; project.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sharing files with Windows users&lt;/li&gt;
&lt;li&gt;Cross-platform compatibility&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;5. Compare the Tools&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tar&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Archive files&lt;/td&gt;
&lt;td&gt;Backups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gzip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compress files&lt;/td&gt;
&lt;td&gt;Saving space&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tar + gzip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Archive and compress&lt;/td&gt;
&lt;td&gt;Linux backups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Archive and compress&lt;/td&gt;
&lt;td&gt;Sharing files across operating systems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;Real-World Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need to back up a website before making changes.&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;# Create backup&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-czvf&lt;/span&gt; website-backup.tar.gz /var/www/html
&lt;span class="c"&gt;# Restore later if needed&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzvf&lt;/span&gt; website-backup.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a common practice before upgrades, migrations, or configuration changes.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Common Beginner Mistakes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thinking &lt;code&gt;tar&lt;/code&gt; compresses files by itself&lt;/li&gt;
&lt;li&gt;Forgetting &lt;code&gt;-z&lt;/code&gt; when creating &lt;code&gt;.tar.gz&lt;/code&gt; archives&lt;/li&gt;
&lt;li&gt;Compressing files that are already compressed (like &lt;code&gt;.jpg&lt;/code&gt; or &lt;code&gt;.mp4&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Extracting archives into the wrong directory&lt;/li&gt;
&lt;li&gt;Deleting backups before verifying they can be restored&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Simple Mental Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of it like packing for a trip:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;tar&lt;/strong&gt; → Put all your clothes into one suitcase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gzip&lt;/strong&gt; → Compress the suitcase to make it smaller.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tar.gz&lt;/strong&gt; → Pack everything into one suitcase and compress it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;zip&lt;/strong&gt; → A suitcase that's easy to share with almost any operating system.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this guide you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What file compression is&lt;/li&gt;
&lt;li&gt;Archive vs. compression&lt;/li&gt;
&lt;li&gt;Creating archives with &lt;code&gt;tar&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Compressing files with &lt;code&gt;gzip&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Creating &lt;code&gt;.tar.gz&lt;/code&gt; archives&lt;/li&gt;
&lt;li&gt;Working with ZIP files&lt;/li&gt;
&lt;li&gt;Common beginner mistakes&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Why This Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;File compression is used every day by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux administrators&lt;/li&gt;
&lt;li&gt;DevOps engineers&lt;/li&gt;
&lt;li&gt;Cloud engineers&lt;/li&gt;
&lt;li&gt;Developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're creating backups, transferring files, or saving disk space, understanding these tools is an essential Linux skill.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt;&lt;br&gt;
You’ve now covered the essential Linux fundamentals.&lt;/p&gt;

&lt;p&gt;In the next and final post, we’ll combine everything from this series into a practical troubleshooting workflow you can use to diagnose Linux issues with confidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Post&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linux Troubleshooting Flow for Beginners&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Question for You&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Which compression format do you use most often: &lt;strong&gt;&lt;code&gt;.tar.gz&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;.zip&lt;/code&gt;&lt;/strong&gt;? And in what situation?&lt;/p&gt;




</description>
      <category>linux</category>
      <category>devops</category>
      <category>beginners</category>
      <category>sysadmin</category>
    </item>
    <item>
      <title>Viewing Files in Linux Explained Simply (cat, less, head, tail &amp; wc)</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 21 Jul 2026 06:38:18 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/viewing-files-in-linux-explained-simply-cat-less-head-tail-wc-4epp</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/viewing-files-in-linux-explained-simply-cat-less-head-tail-wc-4epp</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finding a file is only half the job.&lt;/p&gt;

&lt;p&gt;The next step is reading it.&lt;/p&gt;

&lt;p&gt;Whether it's a configuration file, a log, or a text document, Linux provides several commands to view files efficiently.&lt;/p&gt;

&lt;p&gt;Each command has a different purpose.&lt;/p&gt;

&lt;p&gt;Knowing which one to use can save time and make troubleshooting much easier.&lt;/p&gt;

&lt;p&gt;Let's simplify them.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why Not Just Use cat for Everything?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many beginners learn:&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="nb"&gt;cat &lt;/span&gt;filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use it for every file.&lt;/p&gt;

&lt;p&gt;It works...&lt;/p&gt;

&lt;p&gt;Until the file has &lt;strong&gt;50,000 lines&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Linux provides better tools depending on what you're trying to do.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1. View the Entire File with &lt;code&gt;cat&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cat&lt;/code&gt; command displays the complete contents of a file.&lt;/p&gt;

&lt;p&gt;Example:&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="nb"&gt;cat &lt;/span&gt;config.txt
&lt;span class="nb"&gt;cat &lt;/span&gt;file1.txt file2.txt     &lt;span class="c"&gt;# Combine files&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; notes.txt             &lt;span class="c"&gt;# Create new file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Best for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small files&lt;/li&gt;
&lt;li&gt;Quick checks&lt;/li&gt;
&lt;li&gt;Combining files&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;2. Read Large Files with &lt;code&gt;less&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Large files are difficult to read with &lt;code&gt;cat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;less /var/log/syslog
less /etc/nginx/nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful shortcuts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Space → Next page&lt;/li&gt;
&lt;li&gt;b → Previous page&lt;/li&gt;
&lt;li&gt;/text → Search&lt;/li&gt;
&lt;li&gt;q → Quit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration files&lt;/li&gt;
&lt;li&gt;Large logs&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;3. View the Beginning with &lt;code&gt;head&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes you only need the first few lines.&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="nb"&gt;head &lt;/span&gt;file.txt
&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; file.txt          &lt;span class="c"&gt;# First 20 lines&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checking file headers&lt;/li&gt;
&lt;li&gt;Previewing files&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;4. View the End with &lt;code&gt;tail&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Need the latest log entries?&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="nb"&gt;tail &lt;/span&gt;file.txt
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; file.txt          &lt;span class="c"&gt;# Last 20 lines&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect for log files.&lt;br&gt;
Checking recent changes.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;5. Monitor Files Live with &lt;code&gt;tail -f&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most-used Linux troubleshooting commands.&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="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/error.log
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; app.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As new lines are written, they appear instantly.&lt;/p&gt;

&lt;p&gt;Stop with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ctrl + C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitoring logs&lt;/li&gt;
&lt;li&gt;Watching application output&lt;/li&gt;
&lt;li&gt;Debugging services&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;6. Count with &lt;code&gt;wc&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Want to know how big a file is?&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="nb"&gt;wc &lt;/span&gt;file.txt
&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; file.txt             &lt;span class="c"&gt;# Count only lines&lt;/span&gt;
&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; file.txt             &lt;span class="c"&gt;# Count words&lt;/span&gt;
&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; file.txt             &lt;span class="c"&gt;# Count characters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scripts&lt;/li&gt;
&lt;li&gt;Reports&lt;/li&gt;
&lt;li&gt;Log analysis&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Real-World Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An application isn't starting.&lt;/p&gt;

&lt;p&gt;First, check the configuration file:&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;# First, check the configuration file:&lt;/span&gt;
less /etc/nginx/nginx.conf

&lt;span class="c"&gt;# Monitor the error log:&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/error.log

&lt;span class="c"&gt;# Need to know how many errors occurred?&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; error app.log | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This is a common workflow when troubleshooting Linux systems.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Common Beginner Mistakes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;cat&lt;/code&gt; for huge files&lt;/li&gt;
&lt;li&gt;Forgetting &lt;code&gt;less&lt;/code&gt; supports searching&lt;/li&gt;
&lt;li&gt;Not using &lt;code&gt;tail -f&lt;/code&gt; for live logs&lt;/li&gt;
&lt;li&gt;Thinking &lt;code&gt;head&lt;/code&gt; and &lt;code&gt;tail&lt;/code&gt; only work with 10 lines&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Simple Mental Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of these commands like reading a book.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Think of it as...&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read the whole book&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;less&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read page by page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read the first page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read the last page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tail -f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Watch new pages being written&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Count pages, words, or characters&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this guide you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cat&lt;/code&gt; → View complete files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;less&lt;/code&gt; → Read large files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;head&lt;/code&gt; → View the beginning&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tail&lt;/code&gt; → View the end&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tail -f&lt;/code&gt; → Monitor files live&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wc&lt;/code&gt; → Count lines, words, and characters&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Why This Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configuration files and logs are everywhere in Linux.&lt;/p&gt;

&lt;p&gt;Knowing how to read them efficiently is an essential skill for developers, system administrators, and DevOps engineers.&lt;/p&gt;

&lt;p&gt;The right command can save time and make troubleshooting much easier.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Next Post&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File Compression in Linux Explained Simply (tar, gzip, zip &amp;amp; unzip)&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Question for You&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Which command do you use the most when reading files in Linux?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;less&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Or something else?&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>linux</category>
      <category>devops</category>
      <category>beginners</category>
      <category>sysadmin</category>
    </item>
    <item>
      <title>Finding Files &amp; Text in Linux Explained Simply (find, grep, which &amp; whereis)</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 14 Jul 2026 03:03:02 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/finding-files-text-in-linux-explained-simply-find-grep-which-whereis-4lll</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/finding-files-text-in-linux-explained-simply-find-grep-which-whereis-4lll</guid>
      <description>&lt;p&gt;One of the most common questions Linux beginners ask is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Where is this file?”&lt;/li&gt;
&lt;li&gt;“How do I find a specific error in logs?”&lt;/li&gt;
&lt;li&gt;“Where is this command installed?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linux has powerful tools to answer these questions quickly.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll learn the most useful search commands.&lt;/p&gt;




&lt;h3&gt;
  
  
  Finding Files vs Searching Text
&lt;/h3&gt;

&lt;p&gt;These are two different tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Finding files&lt;/strong&gt; = Locating a file or directory on the system → &lt;code&gt;find&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Searching text&lt;/strong&gt; = Looking for words inside files → &lt;code&gt;grep&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  1. Find Files with &lt;code&gt;find&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find a specific file&lt;/span&gt;
find /home &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"nginx.conf"&lt;/span&gt;

&lt;span class="c"&gt;# Search entire system (ignore permission errors)&lt;/span&gt;
find / &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.log"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Find only directories&lt;/span&gt;
find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; d

&lt;span class="c"&gt;# Find only files&lt;/span&gt;
find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f

&lt;span class="c"&gt;# Find files larger than 100MB&lt;/span&gt;
find / &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-size&lt;/span&gt; +100M 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Useful for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finding configuration files&lt;/li&gt;
&lt;li&gt;Locating log files&lt;/li&gt;
&lt;li&gt;Finding large files&lt;/li&gt;
&lt;li&gt;Searching project directories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Tip:&lt;/strong&gt; Always try to narrow the search path instead of searching from &lt;code&gt;/&lt;/code&gt; whenever possible.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Search Text Inside Files with &lt;code&gt;grep&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search for a word&lt;/span&gt;
&lt;span class="nb"&gt;grep &lt;/span&gt;error app.log

&lt;span class="c"&gt;# Case insensitive search&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; error app.log

&lt;span class="c"&gt;# Search recursively in directory&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"database"&lt;/span&gt; /etc/

&lt;span class="c"&gt;# Show line numbers&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"listen"&lt;/span&gt; nginx.conf

&lt;span class="c"&gt;# Count matches&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"failed"&lt;/span&gt; auth.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Useful for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Searching logs&lt;/li&gt;
&lt;li&gt;Finding configuration values&lt;/li&gt;
&lt;li&gt;Looking for error messages&lt;/li&gt;
&lt;li&gt;Debugging applications&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Find Executable Location with &lt;code&gt;which&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;which python3
which docker
which nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shows the full path of the command that will be executed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful for:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finding executable locations&lt;br&gt;
Checking which version of a command Linux will run&lt;br&gt;
Verifying software installation&lt;/p&gt;


&lt;h3&gt;
  
  
  4. Find Program Files with &lt;code&gt;whereis&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;whereis nginx
whereis python3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;It can show:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Binary location&lt;br&gt;
Source files (if available)&lt;br&gt;
Manual pages&lt;/p&gt;

&lt;p&gt;Useful when you want to know where a program and its documentation are stored.&lt;/p&gt;


&lt;h3&gt;
  
  
  Bonus: Fast File Search with &lt;code&gt;locate&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;locate nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Much faster than &lt;code&gt;find&lt;/code&gt; because it uses a database.&lt;/p&gt;

&lt;p&gt;If it doesn't return recent files, Update database:&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="nb"&gt;sudo &lt;/span&gt;updatedb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: locate may not be installed by default on every Linux distribution.&lt;/p&gt;




&lt;h3&gt;
  
  
  Real-World Troubleshooting Example
&lt;/h3&gt;

&lt;p&gt;Nginx is not starting.&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;# Find config file&lt;/span&gt;
find /etc &lt;span class="nt"&gt;-name&lt;/span&gt; nginx.conf 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Search for errors in logs&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; error /var/log/nginx/error.log

&lt;span class="c"&gt;# Check executable&lt;/span&gt;
which nginx

&lt;span class="c"&gt;# See all related files&lt;/span&gt;
whereis nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a common workflow during Linux troubleshooting.&lt;/p&gt;




&lt;h3&gt;
  
  
  Common Beginner Mistakes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;find /&lt;/code&gt; instead of a specific directory&lt;/li&gt;
&lt;li&gt;Forgetting &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; when searching the whole system&lt;/li&gt;
&lt;li&gt;Confusing &lt;code&gt;find&lt;/code&gt; with &lt;code&gt;grep&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Not knowing the difference between &lt;code&gt;which&lt;/code&gt; and &lt;code&gt;whereis&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Forgetting that &lt;code&gt;locate&lt;/code&gt; may require an updated database&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Simple Mental Model
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Use For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Locate files and directories&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search text inside files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;which&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Find executable path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;whereis&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Find program + docs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;locate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fast filename search&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In this guide you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to find files with &lt;code&gt;find&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to search text with &lt;code&gt;grep&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to locate commands with &lt;code&gt;which&lt;/code&gt; and &lt;code&gt;whereis&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to perform fast filename searches with &lt;code&gt;locate&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next Post:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Viewing Files in Linux (cat, less, head, tail &amp;amp; wc)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Question for You&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Which command do you use most while troubleshooting — &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;, or something else?&lt;/p&gt;




</description>
      <category>linux</category>
      <category>devops</category>
      <category>beginners</category>
      <category>sysadmin</category>
    </item>
    <item>
      <title>Linux Package Management Explained Simply (apt, dnf, yum &amp; rpm)</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 07 Jul 2026 03:13:00 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/linux-package-management-explained-simply-apt-dnf-yum-rpm-11gn</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/linux-package-management-explained-simply-apt-dnf-yum-rpm-11gn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Quick Note&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In my previous article, I mentioned that &lt;strong&gt;Linux Troubleshooting Flow for Beginners&lt;/strong&gt; would be the final post in this series.&lt;/p&gt;

&lt;p&gt;While preparing it, I realized there were a few practical Linux skills every beginner should learn first. These topics will make the troubleshooting guide much easier to understand and follow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Before we wrap up the series, we'll cover:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Package Management&lt;br&gt;
Finding Files &amp;amp; Text&lt;br&gt;
Viewing Files Efficiently&lt;br&gt;
File Compression&lt;/p&gt;

&lt;p&gt;Then we'll bring everything together in the final &lt;strong&gt;Linux Troubleshooting Flow for Beginners.&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Installing software on Linux is very different from Windows.&lt;/p&gt;

&lt;p&gt;On Windows, you usually download an &lt;code&gt;.exe&lt;/code&gt; installer.&lt;br&gt;&lt;br&gt;
On Linux, software is typically installed and managed using &lt;code&gt;package managers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is one of the most practical skills every Linux beginner should learn early.&lt;/p&gt;


&lt;h3&gt;
  
  
  What is a Package?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;package&lt;/strong&gt; is a ready-to-install bundle that contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The main program&lt;/li&gt;
&lt;li&gt;Required libraries&lt;/li&gt;
&lt;li&gt;Configuration files&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Examples:&lt;/strong&gt; &lt;code&gt;nginx&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt;, &lt;code&gt;docker&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Think of a package as a ready-to-install software box.&lt;/p&gt;


&lt;h3&gt;
  
  
  What is a Package Manager?
&lt;/h3&gt;

&lt;p&gt;A package manager is a tool that installs, updates, removes, and manages software packages.&lt;br&gt;
Instead of downloading software manually, you simply run a command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt install git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The package manager automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Downloads packages from trusted repositories&lt;/li&gt;
&lt;li&gt;Install required dependencies automatically&lt;/li&gt;
&lt;li&gt;Upgrade installed software&lt;/li&gt;
&lt;li&gt;Removes them cleanly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of manual downloading, you just run one command.&lt;/p&gt;


&lt;h3&gt;
  
  
  Why Use a Package Manager?
&lt;/h3&gt;

&lt;p&gt;Without package managers, you would have to:&lt;/p&gt;

&lt;p&gt;Search for software manually&lt;br&gt;
Download files from websites&lt;br&gt;
Install dependencies yourself&lt;br&gt;
Update each application separately&lt;/p&gt;

&lt;p&gt;Package managers automate all of this.&lt;/p&gt;


&lt;h3&gt;
  
  
  What is a Repository?
&lt;/h3&gt;

&lt;p&gt;Package managers download software from repositories.&lt;/p&gt;

&lt;p&gt;A repository is a trusted online collection of software packages maintained by your Linux distribution.&lt;/p&gt;

&lt;p&gt;Instead of downloading software from random websites, Linux installs it securely from these repositories.&lt;/p&gt;


&lt;h3&gt;
  
  
  Common Package Managers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Distribution&lt;/th&gt;
&lt;th&gt;Package Manager&lt;/th&gt;
&lt;th&gt;Low-level Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ubuntu / Debian&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dpkg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fedora / RHEL / Rocky&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dnf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpm&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Older RHEL / CentOS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;yum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpm&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most Ubuntu users will use apt, while Fedora and modern RHEL-based systems use dnf.&lt;/p&gt;


&lt;h3&gt;
  
  
  Most Useful Commands
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Update Package List&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before installing software, update the package list.&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="nb"&gt;sudo &lt;/span&gt;apt update          &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf check-update    &lt;span class="c"&gt;# Fedora/RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: apt update does not upgrade installed packages.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2. Upgrade Installed Packages&lt;/strong&gt;&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="nb"&gt;sudo &lt;/span&gt;apt upgrade   &lt;span class="c"&gt;#Ubuntu/Debian&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf upgrade   &lt;span class="c"&gt;#Fedora/RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installs the latest available versions of your installed packages.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3. Install a Package&lt;/strong&gt;&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="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx   &lt;span class="c"&gt;#Ubuntu/Debian&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;nginx   &lt;span class="c"&gt;#Fedora/RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example packages:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;sudo apt install git&lt;br&gt;
sudo apt install curl&lt;br&gt;
sudo apt install vim&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;4. Remove a Package&lt;/strong&gt;&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="nb"&gt;sudo &lt;/span&gt;apt remove nginx    &lt;span class="c"&gt;#Ubuntu/Debian&lt;/span&gt;
&lt;span class="c"&gt;# Remove package and configuration files&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt purge nginx     
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf remove nginx    &lt;span class="c"&gt;#Fedora/RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;5. Search for Packages&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt search docker    &lt;span class="c"&gt;#Ubuntu/Debian&lt;/span&gt;
dnf search docker    &lt;span class="c"&gt;#Fedora/RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful when you're unsure of the exact package name.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;6. View Package Information&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt show nginx    &lt;span class="c"&gt;#Ubuntu/Debian&lt;/span&gt;
dnf info nginx    &lt;span class="c"&gt;#Fedora/RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Shows details such as:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Version&lt;br&gt;
Description&lt;br&gt;
Dependencies&lt;br&gt;
Package size&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;7. List Installed Packages&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt list &lt;span class="nt"&gt;--installed&lt;/span&gt;   &lt;span class="c"&gt;#Ubuntu/Debian&lt;/span&gt;
dnf list installed     &lt;span class="c"&gt;#Fedora/RHEL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for verifying whether software is already installed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Low-Level Tool: rpm
&lt;/h3&gt;

&lt;p&gt;The rpm command works directly with RPM package files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rpm &lt;span class="nt"&gt;-q&lt;/span&gt; nginx          &lt;span class="c"&gt;# Check if installed&lt;/span&gt;
rpm &lt;span class="nt"&gt;-qi&lt;/span&gt; nginx         &lt;span class="c"&gt;# Detailed info&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usually you don't need to use rpm directly. On RPM-based systems, dnf handles package installation and dependencies for you.&lt;/p&gt;




&lt;h3&gt;
  
  
  Common Beginner Mistakes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Running &lt;code&gt;apt upgrade&lt;/code&gt; without &lt;code&gt;apt update&lt;/code&gt; first&lt;/li&gt;
&lt;li&gt;Confusing apt update with apt upgrade&lt;/li&gt;
&lt;li&gt;Installing software from random websites instead of official repositories&lt;/li&gt;
&lt;li&gt;Forgetting to use &lt;code&gt;sudo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Removing important system packages&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Simple Mental Model
&lt;/h3&gt;

&lt;p&gt;Think of a package manager like an &lt;strong&gt;App Store&lt;/strong&gt; for Linux:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Package = App&lt;/li&gt;
&lt;li&gt;Repository = App Store&lt;/li&gt;
&lt;li&gt;Package Manager = Installer + Updater&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In this guide you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What packages and package managers are&lt;/li&gt;
&lt;li&gt;Basic package management commands using apt and dnf&lt;/li&gt;
&lt;li&gt;Basic package management commands&lt;/li&gt;
&lt;li&gt;Common mistakes to avoid&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Package management is a daily task for:&lt;/p&gt;

&lt;p&gt;Linux administrators&lt;br&gt;
DevOps engineers&lt;br&gt;
Cloud engineers&lt;br&gt;
Developers&lt;/p&gt;

&lt;p&gt;If you know how to manage packages, setting up and maintaining Linux systems becomes much easier.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Next Post:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Finding Files &amp;amp; Text in Linux Explained Simply (find, grep, which &amp;amp; whereis)&lt;/p&gt;




</description>
      <category>devops</category>
      <category>linux</category>
      <category>beginners</category>
      <category>sysadmin</category>
    </item>
    <item>
      <title>Linux Logs Explained Simply</title>
      <dc:creator>Sreekanth Kuruba</dc:creator>
      <pubDate>Tue, 30 Jun 2026 03:22:27 +0000</pubDate>
      <link>https://dev.to/sreekanth_kuruba_91721e5d/linux-logs-explained-simply-3pjn</link>
      <guid>https://dev.to/sreekanth_kuruba_91721e5d/linux-logs-explained-simply-3pjn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;post: 7&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When something breaks in Linux, experienced engineers don’t guess.&lt;/p&gt;

&lt;p&gt;They check the logs.&lt;/p&gt;

&lt;p&gt;👉 Logs are the “black box recorder” of a Linux system.&lt;/p&gt;

&lt;p&gt;They tell you:&lt;/p&gt;

&lt;p&gt;what happened&lt;br&gt;
when it happened&lt;br&gt;
why it failed&lt;/p&gt;

&lt;p&gt;If you can read logs properly, you can debug almost anything.&lt;/p&gt;


&lt;h3&gt;
  
  
  What Are Logs?
&lt;/h3&gt;

&lt;p&gt;Logs are records of system and application activity.&lt;/p&gt;

&lt;p&gt;Linux constantly records:&lt;/p&gt;

&lt;p&gt;System events&lt;br&gt;
Errors&lt;br&gt;
User activity&lt;br&gt;
Application behavior&lt;/p&gt;

&lt;p&gt;Linux constantly records:&lt;/p&gt;


&lt;h3&gt;
  
  
  Where are Logs Stored?
&lt;/h3&gt;

&lt;p&gt;Most Linux logs are stored inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check logs directory:&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="nb"&gt;cd&lt;/span&gt; /var/log
&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the first place DevOps engineers check during system issues.&lt;/p&gt;




&lt;h3&gt;
  
  
  Important Log Files
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Log File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Command to View&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/var/log/syslog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;General system messages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail /var/log/syslog&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/var/log/auth.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Login attempts &amp;amp; authentication&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail /var/log/auth.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/var/log/kern.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Kernel &amp;amp; hardware messages&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;dmesg&lt;/code&gt; or &lt;code&gt;tail /var/log/kern.log&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/var/log/nginx/error.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Web server errors (Nginx)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail /var/log/nginx/error.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/var/log/dmesg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boot and hardware logs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dmesg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;/var/log/apache2/ -&amp;gt; Apache logs&lt;/p&gt;

&lt;p&gt;These logs help you identify system, security, and application-level issues.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;View Logs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using&lt;/strong&gt; &lt;code&gt;cat&lt;/code&gt;&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="nb"&gt;cat&lt;/span&gt; /var/log/syslog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good for small files.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Using&lt;/strong&gt; &lt;code&gt;less&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;less /var/log/syslog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful keys::&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Space&lt;/code&gt; → Next page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; → Previous page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;q&lt;/code&gt;→ Quit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Best for large log files.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Using&lt;/strong&gt; &lt;code&gt;tail&lt;/code&gt;&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="nb"&gt;tail&lt;/span&gt; /var/log/syslog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Show last 10 lines.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Real-Time Monitoring (tail -f)&lt;/strong&gt;&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="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/syslog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 -f = follow live updates&lt;/p&gt;

&lt;p&gt;This is one of the most-used debugging commands in production servers.&lt;/p&gt;

&lt;p&gt;Stop with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ctrl + C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Searching Logs with grep&lt;/strong&gt;&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="nb"&gt;grep &lt;/span&gt;error /var/log/syslog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Case-insensitive:&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="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; failed /var/log/auth.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Show latest matching errors:&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="nb"&gt;grep &lt;/span&gt;error /var/log/syslog | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Essential for filtering huge logs quickly.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Boot &amp;amp; Hardware Logs (dmesg)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;dmesg&lt;/p&gt;

&lt;p&gt;Shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boot messages&lt;/li&gt;
&lt;li&gt;Hardware detection&lt;/li&gt;
&lt;li&gt;Kernel events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful for startup and hardware troubleshooting.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Modern Log System:&lt;/strong&gt; &lt;code&gt;journalctl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Modern Linux systems use &lt;strong&gt;systemd logs&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recent errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-xe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specific service logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Live monitoring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last 1 hour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 hour ago"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 journalctl is the modern replacement for many traditional log files.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What is Log Rotation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Logs grow continuously.&lt;/p&gt;

&lt;p&gt;Without cleanup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;disks fill up&lt;/li&gt;
&lt;li&gt;systems slow down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linux automatically rotates logs using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logrotate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Old logs are compressed or removed automatically.&lt;/p&gt;




&lt;h3&gt;
  
  
  Real-Life Troubleshooting Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Website is not working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status nginx
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/error.log
journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; nginx &lt;span class="nt"&gt;-xe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 In real systems, logs usually reveal the exact root cause.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚠️ Common Beginner Mistakes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;guessing instead of checking logs&lt;/li&gt;
&lt;li&gt;using cat on huge files&lt;/li&gt;
&lt;li&gt;deleting logs blindly&lt;/li&gt;
&lt;li&gt;ignoring tail -f&lt;/li&gt;
&lt;li&gt;assuming service is healthy because it says “active”&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Simple Mental Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of logs like CCTV recordings:&lt;/p&gt;

&lt;p&gt;system logs → building activity&lt;br&gt;
auth logs → door access records&lt;br&gt;
kernel logs → hardware monitoring&lt;br&gt;
app logs → employee activity&lt;/p&gt;

&lt;p&gt;👉 Debugging Linux = investigating evidence&lt;/p&gt;




&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;what logs are&lt;br&gt;
where logs are stored (&lt;code&gt;/var/log&lt;/code&gt;)&lt;br&gt;
important log files&lt;br&gt;
&lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;less&lt;/code&gt;, &lt;code&gt;tail&lt;/code&gt;&lt;br&gt;
live monitoring with &lt;code&gt;tail -f&lt;/code&gt;&lt;br&gt;
searching logs with &lt;code&gt;grep&lt;/code&gt;&lt;br&gt;
boot logs using &lt;code&gt;dmesg&lt;/code&gt;&lt;br&gt;
modern logging with &lt;code&gt;journalctl&lt;/code&gt;&lt;br&gt;
log rotation basics&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why Logs Matter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Logs are the foundation of:&lt;/p&gt;

&lt;p&gt;Linux troubleshooting&lt;br&gt;
DevOps debugging&lt;br&gt;
production incident response&lt;br&gt;
server monitoring&lt;br&gt;
security analysis&lt;/p&gt;

&lt;p&gt;👉 The better you read logs, the faster you solve problems.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;End of Linux Beginner Series&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You now learned:&lt;/p&gt;

&lt;p&gt;Linux basics&lt;br&gt;
filesystem structure&lt;br&gt;
permissions&lt;br&gt;
users &amp;amp; groups&lt;br&gt;
processes&lt;br&gt;
disk usage&lt;br&gt;
networking&lt;br&gt;
logs &amp;amp; troubleshooting&lt;/p&gt;

&lt;p&gt;That’s already more Linux knowledge than most beginners have.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Next Step:&lt;/strong&gt;&lt;br&gt;
Linux Troubleshooting Flow for Beginners&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Question&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Which topic in this Linux series helped you the most?&lt;/p&gt;

&lt;p&gt;And what Linux topic should the next series cover?&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>beginners</category>
      <category>sysadmin</category>
    </item>
  </channel>
</rss>
