<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[CloudOps Chronicle]]></title><description><![CDATA[CloudOps Chronicle]]></description><link>https://cloudopschronicle.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a884ecd760ba0982d0d3822/5d0817c4-15ab-42d3-992f-161545a75706.jpg</url><title>CloudOps Chronicle</title><link>https://cloudopschronicle.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 31 Aug 2026 16:02:05 GMT</lastBuildDate><atom:link href="https://cloudopschronicle.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building Smaller Docker Images Using Multi-Stage Builds]]></title><description><![CDATA[A practical introduction to Docker Multi-Stage Builds for creating smaller, cleaner, and production-ready container images.
Introduction
Up until now, I had been building simple Flask applications usi]]></description><link>https://cloudopschronicle.hashnode.dev/building-smaller-docker-images-using-multi-stage-builds</link><guid isPermaLink="true">https://cloudopschronicle.hashnode.dev/building-smaller-docker-images-using-multi-stage-builds</guid><category><![CDATA[Docker]]></category><category><![CDATA[Docker compose]]></category><category><![CDATA[docker images]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Manoj Naik]]></dc:creator><pubDate>Wed, 26 Aug 2026 12:16:13 GMT</pubDate><content:encoded><![CDATA[<p><code>A practical introduction to Docker Multi-Stage Builds for creating smaller, cleaner, and production-ready container images.</code></p>
<h3>Introduction</h3>
<p>Up until now, I had been building simple Flask applications using a single Dockerfile. While this approach works, it often results in larger Docker images that contain unnecessary files, build tools, and dependencies.</p>
<p>In real-world environments, organisations aim to:</p>
<ul>
<li><p>Reduce image size</p>
</li>
<li><p>Improve security</p>
</li>
<li><p>Speed up deployments</p>
</li>
<li><p>Optimise container performance</p>
</li>
</ul>
<p>Docker Multi-Stage Builds help achieve these goals.</p>
<p>In this article, I'll show how I built a simple Flask application using a Multi-Stage Dockerfile and explain why this approach is considered a Docker best practice.</p>
<h3>What is a Multi-Stage Build?</h3>
<p>A Multi-Stage Build allows us to use multiple <code>FROM</code> statements within a single Dockerfile.</p>
<p>Typically:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/e2e3c306-42ea-4855-b7b6-887e6c243c9c.png" alt="" style="display:block;margin:0 auto" />

<p>Instead of deploying everything from the build process, only the files required for runtime are copied into the final image.</p>
<h3>Why Use Multi-Stage Builds?</h3>
<p>Benefits include:</p>
<ul>
<li><p>Smaller Image Size</p>
</li>
<li><p>Improved Security</p>
</li>
<li><p>Faster Container Downloads</p>
</li>
<li><p>Faster Deployments</p>
</li>
<li><p>Better Resource Utilisation</p>
</li>
<li><p>Production-Ready Images</p>
</li>
</ul>
<h3>Project Structure</h3>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/77ae77a0-9048-435d-b29e-21e4688ee919.png" alt="" style="display:block;margin:0 auto" />

<h3>Step 1: Create the Flask Application</h3>
<p>Create a file called <a href="http://app.py"><code>app.py</code></a>.</p>
<pre><code class="language-shell">from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return """
    &lt;h1&gt;CloudOps Chronicle&lt;/h1&gt;
    &lt;h2&gt;Docker Multi-Stage Build Demo&lt;/h2&gt;
    """

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
</code></pre>
<p>The application simply displays a welcome page.</p>
<h3>Step 2: Define Dependencies</h3>
<p>Create <code>requirements.txt</code>.</p>
<pre><code class="language-shell">flask
</code></pre>
<p>This file contains the Python package required by the application.</p>
<h3>Step 3: Create a Multi-Stage Dockerfile</h3>
<pre><code class="language-shell"># Stage 1 - Builder

FROM python:3.12 AS builder

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .


# Stage 2 - Runtime

FROM python:3.12-slim

WORKDIR /app

COPY --from=builder /app /app

