<?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: Ramya Perumal</title>
    <description>The latest articles on DEV Community by Ramya Perumal (@ramya_perumal).</description>
    <link>https://dev.to/ramya_perumal</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%2F3900955%2F3e2feb4c-f889-4df6-b8ef-5b1a1ac619ca.png</url>
      <title>DEV Community: Ramya Perumal</title>
      <link>https://dev.to/ramya_perumal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ramya_perumal"/>
    <language>en</language>
    <item>
      <title>RAG - Memory Systems</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:08:59 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/rag-memory-systems-17aj</link>
      <guid>https://dev.to/ramya_perumal/rag-memory-systems-17aj</guid>
      <description>&lt;p&gt;We need memory to store the previous conversational history. &lt;/p&gt;

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

&lt;p&gt;Previous question is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; File handling in Python&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assistant:&lt;/strong&gt; Explain about file handling.&lt;/p&gt;

&lt;p&gt;Next time, the user asks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; What are the modes in it?&lt;/p&gt;

&lt;p&gt;The LLM should understand the context and then respond.&lt;/p&gt;




&lt;p&gt;Below are the details that can be stored in the memory.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Past Conversations&lt;/li&gt;
&lt;li&gt;User Preferences that we specify in the system prompts, e.g., JSON format&lt;/li&gt;
&lt;li&gt;Past Decisions&lt;/li&gt;
&lt;li&gt;Previous Tasks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Based on the details we are storing, we will choose between long-term or short-term memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short-Term Memory
&lt;/h2&gt;

&lt;p&gt;Redis, Valkey, Memcached, and Cosmos, which are cached databases, can be used for short-term memory to store the last few conversations or a summary.&lt;/p&gt;

&lt;p&gt;We can set a general data invalidation rule to erase the content or use an &lt;strong&gt;LRU cache eviction policy&lt;/strong&gt;, where the least recently used data will be erased from the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Long-Term Memory
&lt;/h2&gt;

&lt;p&gt;Postgres, Pinecone, and MongoDB can be used for long-term memory to store long conversation histories.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Is Functioning
&lt;/h3&gt;

&lt;p&gt;A summary of the entire conversation history will be stored in short-term memory to reduce latency whenever needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Episodic Memory
&lt;/h2&gt;

&lt;p&gt;Episodic memory is a type of memory that stores specific events or experiences that happened in the past, usually together with information about what happened, when it happened, and the context surrounding it.&lt;/p&gt;

&lt;p&gt;We can use either a short-term or long-term memory database depending on the use case. It is a kind of combination of short-term and long-term memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I am planning a trip to Paris.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
How many days will you stay?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
5 days.&lt;/p&gt;

&lt;p&gt;Later,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Can you suggest an itinerary?&lt;/p&gt;

&lt;h3&gt;
  
  
  Episode 1
&lt;/h3&gt;

&lt;p&gt;User wants to travel to Paris.&lt;/p&gt;

&lt;p&gt;Trip duration: 5 days.&lt;/p&gt;

&lt;p&gt;User previously mentioned:&lt;/p&gt;

&lt;p&gt;Destination = Paris&lt;br&gt;&lt;br&gt;
Duration = 5 days&lt;/p&gt;

&lt;p&gt;This information can be used to provide a more relevant response.&lt;/p&gt;

&lt;p&gt;This helps the LLM understand what happened previously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic Memory
&lt;/h2&gt;

&lt;p&gt;Semantic memory contains facts extracted from previous conversational history. Semantic memory is generally considered long-term memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Paris is the capital of France.&lt;/p&gt;

&lt;p&gt;The Louvre is a museum in Paris.&lt;/p&gt;

&lt;p&gt;France uses the Euro.&lt;/p&gt;

&lt;p&gt;That's general knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sliding Window Memory
&lt;/h2&gt;

&lt;p&gt;It is a short-term memory. Here, we store the last 3 to 4 conversations.&lt;/p&gt;

&lt;p&gt;Redis or Valkey, like any cache memory, can be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summarized Memory
&lt;/h2&gt;

&lt;p&gt;Each and every time, the conversation, which includes the user query and response, will be summarized.&lt;/p&gt;

&lt;p&gt;Even though token consumption during summarization is more, overall token consumption will be less.&lt;/p&gt;

&lt;p&gt;It is a long-term memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entity Fact Memory
&lt;/h2&gt;

&lt;p&gt;This memory is used to store facts about a particular entity.&lt;/p&gt;

&lt;p&gt;The difference between entity fact memory and semantic memory is that &lt;strong&gt;semantic memory is the broader category&lt;/strong&gt;. Entity fact memory is one way of organizing and storing semantic knowledge about specific entities.&lt;/p&gt;

&lt;p&gt;It can be used as either long-term or short-term memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Semantic Memory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Entity: Python&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Python → is a programming language&lt;br&gt;&lt;br&gt;
Python → is used for AI&lt;br&gt;&lt;br&gt;
Python → supports object-oriented programming&lt;br&gt;&lt;br&gt;
Python → was created by Guido van Rossum&lt;/p&gt;

&lt;h3&gt;
  
  
  Entity Fact Memory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Entity: Alice&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alice → works at ABC Company&lt;br&gt;&lt;br&gt;
Alice → prefers Python&lt;br&gt;&lt;br&gt;
Alice → is working on Project X&lt;/p&gt;

&lt;p&gt;It is not a good practice to store the entire conversation. We can make decisions based on the conversation and then store the relevant information. This is a good practice.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>nlp</category>
    </item>
    <item>
      <title>RAG - Multivector Retrievel, Multi Hop, Conversational RAG</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Wed, 12 Aug 2026 17:51:51 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/rag-multivector-retrievel-multi-hop-conversational-rag-km7</link>
      <guid>https://dev.to/ramya_perumal/rag-multivector-retrievel-multi-hop-conversational-rag-km7</guid>
      <description>&lt;h2&gt;
  
  
  Multi-Vector Retrieval
&lt;/h2&gt;

&lt;p&gt;In a typical RAG pipeline, every chunk is converted into an embedding and stored in the vector database.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Multi-Vector Retrieval&lt;/strong&gt;, instead of creating a single embedding for a chunk, multiple embeddings are created to represent different aspects of the original chunk.&lt;/p&gt;

&lt;p&gt;Each embedding captures a different perspective of the same content. The metadata of each embedding contains a reference to the original chunk.&lt;/p&gt;

&lt;p&gt;When a user query is received, the retriever searches across all these embeddings. Since each embedding represents a different aspect of the content, the chances of retrieving more relevant information are higher.&lt;/p&gt;

&lt;p&gt;This approach generally provides better retrieval performance.&lt;/p&gt;

&lt;p&gt;However, it is a &lt;strong&gt;costly approach&lt;/strong&gt; because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple embeddings are generated for every chunk.&lt;/li&gt;
&lt;li&gt;More storage is required in the vector database.&lt;/li&gt;
&lt;li&gt;More tokens are consumed during embedding generation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If no other optimization technique is able to improve the RAG performance, &lt;strong&gt;Multi-Vector Retrieval&lt;/strong&gt; can be considered as a final optimization step.&lt;/p&gt;




&lt;h1&gt;
  
  
  Multi-Hop
&lt;/h1&gt;

&lt;p&gt;Multi-Hop Retrieval is used when the answer cannot be obtained from a single piece of context. Instead, the LLM has to retrieve multiple related contexts and connect them to generate the final answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Suppose the knowledge base contains the following information:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Biryani contains spices.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The spices used in biryani are cardamom, cinnamon, cloves, etc.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now suppose the user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What spices need to be added to biryani?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The LLM first retrieves the information:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Biryani contains spices."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It then &lt;strong&gt;hops&lt;/strong&gt; to the next related context:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"The spices used in biryani are cardamom, cinnamon, cloves, etc."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, it combines both pieces of information to generate the complete answer.&lt;/p&gt;

