<?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: Vishal</title>
    <description>The latest articles on DEV Community by Vishal (@vishal_09).</description>
    <link>https://dev.to/vishal_09</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3264118%2Fff42f8ee-14db-4275-809a-8bd4fc8a19f1.jpeg</url>
      <title>DEV Community: Vishal</title>
      <link>https://dev.to/vishal_09</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vishal_09"/>
    <language>en</language>
    <item>
      <title>🚀 Wrapping Up My GitLab CI/CD Journey with 2 Real Projects</title>
      <dc:creator>Vishal</dc:creator>
      <pubDate>Wed, 09 Jul 2025 17:59:37 +0000</pubDate>
      <link>https://dev.to/vishal_09/wrapping-up-my-gitlab-cicd-journey-with-2-real-projects-iog</link>
      <guid>https://dev.to/vishal_09/wrapping-up-my-gitlab-cicd-journey-with-2-real-projects-iog</guid>
      <description>&lt;h2&gt;
  
  
  🛠️ My Hands-On Dive into GitLab CI/CD
&lt;/h2&gt;

&lt;p&gt;Instead of just learning CI/CD concepts in theory, I decided to put them into practice.I built two real pipelines for real apps — one with a Go Backend, another with a Nodejs  — using GitLab CI/CD.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 What I Tried to Do
&lt;/h2&gt;

&lt;p&gt;I worked on two projects to understand GitLab CI/CD in action:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;1: Built a 3-stage pipeline (&lt;strong&gt;Build → Test → Deploy&lt;/strong&gt;) for a &lt;strong&gt;React frontend&lt;/strong&gt; and &lt;strong&gt;Go backend&lt;/strong&gt; app. This helped me automate the entire flow from code to container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;2: Set up and used a &lt;strong&gt;self-hosted GitLab Runner&lt;/strong&gt; to run jobs on my own system. It gave me hands-on experience with job execution and custom runner configurations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project 1 – Full Stack App Pipeline
&lt;/h2&gt;

&lt;p&gt;Work done on &lt;a href="https://gitlab.com/demo_group8185827/full_stack_project" rel="noopener noreferrer"&gt;gitlab_link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this pipeline setup, I used an existing open-source project from GitHub. It’s a &lt;strong&gt;full-stack application&lt;/strong&gt; with a &lt;strong&gt;React frontend&lt;/strong&gt; and a &lt;strong&gt;Go backend&lt;/strong&gt; — a great combo to test out CI/CD workflows.The project simulates a basic web app architecture, making it perfect for understanding how continuous integration and deployment work across both frontend and backend.By using this real-world project, I was able to apply CI/CD concepts practically and troubleshoot challenges that commonly appear in production environments.The project that i have referred - &lt;a href="https://github.com/Shpota/skmz" rel="noopener noreferrer"&gt;Github_link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🐞 Issues I Faced
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;At first, I wrote the CI job script assuming it would just execute like a normal shell environment. But I didn’t know that &lt;strong&gt;GitLab’s SaaS runners&lt;/strong&gt; use &lt;strong&gt;Docker images&lt;/strong&gt; to execute each job.That meant:- The runner didn’t know how to run my commands — because it had &lt;strong&gt;no idea what environment or dependencies were needed&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I wanted to use &lt;code&gt;docker build&lt;/code&gt; inside my pipeline job, but it kept failing. What I didn’t realize is that: You &lt;strong&gt;can’t directly use Docker inside a container&lt;/strong&gt; unless you set it up properly.GitLab SaaS runners run jobs &lt;strong&gt;inside containers&lt;/strong&gt;, and to use Docker commands there, you need a setup called &lt;strong&gt;Docker-in-Docker (DinD)&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;To fix this, I learned about something called &lt;strong&gt;Docker-in-Docker (DinD)&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DinD allows Docker to run &lt;em&gt;inside&lt;/em&gt; a Docker container by connecting to a &lt;strong&gt;Docker daemon&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;By enabling &lt;code&gt;privileged: true&lt;/code&gt; and using the official &lt;code&gt;docker:latest&lt;/code&gt; image along with a service like &lt;code&gt;docker:dind&lt;/code&gt;, I was able to use Docker commands inside my pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a snippet from the working &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker:latest&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker:dind&lt;/span&gt;

&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;DOCKER_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp://docker:2375/&lt;/span&gt;
  &lt;span class="na"&gt;DOCKER_TLS_CERTDIR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;

&lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker info&lt;/span&gt;

&lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker compose build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker compose up -d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is the &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file screenshot&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Project 2 – Using Custom GitLab Runners
&lt;/h2&gt;