RUN pip install --no-cache-dir flask

EXPOSE 5000

CMD ["python", "app.py"]
</code></pre>
<h3>Understanding the Dockerfile</h3>
<p>Builder Stage:</p>
<p><code>FROM python:3.12 AS builder</code></p>
<p>The first stage prepares the application environment and installs dependencies.</p>
<p>Runtime Stage:</p>
<p><code>FROM python:3.12-slim</code></p>
<p>A smaller base image is used for running the application. This helps reduce image size.</p>
<p>Copy from Previous Stage:</p>
<p><code>COPY --from=builder /app /app</code></p>
<p>This is the key part of a Multi-Stage Build.</p>
<p>Docker copies only what is needed from the builder stage into the runtime stage.</p>
<h3>Step 4: Build the Image</h3>
<p>Build the Docker image:</p>
<pre><code class="language-shell">docker build -t multi-stage-flask:v1 .
</code></pre>
<p>Verify:</p>
<pre><code class="language-shell">docker images
</code></pre>
<p>Example:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/8a807f7a-0d0b-477b-af7b-2158efc4e495.png" alt="" style="display:block;margin:0 auto" />

<h3>Step 5: Run the Container</h3>
<pre><code class="language-shell">docker run -d \
--name multi-stage-demo \
-p 5000:5000 \
multi-stage-flask:v1
</code></pre>
<p>Verify:</p>
<pre><code class="language-shell">docker ps
</code></pre>
<h3>Step 6: Test the Application</h3>
<pre><code class="language-shell">curl http://localhost:5000
</code></pre>
<h3>Conclusion</h3>
<p>Docker Multi-Stage Builds are a simple but powerful technique for creating efficient container images.</p>
<p>By separating the build process from the runtime environment, we can build smaller, cleaner, and more secure images that are better suited for production deployments.</p>
<p>For anyone learning Docker and preparing for Kubernetes, understanding Multi-Stage Builds is an important step towards mastering containerisation.</p>
<p><strong>Happy Learning!</strong></p>
]]></content:encoded></item><item><title><![CDATA[Understanding Docker Volumes: Persisting Data Beyond Containers]]></title><description><![CDATA[A practical guide to storing application data using Docker Volumes.
Introduction
Containers are designed to be temporary and disposable. This raised an important question:

What happens to application]]></description><link>https://cloudopschronicle.hashnode.dev/understanding-docker-volumes-persisting-data-beyond-containers</link><guid isPermaLink="true">https://cloudopschronicle.hashnode.dev/understanding-docker-volumes-persisting-data-beyond-containers</guid><category><![CDATA[Docker]]></category><category><![CDATA[docker images]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Flask Framework]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Manoj Naik]]></dc:creator><pubDate>Wed, 26 Aug 2026 04:25:40 GMT</pubDate><content:encoded><![CDATA[<p><code>A practical guide to storing application data using Docker Volumes.</code></p>
<h3>Introduction</h3>
<p>Containers are designed to be temporary and disposable. This raised an important question:</p>
<blockquote>
<p>What happens to application data when a container is removed?</p>
</blockquote>
<p>To understand this concept, I built a simple Flask application that stores a visitor counter in a file. I then tested what happens with and without Docker Volumes.</p>
<p>In this article, I'll explain how Docker Volumes help preserve data even when containers are deleted and recreated.</p>
<h3>The Problem</h3>
<p>Example:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/1c3ca111-093c-4ac2-9c05-039d8e36365c.png" alt="" style="display:block;margin:0 auto" />

<p>If the container is removed:</p>
<pre><code class="language-shell">docker rm -f mycontainer
</code></pre>
<p>the data disappears as well.</p>
<p>For applications such as:</p>
<ul>
<li><p>Databases</p>
</li>
<li><p>Log storage</p>
</li>
<li><p>User uploads</p>
</li>
<li><p>Application configuration</p>
</li>
</ul>
<p>This behaviour is not desirable.</p>
<h3>What is a Docker Volume?</h3>
<p>A Docker Volume is a storage mechanism managed by Docker.</p>
<p>Rather than storing data inside the container, data is stored separately on the host.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/5102f542-b7c0-45b6-9081-95c0a7c1884e.png" alt="" style="display:block;margin:0 auto" />

