<?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: Om Patil</title>
    <description>The latest articles on DEV Community by Om Patil (@om_patil).</description>
    <link>https://dev.to/om_patil</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%2F3270735%2F57940bd5-c754-46de-9887-a73109ac0cf3.jpg</url>
      <title>DEV Community: Om Patil</title>
      <link>https://dev.to/om_patil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/om_patil"/>
    <language>en</language>
    <item>
      <title>Step-by-Step Deployment Guide for Spring Boot Services on Ubuntu Server with CI/CD &amp; Reverse Proxy</title>
      <dc:creator>Om Patil</dc:creator>
      <pubDate>Thu, 19 Jun 2025 13:56:18 +0000</pubDate>
      <link>https://dev.to/om_patil/step-by-step-deployment-guide-for-spring-boot-services-on-ubuntu-server-with-cicd-reverse-proxy-1lb6</link>
      <guid>https://dev.to/om_patil/step-by-step-deployment-guide-for-spring-boot-services-on-ubuntu-server-with-cicd-reverse-proxy-1lb6</guid>
      <description>&lt;p&gt;🧭 Overview&lt;br&gt;
In this guide, I’ll walk you through a complete deployment pipeline for Spring Boot services using GitHub Actions, Ubuntu servers, and Nginx. We'll deploy two environments—Dev and Prod—on separate servers and configure:&lt;/p&gt;

&lt;p&gt;✅ Systemd-based service management&lt;br&gt;
✅ Auto-start on reboot&lt;br&gt;
✅ Reverse proxy with Nginx&lt;br&gt;
✅ CI/CD using GitHub Actions&lt;br&gt;
✅ Branch-based deployment:&lt;br&gt;
→ Push to dev → Deploys to Dev server&lt;br&gt;
→ Push to main → Deploys to Prod server&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      ┌────────────┐
      │ Static IP  │
      │ your-ip    │
      └────┬───────┘
           │
    ┌──────┴──────┐
    │  Reverse    │
    │   Proxy     │
    │   (Nginx)   │
    └────┬───────┘
  ┌──────┴───────┐
  │              │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;┌─────▼─────┐   ┌────▼─────┐&lt;br&gt;
│ Dev Server│   │ Prod Server│&lt;br&gt;
│your-ip    │   │  your-ip   |&lt;br&gt;
│ Port 8081 │   │ Port 8082  │&lt;br&gt;
└───────────┘   └────────────┘&lt;/p&gt;

&lt;p&gt;🔧 1. Initial Server Setup&lt;br&gt;
✅ Install Java 21&lt;br&gt;
sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y&lt;br&gt;
sudo apt install openjdk-21-jdk -y&lt;br&gt;
java -version&lt;/p&gt;

&lt;p&gt;📁 Create App Directory&lt;br&gt;
mkdir ~/apps&lt;br&gt;
cd ~/apps&lt;/p&gt;

&lt;p&gt;📦 2. Deploy Spring Boot Applications&lt;br&gt;
Upload your JARs to respective servers:&lt;/p&gt;

&lt;p&gt;scp dev-app.jar ubuntu@your-ip:/home/ubuntu/apps/&lt;br&gt;
scp prod-app.jar ubuntu@your-ip:/home/ubuntu/apps/&lt;/p&gt;

&lt;p&gt;⚙️ 3. Create systemd Services&lt;br&gt;
Use environment variables for better flexibility.&lt;/p&gt;

&lt;p&gt;🔑 Create Environment Files&lt;br&gt;
On Dev Server:&lt;br&gt;
echo "SERVER_PORT=8081" &amp;gt; /home/ubuntu/apps/dev.env&lt;/p&gt;

&lt;p&gt;On Prod Server:&lt;br&gt;
echo "SERVER_PORT=8082" &amp;gt; /home/ubuntu/apps/prod.env&lt;/p&gt;