&lt;p&gt;In this process, the LLM &lt;strong&gt;hops from one retrieved context to another&lt;/strong&gt; until it gathers enough information to answer the user's query.&lt;/p&gt;

&lt;p&gt;Each retrieved context should have a meaningful relationship with the next one so that the LLM can follow the chain of information and produce the correct response.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conversational RAG
&lt;/h1&gt;

&lt;p&gt;A user may not restrict themselves to asking only one query. They may ask a sequence of queries. Here, we are going to look at how to build &lt;strong&gt;Conversational RAG&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traditional Flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;User Query&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retriever&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related Documents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LLM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Answer&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A user may ask questions that are indirect or related to the previous question. So, we need to implement &lt;strong&gt;Query Transformation and Expansion&lt;/strong&gt; to get the related queries and their responses.&lt;/p&gt;

&lt;p&gt;Therefore, we need to have memory to store the previous conversation history.&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%2Fhqaubq2088jxc2ogjldf.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%2Fhqaubq2088jxc2ogjldf.png" alt=" " width="351" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conversational RAG will be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Conversation History + Current Question&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Intent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Query Transformation and Expansion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retriever&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Relevant Context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LLM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Context-Aware Answer&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here, we are going to see how we can store conversation history in memory.&lt;/p&gt;

&lt;p&gt;We can use &lt;strong&gt;persistent memory&lt;/strong&gt; such as PostgreSQL or SQLite, or &lt;strong&gt;short-term memory&lt;/strong&gt; using Redis, Valkey, Memcached, etc. We can also use a pickle file to store the history.&lt;/p&gt;

&lt;p&gt;If we are using a file, make sure that the application we are using is &lt;strong&gt;single-threaded&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To store the history, we can use the &lt;strong&gt;session ID&lt;/strong&gt; as the primary key.&lt;/p&gt;

&lt;p&gt;Always store the entire history in long-term memory. However, we cannot store the entire history in short-term memory.&lt;/p&gt;

&lt;p&gt;The purpose of storing history in short-term memory is to reduce latency.&lt;/p&gt;

&lt;p&gt;To solve this problem, we can store the entire history in long-term memory and summarize the conversation history and store the summary in short-term memory whenever needed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nlp</category>
      <category>rag</category>
    </item>
    <item>
      <title>RAG - Parent Retriever</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Wed, 05 Aug 2026 01:52:04 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/rag-parent-retriever-49dd</link>
      <guid>https://dev.to/ramya_perumal/rag-parent-retriever-49dd</guid>
      <description>&lt;h2&gt;
  
  
  RAG Pipeline Optimization Techniques
&lt;/h2&gt;

&lt;p&gt;The following techniques are commonly used to optimize a RAG pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Semantic Caching&lt;/li&gt;
&lt;li&gt;Query Transformation and Expansion&lt;/li&gt;
&lt;li&gt;Context Compression&lt;/li&gt;
&lt;li&gt;Parent Retrieval&lt;/li&gt;
&lt;li&gt;Multi-Vector Retrieval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These techniques are used to improve the quality of the responses generated by the LLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  Parent Retrieval
&lt;/h2&gt;

&lt;p&gt;Today, we are going to focus on &lt;strong&gt;Parent Retrieval&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A chunk is a small portion of a document or paragraph, typically consisting of &lt;strong&gt;500–1000 words&lt;/strong&gt;. When these chunks are converted into embeddings and stored in a vector database, semantically related chunks are positioned close to one another.&lt;/p&gt;

&lt;p&gt;When a user submits a query, the system retrieves the chunks that are closest to the query. However, not all the retrieved chunks may be the most relevant. Sometimes, we may miss other chunks that provide better context for the user's query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Suppose we have the following paragraphs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paragraph 1 (P1)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1&lt;/li&gt;
&lt;li&gt;L2&lt;/li&gt;
&lt;li&gt;L3&lt;/li&gt;
&lt;li&gt;L4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each line is stored as an individual chunk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1C1&lt;/li&gt;
&lt;li&gt;P1C2&lt;/li&gt;
&lt;li&gt;P1C3&lt;/li&gt;
&lt;li&gt;P1C4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Paragraph 2 (P2)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1&lt;/li&gt;
&lt;li&gt;L2&lt;/li&gt;
&lt;li&gt;L3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each line is also stored as individual chunks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P2C1&lt;/li&gt;
&lt;li&gt;P2C2&lt;/li&gt;
&lt;li&gt;P2C3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suppose the expected answer to the user query is &lt;strong&gt;P1C2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The vector database retrieves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1C2&lt;/li&gt;
&lt;li&gt;P2C3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although &lt;strong&gt;P1C2&lt;/strong&gt; is correctly retrieved, the related chunks &lt;strong&gt;P1C1&lt;/strong&gt;, &lt;strong&gt;P1C3&lt;/strong&gt;, and &lt;strong&gt;P1C4&lt;/strong&gt; may provide much better context than &lt;strong&gt;P2C3&lt;/strong&gt;. Since these chunks are not retrieved, we may lose important context that could improve the final LLM response.&lt;/p&gt;




&lt;p&gt;If we store the document paragraph-wise instead of using smaller chunks, we may retrieve unnecessary context, which increases token consumption.&lt;/p&gt;




&lt;h2&gt;
  
  
  Solution – Parent Retrieval
&lt;/h2&gt;

&lt;p&gt;Suppose &lt;strong&gt;Paragraph 1&lt;/strong&gt; is divided into four chunks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1C1&lt;/li&gt;
&lt;li&gt;P1C2&lt;/li&gt;
&lt;li&gt;P1C3&lt;/li&gt;
&lt;li&gt;P1C4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whenever a specific chunk is retrieved from the vector database, it also contains a reference to its &lt;strong&gt;parent paragraph&lt;/strong&gt;, which is stored in the chunk's metadata.&lt;/p&gt;

&lt;p&gt;For example, if &lt;strong&gt;P1C2&lt;/strong&gt; is retrieved, the metadata also contains a reference to &lt;strong&gt;Paragraph 1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Using this reference, the retriever can also fetch the remaining chunks belonging to the same parent paragraph:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1C1&lt;/li&gt;
&lt;li&gt;P1C3&lt;/li&gt;
&lt;li&gt;P1C4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that we do not miss important context that is closely related to the user's query.&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%2Fenyocpggmr7cuoiwem66.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%2Fenyocpggmr7cuoiwem66.png" alt=" " width="447" height="406"&gt;&lt;/a&gt;&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%2F973079vpt09pl2cwliy6.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%2F973079vpt09pl2cwliy6.png" alt=" " width="298" height="435"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Suppose the user query is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Create a dictionary"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The retrieved chunks are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1C2&lt;/li&gt;
&lt;li&gt;P2C2&lt;/li&gt;
&lt;li&gt;P2C3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of sending only these chunks to the LLM, Parent Retrieval also includes the remaining chunks from the same parent paragraph:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;P1C1&lt;/li&gt;
&lt;li&gt;P1C3&lt;/li&gt;
&lt;li&gt;P1C4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Providing this additional context enables the LLM to generate a more accurate response.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Should Parent Retrieval Be Used?
&lt;/h2&gt;

&lt;p&gt;Parent Retrieval is useful when we feel that important context is missing from the retrieved chunks and we want to include additional context that is closely related to the query.&lt;/p&gt;

&lt;p&gt;The parent paragraph is stored similarly to other chunks. However, it is &lt;strong&gt;not used directly for vector search&lt;/strong&gt;. Instead, its reference is stored in each chunk's metadata, allowing the retriever to fetch the parent context whenever required.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>nlp</category>
    </item>
    <item>
      <title>RAG - Context Compression</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Thu, 30 Jul 2026 01:58:52 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/rag-context-compression-bok</link>
      <guid>https://dev.to/ramya_perumal/rag-context-compression-bok</guid>
      <description>&lt;p&gt;In a RAG pipeline, documents are first split into chunks, converted into embeddings, and stored in a vector database.&lt;/p&gt;

