<?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: Victor N</title>
    <description>The latest articles on DEV Community by Victor N (@njengac).</description>
    <link>https://dev.to/njengac</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2987277%2Fc4c3fb22-1261-4081-9b58-2454c4ad3600.png</url>
      <title>DEV Community: Victor N</title>
      <link>https://dev.to/njengac</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/njengac"/>
    <language>en</language>
    <item>
      <title>Building an Isolated Application Environment on a Linux Server</title>
      <dc:creator>Victor N</dc:creator>
      <pubDate>Fri, 28 Mar 2025 22:56:14 +0000</pubDate>
      <link>https://dev.to/njengac/build-your-own-container-understanding-docker-through-diy-implementation-mmn</link>
      <guid>https://dev.to/njengac/build-your-own-container-understanding-docker-through-diy-implementation-mmn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: Understanding Containerization
&lt;/h2&gt;

&lt;p&gt;Hello Community, its wonderful moment being here and blogging for the first time, I choose to do my first with this DevOps task in HNG12-Stage 8, &lt;strong&gt;Building an Isolated Application Environment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This hands-on project transformed my understanding of containerization technologies and revealed the "magic" behind tools like Docker that we often take for granted.&lt;/p&gt;

&lt;p&gt;Containerization has become the backbone of modern application deployment, but have you ever wondered what's actually happening under the hood? While we can easily run &lt;code&gt;docker run nginx&lt;/code&gt; and see a web server spring to life, the underlying mechanisms are a fascinating combination of Linux kernel features working in concert to create isolated environments.&lt;/p&gt;

&lt;p&gt;Imagine being able to run multiple applications on the same server, each believing it has its own private operating system, file system, and network—all while efficiently sharing the same physical resources. This is the power of containerization, and in this blog post, I'll demystify how it works by building a container system from scratch.&lt;/p&gt;

&lt;p&gt;Join me as we dive deep into the building blocks of containers and transform abstract concepts into working code. This step-by-step guide will illuminate the inner workings of one of modern computing's most transformative technologies. In this blog post, I'll take you through my implementation of a custom container system built from scratch using the foundational Linux technologies that power Docker and other container platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Containerization Matters
&lt;/h2&gt;

&lt;p&gt;Before diving into implementation, let's understand why containerization is so important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Containers ensure applications run the same way across different environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt;: Applications run in their own spaces without interfering with each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Efficiency&lt;/strong&gt;: Containers share the host OS kernel, making them lighter than VMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Container orchestration allows easy scaling of applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevOps Enablement&lt;/strong&gt;: Containers bridge development and operations by standardizing deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Overview: Building a Container System from Scratch
&lt;/h2&gt;

&lt;p&gt;This project involved creating a container system using Linux's native capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Filesystem Isolation&lt;/strong&gt;: Using &lt;code&gt;chroot&lt;/code&gt; to create a separate root filesystem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process Isolation&lt;/strong&gt;: Using Linux namespaces to separate processes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Limitations&lt;/strong&gt;: Using cgroups to restrict CPU, memory, and other resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Isolation&lt;/strong&gt;: Creating separate network interfaces and routing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Setting Up the Environment
&lt;/h3&gt;

&lt;p&gt;First, I installed the necessary tools:&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="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; util-linux debootstrap iptables iproute2 cgroup-tools net-tools curl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Creating a Container Root Filesystem
&lt;/h3&gt;

&lt;p&gt;I used debootstrap to create a minimal Ubuntu system for the container:&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;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; container/rootfs
&lt;span class="nb"&gt;sudo &lt;/span&gt;debootstrap &lt;span class="nt"&gt;--variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;minbase focal ~/container/rootfs/
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"container"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; ~/container/rootfs/etc/hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then installed some basic utilities inside the container filesystem:&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 chroot &lt;/span&gt;container/rootfs/ apt update
&lt;span class="nb"&gt;sudo chroot &lt;/span&gt;container/rootfs/ apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; python3 net-tools iputils-ping iproute2 curl
&lt;span class="nb"&gt;sudo chroot &lt;/span&gt;container/rootfs/ useradd &lt;span class="nt"&gt;-m&lt;/span&gt; container-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Implementing Resource Limitations with Cgroups
&lt;/h3&gt;

&lt;p&gt;Cgroups allow controlling the resources available to the container:&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 cgroups under each controller&lt;/span&gt;
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /sys/fs/cgroup/cpu/container
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /sys/fs/cgroup/memory/container
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /sys/fs/cgroup/blkio/container
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /sys/fs/cgroup/pids/container