<p>Because the volume exists independently of the container, the data remains available even after the container is removed.</p>
<h3>Project Architecture</h3>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/2e47ef6f-2a42-47e2-bbab-fb3934309c34.png" alt="" style="display:block;margin:0 auto" />

<p>The application stores a simple visit counter inside a file located in a Docker Volume.</p>
<h3>Project Structure</h3>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/88e22c9a-36bf-4d4e-acd9-d2dc6aa487e4.png" alt="" style="display:block;margin:0 auto" />

<h3>Step 1: Create the Flask Application</h3>
<p>Create <a href="http://app.py"><code>app.py</code></a>.</p>
<pre><code class="language-shell">from flask import Flask
import os

app = Flask(__name__)

COUNTER_FILE = "/data/counter.txt"

@app.route('/')
def home():

    if not os.path.exists(COUNTER_FILE):
        with open(COUNTER_FILE, "w") as f:
            f.write("0")

    with open(COUNTER_FILE, "r") as f:
        count = int(f.read())

    count += 1

    with open(COUNTER_FILE, "w") as f:
        f.write(str(count))

    return f"""
    &lt;h1&gt;CloudOps Chronicle&lt;/h1&gt;
    &lt;h2&gt;Docker Volume Demo&lt;/h2&gt;
    &lt;h3&gt;Visits: {count}&lt;/h3&gt;
    """

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
</code></pre>
<p>Each time the page is accessed, the counter value increases and is written to a file.</p>
<h3>Step 2: Create requirements.txt</h3>
<pre><code class="language-shell">flask
</code></pre>
<h3>Step 3: Create the Dockerfile</h3>
<pre><code class="language-shell">FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

RUN mkdir /data

EXPOSE 5000

CMD ["python", "app.py"]
</code></pre>
<p>Build the image:</p>
<pre><code class="language-shell">docker build -t flask-volume:v1 .
</code></pre>
<p>Testing Without a Volume</p>
<pre><code class="language-shell">docker run -d \
--name flask-volume-test \
-p 5000:5000 \
flask-volume:v1
</code></pre>
<p>Access the application:</p>
<pre><code class="language-shell">curl http://localhost:5000
</code></pre>
<p>Example:</p>
<pre><code class="language-shell">Visits: 1
Visits: 2
Visits: 3
</code></pre>
<p>Now remove the container:</p>
<pre><code class="language-shell">docker rm -f flask-volume-test
</code></pre>
<p>Start it again:</p>
<pre><code class="language-shell">docker run -d \
--name flask-volume-test \
-p 5000:5000 \
flask-volume:v1
</code></pre>
<p>The counter starts again from:</p>
<p><code>Visits: 1</code></p>
<p>The data was lost.</p>
<h3>Creating a Docker Volume</h3>
<p>Create a volume:</p>
<pre><code class="language-shell">docker volume create visit-data
</code></pre>
<p>Verify:</p>
<pre><code class="language-shell">docker volume ls
</code></pre>
<h3>Running With a Volume</h3>
<p>Start the container again, this time mounting the volume.</p>
<pre><code class="language-shell">docker run -d \
--name flask-volume-test \
-p 5000:5000 \
-v visit-data:/data \
flask-volume:v1
</code></pre>
<p>The <code>-v</code> option maps the Docker Volume to the <code>/data</code> directory inside the container.</p>
<h3>Verify Data Persistence</h3>
<p>Access the application several times:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/d4727dd7-113a-4fee-b9a7-c35a48ee6480.png" alt="" style="display:block;margin:0 auto" />

