<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Devops on Daffa Abhipraya</title><link>https://blog.abhipraya.dev/tags/devops/</link><description>Recent content in Devops on Daffa Abhipraya</description><generator>Hugo</generator><language>en-us</language><copyright>© Daffa Abhipraya</copyright><lastBuildDate>Sat, 11 Apr 2026 00:00:00 +0700</lastBuildDate><atom:link href="https://blog.abhipraya.dev/tags/devops/index.xml" rel="self" type="application/rss+xml"/><item><title>PPL: Self-Hosted Error Monitoring with Custom Instrumentation</title><link>https://blog.abhipraya.dev/ppl/part-a/monitoring/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0700</pubDate><guid>https://blog.abhipraya.dev/ppl/part-a/monitoring/</guid><description>&lt;p>Error monitoring is one of those things that feels optional until the first production bug slips through unnoticed. A user reports &amp;ldquo;the page is broken,&amp;rdquo; you check the server, everything looks fine, and three hours later you discover a background task has been silently failing since the last deploy. This blog covers how we built monitoring that catches those failures before users do.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Note:&lt;/strong> Our project is hosted on an internal GitLab instance, so we use the term &lt;strong>MR (Merge Request)&lt;/strong> throughout this blog. If you&amp;rsquo;re coming from GitHub, MRs are the equivalent of &lt;strong>Pull Requests (PRs)&lt;/strong>.&lt;/p></description></item><item><title>PPL: New Learnings Applied to SIRA [Sprint 2, Week 1]</title><link>https://blog.abhipraya.dev/ppl/part-c/s2w1-aptitude/</link><pubDate>Mon, 30 Mar 2026 00:00:00 +0700</pubDate><guid>https://blog.abhipraya.dev/ppl/part-c/s2w1-aptitude/</guid><description>&lt;h2 id="overview">
 &lt;a class="anchor" href="#overview" data-anchor="overview" aria-hidden="true">#&lt;/a>
 Overview
&lt;/h2>
&lt;p>Sprint 2 Week 1 (Mar 24 to 30) combined feature development with infrastructure hardening. The week produced two full-stack features (multi-device session management and email integration), a developer tooling improvement (Superset workspace isolation), and iterative CI quality gate improvements. Each required learning at least one technology from scratch.&lt;/p>
&lt;hr>
&lt;h2 id="1-multi-device-session-management">
 &lt;a class="anchor" href="#1-multi-device-session-management" data-anchor="1-multi-device-session-management" aria-hidden="true">#&lt;/a>
 1. Multi-Device Session Management
&lt;/h2>
&lt;p>SIRA needed per-device session tracking: users should see which devices are logged in, and admins should be able to revoke sessions remotely. This isn&amp;rsquo;t a standard Supabase Auth feature; it required a custom session layer on top of the existing JWT auth.&lt;/p></description></item><item><title>PPL: Building an Integrated Tool Ecosystem for a 9-Person University Team</title><link>https://blog.abhipraya.dev/ppl/part-a/teamwork-tools/</link><pubDate>Thu, 12 Mar 2026 00:00:00 +0700</pubDate><guid>https://blog.abhipraya.dev/ppl/part-a/teamwork-tools/</guid><description>&lt;h2 id="why-tooling-is-a-team-problem-not-a-devops-problem">
 &lt;a class="anchor" href="#why-tooling-is-a-team-problem-not-a-devops-problem" data-anchor="why-tooling-is-a-team-problem-not-a-devops-problem" aria-hidden="true">#&lt;/a>
 Why Tooling Is a Team Problem, Not a DevOps Problem