&lt;p&gt;When a user query arrives, it is converted into an embedding and used to retrieve relevant results from the vector database. Although the retrieved results may be relevant, they may not always be directly related to the user's query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User Query&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"FastAPI dependency injection"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The retrieved results may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Use FastAPI in deployment"&lt;/li&gt;
&lt;li&gt;"How to dockerize a FastAPI application"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These results may be semantically related to FastAPI, but they are not necessarily the most accurate results for the user's query. This depends on how the documents were embedded and stored in the vector database.&lt;/p&gt;

&lt;p&gt;To improve the quality of the retrieved context, the fetched results can be compressed into one or two chunks before they are passed to the augmentation phase. This reduces the number of tokens used during augmentation and acts as an optimization technique.&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%2F015ssrvunq72fhy559f3.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%2F015ssrvunq72fhy559f3.png" alt=" " width="679" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above example, the chunks retrieved from the vector database may not be completely relevant to the user query. Therefore, we compress the retrieved chunks without changing their original context and create one or two chunks that are more relevant to the query.&lt;/p&gt;

&lt;p&gt;Context compression is &lt;strong&gt;not&lt;/strong&gt; a mandatory step in every RAG pipeline. It is generally adopted based on trial and error and depends on the application's requirements.&lt;/p&gt;

&lt;p&gt;This compression technique is mainly useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are token constraints.&lt;/li&gt;
&lt;li&gt;Higher-quality retrieval results are expected.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Context Compression Techniques
&lt;/h2&gt;

&lt;p&gt;There are different approaches for context compression:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;LLM-based Compression&lt;/li&gt;
&lt;li&gt;Embedding-based Compression&lt;/li&gt;
&lt;li&gt;Keyword-based Compression&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. LLM-based Compression
&lt;/h2&gt;

&lt;p&gt;In this approach, the relevant chunks retrieved from the vector database are given to an LLM for compression.&lt;/p&gt;

&lt;p&gt;For example, suppose four chunks are retrieved from the vector database. Instead of sending all four chunks to the main LLM, they are first passed to another LLM whose responsibility is only to compress them into one or two meaningful chunks.&lt;/p&gt;

&lt;p&gt;Although using an LLM for compression may appear expensive, a &lt;strong&gt;locally deployed LLM&lt;/strong&gt; or a &lt;strong&gt;low-cost LLM&lt;/strong&gt; is typically used for this task.&lt;/p&gt;

&lt;p&gt;The purpose of this LLM is &lt;strong&gt;not&lt;/strong&gt; to generate the final response. Its responsibility is only to merge and compress the retrieved chunks while preserving their context.&lt;/p&gt;

&lt;p&gt;The compressed chunks are then sent to a more powerful or application-specific LLM to generate the final response.&lt;/p&gt;

&lt;p&gt;This creates a &lt;strong&gt;two-stage pipeline&lt;/strong&gt;, which is more token-efficient while still producing high-quality output.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Embedding-based Compression
&lt;/h2&gt;

&lt;p&gt;In embedding-based compression, the embeddings of the top retrieved chunks are compared with the embedding of the user query using &lt;strong&gt;cosine similarity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The chunks that are most relevant to the user query are selected and used as the compressed context.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Keyword-based Compression
&lt;/h2&gt;

&lt;p&gt;Keyword-based compression uses techniques such as &lt;strong&gt;TF-IDF&lt;/strong&gt; or the &lt;strong&gt;BM25&lt;/strong&gt; algorithm.&lt;/p&gt;

&lt;p&gt;The keywords present in the user query are compared with the retrieved chunks.&lt;/p&gt;

&lt;p&gt;The chunks that have the highest keyword relevance are selected and used as the compressed context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Combining Compression Techniques
&lt;/h2&gt;

&lt;p&gt;A single application is not limited to using only one compression technique.&lt;/p&gt;

&lt;p&gt;Depending on the application requirements, two or more context compression techniques can be combined to improve retrieval quality while reducing token usage.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>nlp</category>
    </item>
    <item>
      <title>RAG - Query Transformation and Expansion</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Wed, 29 Jul 2026 17:27:33 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/rag-query-transformation-and-expansion-n6i</link>
      <guid>https://dev.to/ramya_perumal/rag-query-transformation-and-expansion-n6i</guid>
      <description>&lt;h2&gt;
  
  
  Query Transformation
&lt;/h2&gt;

&lt;p&gt;When a user asks a blended or incomplete query, such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How do I deploy it?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the LLM uses the background context it already has to transform the query into a more meaningful one.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How do I deploy a FastAPI application?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By transforming the query into a more specific one, the system is able to retrieve more relevant documents from the vector database.&lt;/p&gt;

&lt;p&gt;For query transformation to work effectively, the LLM should have some background information about the conversation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Query Expansion
&lt;/h2&gt;

&lt;p&gt;When a user query is converted into an embedding, the point obtained in the vector database may not be close to the most relevant documents.&lt;/p&gt;

&lt;p&gt;By expanding the query into different variations, we can retrieve more relevant documents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Original User Query&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"How do I deploy a FastAPI application?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Expanded Queries&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy FastAPI using Docker&lt;/li&gt;
&lt;li&gt;FastAPI deployment guide&lt;/li&gt;
&lt;li&gt;FastAPI deployment on AWS&lt;/li&gt;
&lt;li&gt;FastAPI with Gunicorn&lt;/li&gt;
&lt;li&gt;FastAPI with Uvicorn&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are different variations of the original user query.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Does Query Expansion Work?
&lt;/h2&gt;

&lt;p&gt;For each variation of the user query, the system retrieves a set of relevant contexts from the vector database.&lt;/p&gt;

&lt;p&gt;During the augmentation phase, the retrieved contexts, along with the original user query, are sent to the LLM so that it can generate more accurate results.&lt;/p&gt;




&lt;h2&gt;
  
  
  Query Expansion and Query Transformation
&lt;/h2&gt;

&lt;p&gt;Both &lt;strong&gt;query expansion&lt;/strong&gt; and &lt;strong&gt;query transformation&lt;/strong&gt; are performed by the LLM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query Transformation&lt;/strong&gt; rewrites an incomplete or ambiguous query into a more meaningful query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Query Expansion&lt;/strong&gt; generates multiple variations of the user query to improve document retrieval.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Alternative Approach
&lt;/h2&gt;

&lt;p&gt;Instead of calling the LLM for query expansion, we can use a rule-based approach by storing related queries for a user query as a cluster in the vector database.&lt;/p&gt;

&lt;p&gt;When a user submits a query, the system retrieves the related queries from the cluster and uses them to improve document retrieval.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>nlp</category>
    </item>
    <item>
      <title>RAG - Semantic Caching</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Sat, 18 Jul 2026 17:12:20 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/rag-semantic-caching-2h67</link>
      <guid>https://dev.to/ramya_perumal/rag-semantic-caching-2h67</guid>
      <description>&lt;p&gt;When a user submits a query, the query is converted into an embedding and searched against the vector database to retrieve the relevant documents.&lt;/p&gt;

&lt;p&gt;But what happens if the user asks the same or a very similar query again?&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;semantic caching&lt;/strong&gt; comes into the picture.&lt;/p&gt;

&lt;p&gt;Instead of searching the vector database again, the system stores the previous search result in a cache. A cache is a temporary storage where frequently accessed or recently queried results are stored. When the user asks the same or a semantically similar query again, the system can retrieve the result directly from the cache instead of querying the vector database again.&lt;/p&gt;




&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Saves retrieval time&lt;/li&gt;
&lt;li&gt;Reduces token consumption&lt;/li&gt;
&lt;li&gt;Reduces the number of calls to the vector database&lt;/li&gt;
&lt;li&gt;Reduces the number of calls to the LLM&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How Do We Store Results in the Cache?
&lt;/h2&gt;