<p>Now remove the container:</p>
<pre><code class="language-shell">docker rm -f flask-volume-test
</code></pre>
<p>Create it again:</p>
<pre><code class="language-shell">docker run -d \
--name flask-volume-test \
-p 5000:5000 \
-v visit-data:/data \
flask-volume:v1
</code></pre>
<p>Access the application:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/9522ee34-dc31-4de4-b9f3-49e267c7c435.png" alt="" style="display:block;margin:0 auto" />

<p>The counter continues from the previous value.</p>
<p>Success!</p>
<p>The data survived because it was stored inside the Docker Volume rather than inside the container.</p>
<h3>Inspecting the Volume</h3>
<p>List volumes:</p>
<pre><code class="language-shell">docker volume ls
</code></pre>
<p>Inspect the volume:</p>
<pre><code class="language-shell">docker volume inspect visit-data
</code></pre>
<p>This shows where Docker stores the volume data on the host system.</p>
<h3>Conclusion</h3>
<p>Docker containers are designed to be temporary, but application data should not be.</p>
<p>Docker Volumes provide a simple and effective way to persist data beyond the lifecycle of a container.</p>
<p>Happy Learning!</p>
]]></content:encoded></item><item><title><![CDATA[Running a Flask Application Behind NGINX Using Docker Compose]]></title><description><![CDATA[A hands-on guide to building a multi-container application using Flask, NGINX, and Docker Compose.
Introduction
Most production applications do not expose the application server directly to users. Ins]]></description><link>https://cloudopschronicle.hashnode.dev/running-a-flask-application-behind-nginx-using-docker-compose</link><guid isPermaLink="true">https://cloudopschronicle.hashnode.dev/running-a-flask-application-behind-nginx-using-docker-compose</guid><category><![CDATA[Docker]]></category><category><![CDATA[Docker compose]]></category><category><![CDATA[Flask Framework]]></category><category><![CDATA[nginx]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Manoj Naik]]></dc:creator><pubDate>Tue, 25 Aug 2026 10:25:34 GMT</pubDate><content:encoded><![CDATA[<p><code>A hands-on guide to building a multi-container application using Flask, NGINX, and Docker Compose.</code></p>
<h2>Introduction</h2>
<p>Most production applications do not expose the application server directly to users. Instead, a reverse proxy such as NGINX sits in front of the application and handles incoming requests.</p>
<p>In this project, I built a simple architecture where:</p>
<ul>
<li><p>NGINX receives client requests</p>
</li>
<li><p>NGINX forwards requests to a Flask application</p>
</li>
<li><p>Both services run as separate containers</p>
</li>
<li><p>Docker Compose manages the entire deployment</p>
</li>
</ul>
<h2>Project Architecture</h2>
<pre><code class="language-plaintext">            User
              |
              v
        NGINX Proxy
          Port 80
              |
              v
       Flask Application
          Port 5000
</code></pre>
<p>The user only interacts with NGINX.</p>
<p>NGINX forwards traffic internally to the Flask container.</p>
<h2>Project Structure</h2>
<pre><code class="language-plaintext">nginx-flask/
├── app.py
├── requirements.txt
├── Dockerfile
├── nginx.conf
├── docker-compose.yml
└── README.md
</code></pre>
<h2>Step 1: Create the Flask Application</h2>
<p>Create <a href="http://app.py"><code>app.py</code></a>:</p>
<pre><code class="language-plaintext">from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return """
    &lt;h1&gt;CloudOps Chronicle&lt;/h1&gt;
    &lt;h2&gt;NGINX Reverse Proxy Demo&lt;/h2&gt;
    """

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
</code></pre>
<p>The application listens on port <strong>5000</strong>.</p>
<h2>Step 2: Create requirements.txt</h2>
<pre><code class="language-plaintext">flask
</code></pre>
<p>This file contains the Python dependencies required by the application.</p>
<h2>Step 3: Create the Dockerfile</h2>
<pre><code class="language-plaintext">FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]
</code></pre>
<p>Build the image:</p>
<pre><code class="language-plaintext">docker build -t nginx-flask-web .
</code></pre>
<p>Verify:</p>
<pre><code class="language-plaintext">docker images
</code></pre>
<h2>Step 4: Configure NGINX</h2>
<p>Create <code>nginx.conf</code>:</p>
<pre><code class="language-plaintext">events {}

