<?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: Korak Kurani</title>
    <description>The latest articles on DEV Community by Korak Kurani (@korak997).</description>
    <link>https://dev.to/korak997</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%2F1609672%2F1bcfcb74-1f81-4def-9659-b6e99b7e800c.png</url>
      <title>DEV Community: Korak Kurani</title>
      <link>https://dev.to/korak997</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/korak997"/>
    <language>en</language>
    <item>
      <title>Home Lab Hero: Exposing Local Services Safely without Port Forwarding</title>
      <dc:creator>Korak Kurani</dc:creator>
      <pubDate>Sat, 14 Mar 2026 20:04:06 +0000</pubDate>
      <link>https://dev.to/korak997/home-lab-hero-exposing-local-services-safely-without-port-forwarding-51gd</link>
      <guid>https://dev.to/korak997/home-lab-hero-exposing-local-services-safely-without-port-forwarding-51gd</guid>
      <description>&lt;h1&gt;
  
  
  Building a Secure Private Cloud in 2026: Coolify, Directus &amp;amp; Cloudflare Tunnels
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How I stopped opening ports on my router and built a three-layer fortress for my home server — no VPN, no exposed IP, no compromise.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Problem: The "Home Server" Headache
&lt;/h2&gt;

&lt;p&gt;We've all been there.&lt;/p&gt;

&lt;p&gt;You've spent a Sunday afternoon setting up a beautiful self-hosted service on your local machine — maybe a headless CMS like Directus, a media server like Jellyfin, or a custom internal tool you've been hacking on for weeks. It works perfectly on your home network. Then you step out to a café, pull out your phone, and the illusion shatters. You can't access it. You're locked out of your own creation.&lt;/p&gt;

&lt;p&gt;The traditional solutions are uncomfortable at best and dangerous at worst:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Port forwarding&lt;/strong&gt; means punching holes in your router's firewall, directly exposing your home IP address to the public internet. One misconfigured service and you have a serious problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CGNAT (Carrier-Grade NAT)&lt;/strong&gt; is increasingly common with ISPs and makes traditional port forwarding outright impossible for many users. Your router isn't even the outermost layer anymore — your ISP is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic DNS&lt;/strong&gt; solves the changing-IP problem but does nothing for the security issues above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A VPN like WireGuard&lt;/strong&gt; is a solid approach, but it requires you to remember to activate it on every device, every time. It's friction, and friction leads to bad habits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There had to be a better way. In 2026, there is — and this post walks through exactly how I built it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Philosophy: A Three-Layer Fortress
&lt;/h2&gt;

&lt;p&gt;Before diving into the technical steps, it's worth understanding the &lt;em&gt;design philosophy&lt;/em&gt; behind this stack. Instead of reacting to security threats, we're building a system that is secure by default — where every layer reinforces the next.&lt;/p&gt;

&lt;p&gt;Think of it like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Orchestrator&lt;/strong&gt; manages and deploys your services cleanly, in isolated containers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Application&lt;/strong&gt; is your actual service, running privately with no public exposure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Bridge&lt;/strong&gt; creates an outbound-only, encrypted tunnel to the internet — so traffic reaches you without anyone ever knowing where "you" are.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the modern private cloud stack. Here's what each layer looks like in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 🧩 Coolify — The Orchestrator
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://coolify.io" rel="noopener noreferrer"&gt;Coolify&lt;/a&gt; is a self-hosted Platform-as-a-Service (PaaS) that brings the developer experience of platforms like Heroku or Railway to your own hardware. It wraps Docker and Docker Compose in a clean web UI, so you can deploy, manage, monitor, and update containerised applications with a few clicks — no memorising &lt;code&gt;docker-compose&lt;/code&gt; flags required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Coolify instead of managing Docker directly?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual dashboard for all running services&lt;/li&gt;
&lt;li&gt;Built-in environment variable management&lt;/li&gt;
&lt;li&gt;One-click deployments and redeployments&lt;/li&gt;
&lt;li&gt;Automatic container health monitoring&lt;/li&gt;
&lt;li&gt;Log streaming directly in the browser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For anyone running more than one or two services on a home server, Coolify is transformative. It turns container orchestration from a chore into a pleasant experience.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. 🗄️ Directus — The Data Engine
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://directus.io" rel="noopener noreferrer"&gt;Directus&lt;/a&gt; is an open-source headless CMS and data platform. Unlike traditional CMS platforms that dictate your content structure, Directus wraps around any SQL database and instantly generates a REST and GraphQL API. It's database-first, meaning your data is never locked in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Directus?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexible, schema-agnostic data modelling&lt;/li&gt;
&lt;li&gt;Auto-generated REST &amp;amp; GraphQL APIs&lt;/li&gt;
&lt;li&gt;A beautiful, intuitive admin UI&lt;/li&gt;
&lt;li&gt;Role-based access control out of the box&lt;/li&gt;
&lt;li&gt;Works seamlessly with PostgreSQL, MySQL, SQLite, and more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this project, Directus serves as the content backend — the place where all data lives and is managed. It's the thing we ultimately want to access securely from anywhere in the world.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. 🌐 Cloudflare Tunnels — The Bridge
&lt;/h3&gt;

