<?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>Forem: Ankit Kumar</title>
    <description>The latest articles on Forem by Ankit Kumar (@ankit_kumar_5e2e417bf7e3d).</description>
    <link>https://forem.com/ankit_kumar_5e2e417bf7e3d</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%2F2786478%2Fb540d906-7499-4cbe-ba7b-feb0405ae1bb.jpg</url>
      <title>Forem: Ankit Kumar</title>
      <link>https://forem.com/ankit_kumar_5e2e417bf7e3d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ankit_kumar_5e2e417bf7e3d"/>
    <language>en</language>
    <item>
      <title>Deploying Scalable Applications with Docker Swarm and Docker Compose</title>
      <dc:creator>Ankit Kumar</dc:creator>
      <pubDate>Mon, 08 Sep 2025 07:45:24 +0000</pubDate>
      <link>https://forem.com/ankit_kumar_5e2e417bf7e3d/deploying-scalable-applications-with-docker-swarm-and-docker-compose-3pim</link>
      <guid>https://forem.com/ankit_kumar_5e2e417bf7e3d/deploying-scalable-applications-with-docker-swarm-and-docker-compose-3pim</guid>
      <description>&lt;h2&gt;
  
  
  Part 1: Building the cluster (The Foundation)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Go to the Play-With-Docker and Create Instances&lt;/strong&gt;&lt;br&gt;
You will create 5 instances. These will be your 5 servers. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Initialize the Swarm (Nominate the First Leader)&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 swarm init --advertise-addr [ManagerNodeIP]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You pick one of your 5 instances to be the first Manager Node. This command "starts" the swarm and declares this node as the leader. The --advertise-addr tells other nodes which IP address they should use to find and connect to this manager.&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%2Fmu4y9afepn7ei5v7nwsz.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%2Fmu4y9afepn7ei5v7nwsz.png" alt=" " width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Add Worker Nodes (Recruit the Workers)&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 swarm join --token SWMTKN-1-17xx0ratormliuuff545oiotqjjgdrlfvbmji5xny007bhdqdx-98ny7h91d36bcy4dgfd8zujm9 192.168.0.29:2377
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You copy the join command from the manager and paste it into 3 of your other instances. The long token is like a secret password that proves they are allowed to join your swarm. These nodes become Worker Nodes. Their only job is to run containers as instructed by the manager.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Add a Second Manager (Get a Backup Leader)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commands:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.On the first manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker swarm join-token manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.On the last remaining instance: Paste command which appears after join-token manager command into the remained instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker swarm join --token SWMTKN-1-17xx0ratormliuuff545oiotqjjgdrlfvbmji5xny007bhdqdx-1hahfhs9mrrgsb0nsyzk8vpyp 192.168.0.29:2377
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F4uo3sc6nwmcz5enxucep.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%2F4uo3sc6nwmcz5enxucep.png" alt=" " width="800" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Verify the Cluster&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 node ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Part 2: Defining and Deploying Your Application
&lt;/h2&gt;

&lt;p&gt;This is the docker-compose.yml file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.8"

services:
  mydatabase:
    image: mysql:5.7
    restart: always
    volumes: 
      - mydata:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    networks:
      - mynet
  mywordpress:
    image: wordpress:latest
    deploy:
      replicas: 3
      update_config:
        parallelism: 2
        delay: 5s
        order: stop-first
    depends_on: 
      - mydatabase
    restart: always
    ports:
      - "80:80"
      - "443:443"
    environment: 
      WORDPRESS_DB_HOST: mydatabase:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    networks:
      - mynet

volumes:
  mydata:

networks:
  mynet:
    driver: overlay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7. Deploy the Stack&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 stack deploy --compose-file docker-compose.yml firststack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;docker stack&lt;/code&gt;: The command for managing multi-service applications in Swarm.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;deploy&lt;/code&gt;: The action to create or update the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;firststack&lt;/code&gt;: The name you are giving your application stack.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The manager will now read your file and start creating containers on the worker nodes according to your specifications (1 MySQL container and 3 WordPress containers).&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%2Fbcd630umepxwi9x7ggg6.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%2Fbcd630umepxwi9x7ggg6.png" alt=" " width="800" height="104"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3: Verifying and Testing the Application
&lt;/h2&gt;