&lt;p&gt;Work done on &lt;a href="https://gitlab.com/demo_group8185827/todo_app_from_tws/-/blob/master/.gitlab-ci.yml?ref_type=heads" rel="noopener noreferrer"&gt;Gitlab_link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For my second project, I wanted to explore how GitLab CI/CD can work across multiple environments by using two custom GitLab runners. I set up one runner on my local machine &lt;strong&gt;(Runner dev)&lt;/strong&gt; and another on an AWS EC2 instance &lt;strong&gt;(Runner aws)&lt;/strong&gt;. The goal was to simulate a real-world DevOps workflow where the application is built locally and store the image of application on gitlab artifacts and then deployed remotely.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;Runner dev&lt;/strong&gt; (my local system), I built the Docker image of the Nodejs application and then pushed that image as a build artifact or stored it temporarily. GitLab CI/CD allowed me to pass this artifact between jobs. In the next stage, the job assigned to &lt;strong&gt;Runner aws&lt;/strong&gt; (on AWS) picked up this artifact. There, I used the built image to deploy the app by running the container on the EC2 instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue I Faced
&lt;/h2&gt;

&lt;p&gt;One of the most confusing problems I ran into was that even after modifying my application code and rebuilding the Docker image on Runner dev (my local machine), those changes weren’t showing up when I deployed the app on Runner aws (EC2). I thought deleting the old Docker image and rebuilding it would ensure the latest version got deployed, but somehow the updates weren’t reflected.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Solved the Issue
&lt;/h2&gt;

&lt;p&gt;✅ How I Solved It&lt;br&gt;
After a lot of trial and error, I realized something important GitLab CI with Docker Compose generates images with names like:&lt;br&gt;
&lt;code&gt;&amp;lt;gitlab_folder_name&amp;gt;_&amp;lt;service_name&amp;gt; by default&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Initially, I was deleting the container using the name I gave in docker-compose.yml (via container_name), but that doesn't remove the actual image. So even though I ran:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;…the image still didn’t reflect my recent code changes — because Docker was still using the existing image with the same name.&lt;br&gt;
Solution? I listed the images with docker images, found the correct one (named like todo_app_from_tws_web), and deleted it using:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then I rebuilt the image and re-ran the pipeline — and this time, the new changes were reflected correctly on the deployment side (AWS runner).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.gitlab-ci.yml file of Todo app&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Fdfi5jtazg0gddclvny8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfi5jtazg0gddclvny8p.png" alt=" " width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stages of Pipeline&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2F33opykk3qp6gutr8uffv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33opykk3qp6gutr8uffv.png" alt=" " width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifacts of the project&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Ft9uzsvhlz5ei9iw2tra7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9uzsvhlz5ei9iw2tra7.png" alt=" " width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🟢 And finally... it’s alive!&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Fuonc4wm8h60ba8i5odx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuonc4wm8h60ba8i5odx0.png" alt=" " width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources That Helped Me Along the Way
&lt;/h2&gt;

&lt;p&gt;I didn't figure it all out on my own - these resources were super helpful during the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.gitlab.com/" rel="noopener noreferrer"&gt;gitlab docs&lt;/a&gt; - From Errors to Execution!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=lFfqBxZf-6c" rel="noopener noreferrer"&gt;Youtube Tutorial&lt;/a&gt; - To visually understand the concept.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://google.com" rel="noopener noreferrer"&gt;Google&lt;/a&gt; - For quick searches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're starting out, I highly recommend using these - they make learning much easier!&lt;/p&gt;

&lt;h2&gt;
  
  
  🙌 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Working with GitLab CI/CD pipelines across two different setups taught me more than just YAML and jobs — it showed how real DevOps systems behave in action. From understanding how GitLab SaaS runners execute jobs, to handling image build issues across custom self-hosted runners, this hands-on experience gave me clarity on what goes on behind automated deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  💬 Over to You
&lt;/h2&gt;

&lt;p&gt;Have you worked with GitLab CI/CD pipelines or tried setting up your own runners? Faced any weird issues like Docker not reflecting changes or environment configs acting up?&lt;br&gt;
I’d love to hear how you tackled them — or even if you're just starting out, feel free to reach out!&lt;/p&gt;

&lt;p&gt;Let’s connect and grow together in this DevOps journey:&lt;br&gt;
 Connect on &lt;a href="https://www.linkedin.com/in/vishal-taware-9a1573249/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
 Say hi on &lt;a href="https://x.com/VishalTaware07" rel="noopener noreferrer"&gt;X (Twitter)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>docker</category>
      <category>automation</category>
      <category>devops</category>
    </item>
    <item>
      <title>Running Django &amp; Java Apps in Containers — My Docker Week Recap</title>
      <dc:creator>Vishal</dc:creator>
      <pubDate>Tue, 01 Jul 2025 12:29:32 +0000</pubDate>
      <link>https://dev.to/vishal_09/running-django-java-apps-in-containers-my-docker-week-recap-109o</link>
      <guid>https://dev.to/vishal_09/running-django-java-apps-in-containers-my-docker-week-recap-109o</guid>
      <description>&lt;p&gt;In my DevOps learning journey, I spent this past week diving into Docker — not just understanding the commands, but applying them in real projects.&lt;/p&gt;