&lt;p&gt;This is the secret sauce. &lt;a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/" rel="noopener noreferrer"&gt;Cloudflare Tunnels&lt;/a&gt; (formerly Cloudflare Argo Tunnel) allows you to expose a locally running service to the internet &lt;strong&gt;without opening a single port on your router&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here's the magic: instead of the internet &lt;em&gt;coming to you&lt;/em&gt;, your server &lt;em&gt;reaches out&lt;/em&gt; to Cloudflare. The &lt;code&gt;cloudflared&lt;/code&gt; daemon running on your machine establishes a persistent, encrypted, outbound-only connection to Cloudflare's global edge network. When a user visits your domain, Cloudflare routes the request through that tunnel to your local machine — without ever knowing (or exposing) your real IP address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Cloudflare Tunnels?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero inbound ports required — works even behind CGNAT&lt;/li&gt;
&lt;li&gt;Your home IP is completely hidden from the public&lt;/li&gt;
&lt;li&gt;Free SSL/TLS certificates, automatically managed&lt;/li&gt;
&lt;li&gt;Integrates natively with Cloudflare's Zero Trust access controls&lt;/li&gt;
&lt;li&gt;Runs as a lightweight, containerised daemon&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step-by-Step: Building the Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1 — Deploying Directus with Coolify
&lt;/h3&gt;

&lt;p&gt;The first phase is getting Directus up and running locally, managed by Coolify.&lt;/p&gt;

&lt;h4&gt;
  
  
  Installing Coolify
&lt;/h4&gt;

&lt;p&gt;Coolify is designed to run on a fresh Linux server or even a local machine. Installation is a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://cdn.coollabs.io/coolify/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once running, access the Coolify dashboard at &lt;code&gt;http://your-server-ip:8000&lt;/code&gt; and complete the initial setup. From here, everything is managed through the UI.&lt;/p&gt;

&lt;h4&gt;
  
  
  Deploying Directus via Docker Compose
&lt;/h4&gt;

&lt;p&gt;In Coolify, create a new service and select &lt;strong&gt;Docker Compose&lt;/strong&gt; as the deployment method. Use a compose file similar to the following:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:15-alpine&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;directus&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;supersecretpassword&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;directus&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres_data:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;directus"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

  &lt;span class="na"&gt;directus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;directus/directus:latest&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8055:8055"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-random-key-here"&lt;/span&gt;
      &lt;span class="na"&gt;SECRET&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-random-secret-here"&lt;/span&gt;
      &lt;span class="na"&gt;DB_CLIENT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg"&lt;/span&gt;
      &lt;span class="na"&gt;DB_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database"&lt;/span&gt;
      &lt;span class="na"&gt;DB_PORT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432"&lt;/span&gt;
      &lt;span class="na"&gt;DB_DATABASE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;directus"&lt;/span&gt;
      &lt;span class="na"&gt;DB_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;directus"&lt;/span&gt;
      &lt;span class="na"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;supersecretpassword"&lt;/span&gt;
      &lt;span class="na"&gt;ADMIN_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin@example.com"&lt;/span&gt;
      &lt;span class="na"&gt;ADMIN_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-admin-password"&lt;/span&gt;
      &lt;span class="na"&gt;PUBLIC_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://cms.yourdomain.com"&lt;/span&gt;  &lt;span class="c1"&gt;# ← Critical!&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;directus_uploads:/directus/uploads&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;directus_uploads&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ⚠️ The Critical &lt;code&gt;PUBLIC_URL&lt;/code&gt; Setting
&lt;/h4&gt;

&lt;p&gt;The single most important environment variable here is &lt;code&gt;PUBLIC_URL&lt;/code&gt;. Directus uses this value to construct absolute URLs for things like password reset emails, file previews, and the Admin UI's API calls.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;PUBLIC_URL&lt;/code&gt; is set to &lt;code&gt;http://localhost:8055&lt;/code&gt; but you access Directus via &lt;code&gt;https://cms.yourdomain.com&lt;/code&gt;, the admin panel will make API calls to the wrong address and break in subtle, confusing ways. &lt;strong&gt;Set this to your final public domain from the start.&lt;/strong&gt; In our case, that will be the domain we configure through Cloudflare.&lt;/p&gt;