&lt;p&gt;🧪 Dev Service: /etc/systemd/system/dev-app.service&lt;br&gt;
[Unit]&lt;br&gt;
Description=Spring Boot Dev Application&lt;br&gt;
After=network.target&lt;/p&gt;

&lt;p&gt;[Service]&lt;br&gt;
User=ubuntu&lt;br&gt;
WorkingDirectory=/home/ubuntu/apps&lt;br&gt;
EnvironmentFile=/home/ubuntu/apps/dev.env&lt;br&gt;
ExecStart=/usr/bin/java -jar /home/ubuntu/apps/dev-app.jar --server.port=${SERVER_PORT}&lt;br&gt;
SuccessExitStatus=143&lt;br&gt;
Restart=always&lt;br&gt;
RestartSec=5&lt;br&gt;
StandardOutput=file:/home/ubuntu/apps/dev-output.log&lt;br&gt;
StandardError=file:/home/ubuntu/apps/dev-error.log&lt;/p&gt;

&lt;p&gt;[Install]&lt;br&gt;
WantedBy=multi-user.target&lt;br&gt;
Repeat similarly for prod-app.service with prod.env.&lt;/p&gt;

&lt;p&gt;▶️ 4. Enable and Start Services&lt;br&gt;
sudo systemctl daemon-reload&lt;br&gt;
sudo systemctl enable dev-app       # On Dev Server&lt;br&gt;
sudo systemctl enable prod-app      # On Prod Server&lt;/p&gt;

&lt;p&gt;sudo systemctl start dev-app&lt;br&gt;
sudo systemctl start prod-app&lt;/p&gt;

&lt;p&gt;✅ 5. Verify Deployment&lt;br&gt;
Check status:&lt;br&gt;
systemctl status dev-app&lt;br&gt;
systemctl status prod-app&lt;/p&gt;

&lt;p&gt;Test API:&lt;br&gt;
curl http://:8081/endpoint&lt;br&gt;
curl http://:8082/endpoint&lt;/p&gt;

&lt;p&gt;🔄 6. CI/CD: Auto-Deploy with GitHub Actions&lt;br&gt;
Create workflow files for each branch.&lt;/p&gt;

&lt;p&gt;Example: .github/workflows/deploy-dev.yml&lt;br&gt;
on:&lt;br&gt;
  push:&lt;br&gt;
    branches: [dev]&lt;/p&gt;

&lt;p&gt;jobs:&lt;br&gt;
  deploy:&lt;br&gt;
    runs-on: ubuntu-latest&lt;br&gt;
    steps:&lt;br&gt;
      - name: Copy JAR to Dev Server&lt;br&gt;
        uses: appleboy/scp-action@master&lt;br&gt;
        with:&lt;br&gt;
          host: ${{ secrets.DEV_HOST }}&lt;br&gt;
          username: ubuntu&lt;br&gt;
          key: ${{ secrets.SSH_KEY }}&lt;br&gt;
          source: target/dev-app.jar&lt;br&gt;
          target: /home/ubuntu/apps/dev-app.jar&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - name: Restart Dev App
    uses: appleboy/ssh-action@master
    with:
      host: ${{ secrets.DEV_HOST }}
      username: ubuntu
      key: ${{ secrets.SSH_KEY }}
      script: sudo systemctl restart dev-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Repeat similarly for main branch → Prod server.&lt;/p&gt;

&lt;p&gt;📜 7. Logging with Rotation&lt;br&gt;
Logs are stored at:&lt;/p&gt;

&lt;p&gt;/home/ubuntu/apps/dev-output.log&lt;/p&gt;

&lt;p&gt;/home/ubuntu/apps/prod-output.log&lt;/p&gt;

&lt;p&gt;📦 Add Log Rotation&lt;br&gt;
Create /etc/logrotate.d/dev-app:&lt;/p&gt;