&lt;span class="c"&gt;# Set CPU limit to 20% of one core&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;100000 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/fs/cgroup/cpu/container/cpu.cfs_period_us
&lt;span class="nb"&gt;echo &lt;/span&gt;20000 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us

&lt;span class="c"&gt;# Memory limit: 256MB&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;268435456 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/fs/cgroup/memory/container/memory.limit_in_bytes

&lt;span class="c"&gt;# Block I/O weight&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;500 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/fs/cgroup/blkio/container/blkio.weight

&lt;span class="c"&gt;# Maximum 100 processes&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;100 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/fs/cgroup/pids/container/pids.max
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Setting Up Network Isolation
&lt;/h3&gt;

&lt;p&gt;I created a separate network namespace with virtual interfaces:&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 network namespace&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns add container_ns

&lt;span class="c"&gt;# Create veth pair (virtual network interfaces)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link &lt;/span&gt;add veth0 &lt;span class="nb"&gt;type &lt;/span&gt;veth peer name veth1

&lt;span class="c"&gt;# Move veth1 to container namespace&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;veth1 netns container_ns

&lt;span class="c"&gt;# Configure interfaces&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip addr add 192.168.100.1/24 dev veth0
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;veth0 up

&lt;span class="c"&gt;# Configure container interface&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;container_ns ip &lt;span class="nb"&gt;link set &lt;/span&gt;lo up
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;container_ns ip &lt;span class="nb"&gt;link set &lt;/span&gt;veth1 up
&lt;span class="nb"&gt;sudo &lt;/span&gt;ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;container_ns ip addr add 192.168.100.2/24 dev veth1

&lt;span class="c"&gt;# Set up NAT for internet access&lt;/span&gt;
&lt;span class="nv"&gt;OUTIF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ip route | &lt;span class="nb"&gt;grep &lt;/span&gt;default | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $5}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.100.0/24 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$OUTIF&lt;/span&gt; &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$OUTIF&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; veth0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$OUTIF&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; veth0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Enable IP forwarding&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /proc/sys/net/ipv4/ip_forward
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Creating the Container Init Script
&lt;/h3&gt;

&lt;p&gt;This script runs inside the container to set up the environment:&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;# I created a script to run inside the chroot&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cat &amp;gt; container/rootfs/init.sh &amp;lt;&amp;lt; EOF
#!/bin/bash
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t tmpfs tmpfs /tmp
/bin/bash
EOF'&lt;/span&gt;
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; +x container/rootfs/init.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Creating a Container Entry Script
&lt;/h3&gt;

&lt;p&gt;I created a script to launch the container with all isolation features:&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;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;span class="c"&gt;# Enter the container with proper namespace isolation&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;cgexec &lt;span class="nt"&gt;-g&lt;/span&gt; cpu,memory,blkio,pids:container &lt;span class="se"&gt;\&lt;/span&gt;
  ip netns &lt;span class="nb"&gt;exec &lt;/span&gt;container_ns &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;chroot &lt;/span&gt;container/rootfs /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"mount -t proc proc /proc &amp;amp;&amp;amp; mount -t sysfs sys /sys &amp;amp;&amp;amp; mount -t tmpfs tmpfs /tmp &amp;amp;&amp;amp; echo 'Container shell starting...' &amp;amp;&amp;amp; /bin/bash"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I saved this as enter_container.sh and made it executable:&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 chmod&lt;/span&gt; +x enter_container.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Deploying a Test Application
&lt;/h3&gt;

&lt;p&gt;I created a simple Python web server to test the container:&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;bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'cat &amp;gt; container/rootfs/app.py &amp;lt;&amp;lt; EOF
from http.server import HTTPServer, BaseHTTPRequestHandler

class SimpleHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(b"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello from Custom Container!&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;")

httpd = HTTPServer(("0.0.0.0", 8000), SimpleHandler)
print("Server running at http://0.0.0.0:8000")
httpd.serve_forever()
EOF'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the Technologies Work Together
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Linux Namespaces
&lt;/h3&gt;

&lt;p&gt;Namespaces isolate different aspects of the container:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PID Namespace&lt;/strong&gt;: Containers see their own process IDs, starting from 1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Namespace&lt;/strong&gt;: Container has its own networking stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UTS Namespace&lt;/strong&gt;: Container has its own hostname&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mount Namespace&lt;/strong&gt;: Container has its own mount points&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IPC Namespace&lt;/strong&gt;: Container has its own inter-process communication mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this implementation, I used &lt;code&gt;ip netns&lt;/code&gt; for the network namespace and &lt;code&gt;unshare&lt;/code&gt; (implicitly through chroot) for other namespaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cgroups (Control Groups)
&lt;/h3&gt;

