Setting Up CI/CD with GitHub Actions Self-Hosted Runner (And Everything That Broke Along the Way)

I finally did it. After weeks of manually SSHing into my production server, pulling Docker images, and restarting containers like it’s 2015, I set up a proper CI/CD pipeline for my hobby project. The goal was simple: push to main, and everything deploys automatically. The journey? Not so simple. Here’s everything I learned. The Setup My project Sudden is a monorepo with: Backend: Spring Boot application Frontend: React application Infrastructure: MongoDB, Redis, all orchestrated with Docker Compose Deployment: Single production server running everything Before this, my deployment process looked like: ...

January 17, 2026

Volumes in DevOps: Learning the Hard Way

How I learned to stop losing data and started using persistent storage When you’re new to DevOps, you make mistakes. I made several. The biggest one? Running an application with all its data stored directly on the instance, assuming it would always be there. The Problem: Data Loss I spun up an instance, cloned my hobby project from GitHub, built the application, and opened it to the internet. Everything worked fine. But I didn’t understand one critical thing: where was my data living? ...

December 20, 2025

Understanding CIDR Notation in IP Addresses

You know that devices on a network have IP addresses like 192.168.1.5, right? Each device gets its own unique address so data knows where to go. Now, here’s the real-world problem that CIDR notation solves: Imagine you’re setting up a home network with 10 devices. You need to tell your router: “These 10 IP addresses all belong to MY network, and everything else is outside my network.” You could list all 10 addresses individually: ...

October 28, 2025

Automating SSL Renewals: Saving Time and Avoiding Expired Certificates

(Inspired by the automation setup shown in the post shared — 47 SSL certificates renewed automatically, 32 engineer hours saved per year, and zero expired certificates.) https://x.com/brankopetric00/status/1980779147635888396 The Pain We All Know Every 90 days, the same calendar reminder would pop up: “Renew SSL certificates.” That used to mean two hours of tedious work — generating a new CSR, getting it signed, uploading it to our load balancer, and praying we didn’t break anything in production. ...

October 22, 2025

Spring Boot Release Types Explained

Stable (3.5.6) Recommended for production environments Fully tested and reliable Current stable version: 3.5.6 Milestone (4.0.0-M3) Early preview of upcoming features Not recommended for production use Useful for testing new functionality before final release Current milestone version: 4.0.0-M3 Snapshot Ongoing development builds Unstable and may contain bugs Represents the very latest code changes Not suitable for production environments Older Releases (3.4.x) Still usable in existing applications Missing latest updates, improvements, and security patches Consider upgrading to newer stable versions when possible Recommendation: Always use stable releases for production environments. Explore milestone versions only if you want to test upcoming features. ...

October 10, 2025

Understanding CORS: Same-Origin Policy and Handling Cross-Origin Requests

Every web developer has at some point seen the dreaded red error: “Access to fetch at ‘http://localhost:8081’ from origin ‘http://localhost:5173’ has been blocked by CORS policy…” Let’s unpack why this happens, why the browser enforces it, and how to handle it cleanly in both development and production. 🧩 What Is an Origin? An origin is defined as the combination of: scheme + domain + port Examples: https://example.com → Origin A https://api.example.com → Origin B (different subdomain) http://localhost:5173 → Origin C (different port) If any of these differ, you’re dealing with cross-origin access. ...

October 10, 2025

Proxy vs Reverse Proxy: Understanding the Differences

A proxy is a middle server that acts on someone’s behalf. It forwards requests and responses instead of letting the two parties talk directly. Forward Proxy Stands in for: the client Flow: Client → proxy → internet Purpose: hides the user, controls access, adds privacy or caching Example: a company proxy that filters employee web traffic Reverse Proxy Stands in for: the server Flow: Client → reverse proxy → backend servers Purpose: hides servers, balances load, adds security, handles SSL Example: Nginx receiving requests before passing them to app servers The “Stands In” Idea Forward proxy = pretends to be the client Reverse proxy = pretends to be the server Final takeaway: ...

September 27, 2025

Understanding JWT: A Simplified Tech Overview

Understanding JWT: A Simplified Tech Overview 🚀 Let’s break down JWT (JSON Web Token) simply and clearly, step-by-step, just like a casual tech chat! 1. What is JWT? 🤔 JWT (JSON Web Token) is a secure, compact, URL-friendly token format used for safely exchanging information between two systems. It’s commonly used for: Authentication: Confirming who you are. Authorization: Checking permissions for accessing resources. Imagine JWT as your digital ID card issued by servers to clients. ...

March 8, 2025

ISO-8601 Duration Format in a Nutshell

ISO-8601 standardizes how we represent durations in a compact, unambiguous way. The basic structure for durations is: P[n]Y[n]M[n]DT[n]H[n]M[n]S Breakdown: P: Marks the start of the duration period. [n]Y: Number of years. [n]M: Number of months (before the T separator). [n]W: Number of weeks. [n]D: Number of days. T: Separates the date components from the time components. [n]H: Number of hours. [n]M: Number of minutes (after T, M now means minutes). [n]S: Number of seconds. Quick Examples: ...

February 3, 2025

Multiple Git Accounts: Managing Different Credentials

How to Push Your Local Git Repository to a Personal Account and Manage Multiple Configurations Managing Git repositories can sometimes get tricky, especially when you’re switching between accounts (like an organization and a personal account). This guide walks you through the process of pushing your local repository to a remote origin and ensuring the correct account credentials are used. Step 1: Initialize Git and Push to a Remote Repository 1. Create a Remote Repository Go to your Git hosting platform (e.g., GitHub, GitLab, Bitbucket). Create a new repository and copy its URL (e.g., https://github.com/username/repository.git). 2. Link Your Local Repo to the Remote If you’ve already initiated Git locally, link it to your remote repository using: ...

January 17, 2025