&lt;p&gt;** 8. Inspect the Stack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker stack ls
docker stack services firststack
docker stack ps firststack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker stack ls&lt;/code&gt;: Lists all the stacks running on your swarm.&lt;/li&gt;
&lt;/ul&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%2Fqfs5bb57jc89vix2m0et.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%2Fqfs5bb57jc89vix2m0et.png" alt=" " width="400" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker stack services firststack&lt;/code&gt;: Shows the services in your stack (&lt;code&gt;firststack_mydatabase&lt;/code&gt; and &lt;code&gt;firststack_mywordpress&lt;/code&gt;) and how many replicas are running.&lt;/li&gt;
&lt;/ul&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%2F7647lvfrt4u981m4w42j.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%2F7647lvfrt4u981m4w42j.png" alt=" " width="800" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker stack ps firststack&lt;/code&gt;: This is the most detailed view. It shows every individual container (called a "task" in Swarm), which node it's running on, and its current state.&lt;/li&gt;
&lt;/ul&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%2Fr7fm5y42opmic00jgsxw.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%2Fr7fm5y42opmic00jgsxw.png" alt=" " width="800" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Test the Self-Healing Feature&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Action:&lt;/strong&gt; You'll go to one of the worker nodes and manually stop a WordPress container using &lt;code&gt;docker container stop [containerID]&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What's Happening Here?&lt;/strong&gt; You are simulating a crash. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Result:&lt;/strong&gt; The Swarm manager is constantly monitoring the cluster. It will see that one of the &lt;code&gt;mywordpress&lt;/code&gt; replicas is gone (the desired state is 3, but the current state is 2). It will immediately command a worker node to start a new WordPress container to bring the count back up to 3.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verification:&lt;/strong&gt; If you run docker stack ps firststack on the manager again, you will see the stopped container and a new one that was recently started to replace it. This proves the "self-healing" power of Swarm.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker stack ps firststack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fu4m2frb85rrub9qm3l6u.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%2Fu4m2frb85rrub9qm3l6u.png" alt=" " width="800" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>linux</category>
    </item>
    <item>
      <title>From a Single Container to a Secure Application Stack: A Practical Guide to Docker and Server Hardening</title>
      <dc:creator>Ankit Kumar</dc:creator>
      <pubDate>Sun, 07 Sep 2025 12:25:13 +0000</pubDate>
      <link>https://forem.com/ankit_kumar_5e2e417bf7e3d/from-a-single-container-to-a-secure-application-stack-a-practical-guide-to-docker-and-server-1opg</link>
      <guid>https://forem.com/ankit_kumar_5e2e417bf7e3d/from-a-single-container-to-a-secure-application-stack-a-practical-guide-to-docker-and-server-1opg</guid>
      <description>&lt;p&gt;Hello, fellow tech enthusiasts and DevOps practitioners!&lt;/p&gt;

&lt;p&gt;The world of DevOps is vast, but its foundation is built on a few core principles: containerization, orchestration, and security. Today, I want to walk you through a practical journey I took to solidify my understanding of these pillars. We'll start with a single container and the challenge of data persistence, then scale up to a multi-service application, and finally, zoom out to secure the very server our containers run on.&lt;/p&gt;

&lt;p&gt;This isn't just a list of commands; it's a step-by-step guide with explanations of &lt;strong&gt;why&lt;/strong&gt; we do what we do. Let's dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  LAB 1: Solving the Problem — Why Docker Volumes are Essential
&lt;/h2&gt;

&lt;p&gt;By their nature, Docker containers are &lt;strong&gt;ephemeral&lt;/strong&gt;. Think of them as temporary workspaces. If you remove a container, all the files and data created inside it vanish forever. This is fine for stateless applications, but what about a database or a web server that hosts user content? We need that data to stick around.&lt;/p&gt;

&lt;p&gt;This is the problem that &lt;strong&gt;Docker Volumes&lt;/strong&gt; solve. A volume is like an external hard drive that you plug into your container. It's managed by Docker but exists &lt;em&gt;outside&lt;/em&gt; of any single container's lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Hands-On Scenario: Proving Data Persistence
&lt;/h3&gt;