http {

    server {

        listen 80;

        location / {

            proxy_pass http://web:5000;

        }

    }

}
</code></pre>
<p>The important part is:</p>
<p>proxy_pass <a href="http://web:5000">http://web:5000</a>;</p>
<p>Here:</p>
<ul>
<li><p><code>web</code> is the Docker Compose service name</p>
</li>
<li><p><code>5000</code> is the Flask application port</p>
</li>
</ul>
<p>Docker Compose automatically provides DNS-based service discovery.</p>
<h2>Step 5: Create Docker Compose File</h2>
<p>Create <code>docker-compose.yml</code>:</p>
<pre><code class="language-plaintext">services:

  web:
    image: nginx-flask-web:latest
    container_name: flask-app-1

  nginx:
    image: nginx:latest
    container_name: nginx-proxy

    ports:
      - "80:80"

    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf

    depends_on:
      - web
</code></pre>
<h2>Step 6: Start the Application</h2>
<pre><code class="language-plaintext">docker compose up -d
</code></pre>
<p>Verify:</p>
<pre><code class="language-plaintext">docker ps
</code></pre>
<p>Example output:</p>
<pre><code class="language-plaintext">CONTAINER ID   IMAGE                 NAMES
xxxxxxxx       nginx:latest          nginx-proxy
xxxxxxxx       nginx-flask-web       flask-app
</code></pre>
<h2>Step 7: Test the Application</h2>
<pre><code class="language-plaintext">http://localhost
  or
http://&lt;server-public-ip&gt;
</code></pre>
<p>Although users access port 80, the application is actually running on port 5000.</p>
<p>NGINX handles the forwarding.</p>
<h3>Challenges Faced</h3>
<p>During the implementation, you might encountered a few issues:</p>
<ul>
<li><p>Docker Compose Buildx dependency requirements</p>
</li>
<li><p>Understanding the difference between <code>ports</code> and <code>expose</code></p>
</li>
<li><p>Service discovery between containers</p>
</li>
<li><p>NGINX proxy configuration</p>
</li>
</ul>
<h3>Conclusion</h3>
<p>Running Flask behind NGINX using Docker Compose was an excellent exercise in understanding modern application architecture.</p>
<p>If you're learning Docker, I highly recommend trying this project before moving to Kubernetes.</p>
<p>Happy Learning!</p>
<p>for reference : <a href="https://github.com/h-manojbabu/docker-image-build/tree/main/nginx-flask">https://github.com/h-manojbabu/docker-image-build/tree/main/nginx-flask</a></p>
]]></content:encoded></item><item><title><![CDATA[Building a Multi-Container Flask and Redis Application Using Docker Compose

]]></title><description><![CDATA[After building a static website container and a simple Flask application, I wanted to take the next step to running multiple containers together.
In real-world applications, a single container is rare]]></description><link>https://cloudopschronicle.hashnode.dev/building-a-multi-container-flask-and-redis-application-using-docker-compose</link><guid isPermaLink="true">https://cloudopschronicle.hashnode.dev/building-a-multi-container-flask-and-redis-application-using-docker-compose</guid><category><![CDATA[Docker]]></category><category><![CDATA[dockercompose]]></category><category><![CDATA[Flask Framework]]></category><category><![CDATA[Python]]></category><category><![CDATA[Redis]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Manoj Naik]]></dc:creator><pubDate>Tue, 25 Aug 2026 06:26:49 GMT</pubDate><content:encoded><![CDATA[<p>After building a static website container and a simple Flask application, I wanted to take the next step to running multiple containers together.</p>
<p>In real-world applications, a single container is rarely enough. Applications often need databases, caches, message queues, and supporting services.</p>
<p>In this project, I built a simple Flask application that communicates with a Redis container using Docker Compose.</p>
<p>By the end of this exercise, we can learned:</p>
<p>--&gt;Docker Compose<br />--&gt;Multi-container applications<br />--&gt;Container networking<br />--&gt;Service discovery<br />--&gt;Flask and Redis integration</p>
<p>Why Docker Compose?</p>
<p>Docker Compose allows us to define and run multiple containers as a single application.</p>
<p>Without Docker Compose:</p>
<p><code>Container 1 → Start manually</code></p>
<p><code>Container 2 → Start manually</code></p>
<p><code>Network → Create manually</code></p>
<p><code>Dependencies → Configure manually</code></p>
<p>With Docker Compose:</p>
<p><code>docker compose up -d</code></p>
<p>Everything starts automatically.</p>
<h3>Project Architecture</h3>
<pre><code class="language-plaintext">+-----------------+
| Flask Web App   |
| Port 5000       |
+--------+--------+
         |
         |
         v