&lt;p&gt;This blog summarizes what I built, what I learned, and the small hurdles I faced while containerizing and deploying two full-stack applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚧 What I Tried to Build
&lt;/h2&gt;

&lt;p&gt;I worked on two different projects to get hands-on Docker experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ A Python Django Web Application&lt;/li&gt;
&lt;li&gt;✅ A Java Maven-Based Application&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Project -1: Python Django Web Application
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🔍 What I Tried to Do
&lt;/h4&gt;

&lt;p&gt;For the first project, I took a basic Django app and containerized it using Docker. My goal was to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write a &lt;code&gt;Dockerfile&lt;/code&gt; that sets up Python, dependencies, and the Django project.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;docker-compose.yml&lt;/code&gt; to run both the Django app and a MYSQL database together.&lt;/li&gt;
&lt;li&gt;Set up a reverse proxy using NGINX to expose the app on a clean port (like 8080).&lt;/li&gt;
&lt;li&gt;Make sure everything can be started with just &lt;strong&gt;one command&lt;/strong&gt; using &lt;code&gt;docker-compose up&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project helped me understand how multi-container apps work, how services interact inside a Docker network, and how to troubleshoot startup issues in web apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  🐞 Issues I Faced
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Forgot to Add Containers to the Same Network&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
At first, my app and NGINX couldn’t talk to each other.I didn’t realize that all related containers need to be on the same Docker network to communicate.This tiny thing cost me a lot of time — everything looked okay, but nothing worked until I added the correct network in the &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Database Connection Problems&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
My Django app kept throwing errors when trying to connect to MySQL. After a lot of digging, I found out it was due to small things like incorrect hostnames or missing environment variables.One wrong word in the DB settings was enough to break everything.Lesson learned: always double-check your database config.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Used Wrong Name in NGINX Config&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In the NGINX config, I accidentally used the container name instead of the service name from the Docker Compose file.This gave me “bad gateway” errors. I didn’t know at the time that NGINX looks for the &lt;strong&gt;service name&lt;/strong&gt;, not the container name, when it tries to connect. It seems obvious now, but it wasn’t when I first started — and that’s okay.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ How I Solved Them
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Docker Network Confusion&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Now, whenever I write a &lt;code&gt;docker-compose.yml&lt;/code&gt;, I make sure that all services are assigned to a common network — even if it seems optional at first.This way, containers can talk to each other smoothly without throwing “connection refused” errors.&lt;br&gt;&lt;br&gt;
Here's a small reminder I use now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;
    &lt;span class="s"&gt;networks&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mynetwork&lt;/span&gt;
  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;
    &lt;span class="s"&gt;networks&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mynetwork&lt;/span&gt;
&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mynetwork&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. MySQL Connection Troubles&lt;/strong&gt;&lt;br&gt;
A small typo in your environment variable (like &lt;code&gt;MYSQL_USER&lt;/code&gt;, &lt;code&gt;MYSQL_PASSWORD&lt;/code&gt;, or &lt;code&gt;MYSQL_HOST&lt;/code&gt;) can ruin your day. I spent hours figuring out that my Django app couldn’t talk to &lt;strong&gt;MySQL&lt;/strong&gt; just because I had a wrong key in the env file. Now I double-check every setting and make sure all configs match between app and database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. NGNIX Configuration Issue&lt;/strong&gt;&lt;br&gt;
In the beginning, I was giving the service name inside the &lt;strong&gt;NGINX&lt;/strong&gt; config, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;proxy_pass http://service_name:8000;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which didn’t work.&lt;br&gt;
So I changed it to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;proxy_pass http://container_name:8000;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s how the app looks running inside Docker containers:&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuwfhhqjiqwhjitxzrgs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuwfhhqjiqwhjitxzrgs.png" alt="Containerize the Django App" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Project -2: Java Maven-Based Application
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🔧 What I Tried to Do (Java Maven App)
&lt;/h4&gt;

&lt;p&gt;After successfully containerizing my Django app, I wanted to push myself a little further — this time by working with a Java-based Maven application. The idea was to set up everything inside Docker and manage it through Docker Compose, just like I did with the Django app.But this project came with its own set of new learning curves. Unlike Python, Java applications involve build steps using Maven, so I had to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write a custom Dockerfile that builds the app using Maven and then runs the JAR file.&lt;/li&gt;
&lt;li&gt;Handle MySQL integration inside containers (again), but with a slightly different config structure.&lt;/li&gt;
&lt;li&gt;Configure NGINX to reverse proxy requests to the Java backend.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue I Faced
&lt;/h3&gt;