&lt;p&gt;My goal was to see this in action: could I make data survive even after its original container was deleted?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Creating the "Digital Safe" (Our Volume)&lt;/strong&gt;&lt;br&gt;
First, I told Docker to create a managed, persistent storage space called &lt;code&gt;test&lt;/code&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 volume create test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see all your volumes with docker volume ls. At this point, test is just an empty but safe place for data.&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%2F0mqj3cmuf5kkckofked6.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%2F0mqj3cmuf5kkckofked6.png" alt=" " width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Launching a Web Server and connecting the Volume&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, I launched as Nginx web server. The key part of this command is the -v flag, which connects our &lt;strong&gt;test&lt;/strong&gt; volume to the &lt;strong&gt;/usr/share/nginx/html&lt;/strong&gt; directory inside the container. This is the directory where Nginx looks for its website files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; sudo docker container run --name mywebserver -d -p 80:80 -v test:/usr/share/nginx/html nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happened here is subtle but important:&lt;/strong&gt; since our &lt;code&gt;test&lt;/code&gt; volume was empty, the Nginx container automatically copied it's own default &lt;code&gt;index.html&lt;/code&gt; file into the volume. The volume is now the source of truth for the website's contnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Changing the Data from Inside&lt;/strong&gt;&lt;br&gt;
To prove we were now working with the volume, I entered the running container and changed the &lt;code&gt;index.html&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# for go inside the 'mywebserver' container
docker exec -it mywebserver sh

# Once inside, overwrite the content of the main web page
echo '&amp;lt;h1&amp;gt;Data Persists Beyond the Container!&amp;lt;/h1&amp;gt;' &amp;gt; /usr/share/nginx/html/index.html

# Exit the container shell
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I refreshed my browser at &lt;code&gt;http://localhost:80&lt;/code&gt;, I saw my new message. This confirmed I had successfully modified the data inside the persistent volume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: The Ultimate Test — Destroying the Container&lt;/strong&gt;&lt;br&gt;
Now for the moment of truth. I completely stopped and removed the mywebserver container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker rm -f mywebserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container is gone. A traditional workspace would have been wiped clean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Step 5: Resurrecting the Data with a New Container&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
I launched a brand new, completely separate Nginx container called mywebserver3. However, I connected it to the exact same test volume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker run --name mywebserver3 -d -p 80:80 -v test:/usr/share/nginx/html nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I visited &lt;code&gt;http://localhost:80&lt;/code&gt; again... Success!  The message "Data Persists Beyond the Container!" was there. We proved that the volume keeps our data safe, completely independent of the container's lifecycle. This concept is critical for running databases, CMSs, or any stateful application in Docker.&lt;/p&gt;




&lt;h2&gt;
  
  
  LAB 2: Building a Real Application with Docker Compose
&lt;/h2&gt;

&lt;p&gt;Running one container is useful, but modern applications are rarely that simple. They are usually composed of multiple services working together—a web server, a database, a caching service, etc. Managing the lifecycle and networking of all these containers with individual &lt;code&gt;docker&lt;/code&gt; commands would be a nightmare.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Docker Compose&lt;/strong&gt;. It's a tool for defining and running multi-container applications using a single, simple configuration file: &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Hands-On Scenario: Deploying a WordPress Site&lt;/strong&gt;&lt;br&gt;
I set up a classic web application stack: a WordPress frontend that depends on a MySQL database backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Blueprint&lt;/strong&gt;: &lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;br&gt;
This file is the single source of truth for my entire application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.8"

services:
  # The first service: our MySQL Database
  mydatabase:
    image: mysql:5.7
    restart: always
    volumes: 
      - mydata:/var/lib/mysql # Attach a volume to the DB's data directory!
    environment: 
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    networks:
      - mynet

  # The second service: our WordPress frontend
  mywordpress:
    image: wordpress:latest
    depends_on: 
      - mydatabase # Instruction: Don't start WordPress until the database is ready!
    restart: always
    ports:
      - "80:80" # Expose the web server on port 80 of my computer
    environment: 
      WORDPRESS_DB_HOST: mydatabase:3306 # The magic of Docker networking!
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    networks:
      - mynet

# Global definitions for resources used by the services
volumes:
  mydata: {} # Formally create the volume for our database