&lt;p&gt;/home/ubuntu/apps/dev-output.log {&lt;br&gt;
    daily&lt;br&gt;
    rotate 7&lt;br&gt;
    compress&lt;br&gt;
    missingok&lt;br&gt;
    notifempty&lt;br&gt;
    copytruncate&lt;br&gt;
}&lt;br&gt;
Repeat for prod-output.log.&lt;/p&gt;

&lt;p&gt;🛡️ 8. Security Best Practices&lt;br&gt;
Enable UFW firewall:&lt;/p&gt;

&lt;p&gt;sudo ufw allow 22&lt;br&gt;
sudo ufw allow 80&lt;br&gt;
sudo ufw allow 8081&lt;br&gt;
sudo ufw allow 8082&lt;br&gt;
sudo ufw enable&lt;br&gt;
Disable root SSH login&lt;/p&gt;

&lt;p&gt;Keep servers updated regularly&lt;/p&gt;

&lt;p&gt;Use GitHub Secrets for all sensitive credentials&lt;/p&gt;

&lt;p&gt;🌐 9. Optional: Reverse Proxy with Nginx&lt;br&gt;
Install Nginx on your reverse proxy server:&lt;/p&gt;

&lt;p&gt;sudo apt install nginx -y&lt;/p&gt;

&lt;p&gt;Create config: /etc/nginx/sites-available/reverse-proxy&lt;br&gt;
server {&lt;br&gt;
    listen 80;&lt;br&gt;
    server_name your-ip;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;location /dev/ {
    proxy_pass http://your-ip:8081/;
    proxy_set_header Host $host;
}

location /prod/ {
    proxy_pass http://your-ip:8082/;
    proxy_set_header Host $host;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;Enable and restart:&lt;br&gt;
sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/&lt;br&gt;
sudo nginx -t&lt;br&gt;
sudo systemctl restart nginx&lt;/p&gt;

&lt;p&gt;Test:&lt;br&gt;
&lt;a href="http://your-ip/dev/hello" rel="noopener noreferrer"&gt;http://your-ip/dev/hello&lt;/a&gt; → Dev&lt;br&gt;
&lt;a href="http://your-ip/prod/hello" rel="noopener noreferrer"&gt;http://your-ip/prod/hello&lt;/a&gt; → Prod&lt;/p&gt;

&lt;p&gt;🧠 Pro Tips for Production&lt;br&gt;
Health Check : Use /actuator/health endpoint and restart if it fails&lt;br&gt;
Monitoring : Use htop, glances, or Prometheus + Grafana&lt;br&gt;
Docker (Optional) : Containerize apps to simplify deployment&lt;br&gt;
Secrets : Always use .env files or GitHub Secrets&lt;br&gt;
Recovery : Keep previous .jar backups or use versioned deployment folders&lt;/p&gt;

&lt;p&gt;🏁 Conclusion&lt;br&gt;
With this setup, you’ve built a complete, secure, and automated deployment pipeline for Spring Boot services:&lt;/p&gt;

&lt;p&gt;Branch-based CI/CD deployment&lt;/p&gt;

&lt;p&gt;Nginx reverse proxy with clean routing&lt;/p&gt;

&lt;p&gt;Auto-restarting apps&lt;/p&gt;

&lt;p&gt;Centralized logging with rotation&lt;/p&gt;

&lt;p&gt;Optional Docker support for scaling later&lt;/p&gt;

&lt;p&gt;📢 If this helped you, give a ❤️ or comment below!&lt;br&gt;
Follow me for more hands-on guides in DevOps, Linux, and Java 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dockerizing a Spring Boot Microservice on WSL: My Learning Journey</title>
      <dc:creator>Om Patil</dc:creator>
      <pubDate>Wed, 18 Jun 2025 12:36:16 +0000</pubDate>
      <link>https://dev.to/om_patil/dockerizing-a-spring-boot-microservice-on-wsl-my-learning-journey-2lgf</link>
      <guid>https://dev.to/om_patil/dockerizing-a-spring-boot-microservice-on-wsl-my-learning-journey-2lgf</guid>
      <description>&lt;p&gt;Recently, I Dockerized my Spring Boot microservice and ran it successfully using &lt;strong&gt;WSL (Windows Subsystem for Linux)&lt;/strong&gt;. I also connected it to a &lt;strong&gt;PostgreSQL database running on my Windows host&lt;/strong&gt;. It wasn't all smooth sailing—but I learned a ton, and I'm sharing it here to help fellow developers!&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ My Environment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OS&lt;/strong&gt;: Windows 10 with WSL (Ubuntu)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App&lt;/strong&gt;: Spring Boot Microservice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: PostgreSQL on Windows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: Docker, Maven&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📦 Step-by-Step Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Create a Dockerfile
&lt;/h3&gt;

&lt;p&gt;Here's the &lt;code&gt;Dockerfile&lt;/code&gt; I used to containerize my app:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Dockerfile
FROM openjdk:23-jdk-slim
WORKDIR /app
COPY target/myservice.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
✅ Tip: I used openjdk:23-jdk-slim because my app runs on Java 23.

2️⃣ Build the JAR
I packaged my Spring Boot app using:
mvn clean package -DskipTests

I initially tried ./mvnw but switched to mvn since I already had Maven installed on WSL.

3️⃣ Build the Docker Image
docker build -t jwt-service .

This built my custom image containing the application JAR.

4️⃣ Database Connectivity Challenge
Initially, I used this in application.properties:

spring.datasource.url=jdbc:postgresql://host.docker.internal:5432/myservice_db
But it failed inside WSL.

✅ Fix: I got my actual local IP using ipconfig on Windows and updated it:

spring.datasource.url=jdbc:postgresql://my_ip:5432/myservice_db
5️⃣ PostgreSQL Access Errors
I ran into these issues:

❌ Connection timed out

❌ no pg_hba.conf entry for host...

Fixes:

Edited pg_hba.conf to allow my IP.

Set listen_addresses = '*' in postgresql.conf.

Restarted PostgreSQL on Windows.

Tested it using a temporary PostgreSQL container:

docker run --rm -it postgres:16 psql -h my_ip -U postgres -d myservice_db
Worked perfectly!

6️⃣ Running the App in Docker
docker run -p 8080:8080 --name myservice-container myservice-service
Accessed the API at:
http://localhost:8080/myservice/service

7️⃣ Keep Container Running After Closing WSL
I used -d to run the container in the background:

docker run -d -p 8080:8080 --name jwt-container jwt-service

Or detached from a live container with:

Ctrl + P then Ctrl + Q

🚪 This keeps the container running while exiting the terminal.

🔍 What I Learned
✅ How to Dockerize a Spring Boot app
✅ How to connect from WSL Docker to host PostgreSQL
✅ How to configure pg_hba.conf and postgresql.conf
✅ Using psql inside a container to test connectivity
✅ Running containers in detached mode

🧠 What’s Next?
I plan to fully Dockerize the database as well, and eventually use Docker Compose to orchestrate the full microservice stack.

🙌 Final Thoughts
This wasn't just about Docker commands—it was about solving real-world issues like network configs, file access, and container persistence. I hope this helps someone else facing similar issues.

Feel free to drop your feedback or ask any questions in the comments!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>Learning Linux Commands: A Game-Changer for DevOps on Windows Using WSL</title>
      <dc:creator>Om Patil</dc:creator>
      <pubDate>Tue, 17 Jun 2025 12:48:41 +0000</pubDate>
      <link>https://dev.to/om_patil/learning-linux-commands-a-game-changer-for-devops-on-windows-using-wsl-579g</link>
      <guid>https://dev.to/om_patil/learning-linux-commands-a-game-changer-for-devops-on-windows-using-wsl-579g</guid>
      <description>&lt;p&gt;As someone working in a DevOps environment, I recently started diving into the world of Linux commands—and wow, it’s been a revelation! Whether you’re setting up CI/CD pipelines, configuring servers, or managing Docker containers, Linux is at the heart of everything DevOps.&lt;/p&gt;

&lt;p&gt;But here's the twist: I work on a Windows machine. So how did I manage to get hands-on with Linux? The answer is: WSL (Windows Subsystem for Linux).&lt;/p&gt;

&lt;p&gt;🐧 Why WSL is a Blessing for DevOps Engineers on Windows&lt;br&gt;
WSL allows you to run a full Linux distribution right inside Windows without needing to dual boot or spin up a virtual machine. You get the power and flexibility of Linux while keeping your existing Windows setup.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;Run Linux CLI tools natively&lt;/p&gt;

&lt;p&gt;Use bash scripts, SSH, Git, Docker, etc.&lt;/p&gt;

&lt;p&gt;Access both Linux and Windows files&lt;/p&gt;

&lt;p&gt;Faster and lighter than a VM&lt;/p&gt;

&lt;p&gt;If you're a DevOps engineer using Windows, WSL is your best friend!&lt;/p&gt;

&lt;p&gt;🧠 Linux Commands I Learned (and Why They Matter)&lt;br&gt;
Here are some fundamental Linux commands I learned, along with how they help in day-to-day DevOps tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;cd – Change Directory&lt;br&gt;
cd /path/to/directory&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Navigate between project folders, configuration directories, or log file locations. Knowing your way around the filesystem is essential.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ls – List Files and Directories&lt;br&gt;
ls -l&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Check what's inside a directory, view permissions, timestamps, and file sizes—especially useful when debugging deployment folders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;grep – Search Text in Files&lt;br&gt;
grep "ERROR" logs.txt&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Find errors in huge log files quickly. Combine with tail or cat for log analysis during debugging or monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tail – View the End of a File&lt;br&gt;
tail -n 50 app.log&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Quickly view the latest logs. Perfect for checking what just went wrong in a running application or pipeline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;chmod and chown – Manage Permissions&lt;br&gt;
chmod +x script.sh&lt;br&gt;
chown user:group file.txt&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Control who can execute scripts or access sensitive config files. Crucial for script execution and security in servers or CI/CD workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ps and kill – Manage Processes&lt;br&gt;
ps aux | grep java&lt;br&gt;
kill -9 1234&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Check which processes are consuming resources and kill any stuck or zombie processes—especially handy while managing apps or services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;df and du – Check Disk Space&lt;br&gt;
df -h&lt;br&gt;
du -sh /var/log&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Monitor disk usage to prevent your server from going down due to lack of space—a common issue in cloud-hosted environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;scp and ssh – Secure Copy and Remote Access&lt;br&gt;
scp file.txt user@server:/path&lt;br&gt;
ssh user@server&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Transfer files to/from servers and log into remote machines to troubleshoot or deploy applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;docker – Container Management&lt;br&gt;
docker ps&lt;br&gt;
docker exec -it container_name bash&lt;br&gt;
📌 Why it's useful:&lt;br&gt;
Interact with running containers, debug issues, and manage containerized services—a core part of DevOps.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⚡ Pro Tip: Combine Commands for Superpowers&lt;br&gt;
You can chain commands using pipes (|) or logical operators (&amp;amp;&amp;amp;, ||) to build powerful one-liners:&lt;/p&gt;

&lt;p&gt;ps aux | grep nginx | awk '{print $2}' | xargs kill -9&lt;br&gt;
The above command finds and kills all nginx-related processes. &lt;br&gt;
DevOps magic!&lt;/p&gt;

&lt;p&gt;✨ Final Thoughts&lt;br&gt;
Linux commands are not just something to memorize—they are tools that give you control, speed, and flexibility as a DevOps engineer. And if you're on Windows, don't let that stop you: install WSL, and start practicing today.&lt;/p&gt;

&lt;p&gt;The more you use it, the more natural it becomes—and the more effective you’ll be in managing infrastructure, automating tasks, and solving real-world problems.&lt;/p&gt;

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