+-----------------+
| Redis Database  |
| Port 6379       |
+-----------------+
</code></pre>
<p>The Flask application stores and retrieves a visitor counter from Redis.</p>
<h3>Project Structure</h3>
<pre><code class="language-plaintext">flask-redis/
├── app.py
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
└── README.md
</code></pre>
<h3>Creating the Flask Application</h3>
<p>Create a file named <a href="http://app.py"><code>app.py</code></a>.</p>
<pre><code class="language-plaintext">from flask import Flask
import redis

app = Flask(__name__)

redis_client = redis.Redis(host='redis', port=6379)

@app.route('/')
def index():
    try:
        visits = redis_client.incr('counter')
        return f"""
        &lt;h1&gt;CloudOps Chronicle&lt;/h1&gt;
        &lt;h2&gt;Docker Compose Demo&lt;/h2&gt;
        &lt;h3&gt;Visits: {visits}&lt;/h3&gt;
        """
    except Exception as e:
        return f"Error: {e}"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
</code></pre>
<p>The application increments a counter every time the page is refreshed.</p>
<h3>Defining Dependencies</h3>
<p>Create <code>requirements.txt</code>.</p>
<pre><code class="language-plaintext">flask
redis
</code></pre>
<p>These packages are installed when the Docker image is built.</p>
<h3>Creating the Dockerfile</h3>
<p>Create <code>Dockerfile</code>.</p>
<pre><code class="language-plaintext">FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]
</code></pre>
<h3>Creating Docker Compose Configuration</h3>
<p>Create <code>docker-compose.yml</code>.</p>
<pre><code class="language-plaintext">services:

  web:
    image: flask-redis-web:latest
    container_name: flask-web

    ports:
      - "5000:5000"

    depends_on:
      - redis

  redis:
    image: redis:latest
    container_name: redis-server