networks:
  mynet: # Formally create a private network for our containers
    driver: bridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this file in place, launching the entire stack was as simple as running docker-compose up -d.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Key Learnings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Declarative Infrastructure:&lt;/strong&gt; I didn't have to tell Docker how to do things. I just declared the desired state in the YAML file, and Compose figured it out.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service Discovery:&lt;/strong&gt; The most powerful feature here is networking. The WordPress container found the database using its service name, &lt;code&gt;mydatabase&lt;/code&gt;, as its hostname (&lt;code&gt;WORDPRESS_DB_HOST: mydatabase:3306&lt;/code&gt;). Docker Compose created a private virtual network (&lt;code&gt;mynet&lt;/code&gt;) where containers can find each other by name. No more hard-coding IP addresses!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependency Management:&lt;/strong&gt; The &lt;code&gt;depends_on&lt;/code&gt; key is a lifesaver. It ensures the &lt;code&gt;mydatabase&lt;/code&gt; container is started and healthy before the &lt;code&gt;mywordpress&lt;/code&gt; container even begins to start, preventing connection errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  LAB 3: Securing the Foundation — A Core SysAdmin Skill
&lt;/h2&gt;

&lt;p&gt;Containers are great, but they still run on a host operating system—usually Linux. Securing this host is just as important as securing the application. One of the most fundamental security-hardening steps is &lt;strong&gt;disabling direct root login via SSH.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why? Because it enforces accountability. It forces every administrator to log in with their own personal user account first, and then use &lt;code&gt;sudo&lt;/code&gt; to perform administrative tasks. This creates a clear audit trail (&lt;code&gt;user 'bob' ran command 'xyz'&lt;/code&gt;) instead of a mysterious log of actions performed by the all-powerful root.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Hands-On Scenario: KodeKloud Security Challenge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The task was to apply this security measure on three different app servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Universal 5-Step Process:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;SSH as a Standard User:&lt;/strong&gt; First, I connected to the server using a non-root account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh tony@stapp01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.&lt;strong&gt;Elevate Privileges Correctly:&lt;/strong&gt; I became the root user using the &lt;code&gt;sudo&lt;/code&gt; command, which required my personal password and logged the action.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;3.&lt;strong&gt;Edit the SSH Configuration File:&lt;/strong&gt; Using a text editor like &lt;code&gt;vi&lt;/code&gt;, I opened the SSH daemon's configuration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vi /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.&lt;strong&gt;Change the Security Directive:&lt;/strong&gt; Inside the file, I found the line &lt;code&gt;PermitRootLogin&lt;/code&gt; and changed its value to &lt;code&gt;no&lt;/code&gt;. (It's often commented out with a #, which must be removed).&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;5.&lt;strong&gt;Apply the Changes:&lt;/strong&gt; A configuration change is meaningless until the service is restarted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl restart sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I repeated this simple but critical process on all required servers, ensuring a consistent and secure baseline across the infrastructure.&lt;/p&gt;

&lt;p&gt;Thanks for following along! I hope this detailed walkthrough was helpful.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>security</category>
      <category>linux</category>
    </item>
    <item>
      <title>Ultimate Guide to Containerizing Node.js + MongoDB</title>
      <dc:creator>Ankit Kumar</dc:creator>
      <pubDate>Wed, 13 Aug 2025 17:34:15 +0000</pubDate>
      <link>https://forem.com/ankit_kumar_5e2e417bf7e3d/ultimate-guide-to-containerizing-nodejs-mongodb-3ip6</link>
      <guid>https://forem.com/ankit_kumar_5e2e417bf7e3d/ultimate-guide-to-containerizing-nodejs-mongodb-3ip6</guid>
      <description>&lt;p&gt;Ankit | Jr DevOps Engineer | &lt;code&gt;akv280501@gmail.com&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📁 File Breakdown &amp;amp; Architecture
&lt;/h2&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%2Fu18q5mtxlvd0o0go9eh1.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%2Fu18q5mtxlvd0o0go9eh1.png" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. docker-compose.yml
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; Defines multi-container architecture&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'

services:
  app:
    build: .
    container_name: node_app
    ports:
      - "3000:3000"
    environment:
      - DB_URI=mongodb://mongo:27017/testdb
    depends_on:
      - mongo


  mongo:
    image: mongo:latest
    container_name: mongo_db
    ports:
      - "27017:27017"
    volumes:
      - mongodata:/data/db