&lt;p&gt;Once deployed, Coolify will show Directus as healthy and running — but it's only accessible on your local network for now. That changes in Phase 2.&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 2 — Building the Cloudflare Tunnel
&lt;/h3&gt;

&lt;p&gt;This is where things get elegant. We're going to create a secure bridge between Cloudflare's global network and our locally running Directus instance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A domain name added to Cloudflare (with Cloudflare managing DNS)&lt;/li&gt;
&lt;li&gt;A free Cloudflare account with Zero Trust enabled&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Creating the Tunnel
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Cloudflare Dashboard → Zero Trust → Networks → Tunnels&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create a tunnel&lt;/strong&gt; and give it a name (e.g., &lt;code&gt;home-server&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Cloudflare will generate a unique &lt;strong&gt;Tunnel Token&lt;/strong&gt; — copy this, you'll need it shortly&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Public Hostnames&lt;/strong&gt;, add a new route:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subdomain:&lt;/strong&gt; &lt;code&gt;cms&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain:&lt;/strong&gt; &lt;code&gt;yourdomain.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service:&lt;/strong&gt; &lt;code&gt;http://directus:8055&lt;/code&gt; &lt;em&gt;(the internal Docker service name and port)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Running &lt;code&gt;cloudflared&lt;/code&gt; as a Container
&lt;/h4&gt;

&lt;p&gt;Rather than installing the &lt;code&gt;cloudflared&lt;/code&gt; binary directly on the host, we run it as a Docker container — keeping things clean and managed by Coolify. Add the following to your Docker Compose file (or deploy it as a separate Coolify service):&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;cloudflared&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cloudflare/cloudflared:latest&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tunnel --no-autoupdate run&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;TUNNEL_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-tunnel-token-from-cloudflare"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;directus&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this container starts, it establishes an outbound connection to Cloudflare. Within a few seconds, &lt;code&gt;cms.yourdomain.com&lt;/code&gt; will resolve publicly — routing through Cloudflare's edge directly to your Directus container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No port forwarding. No firewall rules. No exposed IP address.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your Directus instance is now live on the internet. But before you celebrate, we need to lock it down.&lt;/p&gt;




&lt;h3&gt;
  
  
  Phase 3 — The Zero Trust Lockdown
&lt;/h3&gt;

&lt;p&gt;Having a publicly accessible URL is both exciting and frightening. Anyone with the URL can reach your Directus login screen. While Directus itself has authentication, relying solely on an application-level login is a single point of failure. We want an additional layer — one that stops uninvited guests before they even &lt;em&gt;see&lt;/em&gt; Directus.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Cloudflare Access&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Cloudflare Access?
&lt;/h4&gt;

&lt;p&gt;Cloudflare Access is part of Cloudflare's Zero Trust product suite. It acts as an identity-aware proxy that sits &lt;em&gt;in front of&lt;/em&gt; your application. Before a request reaches Directus, Cloudflare intercepts it and demands authentication. Only requests that pass the policy are forwarded through the tunnel.&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting Up an Access Policy
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Zero Trust → Access → Applications&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add an application&lt;/strong&gt; → &lt;strong&gt;Self-hosted&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure it:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application name:&lt;/strong&gt; Directus CMS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application domain:&lt;/strong&gt; &lt;code&gt;cms.yourdomain.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;Access Policy&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Policy name:&lt;/strong&gt; Owner Access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; Allow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Include rule:&lt;/strong&gt; &lt;code&gt;Emails&lt;/code&gt; → &lt;code&gt;your@email.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  How the OTP Login Works
&lt;/h4&gt;

&lt;p&gt;When a user navigates to &lt;code&gt;cms.yourdomain.com&lt;/code&gt;, here's what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cloudflare intercepts the request &lt;strong&gt;before it reaches Directus&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The user is presented with a Cloudflare Access login screen&lt;/li&gt;
&lt;li&gt;They enter their email address&lt;/li&gt;
&lt;li&gt;If the email matches an allowed email in your policy, Cloudflare sends a &lt;strong&gt;One-Time PIN (OTP)&lt;/strong&gt; to that address&lt;/li&gt;
&lt;li&gt;The user enters the PIN, receives a signed JWT session cookie, and is forwarded to Directus&lt;/li&gt;
&lt;li&gt;All subsequent requests carry this cookie, so Directus loads normally&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result: even if someone discovers your &lt;code&gt;cms.yourdomain.com&lt;/code&gt; URL, they cannot proceed without access to your email inbox. The Directus login screen is invisible to the outside world.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Stack Wins
&lt;/h2&gt;

&lt;p&gt;Let's step back and appreciate what we've built.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ No VPN Required
&lt;/h3&gt;

&lt;p&gt;Traditional secure remote access requires a VPN client on every device. You have to remember to connect, manage certificates, and troubleshoot when it doesn't work. With Cloudflare Tunnels + Access, any browser on any device can securely access your service. Your phone, a borrowed laptop, a friend's computer — all work instantly with just an email and an OTP.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Free SSL/TLS, Automatically Managed
&lt;/h3&gt;

&lt;p&gt;Cloudflare handles HTTPS termination at the edge. You get a valid, trusted SSL certificate for your subdomain at no cost, with automatic renewal. There's no Certbot, no Let's Encrypt configuration, no annual renewal panic.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Your Home IP is Completely Hidden
&lt;/h3&gt;

&lt;p&gt;Because &lt;code&gt;cloudflared&lt;/code&gt; only makes &lt;em&gt;outbound&lt;/em&gt; connections, there is no DNS record pointing to your home IP, no open port for scanners to find, and no way for a malicious actor to correlate your domain with your physical location or ISP. From the public internet's perspective, your service lives somewhere inside Cloudflare's network.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Layered Security by Design
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Public Internet
      │
      ▼
Cloudflare Edge (DDoS protection, WAF)
      │
      ▼
Cloudflare Access (Identity verification, OTP)
      │
      ▼
Cloudflare Tunnel (Encrypted, outbound-only)
      │
      ▼
Directus Application (App-level authentication)
      │
      ▼
PostgreSQL (Internal network only, never exposed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer must be bypassed independently. This is defence-in-depth done properly.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Scales With You
&lt;/h3&gt;

&lt;p&gt;This exact pattern works whether you're running one service or twenty. Each new service gets its own subdomain, its own tunnel route, and its own Access policy. Coolify handles the container orchestration; Cloudflare handles the networking and access control. The complexity doesn't grow with the number of services.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Gotchas &amp;amp; Tips
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Directus Admin UI breaking after external access?&lt;/strong&gt;&lt;br&gt;
Almost always a &lt;code&gt;PUBLIC_URL&lt;/code&gt; misconfiguration. Double-check it matches your Cloudflare hostname exactly, including &lt;code&gt;https://&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloudflared container keeps restarting?&lt;/strong&gt;&lt;br&gt;
Verify your &lt;code&gt;TUNNEL_TOKEN&lt;/code&gt; is correct and that the tunnel is in an active state in the Cloudflare dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OTP emails not arriving?&lt;/strong&gt;&lt;br&gt;
Check your spam folder first. If using a custom domain email, ensure your SPF/DKIM records are correctly configured with Cloudflare.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to allow a team member access?&lt;/strong&gt;&lt;br&gt;
Simply add their email to your Access Policy's include rule. They'll be able to authenticate with their own OTP without needing any VPN credentials or shared passwords.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Welcome to the Private Cloud
&lt;/h2&gt;

&lt;p&gt;The era of opening Port 80 on your home router and crossing your fingers is over. Modern tools — Coolify for orchestration, Directus for your data layer, and Cloudflare Tunnels with Zero Trust Access for networking — give individual developers and small teams the kind of infrastructure that used to require a dedicated DevOps engineer and a cloud budget.&lt;/p&gt;

&lt;p&gt;The stack we've built today is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accessible&lt;/strong&gt; — from any device, anywhere in the world, with just a browser&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt; — hidden IP, layered authentication, encrypted transit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt; (or nearly so) — Coolify is open-source, Directus has a generous self-hosted licence, and Cloudflare's free tier covers everything we've used here&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainable&lt;/strong&gt; — clean abstractions at every layer, easy to update and extend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're still running services with a raw &lt;code&gt;docker run&lt;/code&gt; command and a prayer, this is your sign to upgrade. The private cloud is here, and it's better than ever.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built and tested on a home server running Ubuntu 24.04 LTS. Stack versions: Coolify v4, Directus 11, cloudflared 2025.x.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>homelab</category>
      <category>selfhosted</category>
      <category>devops</category>
    </item>
    <item>
      <title>Don't Build a Battleship: An Agile Lesson from a Billion-Dollar Mistake</title>
      <dc:creator>Korak Kurani</dc:creator>
      <pubDate>Tue, 05 Aug 2025 07:31:11 +0000</pubDate>
      <link>https://dev.to/korak997/dont-build-a-battleship-an-agile-lesson-from-a-billion-dollar-mistake-37jj</link>
      <guid>https://dev.to/korak997/dont-build-a-battleship-an-agile-lesson-from-a-billion-dollar-mistake-37jj</guid>
      <description>&lt;p&gt;In the world of project management and software development, there's a powerful allure to the "Big Bang" project. It’s the revolutionary, all-encompassing solution that promises to solve every problem in one giant leap. The reality, however, is that these monolithic projects often become cautionary tales of missed deadlines, budget overruns, and catastrophic failure. There is no better real-world example of this than the US Navy's most expensive warship, a story that holds critical lessons for every developer and project manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 'Big Bang' Trap: A Lesson from a Billion-Dollar Battleship
&lt;/h2&gt;

&lt;p&gt;The core anti-pattern in large-scale projects is trying to build and deliver everything at once. This approach assumes a perfect, unchanging plan where all new components integrate flawlessly from day one. In practice, this strategy is incredibly high-risk because it eliminates opportunities to learn and adapt. One small failure can create a cascade effect that jeopardizes the entire project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Case Study: The USS Gerald R. Ford
&lt;/h3&gt;

&lt;p&gt;The plan for the USS Gerald R. Ford aircraft carrier was the epitome of a "Big Bang" approach. Instead of evolving the existing successful design, the project aimed to simultaneously build a new class of ship while inventing and integrating over a dozen revolutionary, unproven technologies.&lt;/p&gt;

&lt;p&gt;Key new systems included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new Electromagnetic Aircraft Launch System (EMALS)&lt;/li&gt;
&lt;li&gt;A new Advanced Arresting Gear (AAG) for landing&lt;/li&gt;
&lt;li&gt;A new set of Advanced Weapons Elevators (AWEs)&lt;/li&gt;
&lt;li&gt;A new dual-band radar system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fatal flaw was &lt;strong&gt;concurrency&lt;/strong&gt;—building the ship while its core components were still being invented. When the new weapons elevators failed testing, they couldn't be fixed on a workbench. They had to be retrofitted into the bowels of a nearly complete, multi-billion dollar vessel. This single issue, multiplied across many other immature systems, led to years of delays and cost overruns exceeding billions of dollars.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Battleships to Speedboats: Embracing Incremental Delivery
&lt;/h2&gt;

&lt;p&gt;The lesson from the USS Ford is clear: we must avoid the "Big Bang" trap. The solution is to stop thinking like battleship builders and adopt an agile, incremental approach. The goal is to deliver a simple, working version of the product as quickly as possible and then improve it iteratively based on real-world feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Break Down Problems: Start with a Minimum Viable Product (MVP)
&lt;/h3&gt;

&lt;p&gt;Instead of aiming for the final, feature-complete version from A-Z, identify the absolute core functionality that delivers value. This is your Minimum Viable Product (MVP). It's the "walking skeleton" of your application—not pretty, but it works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A "Big Bang" approach tries to build this all at once&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processUserOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;validateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;checkInventory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;applyPromotionalDiscounts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paymentDetails&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;triggerShipment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;sendConfirmationEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;updateAnalyticsDashboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// An MVP approach focuses on the absolute core first&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processMvpOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Just the essentials to be a "viable" product&lt;/span&gt;
  &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paymentDetails&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;triggerShipment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a real-world e-commerce project, your MVP is the version where a user can successfully pay for an item. The AI recommendations, user profiles, and rewards program can wait. Launching the MVP provides immediate value and, more importantly, immediate feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build in Iterative Cycles (Sprints)
&lt;/h3&gt;

&lt;p&gt;Once the MVP is live, you build upon it in short, predictable cycles (sprints). Each sprint adds the next most important feature, allowing the product to evolve based on user needs, not an outdated plan.&lt;/p&gt;

&lt;p&gt;A development roadmap might look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sprint 1 (MVP):&lt;/strong&gt; Users can buy one item with a credit card.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprint 2:&lt;/strong&gt; Add the shopping cart to allow multiple items.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprint 3:&lt;/strong&gt; Implement user accounts and order history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprint 4:&lt;/strong&gt; Introduce a simple "related products" feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This iterative process de-risks development. If a feature added in Sprint 4 isn't well-received, you've only lost two weeks of development time, not two years.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-World Scenario: Refactoring a Legacy System
&lt;/h3&gt;

&lt;p&gt;Imagine you're tasked with refactoring a monolithic legacy application—a common and daunting task. A "Big Bang" approach would be to rewrite the entire application from scratch, a path that is notoriously prone to failure.&lt;/p&gt;

&lt;p&gt;An incremental, agile approach is far safer. You can apply the &lt;strong&gt;Strangler Fig Pattern&lt;/strong&gt;, where you slowly "strangle" the old monolith by replacing it piece by piece with new microservices.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Old monolithic function in the legacy system&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleProfileAndOrders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Complex, tangled code that gets user profile,&lt;/span&gt;
  &lt;span class="c1"&gt;// fetches order history, and calculates loyalty points...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Step 1: Create a new, separate microservice for orders&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getOrderHistory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Clean, focused logic for fetching orders&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Step 2: Route all calls for order history to the new service&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleProfileAndOrders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The monolith still handles the profile part...&lt;/span&gt;
  &lt;span class="c1"&gt;// ...but now calls the new microservice for orders&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;orders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getOrderHistory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By replacing functionality module by module, you reduce risk, deliver value faster, and avoid a massive, high-stakes cutover. Each step is a small, manageable win, just like adding one feature at a time in a new project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The story of the USS Gerald R. Ford is a powerful lesson in the risks of over-ambition and the failure to respect complexity. As developers and project managers, we can learn from this multi-billion dollar mistake. By breaking down monumental tasks, focusing on an MVP, and delivering value incrementally, we can steer our projects away from the "Big Bang" iceberg and towards the safe harbor of successful, iterative delivery.&lt;/p&gt;

</description>
      <category>mvp</category>
      <category>softwareengineering</category>
      <category>management</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Set Up a Local Ubuntu Server to Host Ollama Models with a WebUI</title>
      <dc:creator>Korak Kurani</dc:creator>
      <pubDate>Sat, 14 Dec 2024 10:30:19 +0000</pubDate>
      <link>https://dev.to/korak997/how-to-set-up-a-local-ubuntu-server-to-host-ollama-models-with-a-webui-ok7</link>
      <guid>https://dev.to/korak997/how-to-set-up-a-local-ubuntu-server-to-host-ollama-models-with-a-webui-ok7</guid>
      <description>&lt;p&gt;Are you excited to create a powerful local server to host Ollama models and manage them through an intuitive WebUI? This step-by-step guide will walk you through the entire process—from installing Ubuntu Server to setting up Ollama and integrating OpenWebUI for a seamless experience.&lt;/p&gt;

&lt;p&gt;Whether you’re new to this or a seasoned Ubuntu user, this detailed tutorial is designed to be clear, approachable, and error-free. Let’s dive in and get your server up and running!&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing Ubuntu Server on Your PC
&lt;/h2&gt;

&lt;p&gt;Before we configure your server, you’ll need to install Ubuntu Server on your machine. Here’s how to do it smoothly:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Download the Ubuntu Server ISO
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Head over to the &lt;a href="https://ubuntu.com/download/server" rel="noopener noreferrer"&gt;Ubuntu Server Download Page&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Grab the latest Ubuntu Server ISO file to ensure you’re working with the most recent release.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Create a Bootable USB Drive
&lt;/h3&gt;

&lt;p&gt;To turn your USB into a bootable installer, use a tool like &lt;a href="https://rufus.ie/" rel="noopener noreferrer"&gt;Rufus&lt;/a&gt; (for Windows) or &lt;code&gt;dd&lt;/code&gt; (for Linux/Mac):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using Rufus&lt;/strong&gt;: Launch Rufus, select your downloaded ISO file and USB drive, then hit "Start."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using &lt;code&gt;dd&lt;/code&gt; on Linux/Mac&lt;/strong&gt;:
&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 dd &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/ubuntu-server.iso &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdX &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be sure to replace &lt;code&gt;/dev/sdX&lt;/code&gt; with your USB device’s identifier (e.g., &lt;code&gt;/dev/sdb&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Boot from USB and Install Ubuntu Server
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Plug the USB drive into your PC and restart the machine.&lt;/li&gt;
&lt;li&gt;Access your BIOS/UEFI settings by pressing a key like &lt;code&gt;DEL&lt;/code&gt;, &lt;code&gt;F2&lt;/code&gt;, or &lt;code&gt;F12&lt;/code&gt; during startup (check your device’s manual).&lt;/li&gt;
&lt;li&gt;Set the USB drive as the first boot option, save your changes, and exit.&lt;/li&gt;
&lt;li&gt;Follow the installer’s prompts to set up Ubuntu Server:

&lt;ul&gt;
&lt;li&gt;Choose your preferred language and keyboard layout.&lt;/li&gt;
&lt;li&gt;Configure your network settings.&lt;/li&gt;
&lt;li&gt;Partition your disk (the guided option works well for most users).&lt;/li&gt;
&lt;li&gt;Create a username, password, and hostname for your server.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the installation finishes, reboot your system and remove the USB drive during the restart.&lt;/p&gt;




&lt;h2&gt;
  
  
  Configuring Your Ubuntu Server
&lt;/h2&gt;

&lt;p&gt;With Ubuntu Server installed, let’s get it ready for action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Update and Install Essential Packages
&lt;/h3&gt;

&lt;p&gt;Keep your system current and equipped with key tools by running these commands:&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;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;build-essential dkms linux-headers-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; software-properties-common &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These updates and packages ensure a solid foundation for what’s next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Install Docker
&lt;/h3&gt;

&lt;p&gt;Since we’ll use Docker later to run OpenWebUI, let’s install it now to streamline the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add Docker’s official GPG key and repository:
&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;apt update
   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ca-certificates curl &lt;span class="nt"&gt;-y&lt;/span&gt;
   &lt;span class="nb"&gt;sudo install&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 0755 &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/apt/keyrings
   &lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg &lt;span class="nt"&gt;-o&lt;/span&gt; /etc/apt/keyrings/docker.asc
   &lt;span class="nb"&gt;sudo chmod &lt;/span&gt;a+r /etc/apt/keyrings/docker.asc
   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
     &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; /etc/os-release &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERSION_CODENAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install Docker and its components:
&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;apt &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Verify Docker is running:
&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 status docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see it’s active. If not, start it with:&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;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;(Optional) Allow your user to run Docker without &lt;code&gt;sudo&lt;/code&gt;:
&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;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log out and back in for this to take effect.&lt;/p&gt;

&lt;p&gt;With Docker installed, you’re ready to containerize applications like OpenWebUI later on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Add NVIDIA Repository and Install Drivers
&lt;/h3&gt;

&lt;p&gt;If your server has an NVIDIA GPU, you’ll want to install the proper drivers for optimal performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the NVIDIA PPA repository:
&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;add-apt-repository ppa:graphics-drivers/ppa &lt;span class="nt"&gt;-y&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check for the recommended driver:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ubuntu-drivers devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see output like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   driver   : nvidia-driver-560 - third-party non-free recommended
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install the recommended driver (e.g., version 560):
&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;apt &lt;span class="nb"&gt;install &lt;/span&gt;nvidia-driver-560 &lt;span class="nt"&gt;-y&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Confirm the driver is working:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should display your GPU details and driver version. If it doesn’t, retrace your steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Configure NVIDIA GPU as Default
&lt;/h3&gt;

&lt;p&gt;If your system has an integrated GPU, you’ll need to prioritize the NVIDIA GPU:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List your GPUs:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   lspci | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; vga
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Disable the integrated GPU by blacklisting its driver:
&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;nano /etc/modprobe.d/blacklist-integrated-gpu.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add these lines depending on your integrated GPU:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Intel:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   blacklist i915
   options i915 modeset=0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For AMD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   blacklist amdgpu
   options amdgpu modeset=0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Apply changes and reboot:
&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;update-initramfs &lt;span class="nt"&gt;-u&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Double-check with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Installing and Configuring Ollama
&lt;/h2&gt;

&lt;p&gt;Now, let’s set up Ollama to host your AI models locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install Ollama
&lt;/h3&gt;

&lt;p&gt;Run this simple command to download and install Ollama:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://ollama.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Add Models to Ollama
&lt;/h3&gt;

&lt;p&gt;Ollama supports various models. For example, to pull the &lt;code&gt;llama3&lt;/code&gt; model, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull llama3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to explore other models that suit your needs!&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up OpenWebUI for Easy Interaction
&lt;/h2&gt;

&lt;p&gt;To elevate your Ollama experience, let’s add OpenWebUI—a sleek, user-friendly interface—using the Docker we installed earlier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch OpenWebUI with Docker:
&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;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="nt"&gt;-v&lt;/span&gt; open-webui:/app/backend/data &lt;span class="se"&gt;\&lt;/span&gt;
       &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;OLLAMA_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://127.0.0.1:11434 &lt;span class="se"&gt;\&lt;/span&gt;
       &lt;span class="nt"&gt;--name&lt;/span&gt; open-webui &lt;span class="nt"&gt;--restart&lt;/span&gt; always &lt;span class="se"&gt;\&lt;/span&gt;
       ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs OpenWebUI in a container with persistent data storage (&lt;code&gt;open-webui&lt;/code&gt; volume).&lt;/li&gt;
&lt;li&gt;Connects it to Ollama via the specified base URL.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensures it restarts automatically if your server reboots.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open your browser and navigate to your server’s IP address to access the WebUI.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Testing and Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Let’s make sure everything’s working smoothly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify NVIDIA GPU Functionality
&lt;/h3&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see GPU details, you’re good to go. If you get &lt;code&gt;Command not found&lt;/code&gt;, revisit the driver installation steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Errors and Fixes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Error:&lt;/strong&gt; &lt;code&gt;ERROR:root:aplay command not found&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; Install the missing audio utilities:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;alsa-utils &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Error:&lt;/strong&gt; &lt;code&gt;udevadm hwdb is deprecated. Use systemd-hwdb instead.&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; Update your system:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;hwdb update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt full-upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Optional: CUDA Setup for Compute Workloads
&lt;/h2&gt;

&lt;p&gt;For heavy computational tasks, add CUDA tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install CUDA:
&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;apt &lt;span class="nb"&gt;install &lt;/span&gt;nvidia-cuda-toolkit &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Verify it’s working:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvcc &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrap-Up
&lt;/h2&gt;

&lt;p&gt;Congratulations! You’ve successfully built a robust local Ubuntu server, installed Docker, set up Ollama for AI model hosting, and paired it with OpenWebUI for effortless interaction. This setup is ideal for exploring AI models in a secure, local environment.&lt;/p&gt;

&lt;p&gt;If you hit any snags, revisit the steps or check the official documentation. Now, go enjoy the power of Ollama and OpenWebUI—happy experimenting!&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>ai</category>
      <category>ollama</category>
    </item>
    <item>
      <title>Programming Principles for Everyday Success</title>
      <dc:creator>Korak Kurani</dc:creator>
      <pubDate>Thu, 28 Nov 2024 14:41:59 +0000</pubDate>
      <link>https://dev.to/korak997/programming-principles-for-everyday-success-3bd9</link>
      <guid>https://dev.to/korak997/programming-principles-for-everyday-success-3bd9</guid>
      <description>&lt;p&gt;In a world where technology is constantly evolving, learning to program has become more than just a career choice; it’s a way to structure one’s life. My journey, which took me from a curious kid fascinated by movie hackers to a Fullstack Developer in Berlin, is a testament to the power of self-learning and the unexpected benefits it can bring to everyday life. Here’s a detailed look at how learning programming helped me organize my life better and implement coding techniques beyond the computer screen.&lt;/p&gt;

&lt;p&gt;My Journey into Programming&lt;br&gt;
As a kid, I was always intrigued by the portrayal of hackers in movies. They seemed like wizards, manipulating digital worlds with cryptic code. This fascination led me to explore what goes into building software and, eventually, to realize that those wizards were actually programmers. When I arrived in Germany, I set a goal to work as hard as possible to become one of them. This is how my self-taught journey began.&lt;/p&gt;

&lt;p&gt;Structuring Life with Programming Principles&lt;br&gt;
Learning programming has a profound impact on how I handle day-to-day challenges. Here are some ways programming principles helped structure my life:&lt;/p&gt;

&lt;p&gt;Dividing Problems into Smaller Tasks&lt;/p&gt;

&lt;p&gt;One of the first lessons in programming is to break down a problem into manageable pieces. This approach has been invaluable in my personal life. Whether it’s planning a project at work or organizing household chores, I divide tasks into smaller, more manageable chunks. This makes even the most daunting tasks seem achievable and helps maintain focus and motivation.&lt;/p&gt;

&lt;p&gt;Staying Calm Under Pressure&lt;/p&gt;

&lt;p&gt;In programming, encountering bugs and errors is a given. Initially, this was a source of great frustration. However, over time, I learned to stay calm and approach problems methodically. This mindset shift has translated into my personal life. When faced with stressful situations, I remind myself to stay calm and tackle the issue one step at a time, much like debugging code.&lt;/p&gt;

&lt;p&gt;Rubber Duck Debugging: Talking Through Problems&lt;/p&gt;

&lt;p&gt;A popular technique in programming is rubber duck debugging—explaining your code, line by line, to an inanimate object to find where things went wrong. I’ve found this technique useful beyond programming. When I’m stuck on a problem, I talk myself through it step by step. This often leads to a clearer understanding and a solution.&lt;/p&gt;

&lt;p&gt;Taking Breaks and Trying Again&lt;/p&gt;

&lt;p&gt;Programming taught me the importance of taking breaks. When a problem feels insurmountable, stepping away for a short time can provide a fresh perspective. This principle is now a part of my routine. If I hit a roadblock, I take a break, clear my mind, and come back with renewed energy.&lt;/p&gt;

&lt;p&gt;Persistence: Never Giving Up&lt;/p&gt;

&lt;p&gt;Perhaps the most significant lesson from programming is persistence. Debugging can be incredibly frustrating, but the satisfaction of solving a problem makes it worthwhile. This tenacity has helped me in all areas of life. I now approach challenges with a mindset of not giving up until I find a solution.&lt;/p&gt;

&lt;p&gt;Transforming Life from Chaos to Calm&lt;br&gt;
Before I started applying these programming techniques to my life, I was easily stressed and often gave up on challenging tasks. Learning to code has taught me to stay calm, methodically approach problems, and persist until I achieve my goals. This transformation has led to a more balanced and fulfilling life.&lt;/p&gt;

&lt;p&gt;Sharing My Journey&lt;br&gt;
I hope my story resonates with others, whether you’re a fellow developer or someone looking for ways to bring structure to your life. The techniques and principles I learned through programming are universally applicable and can help anyone achieve a more organized and stress-free existence.&lt;/p&gt;

</description>
      <category>selftaught</category>
      <category>developer</category>
    </item>
  </channel>
</rss>