&lt;/h2>
&lt;p>Most university software engineering courses teach you &lt;em>which&lt;/em> tools to use (Git for version control, Jira for tickets, Docker for deployment). What they rarely teach is &lt;strong>how tools interact with each other&lt;/strong>, and what happens when they don&amp;rsquo;t.&lt;/p>
&lt;p>In a professional environment, a single commit can trigger a cascade: CI runs tests, a Slack bot notifies the team, a coverage report lands in SonarQube, and the ticket moves to &amp;ldquo;In Review&amp;rdquo; on the project board. This doesn&amp;rsquo;t happen by accident. Someone has to build that integration layer, and in a university team, that someone is usually whoever cares enough about developer experience to do it.&lt;/p></description></item><item><title>PPL: New Learnings Applied to SIRA [Sprint 1, Week 3]</title><link>https://blog.abhipraya.dev/ppl/part-c/s1w3-aptitude/</link><pubDate>Tue, 10 Mar 2026 00:00:00 +0700</pubDate><guid>https://blog.abhipraya.dev/ppl/part-c/s1w3-aptitude/</guid><description>&lt;h2 id="overview">
 &lt;a class="anchor" href="#overview" data-anchor="overview" aria-hidden="true">#&lt;/a>
 Overview
&lt;/h2>
&lt;p>Sprint 1 Week 3 (Mar 4 to 10) was infrastructure-heavy. The project needed production-grade tooling that goes well beyond standard coursework: reverse proxies, email alerting, migration safety nets, security scanning, structured logging, and AI-integrated code quality analysis. Each of these required learning a new technology from scratch and applying it directly to the project.&lt;/p>
&lt;hr>
&lt;h2 id="1-nginx-reverse-proxy-for-subdomain-routing">
 &lt;a class="anchor" href="#1-nginx-reverse-proxy-for-subdomain-routing" data-anchor="1-nginx-reverse-proxy-for-subdomain-routing" aria-hidden="true">#&lt;/a>
 1. Nginx Reverse Proxy for Subdomain Routing
&lt;/h2>
&lt;p>SIRA runs three services on a single Nashta VM, each needing its own subdomain:&lt;/p></description></item><item><title>PPL: Static Analysis in SIRA [Sprint 1, Week 2]</title><link>https://blog.abhipraya.dev/ppl/part-b/s1w2-code-quality/</link><pubDate>Wed, 04 Mar 2026 00:00:00 +0700</pubDate><guid>https://blog.abhipraya.dev/ppl/part-b/s1w2-code-quality/</guid><description>&lt;h2 id="the-tool-stack">
 &lt;a class="anchor" href="#the-tool-stack" data-anchor="the-tool-stack" aria-hidden="true">#&lt;/a>
 The Tool Stack
&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Layer&lt;/th>
 &lt;th>Tool&lt;/th>
 &lt;th>Scope&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Frontend lint + format&lt;/td>
 &lt;td>&lt;a href="https://biomejs.dev">Biome&lt;/a>&lt;/td>
 &lt;td>TypeScript/TSX, 40+ enforced rules&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Frontend dead code&lt;/td>
 &lt;td>&lt;a href="https://knip.dev">Knip&lt;/a>&lt;/td>
 &lt;td>Unused exports, imports, dependencies&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Frontend types&lt;/td>
 &lt;td>&lt;code>tsc --noEmit&lt;/code>&lt;/td>
 &lt;td>TypeScript type checking&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Backend lint + format&lt;/td>
 &lt;td>&lt;a href="https://docs.astral.sh/ruff/">Ruff&lt;/a>&lt;/td>
 &lt;td>Python, F401/F841 + style rules&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Backend types&lt;/td>
 &lt;td>&lt;a href="https://mypy.readthedocs.io">mypy&lt;/a>&lt;/td>
 &lt;td>Python static types, strict mode&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CI quality gate&lt;/td>
 &lt;td>&lt;a href="https://sonarqube.cs.ui.ac.id">SonarQube&lt;/a>&lt;/td>
 &lt;td>Coverage, code smells, security hotspots&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="pre-commit-hooks-husky">
 &lt;a class="anchor" href="#pre-commit-hooks-husky" data-anchor="pre-commit-hooks-husky" aria-hidden="true">#&lt;/a>
 Pre-commit Hooks (Husky)
&lt;/h2>
&lt;p>Five checks run sequentially on every &lt;code>git commit&lt;/code>. A failure at any step blocks the commit:&lt;/p></description></item></channel></rss>