volumes:
   mongodata:

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Key Concepts:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service Discovery:&lt;/strong&gt; Containers communicate via service names (mongo)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Port Mapping:&lt;/strong&gt; 3000:3000 exposes Node.js to host machine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Declarative Setup:&lt;/strong&gt; Infrastructure-as-Code&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Dockerfile
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Layer-by-Layer Optimization:&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;FROM node:18-alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Best Practices:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layer Caching:&lt;/strong&gt; Separate &lt;code&gt;COPY package.json&lt;/code&gt; + &lt;code&gt;RUN npm install&lt;/code&gt; speeds up rebuilds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimal Images:&lt;/strong&gt; Alpine reduces attack surface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Explicit Ports:&lt;/strong&gt; Documentation for other developers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. package.json
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dependency Management:&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;{
  "name": "node-mongo-app",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.4.3"
  }
}

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why It Matters:
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;npm start&lt;/code&gt; becomes the container's PID 1 process&lt;/p&gt;

&lt;p&gt;Version pinning (&lt;code&gt;^4.18.2&lt;/code&gt;) prevents breaking changes&lt;/p&gt;

&lt;h3&gt;
  
  
  4. server.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const mongoose = require('mongoose');

const app = express();
const PORT = 3000;

// Connect to MongoDB -&amp;gt; 'mongodb://mongo:27017/testdb'
// 'mongo' is the service name we will use in docker-compose
const dbUri = process.env.DB_URI || 'mongodb://localhost:27017/testdb';
mongoose.connect(dbUri)
    .then(() =&amp;gt; console.log('MongoDB connected successfully!'))
    .catch(err =&amp;gt; console.error('MongoDB connection error:', err));

app.get('/', (req, res) =&amp;gt; {
    res.send('Hello from your Node.js app! Connected to MongoDB.');
});

app.listen(PORT, () =&amp;gt; {
    console.log(`Server is running on http://localhost:${PORT}`);
});

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  🚀 My DevOps Learning Path
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;20 Projects Challenge:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;✅ Node+MongoDB Containers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flask+Redis+PostgreSQL (Coming Soon)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  💬 Let's Build Together!
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;I need your input on:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*Which project should I tackle next?&lt;/p&gt;

&lt;p&gt;*How would you improve this setup?&lt;/p&gt;

&lt;p&gt;*DevOps interview tips for 2-3 yr experience roles&lt;/p&gt;

&lt;h3&gt;
  
  
  Hire Me:
&lt;/h3&gt;

&lt;p&gt;📞 +91-8384860549 | 📧 &lt;a href="//akv280501@gmail.com"&gt;akv280501@gmail.com&lt;/a&gt;&lt;br&gt;
Open to relocation | Immediate joiner&lt;/p&gt;

&lt;h1&gt;
  
  
  DevOps #Docker #Mentorship #Hiring
&lt;/h1&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>resources</category>
      <category>learning</category>
    </item>
    <item>
      <title>Understanding Docker: Containers, Volumes, and Dockerfile by Example</title>
      <dc:creator>Ankit Kumar</dc:creator>
      <pubDate>Thu, 17 Jul 2025 19:58:15 +0000</pubDate>
      <link>https://forem.com/ankit_kumar_5e2e417bf7e3d/understanding-docker-containers-volumes-and-dockerfile-by-example-2el0</link>
      <guid>https://forem.com/ankit_kumar_5e2e417bf7e3d/understanding-docker-containers-volumes-and-dockerfile-by-example-2el0</guid>
      <description>&lt;p&gt;In this blog, we'll walk through some core Docker concepts — including containers, volume mounts, persistent data, and building custom Docker images using Dockerfile. If you're getting into DevOps or containerization, this is the hands-on practical you're looking for!&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatically Clean Up a Docker Container
&lt;/h2&gt;

&lt;p&gt;If you're running short-lived containers (like Alpine Linux), and want to clean them up automatically once they exit, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -it --rm alpine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;--rm&lt;/strong&gt; flag removes the container once it exits, saving disk space and cleanup time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mounting the Host File System in a Container
&lt;/h2&gt;

&lt;p&gt;Containers are isolated, so if you create a file in Container1, it’s not available in Container2. But what if you want to share files between the host and your container?&lt;/p&gt;

&lt;p&gt;That’s where bind mounts come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Share Files?
&lt;/h2&gt;

&lt;p&gt;Instead of rebuilding container images every time, you can mount host files/folders into the container using Docker volumes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax: Bind Mount using -v
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -v &amp;lt;host_path&amp;gt;:&amp;lt;container_path&amp;gt; image_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example: Mount a Host HTML Directory to Nginx
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -v ~/html:/var/www/html nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example: Multiple Volumes
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -v ~/pgdata:/opt/data -v pg.conf:/etc/pg.conf postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be sure to use absolute paths. Docker doesn't understand shortcuts like ~.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task: Passing a File to a Container
&lt;/h2&gt;