&lt;p&gt;Cgroups limit the resources available to processes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CPU Cgroup&lt;/strong&gt;: Limits CPU usage (20% in our case)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Cgroup&lt;/strong&gt;: Limits memory usage (256MB in our case)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block I/O Cgroup&lt;/strong&gt;: Controls disk read/write priority&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PID Cgroup&lt;/strong&gt;: Limits the number of processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I implemented these by creating cgroup directories and setting limit parameters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chroot
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;chroot&lt;/code&gt; changes the root directory for a process, isolating it from the host's filesystem. Our container sees only its own filesystem, starting at &lt;code&gt;/&lt;/code&gt; which is actually &lt;code&gt;container/rootfs/&lt;/code&gt; on the host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges Faced and Solutions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Challenge 1: Permission Issues with Chroot&lt;/strong&gt;&lt;br&gt;
Initially, I encountered permission issues when trying to use chroot:&lt;br&gt;
&lt;code&gt;chroot: cannot change root directory to 'container/rootfs': Permission denied&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: I ensured proper permissions on the directory and used &lt;code&gt;sudo&lt;/code&gt; where necessary. Additionally, I had to run the command with the right user (root) permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 2: Network Namespace Issues&lt;/strong&gt;&lt;br&gt;
Setting up network namespaces was challenging, especially with this stuborn error:&lt;br&gt;
&lt;code&gt;Cannot find device "veth1"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: I implemented a systematic approach to create and configure the network namespace and virtual interfaces, ensuring each step worked before proceeding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 3: Cgroup Mounting Issues&lt;/strong&gt;&lt;br&gt;
I initially tried to create directories directly under &lt;code&gt;/sys/fs/cgroup&lt;/code&gt; but encountered:&lt;br&gt;
&lt;code&gt;mkdir: cannot create directory '/sys/fs/cgroup/container': Read-only file system&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: I learned that in modern systems, cgroups have a specific hierarchy. I created controller-specific directories under each cgroup subsystem directory.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demonstration of the Working Container
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Test 1: Process Isolation
&lt;/h3&gt;

&lt;p&gt;Inside the container, I ran &lt;code&gt;ps aux&lt;/code&gt; and saw only container processes, not host processes.&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.amazonaws.com%2Fuploads%2Farticles%2Fhvvzjwe7udjy2mg5u6xi.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.amazonaws.com%2Fuploads%2Farticles%2Fhvvzjwe7udjy2mg5u6xi.png" alt="Image description" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Test 2: Network Isolation
&lt;/h3&gt;

&lt;p&gt;The container had its own IP address (192.168.100.2) and network stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;From host
ping 192.168.100.2
PING 192.168.100.2 &lt;span class="o"&gt;(&lt;/span&gt;192.168.100.2&lt;span class="o"&gt;)&lt;/span&gt; 56&lt;span class="o"&gt;(&lt;/span&gt;84&lt;span class="o"&gt;)&lt;/span&gt; bytes of data.
64 bytes from 192.168.100.2: &lt;span class="nv"&gt;icmp_seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64 &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4.13 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test 3: Resource Limitations
&lt;/h3&gt;

&lt;p&gt;I verified cgroup restrictions were working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Inside container
&lt;span class="nb"&gt;cat&lt;/span&gt; /sys/fs/cgroup/cpu/cpu.cfs_quota_us
&lt;span class="c"&gt;# Shows 20000 (20% of CPU)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test 4: Web Server Test
&lt;/h3&gt;

&lt;p&gt;I ran the Python web server inside the container and accessed it from the host:&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.amazonaws.com%2Fuploads%2Farticles%2Fto113h92glge4oetxk3w.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.amazonaws.com%2Fuploads%2Farticles%2Fto113h92glge4oetxk3w.png" alt="Image description" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Building a container system from scratch provided deep insights into how containerization actually works. While Docker abstracts away these complexities, understanding the underlying technologies (namespaces, cgroups, and chroot) is invaluable for troubleshooting, optimization, and advanced containerization scenarios. This project demonstrated that containers are not magic—they're a clever combination of Linux kernel features that together provide application isolation, resource control, and portable deployments.&lt;/p&gt;

&lt;p&gt;I know this was a long read but now atleast the next time you run &lt;code&gt;docker run&lt;/code&gt;, you will remember that under the hood, Docker is utilizing these same Linux primitives to create the containerized environment, Thank you and see you next time.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