&lt;p&gt;We can use &lt;strong&gt;Redis&lt;/strong&gt; or &lt;strong&gt;Valkey&lt;/strong&gt; for semantic caching.&lt;/p&gt;

&lt;p&gt;These are &lt;strong&gt;in-memory databases&lt;/strong&gt;, which means they store data in &lt;strong&gt;RAM&lt;/strong&gt; instead of disk. Since data is stored in memory, retrieval is much faster compared to traditional databases.&lt;/p&gt;

&lt;p&gt;Typically, we store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User query&lt;/li&gt;
&lt;li&gt;Related answer&lt;/li&gt;
&lt;li&gt;Metadata&lt;/li&gt;
&lt;li&gt;Embeddings&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Suppose a user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What is today's gold price?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The query and its corresponding answer are stored in Redis.&lt;/p&gt;

&lt;p&gt;Later, another user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Gold price today?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Although both queries have the same meaning, Redis cannot directly retrieve the previous answer because it expects the key to match exactly.&lt;/p&gt;

&lt;p&gt;This is one of the limitations of using Redis as a simple key-value store.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Can We Solve This?
&lt;/h2&gt;

&lt;p&gt;One approach is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve all the keys stored in Redis (for example, using &lt;code&gt;KEYS *&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Generate or retrieve the embedding for each stored query.&lt;/li&gt;
&lt;li&gt;Convert the current user query into an embedding.&lt;/li&gt;
&lt;li&gt;Compare the current query embedding with the stored query embeddings using &lt;strong&gt;cosine similarity&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If the similarity score is above a predefined threshold, retrieve the corresponding answer from Redis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This allows semantically similar queries to reuse cached results even when the text is different.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ways to Implement Semantic Caching
&lt;/h2&gt;

&lt;p&gt;Semantic caching can be implemented in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using frameworks such as &lt;strong&gt;LangChain&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Using in-memory databases such as &lt;strong&gt;Redis&lt;/strong&gt;, &lt;strong&gt;Valkey&lt;/strong&gt;, or other similar databases&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Cache Invalidation
&lt;/h2&gt;

&lt;p&gt;One of the most important aspects of semantic caching is &lt;strong&gt;cache invalidation&lt;/strong&gt;, which determines how long cached data should remain valid before it is automatically removed or refreshed.&lt;/p&gt;

&lt;p&gt;For example, suppose a user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What is today's gold price?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer should only be valid for a limited period. If the application returns yesterday's gold price, the information becomes incorrect.&lt;/p&gt;

&lt;p&gt;There is no single solution for cache invalidation. The appropriate strategy depends on the application and the type of data being cached.&lt;/p&gt;

&lt;p&gt;Different scenarios need to be considered before deciding when cached data should expire.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Should In-Memory Databases Be Used?
&lt;/h2&gt;

&lt;p&gt;In-memory databases are well suited for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Temporary queries&lt;/li&gt;
&lt;li&gt;Frequently asked questions&lt;/li&gt;
&lt;li&gt;Data that is accessed repeatedly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding the meaning of the query, we can define guardrails to determine which queries should be cached and when the cache should be invalidated.&lt;/p&gt;

&lt;p&gt;The main objective is to optimize the RAG pipeline by reducing unnecessary calls to both the vector database and the LLM.&lt;/p&gt;

&lt;p&gt;Although it is not possible to eliminate duplicate requests completely, semantic caching can significantly reduce them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Important Consideration
&lt;/h2&gt;

&lt;p&gt;We should &lt;strong&gt;not&lt;/strong&gt; store every query in an in-memory database.&lt;/p&gt;

&lt;p&gt;Only queries that are valuable for caching should be stored because &lt;strong&gt;RAM has limited storage capacity&lt;/strong&gt;. Therefore, an effective caching strategy should carefully decide which queries are worth storing and for how long.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>beginners</category>
      <category>nlp</category>
    </item>
    <item>
      <title>RAG - Meta Filtering and Reranking</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Sun, 12 Jul 2026 21:43:55 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/rag-meta-filtering-and-reranking-22i1</link>
      <guid>https://dev.to/ramya_perumal/rag-meta-filtering-and-reranking-22i1</guid>
      <description>&lt;p&gt;Generally, when a user asks a query, the system searches for the relevant chunks stored in the vector database using cosine similarity. The better we can filter the data, the smaller the search space becomes, resulting in faster and more efficient retrieval.&lt;/p&gt;

&lt;p&gt;Suppose we have a book with 10 chapters. If we want to search for a particular topic, all the points in the vector database are compared with the user query, and only the closest points are retrieved. This process is called &lt;strong&gt;KNN (K-Nearest Neighbors)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another algorithm is &lt;strong&gt;ANN (Approximate Nearest Neighbors)&lt;/strong&gt;. Instead of checking all the points in the vector database, ANN searches only within a smaller region based on the proximity of the data. As the name suggests, it does not always return the exact result, but it provides the most preferred or approximate results much faster.&lt;/p&gt;

&lt;p&gt;Is there any other method we can use to make the search more effective?&lt;/p&gt;

&lt;p&gt;Metadata Filtering&lt;/p&gt;

&lt;p&gt;Metadata means &lt;strong&gt;data about the data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Metadata is stored along with each chunk. It can contain information related to the chunk, such as the chapter name, topic description, author, or any other relevant details.&lt;/p&gt;

&lt;p&gt;When the user query contains information related to the metadata (for example, a chapter name or topic), the system can directly filter the relevant chunks before performing vector similarity search. This technique is called &lt;strong&gt;metadata filtering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Metadata filtering is supported by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pinecone&lt;/li&gt;
&lt;li&gt;ChromaDB&lt;/li&gt;
&lt;li&gt;Qdrant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FAISS does not provide built-in support for metadata filtering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reranking
&lt;/h2&gt;

&lt;p&gt;Documents are first split into chunks, and each chunk is converted into vectors and stored in the vector database.&lt;/p&gt;

&lt;p&gt;When a user query arrives, it is converted into a vector and searched against the vector database to retrieve the closest chunks. However, we do not know whether the retrieved documents are actually the most relevant to the query. It is not always true that the closest vectors represent the most relevant documents.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Reranking Works
&lt;/h3&gt;

&lt;p&gt;The documents retrieved from the vector database are passed to a &lt;strong&gt;cross-encoder&lt;/strong&gt; along with the user query.&lt;/p&gt;

&lt;p&gt;The cross-encoder assigns a relevance score that indicates how closely each document matches the query. The documents are then displayed in ascending or descending order based on these scores.&lt;/p&gt;

&lt;p&gt;The results produced by the cross-encoder are called &lt;strong&gt;reranked results&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The retrieved documents remain the same as those returned by the vector database, but their order changes. Documents with higher relevance scores appear before those with lower scores.&lt;/p&gt;

&lt;p&gt;A cross-encoder is a neural ranking model. Instead of encoding the query and documents separately, it takes both the query and the document together as input to a transformer model and generates a relevance score for each document.&lt;/p&gt;

&lt;p&gt;There are transformer models specifically designed for reranking tasks. The encoder understands the meaning of both the query and the document and reranks the documents accordingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Reranking?
&lt;/h3&gt;

&lt;p&gt;Reranking is an important step in the RAG pipeline.&lt;/p&gt;

&lt;p&gt;It is especially useful when working with documents that contain images or other multimodal content.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Suppose the user asks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Show me the front view of the truck."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The vector database may retrieve multiple images related to trucks because they are semantically similar.&lt;/p&gt;

&lt;p&gt;The reranker analyzes both the query and the retrieved images (or their associated text descriptions) and assigns relevance scores.&lt;/p&gt;

&lt;p&gt;As a result, the image showing the &lt;strong&gt;front view of the truck&lt;/strong&gt; receives a higher score than the other truck images, making it appear first in the final results.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>rag</category>
      <category>nlp</category>
    </item>
    <item>
      <title>Docker -Networking and Best Practices</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Sat, 27 Jun 2026 20:30:19 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/docker-networking-and-best-practices-17ji</link>
      <guid>https://dev.to/ramya_perumal/docker-networking-and-best-practices-17ji</guid>
      <description>&lt;h1&gt;
  
  
  Docker Networking
&lt;/h1&gt;

&lt;p&gt;Containers are assigned an IP address when they are created. To check the IP address, we can use the following 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 inspect &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we send a request from the host to the container's IP address, the container responds using its assigned IP address.&lt;/p&gt;

&lt;p&gt;By default, Docker creates a &lt;strong&gt;bridge network&lt;/strong&gt;. This bridge network allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Communication between the host and the container (through port mapping).&lt;/li&gt;
&lt;li&gt;Communication between containers connected to the same bridge network.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the default bridge network, containers generally communicate using &lt;strong&gt;IP addresses&lt;/strong&gt;. To communicate using container names (hostnames), we can use a &lt;strong&gt;custom bridge network&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The main difference between the default bridge network and a custom bridge network is that containers on a custom bridge network can communicate using their &lt;strong&gt;container names (DNS resolution)&lt;/strong&gt;, making it suitable for production environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use a Custom Bridge Network
&lt;/h3&gt;

&lt;p&gt;A custom bridge network is useful when an application consists of multiple services running in separate containers. These containers can communicate with one another using their container names instead of IP addresses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Create a Custom Bridge Network
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create and Run Containers Inside the Network
&lt;/h2&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;-it&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; mybridge &lt;span class="nt"&gt;--name&lt;/span&gt; container1 busybox:1.36 sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;-it&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; mybridge &lt;span class="nt"&gt;--name&lt;/span&gt; container2 busybox:1.36 sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, from &lt;strong&gt;container1&lt;/strong&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;ping container2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, from &lt;strong&gt;container2&lt;/strong&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;ping container1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the ping is successful, it confirms that both containers can communicate because they are connected to the same custom bridge network.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example Workflow for a Docker Bridge Network
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Step 1: Build the Images
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; flask_app:v1 &lt;span class="nb"&gt;.&lt;/span&gt;
docker build &lt;span class="nt"&gt;-f&lt;/span&gt; httpd.Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; apache_container:v1 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Create the Network
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Run the Containers
&lt;/h3&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;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; flask_new &lt;span class="nt"&gt;--network&lt;/span&gt; bridge_app flask_app:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; apache_new &lt;span class="nt"&gt;--network&lt;/span&gt; bridge_app apache_container:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Verify the Network
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Test Communication
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ping apache_new
ping flask_new
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use &lt;code&gt;curl&lt;/code&gt; with the application's port to access another container's application.&lt;/p&gt;




&lt;h1&gt;
  
  
  Host Network
&lt;/h1&gt;

&lt;p&gt;Suppose we run an application inside a Docker container.&lt;/p&gt;

&lt;p&gt;If we do &lt;strong&gt;not&lt;/strong&gt; expose the application port using &lt;code&gt;-p&lt;/code&gt;, the application cannot be accessed through the host machine. It can only be accessed using the container's IP address (if reachable).&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;docker run flask_app:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we expose the port:&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;-p&lt;/span&gt; 5000:5000 flask_app:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker maps the host port to the container port, allowing the application to be accessed using the host machine's IP address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Host Network Mode
&lt;/h3&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;--network&lt;/span&gt; host flask_app:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;strong&gt;host network mode&lt;/strong&gt;, the container shares the host's network stack. Therefore, the application can use the host's network directly without explicit port mapping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Host networking is supported on Linux. On Docker Desktop for Windows and macOS, host networking is limited and generally not recommended. Port mapping (&lt;code&gt;-p&lt;/code&gt;) is the standard approach.&lt;/p&gt;




&lt;h1&gt;
  
  
  Docker Image Optimization
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Why Is Image Optimization Needed?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Smaller images start containers faster.&lt;/li&gt;
&lt;li&gt;Smaller images are easier to share.&lt;/li&gt;
&lt;li&gt;Smaller images consume less storage.&lt;/li&gt;
&lt;li&gt;Smaller images download faster.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Multi-Stage Builds
&lt;/h2&gt;

&lt;p&gt;In a multi-stage build, the first stage builds the application, and the second stage copies only the required artifacts into the final image.&lt;/p&gt;

&lt;p&gt;A single-stage build includes both build tools and runtime dependencies, making the image larger.&lt;/p&gt;

&lt;p&gt;A multi-stage build keeps only the files required to run the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-Stage Build
&lt;/h3&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; python:3.9-slim&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&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;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "main.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multi-Stage Build
&lt;/h3&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;python:3.9-slim&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;builder&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; main.py .&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;python:3.9-slim&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;runner&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; --from=builder /app/main.py .&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "main.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Builder stage&lt;/strong&gt; prepares the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runner stage&lt;/strong&gt; copies only the required files, resulting in a smaller final image.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Choose a Minimal Base Image
&lt;/h2&gt;

&lt;p&gt;Using a lightweight base image reduces the final image size.&lt;/p&gt;

&lt;p&gt;Examples:&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; python:3.9-slim&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This image contains only the essential Python packages.&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; python:3.9-alpine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This image is even smaller and includes only minimal functionality. Additional packages must be installed separately.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;not recommended&lt;/strong&gt; to use:&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; python&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because Docker will pull the latest version, which may introduce compatibility issues. Always specify a version tag.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Layer Caching
&lt;/h2&gt;

&lt;p&gt;Docker caches image layers.&lt;/p&gt;

&lt;p&gt;If no changes occur in a layer or any previous layer, Docker reuses the cached layer, making builds much faster.&lt;/p&gt;

&lt;p&gt;The order of Dockerfile instructions is important.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;COPY . /app&lt;/code&gt; is placed near the beginning of the Dockerfile, any source code change invalidates all subsequent layers.&lt;/p&gt;

&lt;p&gt;Instead, place frequently changing instructions lower in the Dockerfile whenever possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Less Efficient
&lt;/h3&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; python:3.9-slim&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&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;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "main.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Better
&lt;/h3&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; python:3.9-slim&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; . /app&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "main.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents Docker from rebuilding the &lt;code&gt;WORKDIR&lt;/code&gt; layer unnecessarily.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Run Containers as a Non-Root User
&lt;/h2&gt;

&lt;p&gt;By default, containers run as the &lt;strong&gt;root user&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A root user can create or modify files anywhere inside the container.&lt;/p&gt;

&lt;p&gt;If the container is compromised, an attacker may gain elevated privileges.&lt;/p&gt;

&lt;p&gt;Running the container as a non-root user improves security because that user has limited permissions.&lt;/p&gt;

&lt;p&gt;Example (Windows Containers):&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;RUN &lt;/span&gt;icacls C:&lt;span class="se"&gt;\a&lt;/span&gt;pp /grant ContainerUser:&lt;span class="o"&gt;(&lt;/span&gt;OI&lt;span class="o"&gt;)(&lt;/span&gt;CI&lt;span class="o"&gt;)&lt;/span&gt;F

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

&lt;/div&gt;



&lt;p&gt;Example (Linux Containers):&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;RUN &lt;/span&gt;useradd &lt;span class="nt"&gt;-m&lt;/span&gt; appuser

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

&lt;/div&gt;



&lt;p&gt;Running applications as a non-root user is considered a Docker best practice.&lt;/p&gt;




&lt;h1&gt;
  
  
  Interview Questions
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Question 1
&lt;/h3&gt;

&lt;p&gt;Which Docker network allows containers to communicate with each other without requiring port mapping on the host?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; Bridge network.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 2
&lt;/h3&gt;

&lt;p&gt;Which statement is true about Docker layer caching?&lt;/p&gt;

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

&lt;p&gt;Docker caches layers unless a previous layer has changed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 3
&lt;/h3&gt;

&lt;p&gt;Why is it considered best practice to run containers as a non-root user?&lt;/p&gt;

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

&lt;p&gt;It helps prevent attackers from gaining root privileges if the container is compromised.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 4
&lt;/h3&gt;

&lt;p&gt;What is the purpose of using a multi-stage build in Docker?&lt;/p&gt;

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

&lt;p&gt;To reduce the size of the final Docker image.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 5
&lt;/h3&gt;

&lt;p&gt;How do you specify a non-root user in Docker?&lt;/p&gt;

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

&lt;p&gt;Use the &lt;code&gt;USER&lt;/code&gt; directive in the Dockerfile or the &lt;code&gt;--user&lt;/code&gt; option when running the container.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 6
&lt;/h3&gt;

&lt;p&gt;Which of the following can invalidate the Docker build cache for a layer?&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Changing the base image version.&lt;/li&gt;
&lt;li&gt;Modifying files copied into that layer.&lt;/li&gt;
&lt;li&gt;Adding or changing an environment variable (&lt;code&gt;ENV&lt;/code&gt;) or build argument (&lt;code&gt;ARG&lt;/code&gt;) used by that layer.&lt;/li&gt;
&lt;li&gt;Changing the Dockerfile instruction itself.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>basic</category>
      <category>virtualmachine</category>
    </item>
    <item>
      <title>Docker – ARG Directive, .dockerignore, and Docker Volumes</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Sat, 27 Jun 2026 20:30:07 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/docker-arg-directive-dockerignore-and-docker-volumes-29kh</link>
      <guid>https://dev.to/ramya_perumal/docker-arg-directive-dockerignore-and-docker-volumes-29kh</guid>
      <description>&lt;h2&gt;
  
  
  ARG Directive
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;ARG&lt;/code&gt; directive acts like a variable. We can define it inside the Dockerfile and change its value during the image build process.&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;ARG&lt;/span&gt;&lt;span class="s"&gt; PYTHON_VERSION=3.8&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:${PYTHON_VERSION}-slim&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the Python version in the Dockerfile is set to &lt;code&gt;3.8&lt;/code&gt;. However, during the build process, we can change it to &lt;code&gt;3.10&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;docker build &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile &lt;span class="nt"&gt;--build-arg&lt;/span&gt; &lt;span class="nv"&gt;PYTHON_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10 &lt;span class="nt"&gt;-t&lt;/span&gt; helloworld_flask:v1 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; means &lt;strong&gt;tag&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; means &lt;strong&gt;Dockerfile path&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can use &lt;code&gt;ARG&lt;/code&gt; to make base image versions and other build-time values configurable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&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; node:20-alpine&lt;/span&gt;

&lt;span class="c"&gt;# 1. Define the arguments&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; APP_DIR=app&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; INSTALL_ARGS="--omit=dev"&lt;/span&gt;

&lt;span class="c"&gt;# 2. Use them in instructions&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /${APP_DIR}&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 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INSTALL_ARGS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;ARG&lt;/code&gt; values can only be changed during the image build process. They cannot be changed during container creation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Docker Ignore
&lt;/h1&gt;

&lt;p&gt;A &lt;code&gt;.dockerignore&lt;/code&gt; file is used to specify files and directories that should not be copied into the Docker build context.&lt;/p&gt;

&lt;p&gt;Create a file named &lt;code&gt;.dockerignore&lt;/code&gt; in the application's root directory.&lt;/p&gt;

&lt;p&gt;Examples of files and folders that can be ignored:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dockerfile
.venv
__pycache__
*.pyc
requirements.txt
.git
.gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ignoring unnecessary files reduces the build context size and speeds up image builds.&lt;/p&gt;




&lt;h1&gt;
  
  
  Docker Volumes
&lt;/h1&gt;

&lt;p&gt;Generally, when a container is created, a writable layer is also created.&lt;/p&gt;

&lt;p&gt;If we create files inside the container, they are stored in the writable layer. However, when the container is deleted, all data in the writable layer is lost.&lt;/p&gt;

&lt;p&gt;What if we need to store files permanently on the host machine?&lt;/p&gt;

&lt;p&gt;This is where Docker volumes come into the picture.&lt;/p&gt;

&lt;p&gt;Docker volumes allow data to persist independently of the container lifecycle.&lt;/p&gt;

&lt;p&gt;When a volume is mounted between a host directory and a container directory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Files created in the container appear on the host machine.&lt;/li&gt;
&lt;li&gt;Files created on the host machine appear inside the container.&lt;/li&gt;
&lt;li&gt;Changes are synchronized between both locations.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Types of Docker Volumes
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Bind-Mounted Volumes&lt;/li&gt;
&lt;li&gt;Docker Managed Volumes (Named Volumes)&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Bind-Mounted Volumes
&lt;/h2&gt;

&lt;p&gt;A bind mount creates a mapping between a host directory and a container directory.&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;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; ./data:/data busybox:1.36 sh
&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;./data&lt;/code&gt; = Host machine directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/data&lt;/code&gt; = Container directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tightly coupled with the host file system.&lt;/li&gt;
&lt;li&gt;Multiple containers can share the same host directory.&lt;/li&gt;
&lt;li&gt;Changes made in either location are reflected in the other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The host directory is not deleted when the container is removed.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Docker Managed Volumes (Named Volumes)
&lt;/h2&gt;

&lt;p&gt;Create a Docker-managed volume:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This creates a volume outside the container lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  List Volumes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker volume &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inspect a Volume
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;This displays information about the volume, including its mount location.&lt;/p&gt;

&lt;p&gt;Example Linux location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/lib/docker/volumes/dockersession/_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mount the Volume to a Container
&lt;/h3&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;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; dockersession:/data123 busybox:1.36 sh
&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;dockersession&lt;/code&gt; = Volume name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/data123&lt;/code&gt; = Container directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multiple containers can use the same volume for data sharing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find Containers Using a Specific Volume
&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;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="nv"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dockersession
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the major benefits of Docker volumes is that they are completely decoupled from the container lifecycle.&lt;/p&gt;

&lt;p&gt;When a container is deleted, the volume and all its data remain safely stored on the host machine.&lt;/p&gt;




&lt;h1&gt;
  
  
  Interview Questions
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;What is the primary use of the ARG instruction in Docker?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; To pass build-time variables to the Dockerfile.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;Which of the following is true about ARG variables in Docker?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; They are used only during the image build process.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;Can an ARG variable be used in a RUN instruction within a Dockerfile?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; Yes, but only after it has been declared.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;Which files can be ignored using &lt;code&gt;.dockerignore&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; Any file or directory within the build context.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;What is the purpose of Docker volumes?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; To store data that persists even after a container is destroyed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;What is the default location of Docker volumes on Linux systems?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&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;/var/lib/docker/volumes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;Which command allows you to list all Docker volumes?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&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;docker volume &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;In which scenario would you use a bind-mounted volume?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; When you need to share specific directories between the host machine and a container.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>basic</category>
      <category>virtualmachine</category>
      <category>wind</category>
    </item>
    <item>
      <title>Docker – Port Mapping, Logs, Container Management, and Image Removal</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Sat, 27 Jun 2026 20:29:51 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/docker-port-mapping-logs-container-management-and-image-removal-20oo</link>
      <guid>https://dev.to/ramya_perumal/docker-port-mapping-logs-container-management-and-image-removal-20oo</guid>
      <description>&lt;h1&gt;
  
  
  Docker – Logs, Remove, and Port Mapping
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Port Mapping
&lt;/h2&gt;

&lt;p&gt;When we run an application inside a container, we define the port on which the application will run. The container runs the application on that port.&lt;/p&gt;

&lt;p&gt;It is not possible to access an application running inside Docker from outside the container unless port mapping is configured.&lt;/p&gt;

&lt;p&gt;Port mapping is specified using the &lt;code&gt;-p&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax:&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;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;host_port&amp;gt;:&amp;lt;container_port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example:&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;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8888:8080
&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;8888&lt;/code&gt; is the host (machine) port used to access the application from outside the container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;8080&lt;/code&gt; is the port defined in the application and exposed inside the container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the host port is already in use, Docker displays an error message.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Check Which Ports Are Being Used by Docker Containers
&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;--format&lt;/span&gt; &lt;span class="s2"&gt;"table {{.ID}}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;{{.Names}}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;{{.Ports}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Detached Mode
&lt;/h2&gt;

&lt;p&gt;To run a container in detached mode, use the &lt;code&gt;-d&lt;/code&gt; option.&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;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 2000:2001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Detached mode means the container runs in the background.&lt;/p&gt;




&lt;h1&gt;
  
  
  Docker Logs
&lt;/h1&gt;

&lt;p&gt;Logs contain information about the activities happening inside a container.&lt;/p&gt;

&lt;h3&gt;
  
  
  View Logs of a Specific Container
&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_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Follow Logs Continuously
&lt;/h3&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_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-f&lt;/code&gt; stands for &lt;strong&gt;follow&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  View Logs from a Specific Time Range
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Seconds &lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;: docker logs &lt;span class="nt"&gt;--since&lt;/span&gt; 30s &amp;lt;container_id&amp;gt;
Minutes &lt;span class="o"&gt;(&lt;/span&gt;m&lt;span class="o"&gt;)&lt;/span&gt;: docker logs &lt;span class="nt"&gt;--since&lt;/span&gt; 5m &amp;lt;container_id&amp;gt;
Hours &lt;span class="o"&gt;(&lt;/span&gt;h&lt;span class="o"&gt;)&lt;/span&gt;: docker logs &lt;span class="nt"&gt;--since&lt;/span&gt; 2h &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker supports seconds (&lt;code&gt;s&lt;/code&gt;), minutes (&lt;code&gt;m&lt;/code&gt;), and hours (&lt;code&gt;h&lt;/code&gt;) for relative time.&lt;/p&gt;

&lt;p&gt;For days, weeks, months, or years, use an ISO 8601 date or timestamp.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Weeks:  docker logs &lt;span class="nt"&gt;--since&lt;/span&gt; 2026-06-14 &amp;lt;container_id&amp;gt;
Months: docker logs &lt;span class="nt"&gt;--since&lt;/span&gt; 2026-05-21 &amp;lt;container_id&amp;gt;
Years:  docker logs &lt;span class="nt"&gt;--since&lt;/span&gt; 2025-06-21 &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Combined Time Units
&lt;/h3&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;--since&lt;/span&gt; 1h30m &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Displays logs from 1 hour and 30 minutes ago.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exact Time
&lt;/h3&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;--since&lt;/span&gt; &lt;span class="s2"&gt;"2026-06-21T17:30:00"&lt;/span&gt; &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Displays logs generated since the specified date and time.&lt;/p&gt;




&lt;h1&gt;
  
  
  Docker Inspect
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;docker inspect&lt;/code&gt; is used to view detailed information about a container, image, network, or volume.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;






&lt;h1&gt;
  
  
  Access a Running or Exited Container
&lt;/h1&gt;

&lt;p&gt;To open a shell inside a running 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 &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;container_id&amp;gt; sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-i&lt;/code&gt; = Interactive mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; = Allocate a terminal&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Docker Remove
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Delete an Exited Container
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm&lt;/span&gt; &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Delete a Running Container
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-f&lt;/code&gt; forcefully stops and removes the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alternative Method
&lt;/h3&gt;

&lt;p&gt;First stop 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;docker stop &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then remove it:&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;rm&lt;/span&gt; &amp;lt;container_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Delete Multiple Containers
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &amp;lt;container_id1&amp;gt; &amp;lt;container_id2&amp;gt; &amp;lt;container_id3&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Alternative Method (Windows)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;FOR&lt;/span&gt; &lt;span class="na"&gt;/F &lt;/span&gt;&lt;span class="s2"&gt;"tokens=*"&lt;/span&gt; &lt;span class="vm"&gt;%i&lt;/span&gt; &lt;span class="kd"&gt;IN&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'docker ps -aq'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;DO&lt;/span&gt; &lt;span class="kd"&gt;docker&lt;/span&gt; &lt;span class="kd"&gt;rm&lt;/span&gt; &lt;span class="na"&gt;-f &lt;/span&gt;&lt;span class="vm"&gt;%i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command removes all containers.&lt;/p&gt;




&lt;h1&gt;
  
  
  Listing Containers
&lt;/h1&gt;

&lt;h2&gt;
  
  
  View Running Containers
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ps&lt;/code&gt; stands for &lt;strong&gt;Process Status&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This command lists only running containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  View All Containers
&lt;/h2&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;This command lists all containers, including exited containers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-a&lt;/code&gt; stands for &lt;strong&gt;all&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  View Only Container IDs
&lt;/h2&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;-aq&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command lists all container IDs.&lt;/p&gt;




&lt;h1&gt;
  
  
  Delete Images
&lt;/h1&gt;



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

&lt;/div&gt;



&lt;p&gt;This command forcefully removes an image.&lt;/p&gt;




&lt;h1&gt;
  
  
  Naming a Container
&lt;/h1&gt;

&lt;p&gt;To assign a name to 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 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; anyname busybox:1.36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; my-container busybox:1.36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a container with the name &lt;code&gt;my-container&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>basic</category>
      <category>virtualmachine</category>
    </item>
    <item>
      <title>Docker – Image and Container Bonding &amp; Client-Server Architecture</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Sat, 27 Jun 2026 20:29:32 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/docker-image-and-container-bonding-client-server-architecture-2apd</link>
      <guid>https://dev.to/ramya_perumal/docker-image-and-container-bonding-client-server-architecture-2apd</guid>
      <description>&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A container is running from an image. If we try to delete the image while the container is running, why can't we delete the image?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Answer:
&lt;/h3&gt;

&lt;p&gt;If we attempt to delete the image, Docker will display an error message stating that the image is being used by a container.&lt;/p&gt;

&lt;p&gt;The reason is that each line in a Dockerfile creates a layer.&lt;/p&gt;

&lt;p&gt;Each layer is a &lt;strong&gt;read-only layer&lt;/strong&gt;. Once a layer is created, it cannot be modified. If we want to make changes to the image, we need to create a new Dockerfile and build a new image.&lt;/p&gt;

&lt;p&gt;When we create a container, only a reference to the image layers is passed to the container. The container has a &lt;strong&gt;writable layer&lt;/strong&gt;, meaning we can create files, modify files, or generate output inside the container. These changes reside only in the container and do not affect the image.&lt;/p&gt;

&lt;p&gt;However, the container always depends on the image. That is why we cannot delete the image while the container is using it.&lt;/p&gt;

&lt;p&gt;This methodology is called &lt;strong&gt;Copy-on-Write (CoW)&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;If an image size is 10 GB, what will be the container size?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Answer:
&lt;/h3&gt;

&lt;p&gt;A container contains only references to the image layers. Therefore, the container size consists of the files and changes stored in the writable layer running inside the container.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What command is used to find the size of a container?&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;docker ps &lt;span class="nt"&gt;--size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;Dive&lt;/strong&gt; application is used to analyze each layer in a Docker image.&lt;/p&gt;




&lt;h1&gt;
  
  
  Client-Server Architecture
&lt;/h1&gt;

&lt;p&gt;Docker works based on the &lt;strong&gt;Client-Server Architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The Docker client sends requests to the Docker daemon, and the Docker daemon responds to the client.&lt;/p&gt;

&lt;p&gt;If a requested image is not found on the local system, Docker retrieves it from a public repository.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This command pulls the image from the repository and runs it on the local system.&lt;/p&gt;




&lt;h3&gt;
  
  
  To pull an image from an image repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker pull busybox:1.36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  To create a container
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  To create a container, execute the &lt;code&gt;ls&lt;/code&gt; command inside it, and exit immediately
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker run busybox:1.36 ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  To create a container and enter interactive mode
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker run -it busybox:1.36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Interview Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Question 1:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In a Client-Server architecture, who sends requests to the server?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; The client.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 2:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What happens when a container is created from an image?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; A writable layer is created.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 3:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What is the purpose of the writable layer in a container?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; To handle file modifications and store changes made inside the container.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 4:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The read-only layers in Docker come from what?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; The base image and its image layers.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 5:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What happens to the writable layer when the container is deleted?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; It is discarded.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 6:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In a Docker environment, the client interacts with what?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; The Docker daemon.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 7:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;How do you start a container in interactive mode?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&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;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;image-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>docker</category>
      <category>basic</category>
      <category>virtualmachine</category>
    </item>
    <item>
      <title>Docker – Need for Docker and Docker Terminologies</title>
      <dc:creator>Ramya Perumal</dc:creator>
      <pubDate>Sat, 27 Jun 2026 20:29:13 +0000</pubDate>
      <link>https://dev.to/ramya_perumal/docker-need-for-docker-and-docker-terminologies-1nmh</link>
      <guid>https://dev.to/ramya_perumal/docker-need-for-docker-and-docker-terminologies-1nmh</guid>
      <description>&lt;h1&gt;
  
  
  Need for Docker
&lt;/h1&gt;

&lt;p&gt;When more than one application runs on a single physical machine, all the applications have to share the machine's memory, CPU, and computational resources.&lt;/p&gt;

&lt;p&gt;Suppose one application consumes more computational power. In that case, the other applications may become slow or even stop responding.&lt;/p&gt;

&lt;p&gt;One solution is to run each application on a separate physical server. Although this provides better performance and isolation, the infrastructure cost and maintenance cost become very high.&lt;/p&gt;

&lt;p&gt;To overcome this problem, the concept of &lt;strong&gt;Virtual Machines (VMs)&lt;/strong&gt; was introduced.&lt;/p&gt;

&lt;p&gt;In a virtual machine environment, each application runs on its own operating system while sharing a single physical machine.&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%2Fcytpsgkdjr2lqfa09sj8.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%2Fcytpsgkdjr2lqfa09sj8.png" alt=" " width="633" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Virtual Machines
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reduced hardware cost.&lt;/li&gt;
&lt;li&gt;Lower maintenance cost.&lt;/li&gt;
&lt;li&gt;Better isolation between applications.&lt;/li&gt;
&lt;li&gt;Multiple operating systems can run on a single physical machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A software component called a &lt;strong&gt;Hypervisor&lt;/strong&gt; is responsible for virtualizing the physical machine and allowing multiple virtual machines to run on it.&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%2F7wv2bqtyrfxur91uirru.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%2F7wv2bqtyrfxur91uirru.png" alt=" " width="799" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Hypervisors
&lt;/h3&gt;

&lt;p&gt;There are two types of Hypervisors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Type 1 Hypervisor
&lt;/h3&gt;

&lt;p&gt;A Type 1 Hypervisor is installed directly on the physical machine (bare metal).&lt;/p&gt;

&lt;h3&gt;
  
  
  Type 2 Hypervisor
&lt;/h3&gt;

&lt;p&gt;A Type 2 Hypervisor is installed on top of a host operating system.&lt;/p&gt;

&lt;p&gt;We generally use &lt;strong&gt;Type 2 Hypervisors&lt;/strong&gt; on personal computers. They allocate virtual resources to each virtual machine either manually or dynamically.&lt;/p&gt;




&lt;p&gt;However, virtual machines still require a complete operating system for every application, which consumes a significant amount of memory and storage.&lt;/p&gt;

&lt;p&gt;This means we are not fully utilizing the operating system resources for every application.&lt;/p&gt;

&lt;p&gt;To overcome this limitation, &lt;strong&gt;Containers&lt;/strong&gt; were introduced.&lt;/p&gt;

&lt;p&gt;Containers include only the minimum libraries and dependencies required to run an application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Containers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Containers consume much less memory than virtual machines.&lt;/li&gt;
&lt;li&gt;Containers start much faster.&lt;/li&gt;
&lt;li&gt;Containers are lightweight.&lt;/li&gt;
&lt;li&gt;Containers are portable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An application is packaged as a &lt;strong&gt;Docker Image&lt;/strong&gt;, which can be shared with any number of users and run consistently across different environments.&lt;/p&gt;




&lt;h1&gt;
  
  
  Docker Terminologies
&lt;/h1&gt;

&lt;p&gt;For better understanding, let's compare Docker concepts with a kitchen.&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;Kitchen Analogy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker Engine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The kitchen where everything happens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The recipe that contains the ingredients and preparation steps.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker Image&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The finished dish prepared using the recipe.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker Container&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A serving (portion) of the finished dish.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker Registry&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A pantry that stores many dishes (images) with different tags.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker Daemon&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The chef who prepares the dish (image) by following the recipe (Dockerfile).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Installing Docker
&lt;/h1&gt;

&lt;p&gt;Download and install Docker Desktop.&lt;/p&gt;

&lt;p&gt;Once the installation is complete, Docker is ready to use.&lt;/p&gt;




&lt;h1&gt;
  
  
  List Images Available on the Local Machine
&lt;/h1&gt;



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

&lt;/div&gt;



&lt;p&gt;This command lists all Docker images available on the local machine.&lt;/p&gt;




&lt;h1&gt;
  
  
  Pull an Image from Docker Hub
&lt;/h1&gt;

&lt;p&gt;If the requested image is not available locally, Docker automatically downloads it from the Docker Registry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker pull hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no tag (version) is specified, Docker downloads the &lt;strong&gt;latest&lt;/strong&gt; version by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker pull hello-world:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To download a specific tagged version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker pull hello-world:nanoserver-ltsc2025
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Create a Container from an Image
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker run hello-world:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  List Containers
&lt;/h1&gt;



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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-a&lt;/code&gt; displays all containers, including exited containers.&lt;/p&gt;




&lt;h1&gt;
  
  
  Interview Questions
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Question 1
&lt;/h3&gt;

&lt;p&gt;What is a Virtual Machine (VM)?&lt;/p&gt;

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

&lt;p&gt;A Virtual Machine is a software emulation of a physical computer. It behaves like a separate computer with its own operating system.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 2
&lt;/h3&gt;

&lt;p&gt;What does a Hypervisor do in virtualization?&lt;/p&gt;

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

&lt;p&gt;A Hypervisor allows multiple virtual machines to run on a single physical host by managing and allocating hardware resources.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 3
&lt;/h3&gt;

&lt;p&gt;What are the advantages of using containers?&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Containers are lightweight.&lt;/li&gt;
&lt;li&gt;Containers start much faster than virtual machines.&lt;/li&gt;
&lt;li&gt;Containers are portable and can run consistently across different environments.&lt;/li&gt;
&lt;li&gt;Containers package only the required dependencies.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Containers share the host operating system kernel. If the host kernel encounters a critical issue, all containers may be affected.&lt;/p&gt;

&lt;p&gt;Virtual machines have separate operating systems. Therefore, if one virtual machine crashes, the others continue to run independently.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 4
&lt;/h3&gt;

&lt;p&gt;Which type of Hypervisor runs directly on physical hardware?&lt;/p&gt;

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

&lt;p&gt;Type 1 Hypervisor.&lt;/p&gt;




&lt;h3&gt;
  
  
  Question 5
&lt;/h3&gt;

&lt;p&gt;What is the difference between a Virtual Machine and a Container?&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Containers share the host operating system kernel.&lt;/li&gt;
&lt;li&gt;Virtual machines run their own operating system on top of a Hypervisor.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Question 6
&lt;/h3&gt;

&lt;p&gt;What is Docker primarily used for?&lt;/p&gt;

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

&lt;p&gt;Docker is primarily used to containerize applications, ensuring portability, consistency, and providing only the minimum required dependencies to run the application.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>basic</category>
      <category>virtualmachine</category>
    </item>
  </channel>
</rss>