</code></pre>
<p>This file defines: Flask container, Redis container, Container Dependencies, Port mapping.</p>
<h3>Building the Application Image</h3>
<p>Build the Flask container image.</p>
<pre><code class="language-plaintext">docker build -t flask-redis-web .
</code></pre>
<p>Verify:</p>
<pre><code class="language-plaintext">docker images
</code></pre>
<p>Example:</p>
<pre><code class="language-plaintext">REPOSITORY         TAG
flask-redis-web    latest
redis              latest
</code></pre>
<h3>Starting the Application</h3>
<p>Launch both containers together.</p>
<pre><code class="language-plaintext">docker compose up -d
</code></pre>
<p>Verify:</p>
<pre><code class="language-plaintext">docker ps
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">CONTAINER ID   IMAGE                    NAMES
265e8b0b5xxx   flask-redis-web:latest   flask-web
fdbf76392xxx   redis:latest             redis-server
</code></pre>
<p>Both services are now running successfully.</p>
<h3>Testing the Application</h3>
<p>Access:</p>
<pre><code class="language-plaintext">http://&lt;server-ip&gt;:5000
</code></pre>
<h3>Checking Container Logs</h3>
<pre><code class="language-plaintext">docker logs flask-web
docker logs redis-server
docker compose logs
</code></pre>
<p>These commands are useful when troubleshooting containerised applications.</p>
<h3>Challenges Faced</h3>
<p><code>During the implementation, I encountered a few issues:</code></p>
<ul>
<li><p><code>Docker Compose plugin compatibility</code></p>
</li>
<li><p><code>Buildx requirements</code></p>
</li>
<li><p><code>Git push conflicts caused by remote repository changes</code></p>
</li>
<li><p><code>Container dependency configuration</code></p>
</li>
</ul>
<h3>Happy Learning!</h3>
]]></content:encoded></item><item><title><![CDATA[Containerising a Python Flask Application Using Docker]]></title><description><![CDATA[After successfully building and publishing a static web page using Docker, I wanted to take the next step by containerising a simple Python Flask application.
In this article, I will walk through crea]]></description><link>https://cloudopschronicle.hashnode.dev/containerising-a-python-flask-application-using-docker</link><guid isPermaLink="true">https://cloudopschronicle.hashnode.dev/containerising-a-python-flask-application-using-docker</guid><dc:creator><![CDATA[Manoj Naik]]></dc:creator><pubDate>Mon, 24 Aug 2026 07:07:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/61969794-ab55-4bcc-918a-f2f1d17e4235.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After successfully building and publishing a static web page using Docker, I wanted to take the next step by containerising a simple Python Flask application.</p>
<p>In this article, I will walk through creating a Flask application, building a Docker image, and running the application inside a container.</p>
<h2>Why Docker?</h2>
<p>Docker allows us to package applications along with their dependencies into a portable container that can run consistently across different environments.</p>
<p>Benefits include:</p>
<ul>
<li><p>Consistent deployments</p>
</li>
<li><p>Simplified dependency management</p>
</li>
<li><p>Faster application delivery</p>
</li>
<li><p>Easy scalability</p>
</li>
</ul>
<p>Project Structure</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a884ecd760ba0982d0d3822/7fe6a7f3-6b4e-4848-9a96-57eb74f7c731.png" alt="" style="display:block;margin:0 auto" />