&lt;p&gt;One of the most confusing parts was figuring out &lt;strong&gt;where the database settings were written&lt;/strong&gt; in the Java Maven project. In Django, it's easy to find — it's in &lt;code&gt;settings.py&lt;/code&gt;. But here, I had to dig around the project folders to finally find the right file.&lt;br&gt;
Even after I updated the database details correctly, the app &lt;strong&gt;still crashed&lt;/strong&gt; — and the logs didn’t help much. Everything seemed fine: all containers were running, and the database was connected. But the app just wouldn't work, and there was &lt;strong&gt;no clear error&lt;/strong&gt; telling me what went wrong.&lt;br&gt;
And Issue was like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Exception &lt;span class="k"&gt;in &lt;/span&gt;thread &lt;span class="s2"&gt;"main"&lt;/span&gt; java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed at
     com.mysql.cj.jdbc.exceptions.SQLError.createSQLException&lt;span class="o"&gt;(&lt;/span&gt;SQLError.java:108&lt;span class="o"&gt;)&lt;/span&gt; at 
     com.mysql.cj.jdbc.exceptions.SQLError.createSQLException&lt;span class="o"&gt;(&lt;/span&gt;SQLError.java:95&lt;span class="o"&gt;)&lt;/span&gt; at
     com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException&lt;span class="o"&gt;(&lt;/span&gt;SQLExceptionsMapping.java:122&lt;span class="o"&gt;)&lt;/span&gt; at     
     com.mysql.cj.jdbc.ConnectionImpl.createNewIO&lt;span class="o"&gt;(&lt;/span&gt;ConnectionImpl.java:862&lt;span class="o"&gt;)&lt;/span&gt; at 
     com.mysql.cj.jdbc.ConnectionImpl.&lt;span class="o"&gt;(&lt;/span&gt;ConnectionImpl.java:444&lt;span class="o"&gt;)&lt;/span&gt; at
     com.mysql.cj.jdbc.ConnectionImpl.getInstance&lt;span class="o"&gt;(&lt;/span&gt;ConnectionImpl.java:230&lt;span class="o"&gt;)&lt;/span&gt; at
     com.mysql.cj.jdbc.NonRegisteringDriver.connect&lt;span class="o"&gt;(&lt;/span&gt;NonRegisteringDriver.java:226&lt;span class="o"&gt;)&lt;/span&gt; at
     com.mysql.cj.jdbc.MysqlDataSource.getConnection&lt;span class="o"&gt;(&lt;/span&gt;MysqlDataSource.java:438&lt;span class="o"&gt;)&lt;/span&gt; at
     com.mysql.cj.jdbc.MysqlDataSource.getConnection&lt;span class="o"&gt;(&lt;/span&gt;MysqlDataSource.java:146&lt;span class="o"&gt;)&lt;/span&gt; at
     com.mysql.cj.jdbc.MysqlDataSource.getConnection&lt;span class="o"&gt;(&lt;/span&gt;MysqlDataSource.java:119&lt;span class="o"&gt;)&lt;/span&gt; at
     ConnectionManager.getConnection&lt;span class="o"&gt;(&lt;/span&gt;ConnectionManager.java:28&lt;span class="o"&gt;)&lt;/span&gt; at
     Main.main&lt;span class="o"&gt;(&lt;/span&gt;Main.java:8&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ How I Solved It
&lt;/h3&gt;

&lt;p&gt;After spending quite some time googling and going through Stack Overflow posts, I finally discovered that the &lt;strong&gt;database configuration&lt;/strong&gt; was located in a file called &lt;code&gt;application.properties&lt;/code&gt; inside the path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src/main/resources/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file had keys like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.datasource.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:mysql://mysql:3306/expenses_tracker?useSSL=false&amp;amp;serverTimezone=UTC&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.username&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Test@123&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.driver-class-name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;com.mysql.cj.jdbc.Driver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, I added these database credentials under the environment section of the Java service in the &lt;strong&gt;docker-compose.yml&lt;/strong&gt; file.&lt;br&gt;
But… even after that, the app still wouldn’t come up.&lt;br&gt;
Eventually, I found a &lt;a href="https://stackoverflow.com/questions/50379839/connection-java-mysql-public-key-retrieval-is-not-allowed" rel="noopener noreferrer"&gt;Stack Overflow&lt;/a&gt; post that pointed out an important issue — Java MySQL drivers block public key retrieval by default, which can silently break DB connections.&lt;br&gt;
So, I updated the URL to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spring.datasource.url&lt;span class="o"&gt;=&lt;/span&gt;jdbc:mysql://mysql:3306/expenses_tracker?allowPublicKeyRetrieval&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;amp;useSSL&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: Setting allowPublicKeyRetrieval=true is helpful in development environments but can be a security risk in production. Use it with caution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After making this change and rebuilding the containers, the Java app finally started working! 🎉&lt;br&gt;
Here’s how the app looks running inside Docker containers:&lt;/p&gt;

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

&lt;h3&gt;
  
  
  📚 Resources That Helped Me Along the Way
&lt;/h3&gt;

&lt;p&gt;I didn’t figure it all out on my own — these resources were super helpful during the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💡 &lt;a href="https://stackoverflow.com/" rel="noopener noreferrer"&gt;Stack Overflow&lt;/a&gt; – For finding answers to weird bugs and errors.&lt;/li&gt;
&lt;li&gt;🎥 &lt;a href="https://www.youtube.com/watch?v=9bSbNNH4Nqw&amp;amp;list=PLlfy9GnSVerQjeoYfoYKEMS1yKl89NOvL&amp;amp;index=4" rel="noopener noreferrer"&gt;YouTube Tutorial&lt;/a&gt; – To visually understand Docker concepts and how to structure files.&lt;/li&gt;
&lt;li&gt;🔍 &lt;a href="https://google.com" rel="noopener noreferrer"&gt;Google&lt;/a&gt; – My go-to for quick searches, Docker docs, and troubleshooting steps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're starting out, I highly recommend using these — they make learning much easier!&lt;/p&gt;

&lt;h3&gt;
  
  
  🙌 Wrapping Up
&lt;/h3&gt;

&lt;p&gt;This project taught me a lot about how Docker actually works when you're building and running real apps. From setting up services to fixing bugs that didn’t even show clear errors — it was frustrating at times, but also really fun to solve.&lt;br&gt;
I made mistakes, looked things up, and slowly started to understand how all the pieces fit together. And honestly, that’s how real learning happens. If you're just starting out like me — keep going, you're doing great! 😄&lt;/p&gt;




&lt;h4&gt;
  
  
  ❓ Over to You
&lt;/h4&gt;

&lt;p&gt;Have you tried using Docker to run your own apps? Did you also face any weird issues that took hours to figure out?&lt;br&gt;
I’d love to hear your story! Feel free to drop a comment — and let’s connect on &lt;a href="https://x.com/VishalTaware07" rel="noopener noreferrer"&gt;X&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/vishal-taware-9a1573249/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; if you’re also learning Docker, DevOps, or backend stuff.&lt;/p&gt;

&lt;p&gt;Thanks for reading - see you in the next blog!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>containers</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🔒 My EC2 Instance Froze — No SSH, No Web CLI. Here's What Caused It (and How I Fixed It)</title>
      <dc:creator>Vishal</dc:creator>
      <pubDate>Tue, 24 Jun 2025 18:57:28 +0000</pubDate>
      <link>https://dev.to/vishal_09/my-ec2-instance-froze-no-ssh-no-web-cli-heres-what-caused-it-and-how-i-fixed-it-1317</link>
      <guid>https://dev.to/vishal_09/my-ec2-instance-froze-no-ssh-no-web-cli-heres-what-caused-it-and-how-i-fixed-it-1317</guid>
      <description>&lt;p&gt;Today I want to share something unexpected I faced — a stuck EC2 instance that wouldn’t respond to SSH or even the AWS Web CLI. It took me a while to figure out what was wrong, but I learned a lot through the process. If you’re new to AWS or DevOps like me, this might save you some stress!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 The Problem
&lt;/h2&gt;

&lt;p&gt;Everything seemed fine at first. But suddenly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I couldn’t SSH into my EC2 instance&lt;/li&gt;
&lt;li&gt;The Web CLI also wouldn’t connect&lt;/li&gt;
&lt;li&gt;The EC2 instance showed as “running” in the console&lt;/li&gt;
&lt;li&gt;Docker containers were running inside from the last few days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first, I thought it was just a temporary glitch. But even after stopping and starting the instance again, &lt;strong&gt;nothing worked.&lt;/strong&gt; I was stuck.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 The Root Cause
&lt;/h2&gt;

&lt;p&gt;After digging deeper (and asking ChatGPT!), I learned that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My EC2 instance was a &lt;strong&gt;t2.micro&lt;/strong&gt;, which uses &lt;strong&gt;CPU credits&lt;/strong&gt; to manage performance.&lt;/li&gt;
&lt;li&gt;I had left &lt;strong&gt;Docker containers running&lt;/strong&gt; for several days.&lt;/li&gt;
&lt;li&gt;This drained my &lt;strong&gt;CPU credit balance to 0&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;When CPU credits are gone, AWS throttles the CPU to 10% — which makes SSH and Web CLI &lt;strong&gt;unusable&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This completely locked me out of my instance. I couldn’t even access it to shut down Docker.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 The Solution That Worked
&lt;/h2&gt;

&lt;p&gt;Here’s how I fixed it without terminating the instance:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Launch a Temporary EC2 Instance
&lt;/h3&gt;

&lt;p&gt;I created a &lt;strong&gt;new t2.micro&lt;/strong&gt; with the same OS as my original instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Detach the Volume
&lt;/h3&gt;

&lt;p&gt;From the AWS Console, I &lt;strong&gt;detached the root volume&lt;/strong&gt; from my stuck instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Attach It to the New Instance
&lt;/h3&gt;

&lt;p&gt;I then &lt;strong&gt;attached the volume&lt;/strong&gt; to the temporary instance as a secondary disk (e.g. &lt;code&gt;/dev/xvdf&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Mount the Volume
&lt;/h3&gt;

&lt;p&gt;I mounted the volume and created a rescue directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; /mnt/rescue
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount /dev/xvdf1 /mnt/rescue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then mounted other required filesystems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;--bind&lt;/span&gt; /dev /mnt/rescue/dev
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;--bind&lt;/span&gt; /sys /mnt/rescue/sys
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;--bind&lt;/span&gt; /proc /mnt/rescue/proc

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Enter chroot Environment
&lt;/h3&gt;

&lt;p&gt;This allowed me to "enter" the original system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chroot&lt;/span&gt; /mnt/rescue

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Disable Docker
&lt;/h3&gt;

&lt;p&gt;Inside the chroot environment, I disabled Docker from auto-starting:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then I exited the chroot:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Reattach the Volume
&lt;/h3&gt;

&lt;p&gt;I detached the volume from the temporary instance and re-attached it to the original EC2 instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Reboot and Success 🎉
&lt;/h3&gt;

&lt;p&gt;Now, when I started the instance, SSH worked again because Docker didn’t start, and the system wasn’t overloaded.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Always monitor CPU credits if you're using t2.micro or burstable instances.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don’t keep containers running forever unless you have a strong reason.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's possible to rescue a stuck instance without deleting it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS chroot rescue method is a powerful trick.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to ChatGPT, I saved hours and didn’t lose my data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-credits-baseline-concepts.html" rel="noopener noreferrer"&gt;AWS CPU Credit Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chat.openai.com/" rel="noopener noreferrer"&gt;ChatGPT 😉 &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Over to You
&lt;/h2&gt;

&lt;p&gt;Have you ever faced something like this?&lt;br&gt;
How do you monitor or avoid issues like this with EC2 or Docker?&lt;/p&gt;

&lt;p&gt;Let’s discuss below or connect with me:&lt;br&gt;
🔗 &lt;a href="https://x.com/VishalTaware07" rel="noopener noreferrer"&gt;x&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/vishal-taware-9a1573249/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading — see you in the next blog! 👋&lt;/p&gt;

</description>
      <category>docker</category>
      <category>aws</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>7 Days of Shell Scripting: My First Step into DevOps Automation</title>
      <dc:creator>Vishal</dc:creator>
      <pubDate>Sat, 14 Jun 2025 06:34:44 +0000</pubDate>
      <link>https://dev.to/vishal_09/7-days-of-shell-scripting-my-first-step-into-devops-automation-2mon</link>
      <guid>https://dev.to/vishal_09/7-days-of-shell-scripting-my-first-step-into-devops-automation-2mon</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;p&gt;On &lt;strong&gt;June 7, 2025&lt;/strong&gt;, I took my first real step into the world of DevOps.I had just wrapped up a crash course in Linux, and I was curious: &lt;strong&gt;"What if I could automate the boring stuff I was doing manually?"&lt;/strong&gt;&lt;br&gt;
That question led me to Shell Scripting. Instead of watching endless tutorials, I gave myself a challenge:  &lt;strong&gt;1 week. 2 real projects. Let’s see what I can build.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This blog captures that journey — the good, the broken, and the lessons.&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ Project 1: Deploying a Django App Using Shell Script
&lt;/h2&gt;

&lt;p&gt;🗂️ &lt;strong&gt;GitHub Link&lt;/strong&gt;: &lt;a href="https://github.com/V0ix/Shell_Scripting/blob/main/deploy_djangoapp_using_bashscript.sh" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  🔍 What I Tried to Build
&lt;/h3&gt;

&lt;p&gt;I wanted to automate the deployment process of a Django app using a single Shell script.&lt;br&gt;&lt;br&gt;
The goal was to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone a GitHub repo&lt;/li&gt;
&lt;li&gt;Set up Docker and Docker Compose&lt;/li&gt;
&lt;li&gt;Build and run the app containers with a single command&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  💡 What I Learned
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;importance of breaking down a task&lt;/strong&gt; into smaller steps using functions — like cloning a repo, checking dependencies, building containers, and running them.&lt;/li&gt;
&lt;li&gt;How to use &lt;strong&gt;Shell commands like &lt;code&gt;cd&lt;/code&gt;, &lt;code&gt;git clone&lt;/code&gt;, &lt;code&gt;if&lt;/code&gt; conditions&lt;/strong&gt;, and &lt;code&gt;echo&lt;/code&gt; for logging inside scripts.&lt;/li&gt;
&lt;li&gt;Learned how to &lt;strong&gt;add logic&lt;/strong&gt; like.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"myapp"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Directory already exists. Skipping clone."&lt;/span&gt;
   &lt;span class="k"&gt;else
    &lt;/span&gt;git clone &amp;lt;repo-url&amp;gt;
   &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Most important thing i learned while deploying the django app is Error Handling.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ❗ Issues I Faced
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Script didn’t execute&lt;/strong&gt; because I forgot to give it execute permission using &lt;code&gt;chmod +x deploy.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Directory already existed&lt;/strong&gt; when I ran the script a second time, which caused &lt;code&gt;git clone&lt;/code&gt; to fail. I had to learn how to add checks to prevent duplicate actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Docker daemon wasn't running&lt;/strong&gt;, so the &lt;code&gt;docker build&lt;/code&gt; command failed with errors. I didn’t realize Docker needs to be started manually or as a service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Docker image naming mistakes&lt;/strong&gt; I initially wrote &lt;code&gt;docker build -t . myapp&lt;/code&gt; instead of the correct &lt;code&gt;docker build -t myapp .&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. No error handling at first&lt;/strong&gt; my script would continue even if a step failed. For example, if &lt;code&gt;git clone&lt;/code&gt; or &lt;code&gt;docker build&lt;/code&gt; failed, the next steps still ran, which made debugging harder.I didn’t realize how important it is to stop the script when something breaks, or at least handle the failure properly.I also forgot to check if commands actually succeeded before moving on, like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; git clone &amp;lt;repo-url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;no check here — even if it fails, the script moves forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ How I Solved Them
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Missing Execute Permission&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I realized that shell scripts need execute permission. I ran:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;chmod&lt;/span&gt; +x deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This allowed the script to run directly with &lt;code&gt;./deploy.sh&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Directory Already Exists Error&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I added a check to see if the folder was already present before cloning:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"django-notes-app"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Directory already exists. Skipping clone."&lt;/span&gt;
&lt;span class="k"&gt;else
&lt;/span&gt;git clone &amp;lt;repo-url&amp;gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Docker Daemon Not Running&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I learned to start the Docker daemon manually using:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Incorrect Docker Build Command&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initially, I mixed up the syntax. Corrected it to:
&lt;/li&gt;
&lt;/ul&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;-t&lt;/span&gt; notes-app &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. No Error Handling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Started using this format to catch and report errors:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;repo-url&amp;gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Git clone failed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ Project 2: Automating AWS EC2 Instance Creation Using Shell Script
&lt;/h2&gt;

&lt;p&gt;🗂️ &lt;strong&gt;GitHub Link&lt;/strong&gt;: &lt;a href="https://github.com/V0ix/Shell_Scripting/blob/main/creating_aws_ec2_intance_bashscript.sh" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 What I Tried to Build
&lt;/h3&gt;

&lt;p&gt;In this project, I wanted to &lt;strong&gt;automate the process of launching an EC2 instance on AWS&lt;/strong&gt; using a simple Bash script — no manual clicks on the AWS Console.&lt;/p&gt;

&lt;p&gt;The goal was to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install AWS CLI&lt;/strong&gt; (if not already installed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create an EC2 instance&lt;/strong&gt; using required parameters like AMI ID, instance type, key pair, subnet ID, and security group&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wait until the instance is in a running state&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle basic error checking&lt;/strong&gt; and output helpful logs throughout the process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I treated this as a real-world mini DevOps task — automating infrastructure provisioning using shell scripting and AWS CLI. This helped me understand how cloud resources can be managed programmatically and how to handle dynamic situations in automation.&lt;/p&gt;

&lt;h3&gt;
  
  
  📘 What I Learned
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validate Before You Automate&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Skipping checks for things like empty AMI IDs or missing subnets led to broken scripts. I learned to always validate user inputs before running any cloud commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IAM Permissions Can Make or Break Automation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Even if the script is correct, missing permissions can silently block EC2 creation. Understanding IAM policies helped me debug smarter and faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clarity in Output Makes Debugging Easier&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Adding clear and structured log messages (&lt;code&gt;[INFO]&lt;/code&gt;, &lt;code&gt;[ERROR]&lt;/code&gt;, etc.) helped me understand what the script was doing at each step — and where it was going wrong.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🐞 Issues I Faced
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Running Script Without Setting Required AWS Parameters&lt;/strong&gt; In the initial version of the script, I left variables like &lt;code&gt;AMI_ID&lt;/code&gt;, &lt;code&gt;SUBNET_ID&lt;/code&gt;, and &lt;code&gt;SECURITY_GROUP_IDS&lt;/code&gt; as empty strings. This caused AWS CLI commands to fail with confusing or unhelpful error messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;An error occurred &lt;span class="o"&gt;(&lt;/span&gt;InvalidAMIID.Malformed&lt;span class="o"&gt;)&lt;/span&gt; when calling the RunInstances operation: Invalid &lt;span class="nb"&gt;id&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Missing IAM Permissions for EC2 Actions&lt;/strong&gt; Even though the script was syntactically correct, it failed to create an instance because the AWS user didn’t have the necessary EC2 permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;You are not authorized to perform this operation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. No Status Feedback During Execution&lt;/strong&gt; The script initially lacked logs or progress messages, which made it hard to trace which part was executing or where exactly it failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Script Continued Execution After Failure&lt;/strong&gt; When AWS CLI wasn’t installed or a command failed, the script still continued, which caused additional errors and wasted time.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ How I Solved Them
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Empty or Incorrect Parameters&lt;/strong&gt;&lt;br&gt;
 I added clear variable assignments in the main function of the script and make sure to never leave them empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;AMI_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ami-0abcd1234example"&lt;/span&gt;        
&lt;span class="nv"&gt;SUBNET_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"subnet-0123example"&lt;/span&gt;
&lt;span class="nv"&gt;SECURITY_GROUP_IDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"sg-0123example"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Missing IAM Permissions&lt;/strong&gt;&lt;br&gt;
I updated the IAM user by attaching the AmazonEC2FullAccess managed policy in the AWS Console.&lt;br&gt;
Then I tested access with a simple command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-instances
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Lack of Logging or Debug Output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I introduced [INFO], [ERROR], and progress messages before and after major steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[INFO] AWS CLI is installed."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[INFO] Creating EC2 instance..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Script Continued Even After Failure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used proper condition checks and exit 1 to safely stop the script if something wasn’t right.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;check_aws_cli&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; which aws &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ERROR] AWS CLI is not installed."&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;1
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[INFO] AWS CLI is installed."&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

main&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; check_aws_cli&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;install_aws_cli
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; check_aws_cli&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ERROR] AWS CLI install failed. Exiting..."&lt;/span&gt;
            &lt;span class="nb"&gt;exit &lt;/span&gt;1
        &lt;span class="k"&gt;fi
    fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📚 Resources That Helped Me Along the Way
&lt;/h3&gt;

&lt;p&gt;I didn’t figure everything out on my own — here are some awesome resources that guided me through this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/ec2/" rel="noopener noreferrer"&gt;AWS EC2 Documentation&lt;/a&gt;&lt;br&gt;&lt;br&gt;
The official AWS documentation was my go-to source for understanding how EC2 instances work and the parameters needed to launch one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/" rel="noopener noreferrer"&gt;AWS CLI User Guide&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Helped me structure commands properly and understand how the CLI interacts with various AWS services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=9Xl1ZTk3BQw&amp;amp;t=10644s" rel="noopener noreferrer"&gt;YouTube: Shell Scripting in One Shot&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Gave me a clear foundation on how to use conditionals, functions, and error handling in shell scripts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to explore these if you're starting out or building something similar.&lt;/p&gt;

&lt;h3&gt;
  
  
  🙌 Wrapping Up
&lt;/h3&gt;

&lt;p&gt;This was a fun and challenging week exploring how powerful Bash can be when combined with AWS CLI. I learned a lot by building, breaking, and fixing things — and I’m just getting started on this DevOps journey.&lt;/p&gt;

&lt;h4&gt;
  
  
  ❓ Over to You
&lt;/h4&gt;

&lt;p&gt;Have you ever tried automating cloud tasks with Bash or any other scripting language?  What was the biggest challenge you faced, or what tools made it easier for you?&lt;br&gt;
Let me know in the comments or connect with me on &lt;a href="https://x.com/VishalTaware07" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/vishal-taware-9a1573249/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; — I’d love to hear your experience!&lt;/p&gt;

&lt;p&gt;Thanks for reading — see you in the next blog! 👋&lt;/p&gt;

</description>
      <category>devops</category>
      <category>bash</category>
      <category>aws</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