&lt;p&gt;Your app crane reads a file named customerdata.json during runtime. Previously, you had to bake that file into every container image. Now, you can pass it at runtime using volume mounts!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-step:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modify the file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim ~/workspace/customerdata.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the Company Name to: The File Store&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the container:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -v ~/workspace/customerdata.json:/customerdata.json crane
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What happens under the hood?
&lt;/h3&gt;

&lt;p&gt;When you mount a file to /customerdata.json, it overrides the internal default file in the image.&lt;/p&gt;

&lt;p&gt;The container still works if you don’t pass the file — it just falls back to the default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistent Volumes
&lt;/h2&gt;

&lt;p&gt;Bind mounts are one-time mounts, but Docker also supports persistent named volumes using docker volume or Docker Compose. These help preserve data across container restarts or recreations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Custom Jenkins Image with Dockerfile
&lt;/h2&gt;

&lt;p&gt;Let’s build a custom Docker image for Jenkins using a Dockerfile.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dockerfile (Example):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:11-jdk

LABEL maintainer="Ankit"
LABEL env=production

ENV apparea=/home/ankit/Practice

RUN mkdir -p $apparea

ADD https://get.jenkins.io/war/2.397/jenkins.war $apparea

WORKDIR $apparea

EXPOSE 8080

CMD ["java", "-jar", "jenkins.war"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Build the Docker Image:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker build -t jenkins-custom .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run the Jenkins Container:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker run -d -p 8080:8080 jenkins-custom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check Running Containers:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker ps -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ft1pawezveuqx7p9widsm.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%2Ft1pawezveuqx7p9widsm.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker vs Dockerfile
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Dockerfile&lt;/th&gt;
&lt;th&gt;Docker Compose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Focus&lt;/td&gt;
&lt;td&gt;Build a single image&lt;/td&gt;
&lt;td&gt;Run multiple containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File Name&lt;/td&gt;
&lt;td&gt;Dockerfile (no extension)&lt;/td&gt;
&lt;td&gt;docker-compose.yml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commands&lt;/td&gt;
&lt;td&gt;FROM, RUN, CMD, COPY, etc.&lt;/td&gt;
&lt;td&gt;services, volumes,etc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use Case&lt;/td&gt;
&lt;td&gt;Single-container builds&lt;/td&gt;
&lt;td&gt;Multi-container applications&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What is docker build?
&lt;/h2&gt;

&lt;p&gt;The docker build command creates Docker images from a Dockerfile.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t &amp;lt;image-name&amp;gt; .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-t lets you tag the image.&lt;/p&gt;

&lt;p&gt;. is the build context (typically the current directory).&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Dockerfile Instructions
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Instruction&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;FROM&lt;/td&gt;
&lt;td&gt;Base image (e.g., Ubuntu, Alpine)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RUN&lt;/td&gt;
&lt;td&gt;Execute commands (e.g., install tools)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COPY&lt;/td&gt;
&lt;td&gt;Copy files from host to image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ADD&lt;/td&gt;
&lt;td&gt;Like COPY but supports remote URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CMD&lt;/td&gt;
&lt;td&gt;Default command for container&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ENTRYPOINT&lt;/td&gt;
&lt;td&gt;Similar to CMD but allows arguments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EXPOSE&lt;/td&gt;
&lt;td&gt;Document container ports&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;With just a few Docker commands and a solid Dockerfile, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mount files from your host system&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid rebuilding images repeatedly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build production-ready images like Jenkins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplify container deployment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have questions or want a full docker-compose.yml example in the next post? Drop a comment or follow me!&lt;/p&gt;




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

&lt;p&gt;🔗 &lt;strong&gt;Follow my work:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/AnkitV1001" rel="noopener noreferrer"&gt;GitHub – @AnkitV1001&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/technoankit/" rel="noopener noreferrer"&gt;LinkedIn – Ankit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Docker #DevOps #Containers #Jenkins #Dockerfile #Volumes #BindMount #OpenSource  #Learning #DevOps #Docker #CI_CD #Kubernetes #HandsOnDevOps #DockerLearning #OpenToWork #BuildInPublic #TechLearning
&lt;/h1&gt;

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