<h2>Creating the Flask Application</h2>
<p>Create a file named <a href="http://app.py"><code>app.py</code></a>:</p>
<pre><code class="language-plaintext">from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return """
    &lt;h1&gt;Welcome to CloudOps Chronicle&lt;/h1&gt;
    &lt;h2&gt;My First Flask Docker Application&lt;/h2&gt;
    """

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
</code></pre>
<h2>Defining Dependencies</h2>
<p>Create a file named <code>requirements.txt</code>:</p>
<pre><code class="language-plaintext">flask==3.1.2
</code></pre>
<h2>Creating the Dockerfile</h2>
<p>Create a file named <code>Dockerfile</code>:</p>
<pre><code class="language-plaintext">FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]
</code></pre>
<h3>Dockerfile Breakdown</h3>
<ul>
<li><p><strong>FROM</strong> – Uses Python 3.12 slim image as the base image.</p>
</li>
<li><p><strong>WORKDIR</strong> – Sets the application working directory.</p>
</li>
<li><p><strong>COPY</strong> – Copies application files into the image.</p>
</li>
<li><p><strong>RUN</strong> – Installs Flask dependency.</p>
</li>
<li><p><strong>EXPOSE</strong> – Exposes port 5000.</p>
</li>
<li><p><strong>CMD</strong> – Starts the Flask application.</p>
</li>
</ul>
<h2>Building the Docker Image</h2>
<p>Build the image using:</p>
<pre><code class="language-plaintext">docker build -t flask-app:v1 .
</code></pre>
<p>verify the images</p>
<pre><code class="language-plaintext">docker images
</code></pre>
<p>Example output :</p>
<pre><code class="language-plaintext">REPOSITORY   TAG
flask-app    v1
</code></pre>
<h2>Running the Container</h2>
<p>Start the container:</p>
<pre><code class="language-plaintext">docker run -d \
--name flask-app \
-p 5000:5000 \
flask-app:v1
</code></pre>
<p>Verify with :</p>
<pre><code class="language-plaintext">docker ps
</code></pre>
<h2>Testing the Application</h2>
<p>Open a browser and access:</p>
<pre><code class="language-plaintext">http://localhost:5000
</code></pre>
<h2>Viewing Container Logs</h2>
<p>To check application logs:</p>
<pre><code class="language-plaintext">docker logs flask-app
</code></pre>
<p>Thanks .</p>
]]></content:encoded></item><item><title><![CDATA[From Dockerfile to Docker Hub: Building and Publishing My First Docker Image]]></title><description><![CDATA[Introduction
Today, I started my Docker learning journey by creating, running, and publishing my first Docker image.
As someone with a background in infrastructure and cloud operations, I wanted to un]]></description><link>https://cloudopschronicle.hashnode.dev/from-dockerfile-to-docker-hub-building-and-publishing-my-first-docker-image</link><guid isPermaLink="true">https://cloudopschronicle.hashnode.dev/from-dockerfile-to-docker-hub-building-and-publishing-my-first-docker-image</guid><dc:creator><![CDATA[Manoj Naik]]></dc:creator><pubDate>Fri, 21 Aug 2026 13:29:29 GMT</pubDate><content:encoded><![CDATA[<h2>Introduction</h2>
<p>Today, I started my Docker learning journey by creating, running, and publishing my first Docker image.</p>
<p>As someone with a background in infrastructure and cloud operations, I wanted to understand the basics of containerisation before diving deeper into Kubernetes and cloud-native technologies.</p>
<p>In this article, I'll walk through the steps I followed to:</p>
<ul>
<li><p>Create a simple Docker image</p>
</li>
<li><p>Run a container</p>
</li>
<li><p>Push the image to Docker Hub</p>
</li>
<li><p>Store the project in GitHub</p>
</li>
</ul>
<h2>What is Docker?</h2>
<p>Docker is a containerisation platform that helps package an application and its dependencies into a lightweight, portable container.</p>
<p>This allows applications to run consistently across different environments.</p>
<hr />
<h2>Project Structure</h2>
<p>My first project was a simple static web page.</p>
<p>staticwebpage/</p>
<p>├── Dockerfile</p>
<p>├── index.html</p>
<p>└── <a href="http://README.md">README.md</a></p>
<h2>Step 1: Create the Web Page</h2>
<p>I created a simple HTML file:</p>






My First Docker Image





<h1>Hello Docker!</h1>

<p>My first container is running successfully.</p>





<h2>Step 2: Create the Dockerfile</h2>
<p>I used the NGINX image as the base image.</p>
<p>FROM nginx:latest</p>
<p>COPY index.html /usr/share/nginx/html/index.html</p>
<p>EXPOSE 80</p>
<p>CMD ["nginx", "-g", "daemon off;"]</p>
<h2>Step 3: Build the Docker Image</h2>
<p>Build the image using:</p>
<p>docker build -t staticwebpage:v1 .</p>
<p>Verify the image:<br />docker images  </p>
<p>Output:<br />REPOSITORY TAG</p>
<p>staticwebpage v1</p>
<h2>Step 4: Run the Container</h2>
<p>Start the container:</p>
<p>docker run -d -p 8080:80 --name staticwebpage staticwebpage:v1</p>
<p>Access the application:</p>
<p><a href="http://localhost:8080">http://:8080</a></p>
<h2>Conclusion</h2>
<p>Building and publishing my first Docker image was a great learning experience. Docker has become a fundamental skill for modern Infrastructure, Cloud, and DevOps engineers, and I'm excited to continue exploring the ecosystem.</p>
<p>If you're just getting started with Docker, I encourage you to build something simple and learn by doing.</p>
<p>Happy Learning! 🚀</p>
<hr />
<p><strong>Author:</strong> Manoj Naik<br /><strong>Publication:</strong> CloudOps Chronicle<br /><strong>Topics:</strong> Docker, DevOps, Cloud Computing, Linux, Infrastructure Engineering</p>
]]></content:encoded></item></channel></rss>