<?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: ogc16</title>
    <description>The latest articles on DEV Community by ogc16 (@ogc16).</description>
    <link>https://dev.to/ogc16</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F885223%2F4a51669c-3728-4f5f-bdba-03e0b0da756f.png</url>
      <title>DEV Community: ogc16</title>
      <link>https://dev.to/ogc16</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ogc16"/>
    <language>en</language>
    <item>
      <title>The Status Quo of AI in Software Development (2026)</title>
      <dc:creator>ogc16</dc:creator>
      <pubDate>Mon, 17 Aug 2026 15:40:14 +0000</pubDate>
      <link>https://dev.to/ogc16/the-status-quo-of-ai-in-software-development-2026-17k8</link>
      <guid>https://dev.to/ogc16/the-status-quo-of-ai-in-software-development-2026-17k8</guid>
      <description>&lt;h2&gt;
  
  
  Artificial Intelligence in 2026: From Companion to Infrastructure
&lt;/h2&gt;

&lt;p&gt;Artificial Intelligence has moved from being a futuristic concept to an everyday companion in software development. In 2026, the landscape is defined by rapid innovation, fierce competition, and unresolved challenges around governance, sustainability, and labor. Developers today are navigating both unprecedented opportunities and complex risks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Industry Dominance
&lt;/h2&gt;

&lt;p&gt;Over 90% of notable AI models now originate from industry rather than academia, signaling commercialization as the primary driver of innovation. Research labs continue to contribute breakthroughs, but the pace of deployment is overwhelmingly shaped by corporate priorities, venture capital, and cloud infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Geopolitical Competition
&lt;/h2&gt;

&lt;p&gt;The United States leads in model releases and data center infrastructure, while China dominates robotics and research output. This rivalry shapes the pace and direction of AI development.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Europe has carved out a niche in regulation, with the AI Act setting global standards.
&lt;/li&gt;
&lt;li&gt;Emerging economies in Africa and India are focusing on applied AI, building tools for agriculture, education, and healthcare.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Compute Explosion
&lt;/h2&gt;

&lt;p&gt;Global AI compute capacity has grown more than threefold annually since 2022, powered largely by Nvidia GPUs. Data centers now consume nearly 30 GW of electricity — comparable to the peak demand of New York City. This raises urgent questions about sustainability and the environmental cost of progress.&lt;/p&gt;




&lt;h2&gt;
  
  
  The ChatGPT Moment
&lt;/h2&gt;

&lt;p&gt;Artificial Intelligence has had many waves, but the one that truly captured global attention was the release of ChatGPT. What began as a conversational model quickly became a cultural phenomenon, reshaping how people interact with technology, learn, and even work.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disruption&lt;/strong&gt;: It challenged traditional search engines, productivity tools, and educational practices.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social Acceptance&lt;/strong&gt;: Within months, it was integrated into classrooms, offices, and personal devices. AI was no longer niche — it was part of everyday life.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This acceptance marked a turning point: AI became a daily companion rather than a distant technology.&lt;/p&gt;




&lt;h2&gt;
  
  
  Competitors and Successors
&lt;/h2&gt;

&lt;p&gt;The success of ChatGPT opened the floodgates for competitors, each pushing boundaries in unique ways:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DeepSeek&lt;/strong&gt;: Efficiency and cost‑effectiveness, democratizing access for startups and individuals.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude (Anthropic)&lt;/strong&gt;: Safety and alignment, trusted by enterprises and governments.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenClaw&lt;/strong&gt;: Multimodal capabilities, handling text, images, and structured data seamlessly.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they signal that the AI race is far from over — innovation is accelerating across domains.&lt;/p&gt;




&lt;h2&gt;
  
  
  Governance and Ethics
&lt;/h2&gt;

&lt;p&gt;Despite progress, unresolved challenges loom large:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Governance&lt;/strong&gt;: Who sets the rules for safe deployment?
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Labor impact&lt;/strong&gt;: Automation reshapes jobs, but reskilling remains uneven.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bias and trust&lt;/strong&gt;: Ensuring fairness and reliability in outputs is still a work in progress.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Future Outlook
&lt;/h2&gt;

&lt;p&gt;Artificial Intelligence in 2026 is no longer a tool but a partner. From classrooms to boardrooms, it shapes decisions, creativity, and governance. Yet the story is unfinished:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI as infrastructure&lt;/strong&gt;: Becoming as essential as electricity or the internet.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid intelligence&lt;/strong&gt;: Humans and AI collaborating rather than competing.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next disruption&lt;/strong&gt;: Multimodal reasoning, embodied AI, or quantum‑accelerated models.
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Artificial Intelligence has entered everyday life, but its trajectory will be defined not just by innovation, but by how societies govern, sustain, and integrate it into human progress.&lt;/em&gt;&lt;br&gt;
 ## Share Your Experience&lt;/p&gt;

&lt;p&gt;Artificial Intelligence is now part of everyday life, but usage varies widely.&lt;br&gt;&lt;br&gt;
Which AI do you rely on most in your daily work or personal projects?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a&gt;ChatGPT&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a&gt;Claude&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a&gt;DeepSeek&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a&gt;OpenClaw&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a&gt;Other AI tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comment below or update your own README to let others know how you’re using AI day‑to‑day.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>deepseek</category>
      <category>openclaw</category>
      <category>claude</category>
    </item>
    <item>
      <title>Deploying IaaS Platform: A Production Playbook</title>
      <dc:creator>ogc16</dc:creator>
      <pubDate>Fri, 14 Aug 2026 13:08:56 +0000</pubDate>
      <link>https://dev.to/ogc16/deploying-iaas-platform-a-production-playbook-421f</link>
      <guid>https://dev.to/ogc16/deploying-iaas-platform-a-production-playbook-421f</guid>
      <description>&lt;p&gt;&lt;em&gt;Learn how to go from &lt;code&gt;docker compose up&lt;/code&gt; to production-grade deployments on Railway, Kubernetes, and beyond.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Follow-up to:&lt;/strong&gt; &lt;a href="https://dev.to/your-handle/building-multi-tenant-iaas-go"&gt;Building a Multi-Tenant IaaS Platform in Go&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Last week's post showed you the architecture of a production-ready IaaS platform. Today, we're going practical: &lt;strong&gt;how to actually run it in production&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;IaaS Platform ships with multiple deployment options because different teams have different constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local dev&lt;/strong&gt; — &lt;code&gt;docker compose&lt;/code&gt; (5 seconds to running)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single host&lt;/strong&gt; — systemd + PostgreSQL (small team, Hetzner/Linode)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containers&lt;/strong&gt; — Docker image + Railway/Render (zero-ops, scales easily)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes&lt;/strong&gt; — StatefulSet + Secrets (enterprise teams)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure-as-Code&lt;/strong&gt; — Terraform (repeatable, auditable)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post walks through each, with real configs you can copy-paste.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: Local Development (5 Minutes)
&lt;/h2&gt;

&lt;p&gt;Start here. No thinking required.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Fastest Possible Start
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/ogc16/iaas-platform.git
&lt;span class="nb"&gt;cd &lt;/span&gt;iaas-platform
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
go run ./cmd/server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What just happened:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL 16 started in a Docker container (listening on &lt;code&gt;localhost:5432&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Server migrations ran automatically&lt;/li&gt;
&lt;li&gt;Control plane listening on &lt;code&gt;http://localhost:8080&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard loaded at &lt;code&gt;/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;API ready at &lt;code&gt;/api/v1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What's Inside &lt;code&gt;docker-compose.yml&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&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:16-alpine&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;5432:5432"&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;iaas&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;iaas&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;iaas&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;pgdata:/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;iaas&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-d&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;iaas"&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;5s&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alpine Linux keeps the image tiny (~150 MB)&lt;/li&gt;
&lt;li&gt;Health checks ensure readiness probes pass&lt;/li&gt;
&lt;li&gt;Volume persists data across container restarts&lt;/li&gt;
&lt;li&gt;Default credentials are fine for local dev (but NOT production)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 2: Single-Host Deployment (1 Hour Setup)
&lt;/h2&gt;

&lt;p&gt;You're ready to show this to early users. Use a cheap VPS: &lt;strong&gt;$5/month on Linode or Hetzner&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Provision the Host
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SSH into a fresh Ubuntu 22.04 server&lt;/span&gt;
ssh root@your-server-ip

&lt;span class="c"&gt;# Update everything&lt;/span&gt;
apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Install Docker&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.docker.com &lt;span class="nt"&gt;-o&lt;/span&gt; get-docker.sh
sh get-docker.sh

&lt;span class="c"&gt;# Install PostgreSQL (system package, NOT container)&lt;/span&gt;
apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; postgresql postgresql-contrib

&lt;span class="c"&gt;# Create DB user for the app&lt;/span&gt;
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
CREATE USER iaas WITH PASSWORD 'YOUR_SECURE_PASSWORD_HERE';
CREATE DATABASE iaas OWNER iaas;
GRANT ALL PRIVILEGES ON DATABASE iaas TO iaas;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Verify connection&lt;/span&gt;
psql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; iaas &lt;span class="nt"&gt;-d&lt;/span&gt; iaas &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;t"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Deploy the Binary
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Download v0.1.0 release binary&lt;/span&gt;
wget https://github.com/ogc16/iaas-platform/releases/download/v0.1.0/iaas-platform-server-linux-amd64
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x iaas-platform-server-linux-amd64

&lt;span class="c"&gt;# Create a user to run the service&lt;/span&gt;
useradd &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/false iaas-platform

&lt;span class="c"&gt;# Move binary to a standard location&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /opt/iaas-platform/bin
&lt;span class="nb"&gt;mv &lt;/span&gt;iaas-platform-server-linux-amd64 /opt/iaas-platform/bin/server
&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; iaas-platform:iaas-platform /opt/iaas-platform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Create a systemd Service
&lt;/h3&gt;

&lt;p&gt;Save this to &lt;code&gt;/etc/systemd/system/iaas-platform.service&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;IaaS Platform Control Plane&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network-online.target postgresql.service&lt;/span&gt;
&lt;span class="py"&gt;Wants&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network-online.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;simple&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;iaas-platform&lt;/span&gt;
&lt;span class="py"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;iaas-platform&lt;/span&gt;

&lt;span class="c"&gt;# Load environment variables from a file
&lt;/span&gt;&lt;span class="py"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/etc/iaas-platform/env&lt;/span&gt;

&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/opt/iaas-platform/bin/server&lt;/span&gt;

&lt;span class="c"&gt;# Auto-restart if the process crashes
&lt;/span&gt;&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;on-failure&lt;/span&gt;
&lt;span class="py"&gt;RestartSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5&lt;/span&gt;

&lt;span class="c"&gt;# Limits
&lt;/span&gt;&lt;span class="py"&gt;LimitNOFILE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;65536&lt;/span&gt;
&lt;span class="py"&gt;TimeoutStopSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;30&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;/etc/iaas-platform/env&lt;/code&gt;:&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="c"&gt;# Production hardening&lt;/span&gt;
&lt;span class="nv"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8080

&lt;span class="c"&gt;# Database (use the user/password from Step 1)&lt;/span&gt;
&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres://iaas:YOUR_SECURE_PASSWORD_HERE@localhost:5432/iaas?sslmode&lt;span class="o"&gt;=&lt;/span&gt;require

&lt;span class="c"&gt;# Generate a strong secret: openssl rand -hex 32&lt;/span&gt;
&lt;span class="nv"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

&lt;span class="c"&gt;# Password hashing&lt;/span&gt;
&lt;span class="nv"&gt;BCRYPT_COST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12

&lt;span class="c"&gt;# Email (optional; without SMTP, password-reset links are logged to stdout)&lt;/span&gt;
&lt;span class="nv"&gt;SMTP_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;smtp.sendgrid.net
&lt;span class="nv"&gt;SMTP_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;587
&lt;span class="nv"&gt;SMTP_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;apikey
&lt;span class="nv"&gt;SMTP_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;SG.xxxxxxxxxxxxx
&lt;span class="nv"&gt;SMTP_FROM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;noreply@yourdomain.com

&lt;span class="c"&gt;# Base URL for password-reset links&lt;/span&gt;
&lt;span class="nv"&gt;APP_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://iaas.yourdomain.com

&lt;span class="c"&gt;# Restrict read access&lt;/span&gt;
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /etc/iaas-platform/env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Enable and Start
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl daemon-reload
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;iaas-platform
systemctl start iaas-platform
systemctl status iaas-platform   &lt;span class="c"&gt;# Verify it's running&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Nginx Reverse Proxy
&lt;/h3&gt;

&lt;p&gt;Put this in &lt;code&gt;/etc/nginx/sites-available/iaas&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;iaas_platform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# HTTP → HTTPS redirect&lt;/span&gt;
&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;iaas.yourdomain.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$server_name$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# HTTPS server&lt;/span&gt;
&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt; &lt;span class="s"&gt;http2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;iaas.yourdomain.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Use Let's Encrypt (or your CA)&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/iaas.yourdomain.com/fullchain.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/iaas.yourdomain.com/privkey.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Security headers (some added by our app, but reinforce here)&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Strict-Transport-Security&lt;/span&gt; &lt;span class="s"&gt;"max-age=63072000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;includeSubDomains&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;preload"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;X-Content-Type-Options&lt;/span&gt; &lt;span class="s"&gt;"nosniff"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;X-Frame-Options&lt;/span&gt; &lt;span class="s"&gt;"DENY"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Referrer-Policy&lt;/span&gt; &lt;span class="s"&gt;"no-referrer"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Request body size limit (prevents DoS; issue #13 will add this to the app)&lt;/span&gt;
    &lt;span class="kn"&gt;client_max_body_size&lt;/span&gt; &lt;span class="mi"&gt;1M&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Proxy to our app&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://iaas_platform&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;# Timeouts for long-polling (health checks, etc.)&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_read_timeout&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_connect_timeout&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;&lt;span class="p"&gt;;&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;h3&gt;
  
  
  Step 7: Get an SSL Certificate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; certbot python3-certbot-nginx
certbot certonly &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; iaas.yourdomain.com

&lt;span class="c"&gt;# Auto-renew&lt;/span&gt;
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;certbot.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 8: Verify It Works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check the app is running&lt;/span&gt;
curl https://iaas.yourdomain.com/healthz
&lt;span class="c"&gt;# Should return: OK&lt;/span&gt;

&lt;span class="c"&gt;# Check readiness (pings the database)&lt;/span&gt;
curl https://iaas.yourdomain.com/readyz
&lt;span class="c"&gt;# Should return: OK&lt;/span&gt;

&lt;span class="c"&gt;# Open in browser&lt;/span&gt;
open https://iaas.yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cost:&lt;/strong&gt; ~$5/month (VPS) + ~$10/year (domain) + free SSL (Let's Encrypt).&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3: Container Deployment (No Server Management)
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;Railway&lt;/strong&gt; or &lt;strong&gt;Render&lt;/strong&gt; for zero-ops deployment. We'll show Railway because it's fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Containerize the App
&lt;/h3&gt;

&lt;p&gt;The repo includes a multi-stage &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.26-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.mod go.sum ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build &lt;span class="nt"&gt;-trimpath&lt;/span&gt; &lt;span class="nt"&gt;-ldflags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-s -w"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /out/server ./cmd/server

&lt;span class="c"&gt;# Runtime stage (distroless = minimal, no shell, no package manager)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gcr.io/distroless/static-debian12:nonroot&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /out/server /usr/local/bin/&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/usr/local/bin/server"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;✅ Image size: ~30 MB (not 800 MB with Alpine)&lt;/li&gt;
&lt;li&gt;✅ No shell or package manager = smaller attack surface&lt;/li&gt;
&lt;li&gt;✅ Runs as non-root by default (&lt;code&gt;uid 65532&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;✅ Security scanning doesn't find phantom vulnerabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Push to Container Registry
&lt;/h3&gt;

&lt;p&gt;Option A: GitHub Container Registry (free, no auth needed for public repos):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; ghcr.io/YOUR_GITHUB_USERNAME/iaas-platform:latest &lt;span class="nb"&gt;.&lt;/span&gt;
docker push ghcr.io/YOUR_GITHUB_USERNAME/iaas-platform:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Option B: Docker Hub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; YOUR_DOCKER_USERNAME/iaas-platform:latest &lt;span class="nb"&gt;.&lt;/span&gt;
docker push YOUR_DOCKER_USERNAME/iaas-platform:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Deploy to Railway
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://railway.app" rel="noopener noreferrer"&gt;railway.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;"New Project"&lt;/strong&gt; → &lt;strong&gt;"Deploy from GitHub"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select your &lt;code&gt;iaas-platform&lt;/code&gt; fork&lt;/li&gt;
&lt;li&gt;Railway auto-detects the Dockerfile&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add PostgreSQL 16&lt;/strong&gt; plugin&lt;/li&gt;
&lt;li&gt;Set environment variables:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;   &lt;span class="n"&gt;ENV&lt;/span&gt;=&lt;span class="n"&gt;production&lt;/span&gt;
   &lt;span class="n"&gt;JWT_SECRET&lt;/span&gt;=&amp;lt;&lt;span class="n"&gt;generate&lt;/span&gt;: &lt;span class="n"&gt;openssl&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt; -&lt;span class="n"&gt;hex&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt;&amp;gt;
   &lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;=&amp;lt;&lt;span class="n"&gt;Railway&lt;/span&gt; &lt;span class="n"&gt;generates&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;automatically&lt;/span&gt;&amp;gt;
   &lt;span class="n"&gt;BCRYPT_COST&lt;/span&gt;=&lt;span class="m"&gt;12&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Deploy button → &lt;strong&gt;Wait 2 minutes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;That's it.&lt;/strong&gt; Railway provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ HTTPS by default (auto-generated domain)&lt;/li&gt;
&lt;li&gt;✅ PostgreSQL managed for you&lt;/li&gt;
&lt;li&gt;✅ Auto-scaling&lt;/li&gt;
&lt;li&gt;✅ $5/month free tier (then $5/gb RAM/month)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your app is now live at:&lt;/strong&gt; &lt;code&gt;https://yourdomain-production-xxxx.railway.app&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 4: Kubernetes Deployment (Enterprise)
&lt;/h2&gt;

&lt;p&gt;For large teams, Kubernetes gives you &lt;strong&gt;orchestration, auto-scaling, and self-healing&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A Kubernetes cluster (EKS, GKE, DigitalOcean, or local &lt;code&gt;minikube&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kubectl&lt;/code&gt; CLI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;helm&lt;/code&gt; (optional but recommended)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Create Secrets
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate a strong JWT secret&lt;/span&gt;
&lt;span class="nv"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;openssl rand &lt;span class="nt"&gt;-hex&lt;/span&gt; 32&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Create a Kubernetes secret&lt;/span&gt;
kubectl create secret generic iaas-platform-secrets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$JWT_SECRET&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres://iaas:password@postgres-svc:5432/iaas &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;BCRYPT_COST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Deploy PostgreSQL (if not using managed RDS)
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;postgres.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ConfigMap&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-config&lt;/span&gt;
&lt;span class="na"&gt;data&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;iaas&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;iaas&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PersistentVolumeClaim&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-pvc&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ReadWriteOnce&lt;/span&gt;
  &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10Gi&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;postgres&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;postgres&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&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:16-alpine&lt;/span&gt;
        &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;configMapRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-config&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&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="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
        &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;data&lt;/span&gt;
          &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/lib/postgresql/data&lt;/span&gt;
        &lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;command&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;pg_isready"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-U"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;iaas"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
          &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&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="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;data&lt;/span&gt;
        &lt;span class="na"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;claimName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-pvc&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-svc&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;postgres&lt;/span&gt; &lt;span class="pi"&gt;}&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="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Deploy the App
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;iaas-platform.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iaas-platform&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;iaas-platform&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;iaas-platform&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;iaas-platform&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;securityContext&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runAsNonRoot&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;runAsUser&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;65532&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server&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;ghcr.io/YOUR_GITHUB_USERNAME/iaas-platform:latest&lt;/span&gt;
        &lt;span class="na"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&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="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
        &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;secretRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iaas-platform-secrets&lt;/span&gt;
        &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;250m"&lt;/span&gt;
          &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;512Mi"&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
        &lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/healthz&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
          &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
        &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/readyz&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&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;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iaas-platform-svc&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;iaas-platform&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&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="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
    &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;autoscaling/v2&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HorizontalPodAutoscaler&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iaas-platform-hpa&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scaleTargetRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
    &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iaas-platform&lt;/span&gt;
  &lt;span class="na"&gt;minReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;maxReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
  &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Resource&lt;/span&gt;
    &lt;span class="na"&gt;resource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cpu&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Utilization&lt;/span&gt;
        &lt;span class="na"&gt;averageUtilization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Apply and Verify
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create namespace&lt;/span&gt;
kubectl create namespace iaas

&lt;span class="c"&gt;# Apply configs&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; postgres.yaml &lt;span class="nt"&gt;-n&lt;/span&gt; iaas
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; iaas-platform.yaml &lt;span class="nt"&gt;-n&lt;/span&gt; iaas

&lt;span class="c"&gt;# Wait for rollout&lt;/span&gt;
kubectl rollout status deployment/iaas-platform &lt;span class="nt"&gt;-n&lt;/span&gt; iaas

&lt;span class="c"&gt;# Get the LoadBalancer IP&lt;/span&gt;
kubectl get svc iaas-platform-svc &lt;span class="nt"&gt;-n&lt;/span&gt; iaas

&lt;span class="c"&gt;# Test it&lt;/span&gt;
curl http://&amp;lt;LOAD_BALANCER_IP&amp;gt;/healthz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Kubernetes gives you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Auto-scaling (CPU-based HPA)&lt;/li&gt;
&lt;li&gt;✅ Self-healing (pod restarts on failure)&lt;/li&gt;
&lt;li&gt;✅ Rolling updates (zero downtime deploys)&lt;/li&gt;
&lt;li&gt;✅ Multi-region ready (Federated clusters)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 5: Infrastructure-as-Code (Terraform)
&lt;/h2&gt;

&lt;p&gt;For repeatable, auditable infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Included
&lt;/h3&gt;

&lt;p&gt;The repo has &lt;code&gt;examples/terraform/&lt;/code&gt; with configs for &lt;strong&gt;single-host Docker deployment&lt;/strong&gt; (great for staging):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# examples/terraform/main.tf&lt;/span&gt;

&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.5"&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;docker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kreuzwerker/docker"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 3.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"docker"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;# PostgreSQL container&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"docker_container"&lt;/span&gt; &lt;span class="s2"&gt;"postgres"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"iaas-platform-postgres"&lt;/span&gt;
  &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;docker_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image_id&lt;/span&gt;
  &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"POSTGRES_USER=iaas"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"POSTGRES_PASSWORD=${var.database_password}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"POSTGRES_DB=iaas"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;ports&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;internal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
    &lt;span class="nx"&gt;external&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database_port&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;volumes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;volume_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;docker_volume&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgres_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="nx"&gt;container_path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/var/lib/postgresql/data"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# App server container&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"docker_container"&lt;/span&gt; &lt;span class="s2"&gt;"server"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"iaas-platform-server"&lt;/span&gt;
  &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;docker_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iaas_platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image_id&lt;/span&gt;
  &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"ENV=production"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"HTTP_ADDR=:${var.server_port}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"DATABASE_URL=postgres://iaas:${var.database_password}@postgres:5432/iaas?sslmode=disable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"JWT_SECRET=${var.jwt_secret}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;ports&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;internal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;server_port&lt;/span&gt;
    &lt;span class="nx"&gt;external&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;server_port&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;docker_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postgres&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;h3&gt;
  
  
  Deploy with Terraform
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;examples/terraform
terraform init
terraform apply &lt;span class="nt"&gt;-var&lt;/span&gt; &lt;span class="nv"&gt;server_image_tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v0.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;✅ Repeatable (same config → same infrastructure)&lt;/li&gt;
&lt;li&gt;✅ Auditable (git history of changes)&lt;/li&gt;
&lt;li&gt;✅ Shareable (colleague runs &lt;code&gt;terraform apply&lt;/code&gt;, gets identical setup)&lt;/li&gt;
&lt;li&gt;✅ Destroyable (tear down with &lt;code&gt;terraform destroy&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Production Readiness Checklist
&lt;/h2&gt;

&lt;p&gt;Before launching, verify:&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;ENV=production&lt;/code&gt; (refuses weak JWT secrets)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;JWT_SECRET&lt;/code&gt; is ≥32 bytes random (run: &lt;code&gt;openssl rand -hex 32&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] TLS enabled (HTTPS only, no HTTP)&lt;/li&gt;
&lt;li&gt;[ ] Database password strong&lt;/li&gt;
&lt;li&gt;[ ] SMTP credentials NOT committed to Git (use env or secrets manager)&lt;/li&gt;
&lt;li&gt;[ ] API key hashing enabled (default)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Health probes working (&lt;code&gt;/healthz&lt;/code&gt;, &lt;code&gt;/readyz&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Logs flowing to stdout (JSON structured via slog)&lt;/li&gt;
&lt;li&gt;[ ] Backups scheduled (&lt;code&gt;pg_dump&lt;/code&gt; daily)&lt;/li&gt;
&lt;li&gt;[ ] Rollback plan documented&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;api-usage.sh&lt;/code&gt; works against production&lt;/li&gt;
&lt;li&gt;[ ] Dashboard loads&lt;/li&gt;
&lt;li&gt;[ ] Can create org, instance, and generate invoice&lt;/li&gt;
&lt;li&gt;[ ] Password reset emails working (if SMTP enabled)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Cost Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Cost/Month&lt;/th&gt;
&lt;th&gt;Setup Time&lt;/th&gt;
&lt;th&gt;Scaling&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Single Host (systemd)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$5-15&lt;/td&gt;
&lt;td&gt;1 hour&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Early-stage startups, learning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Railway/Render&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$5-50&lt;/td&gt;
&lt;td&gt;10 min&lt;/td&gt;
&lt;td&gt;Auto&lt;/td&gt;
&lt;td&gt;Fast iteration, small teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kubernetes (GKE/EKS)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$100+&lt;/td&gt;
&lt;td&gt;2 hours&lt;/td&gt;
&lt;td&gt;Auto&lt;/td&gt;
&lt;td&gt;Enterprise, high traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Terraform (staging)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$10-50&lt;/td&gt;
&lt;td&gt;30 min&lt;/td&gt;
&lt;td&gt;Repeatable&lt;/td&gt;
&lt;td&gt;CI/CD integration, testing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Deployment Workflow (Complete Example)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Build and test locally&lt;/span&gt;
make &lt;span class="nb"&gt;test
&lt;/span&gt;make race
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; iaas-platform:latest &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# 2. Push to registry&lt;/span&gt;
docker tag iaas-platform:latest ghcr.io/you/iaas-platform:v0.1.1
docker push ghcr.io/you/iaas-platform:v0.1.1

&lt;span class="c"&gt;# 3. Deploy to staging (Terraform)&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;examples/terraform
terraform apply &lt;span class="nt"&gt;-var&lt;/span&gt; &lt;span class="nv"&gt;server_image_tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v0.1.1

&lt;span class="c"&gt;# 4. Smoke test&lt;/span&gt;
curl http://staging-server/healthz
bash examples/api-usage.sh

&lt;span class="c"&gt;# 5. Deploy to production (Railway or K8s)&lt;/span&gt;
&lt;span class="c"&gt;# Railway: auto-deploys on git push&lt;/span&gt;
&lt;span class="c"&gt;# K8s: kubectl set image deployment/iaas-platform \&lt;/span&gt;
&lt;span class="c"&gt;#        server=ghcr.io/you/iaas-platform:v0.1.1&lt;/span&gt;

&lt;span class="c"&gt;# 6. Verify&lt;/span&gt;
curl https://iaas.yourdomain.com/healthz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Monitoring in Production
&lt;/h2&gt;

&lt;p&gt;IaaS Platform logs structured JSON (via Go's &lt;code&gt;slog&lt;/code&gt;). Aggregate with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ELK Stack&lt;/strong&gt; — Elasticsearch + Logstash + Kibana&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Datadog&lt;/strong&gt; — SaaS APM (integrates with Kubernetes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grafana Loki&lt;/strong&gt; — Lightweight log aggregation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt; — If using AWS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every request includes an &lt;code&gt;X-Request-ID&lt;/code&gt; for correlation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing:&lt;/strong&gt; Prometheus metrics. That's issue #14; see &lt;a href="https://github.com/ogc16/iaas-platform/blob/master/ROADMAP.md" rel="noopener noreferrer"&gt;ROADMAP.md&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick your platform&lt;/strong&gt; — Start with Railway if unsure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Follow the steps above&lt;/strong&gt; — Copy-paste the configs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test the API&lt;/strong&gt; — Run &lt;code&gt;examples/api-usage.sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explore the dashboard&lt;/strong&gt; — Create an org, spin up an instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open an issue&lt;/strong&gt; — Something missing? File it on GitHub&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  "healthz returns 503"
&lt;/h3&gt;

&lt;p&gt;Database isn't reachable. Check:&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="c"&gt;# Is PostgreSQL running?&lt;/span&gt;
docker ps | &lt;span class="nb"&gt;grep &lt;/span&gt;postgres

&lt;span class="c"&gt;# Can the app reach it?&lt;/span&gt;
curl &lt;span class="nv"&gt;$DATABASE_URL&lt;/span&gt;  &lt;span class="c"&gt;# Should fail gracefully, not hang&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  "502 Bad Gateway"
&lt;/h3&gt;

&lt;p&gt;App crashed. Check logs:&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="c"&gt;# If systemd:&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; iaas-platform &lt;span class="nt"&gt;-f&lt;/span&gt;

&lt;span class="c"&gt;# If Docker:&lt;/span&gt;
docker logs iaas-platform-server

&lt;span class="c"&gt;# If Kubernetes:&lt;/span&gt;
kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; deployment/iaas-platform &lt;span class="nt"&gt;-n&lt;/span&gt; iaas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  "Certificate verification failed"
&lt;/h3&gt;

&lt;p&gt;TLS misconfigured. For development:&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;--insecure&lt;/span&gt; https://localhost:8080/healthz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production, ensure Let's Encrypt cert is valid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl x509 &lt;span class="nt"&gt;-in&lt;/span&gt; /etc/letsencrypt/live/yourdomain.com/fullchain.pem &lt;span class="nt"&gt;-text&lt;/span&gt; &lt;span class="nt"&gt;-noout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;This series has covered:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/..."&gt;Part 1&lt;/a&gt; - Architecture&lt;/strong&gt;: Multi-tenant design, billing engine, async lifecycle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/..."&gt;Part 2&lt;/a&gt; - Deployment&lt;/strong&gt; (this post): Local, single-host, containerized, K8s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3 (coming soon)&lt;/strong&gt; - Scaling beyond v0.1.0: Prometheus metrics, webhook notifications, real compute backends&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Join the Community
&lt;/h2&gt;

&lt;p&gt;The IaaS Platform is open source and growing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/ogc16/iaas-platform" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💬 &lt;a href="https://github.com/ogc16/iaas-platform/discussions" rel="noopener noreferrer"&gt;Discussions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐛 &lt;a href="https://github.com/ogc16/iaas-platform/issues" rel="noopener noreferrer"&gt;Open Issues&lt;/a&gt; (5 good-first-issues for contributors)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Have deployment questions?&lt;/strong&gt; Reply in the comments below or open an issue.&lt;/p&gt;

&lt;p&gt;Happy deploying! 🚀&lt;/p&gt;

</description>
      <category>iaas</category>
      <category>saas</category>
      <category>devops</category>
      <category>docker</category>
    </item>
    <item>
      <title>Learn how to build a cloud control panel with authentication, billing, and resource management — complete with runnable code.</title>
      <dc:creator>ogc16</dc:creator>
      <pubDate>Fri, 14 Aug 2026 12:20:24 +0000</pubDate>
      <link>https://dev.to/ogc16/learn-how-to-build-a-cloud-control-panel-with-authentication-billing-and-resource-management--530e</link>
      <guid>https://dev.to/ogc16/learn-how-to-build-a-cloud-control-panel-with-authentication-billing-and-resource-management--530e</guid>
      <description>&lt;h2&gt;
  
  
  Building a Multi-Tenant IaaS Platform in Go: From Zero to Production
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Learn how to build a cloud control plane with authentication, billing, and resource management — complete with runnable code.&lt;/em&gt;&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I built an open-source Infrastructure-as-a-Service platform in Go with multi-tenant orgs, async compute lifecycle, usage-based billing, and production-grade security. It's ~2,000 lines of code, fully tested, and ready to deploy. &lt;a href="https://github.com/ogc16/iaas-platform" rel="noopener noreferrer"&gt;Check it out on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;A few months ago, I was trying to understand how cloud platforms like AWS, DigitalOcean, and Heroku work under the hood. Specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do they isolate customer data across multiple organizations?&lt;/li&gt;
&lt;li&gt;How does the billing engine track usage and generate invoices?&lt;/li&gt;
&lt;li&gt;How do they manage async compute lifecycle (start/stop/terminate)?&lt;/li&gt;
&lt;li&gt;What does secure multi-tenant architecture actually look like?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I couldn't find a reference implementation that was both &lt;strong&gt;simple enough to learn from&lt;/strong&gt; and &lt;strong&gt;complete enough to be production-like&lt;/strong&gt;. So I built one.&lt;/p&gt;

&lt;p&gt;The result is &lt;strong&gt;IaaS Platform&lt;/strong&gt;: a fully-functional control plane that handles authentication, multi-tenancy, compute resource management, and usage-based billing — all in ~2,000 lines of clean, tested Go code.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does It Do?
&lt;/h2&gt;

&lt;p&gt;Imagine you're building your own version of AWS or Heroku. You need:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ &lt;strong&gt;Authentication &amp;amp; Tenancy&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Users sign up with email/password&lt;/li&gt;
&lt;li&gt;Each user can create multiple organizations&lt;/li&gt;
&lt;li&gt;Organizations have members with roles (admin/member)&lt;/li&gt;
&lt;li&gt;Member suspensions with auto-expiry&lt;/li&gt;
&lt;li&gt;API keys for programmatic access&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2️⃣ &lt;strong&gt;Compute Lifecycle&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Users request compute instances&lt;/li&gt;
&lt;li&gt;Instances move through states asynchronously: &lt;code&gt;pending → running → stopping → stopped&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Per-organization quotas (max 20 instances, 16 vCPU, 32 GB RAM, 500 GB disk)&lt;/li&gt;
&lt;li&gt;Per-region capacity enforcement (e.g., us-east-1 has 64 vCPU total)&lt;/li&gt;
&lt;li&gt;Background reconciler settles transient states&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3️⃣ &lt;strong&gt;Usage-Based Billing&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Track CPU hours, memory GB-hours, disk GB-hours&lt;/li&gt;
&lt;li&gt;Pricing: $0.50/core-hour, $0.20/GB-hour, $0.01/GB-hour&lt;/li&gt;
&lt;li&gt;Generate invoices monthly with line items&lt;/li&gt;
&lt;li&gt;Audit-logged every transaction&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4️⃣ &lt;strong&gt;Production Features&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JWT + API key authentication (both Bearer and X-API-Key)&lt;/li&gt;
&lt;li&gt;Rate limiting (token bucket, 1 req/sec per IP/API key)&lt;/li&gt;
&lt;li&gt;Security headers (CSP, HSTS, X-Frame-Options, etc.)&lt;/li&gt;
&lt;li&gt;Bcrypt password hashing (cost 12)&lt;/li&gt;
&lt;li&gt;API keys stored as SHA-256 hashes at rest&lt;/li&gt;
&lt;li&gt;CodeQL + gitleaks in CI&lt;/li&gt;
&lt;li&gt;Full test suite with integration tests&lt;/li&gt;
&lt;li&gt;OpenAPI 3.0 spec included&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;Here's how the pieces fit together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────┐
│  HTTP Client (curl, SDK, Dashboard)                 │
│  with JWT Bearer or X-API-Key                       │
└─────────────────┬───────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────┐
│  Chi Router + Middleware Layer                      │
│  • CORS, Logging, Rate Limiting, Security Headers   │
│  • Request ID propagation                           │
└─────────────────┬───────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────┐
│  Service Layer (Business Logic)                     │
│  • AuthService (JWT, bcrypt, API keys)              │
│  • ComputeService (quota, capacity, state machine)  │
│  • BillingService (usage tracking, invoices)        │
│  • OrganizationService (multi-tenancy)              │
└─────────────────┬───────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────┐
│  PostgreSQL 16 (pgx driver)                         │
│  • users, organizations, members, instances         │
│  • usage_records, invoices, invoices_line_items     │
│  • quotas, region_capacity                          │
└─────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; The API layer is intentionally thin. All business rules (quota checks, capacity enforcement, multi-tenancy gates) live in the &lt;em&gt;service layer&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let's Look at the Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Multi-Tenant Quota Enforcement
&lt;/h3&gt;

&lt;p&gt;Here's how we prevent one organization from consuming all resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// internal/compute/service.go&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;enforceQuota&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;disk&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quotas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"get quota: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Sum active instances for this org&lt;/span&gt;
    &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SumActiveByOrg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sum org usage: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Check each dimension: instances, CPU, memory, disk&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxInstances&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%w: would exceed quota"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrQuotaExceeded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CPUCores&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxCPUCores&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%w: CPU exceeds quota (%d max)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrQuotaExceeded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxCPUCores&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemoryMB&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxMemoryMB&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%w: memory exceeds quota"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrQuotaExceeded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DiskGB&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxDiskGB&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%w: disk exceeds quota"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrQuotaExceeded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What's important here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-dimensional quotas (not just "max instances", but CPU, memory, disk separately)&lt;/li&gt;
&lt;li&gt;Check enforcement at creation time (fail fast)&lt;/li&gt;
&lt;li&gt;Each org has independent limits&lt;/li&gt;
&lt;li&gt;Graceful error messages that tell users exactly what they hit&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Async State Machine
&lt;/h3&gt;

&lt;p&gt;Instances don't provision instantly. Here's how we handle that without blocking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// internal/compute/service.go&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;instanceTransitions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"pending"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"running"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// reconciler advances this&lt;/span&gt;
        &lt;span class="s"&gt;"terminating"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// user can terminate anytime&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"running"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"stopping"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"terminating"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"stopping"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"stopped"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// reconciler advances this&lt;/span&gt;
        &lt;span class="s"&gt;"terminating"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"stopped"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"pending"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// user restarts&lt;/span&gt;
        &lt;span class="s"&gt;"terminating"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"terminating"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"terminated"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c"&gt;// reconciler advances this&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateInstanceRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputeInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// ... validation &amp;amp; quota checks ...&lt;/span&gt;

    &lt;span class="n"&gt;inst&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputeInstance&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;OrganizationID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;         &lt;span class="s"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// Start here&lt;/span&gt;
        &lt;span class="c"&gt;// ... specs ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Immediately persist to DB&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inst&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Return 202 Accepted to client&lt;/span&gt;
    &lt;span class="c"&gt;// Background reconciler advances pending → running&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;inst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API returns immediately (202 Accepted, not blocking)&lt;/li&gt;
&lt;li&gt;Client polls &lt;code&gt;/orgs/{id}/instances/{id}&lt;/code&gt; to watch status&lt;/li&gt;
&lt;li&gt;Background reconciler (runs every 2 seconds) advances &lt;code&gt;pending → running&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prevents one slow provision from blocking other requests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Usage-Based Billing
&lt;/h3&gt;

&lt;p&gt;Here's how we track usage and generate invoices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// internal/billing/service.go&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;unitPrices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"cpu_hours"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;           &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// $0.50 per CPU hour&lt;/span&gt;
    &lt;span class="s"&gt;"memory_gb_hours"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// $0.20 per GB-hour&lt;/span&gt;
    &lt;span class="s"&gt;"disk_gb_hours"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;// $0.01 per GB-hour&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GenerateInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Invoice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;periodStart&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Month&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;periodEnd&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;periodStart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Get 30-day usage summary&lt;/span&gt;
    &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;usageRepo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;periodStart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Calculate amounts in cents&lt;/span&gt;
    &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;resourceType&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="n"&gt;quantity&lt;/span&gt;     &lt;span class="kt"&gt;float64&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;}{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"cpu_hours"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CPUHours&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"CPU Hours"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"memory_gb_hours"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemoryGBHours&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Memory GB-hours"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"disk_gb_hours"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DiskGBHours&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Disk GB-hours"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;totalCents&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;totalCents&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unitPrices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Create invoice and line items&lt;/span&gt;
    &lt;span class="n"&gt;inv&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Invoice&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;OrganizationID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;AmountCents&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;totalCents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;PeriodStart&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;periodStart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;PeriodEnd&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;periodEnd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;         &lt;span class="s"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoiceRepo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Add detailed line items for transparency&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvoiceLineItem&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;InvoiceID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;inv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ResourceType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;UnitPriceCents&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unitPrices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;AmountCents&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unitPrices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;])),&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoiceRepo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddLineItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;inv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key details:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usage tracked in 30-day windows&lt;/li&gt;
&lt;li&gt;Money always in cents (integer math, no float rounding errors)&lt;/li&gt;
&lt;li&gt;Line items for transparency (customers can see CPU hours vs memory hours)&lt;/li&gt;
&lt;li&gt;Idempotent (calling twice for same month doesn't double-charge)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Multi-Tenant Security
&lt;/h3&gt;

&lt;p&gt;Every service layer operation checks membership before proceeding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Pattern repeated across compute, billing, organizations services&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instanceID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputeInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// ALWAYS check membership first&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orgRepo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FindMember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrNotInOrg&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"check membership: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Then get the resource&lt;/span&gt;
    &lt;span class="n"&gt;inst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FindByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instanceID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Verify it belongs to the right org&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;inst&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrganizationID&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;orgID&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrNotFound&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;inst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this is critical:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-tenancy is enforced at the &lt;em&gt;service layer&lt;/em&gt;, not just the router&lt;/li&gt;
&lt;li&gt;Prevents SQL injection or logic bugs from leaking data across orgs&lt;/li&gt;
&lt;li&gt;Defense in depth: router checks + service checks&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting Started (5 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker &amp;amp; Docker Compose&lt;/li&gt;
&lt;li&gt;Go 1.26+&lt;/li&gt;
&lt;li&gt;curl &amp;amp; jq (for examples)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Start
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Clone the repo&lt;/span&gt;
git clone https://github.com/ogc16/iaas-platform.git
&lt;span class="nb"&gt;cd &lt;/span&gt;iaas-platform

&lt;span class="c"&gt;# 2. Start PostgreSQL&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# 3. Run the server&lt;/span&gt;
go run ./cmd/server

&lt;span class="c"&gt;# 4. Try the API&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/api/v1/auth/signup &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"test@example.com","password":"changeme123","name":"Demo User"}'&lt;/span&gt;

&lt;span class="c"&gt;# 5. Explore the dashboard&lt;/span&gt;
open http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or run the full end-to-end demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash examples/quick-start.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ol&gt;
&lt;li&gt;Start PostgreSQL&lt;/li&gt;
&lt;li&gt;Boot the server&lt;/li&gt;
&lt;li&gt;Create a user account&lt;/li&gt;
&lt;li&gt;Create an organization&lt;/li&gt;
&lt;li&gt;Provision an instance (watch it move from &lt;code&gt;pending&lt;/code&gt; → &lt;code&gt;running&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Record usage and generate an invoice&lt;/li&gt;
&lt;li&gt;Clean up everything&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Production Readiness Checklist
&lt;/h2&gt;

&lt;p&gt;The platform is designed to be deployed to production. Here's what we included:&lt;/p&gt;

&lt;h3&gt;
  
  
  Security ✅
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Passwords: bcrypt (cost 12)&lt;/li&gt;
&lt;li&gt;API keys: stored as SHA-256 hashes&lt;/li&gt;
&lt;li&gt;JWT: HS256, 24h expiry, configurable&lt;/li&gt;
&lt;li&gt;Headers: CSP, HSTS, X-Frame-Options, etc.&lt;/li&gt;
&lt;li&gt;Secret scanning: gitleaks in CI&lt;/li&gt;
&lt;li&gt;Code scanning: CodeQL on every PR&lt;/li&gt;
&lt;li&gt;Audit logging: every action recorded with actor/IP/timestamp&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing ✅
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;45%+ code coverage&lt;/li&gt;
&lt;li&gt;Unit tests for all services&lt;/li&gt;
&lt;li&gt;Integration tests against PostgreSQL&lt;/li&gt;
&lt;li&gt;Race detector enabled in CI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;go vet&lt;/code&gt; &amp;amp; &lt;code&gt;gofmt&lt;/code&gt; checks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operations ✅
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Health probes: &lt;code&gt;/healthz&lt;/code&gt; (always 200) and &lt;code&gt;/readyz&lt;/code&gt; (checks DB)&lt;/li&gt;
&lt;li&gt;Structured logging with request IDs&lt;/li&gt;
&lt;li&gt;OpenAPI 3.0 spec (machine-readable)&lt;/li&gt;
&lt;li&gt;Docker multi-stage build (distroless runtime)&lt;/li&gt;
&lt;li&gt;Graceful shutdown&lt;/li&gt;
&lt;li&gt;Connection pooling (pgx)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment ✅
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Environment-based config (12-factor app)&lt;/li&gt;
&lt;li&gt;TLS support (in-process or reverse proxy)&lt;/li&gt;
&lt;li&gt;Horizontal scaling ready (but bring your own shared rate-limit store)&lt;/li&gt;
&lt;li&gt;Kubernetes-friendly (health probes, graceful shutdown, resource requests)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;This is v0.1.0. The roadmap includes:&lt;/p&gt;

&lt;h3&gt;
  
  
  v1.0
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Prometheus metrics export (&lt;code&gt;/metrics&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] CORS allowlist (currently allows all origins)&lt;/li&gt;
&lt;li&gt;[ ] Request-body size limits&lt;/li&gt;
&lt;li&gt;[ ] API key rotation endpoint&lt;/li&gt;
&lt;li&gt;[ ] golangci-lint integration&lt;/li&gt;
&lt;li&gt;[ ] Transaction support for multi-step writes&lt;/li&gt;
&lt;li&gt;[ ] Database migrations versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  v2.0
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Real compute backends (Docker, Podman, AWS EC2)&lt;/li&gt;
&lt;li&gt;[ ] Webhook notifications for lifecycle events&lt;/li&gt;
&lt;li&gt;[ ] Per-account rate limiting beyond global bucket&lt;/li&gt;
&lt;li&gt;[ ] Control plane dashboard v2 (real-time charts, cost forecasts)&lt;/li&gt;
&lt;li&gt;[ ] Audit logs UI&lt;/li&gt;
&lt;li&gt;[ ] Usage aggregation jobs (move billing out of request path)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;Building this taught me several things I wish I'd known earlier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service layer is the security perimeter.&lt;/strong&gt; Router auth checks are necessary but not sufficient. Every service method should re-verify authorization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Async operations unblock your API.&lt;/strong&gt; Don't provision instances synchronously. Return 202 Accepted, then have a background reconciler advance state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Track money in cents, not dollars.&lt;/strong&gt; Float precision issues will haunt you. Use integers for financial calculations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-dimensionality matters.&lt;/strong&gt; Quotas aren't just "max instances". Real systems need CPU, memory, disk, and network quotas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observability from day one.&lt;/strong&gt; Structured logging, health probes, and OpenAPI specs aren't afterthoughts. Build them in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test with real PostgreSQL.&lt;/strong&gt; Unit tests are great, but integration tests against your actual database catch the bugs that matter.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/ogc16/iaas-platform" rel="noopener noreferrer"&gt;ogc16/iaas-platform&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ Star if you find it useful&lt;/li&gt;
&lt;li&gt;🐛 Open issues for bugs or feature requests&lt;/li&gt;
&lt;li&gt;🤝 PRs welcome — see CONTRIBUTING.md&lt;/li&gt;
&lt;li&gt;💬 Questions? Start a discussion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;If you want to dig deeper:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/ogc16/iaas-platform/blob/master/docs/ARCHITECTURE.md" rel="noopener noreferrer"&gt;Architecture Deep Dive&lt;/a&gt; — detailed system design&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ogc16/iaas-platform/blob/master/SECURITY.md" rel="noopener noreferrer"&gt;Security Model&lt;/a&gt; — threat analysis &amp;amp; configuration hardening&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ogc16/iaas-platform/blob/master/openapi.yaml" rel="noopener noreferrer"&gt;OpenAPI Spec&lt;/a&gt; — every endpoint documented&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ogc16/iaas-platform/blob/master/docs/DEPLOYMENT.md" rel="noopener noreferrer"&gt;Deployment Guide&lt;/a&gt; — production hardening&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Let's Connect
&lt;/h2&gt;

&lt;p&gt;What aspects of building multi-tenant systems interest you most? I'd love to hear your thoughts in the comments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are you building a SaaS platform?&lt;/li&gt;
&lt;li&gt;Which part would you like me to explain in more detail?&lt;/li&gt;
&lt;li&gt;What did you learn from this project?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tweet &lt;a href="https://twitter.com/ogc16" rel="noopener noreferrer"&gt;@ogc16&lt;/a&gt; or reply here.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>go</category>
    </item>
    <item>
      <title>MCP Servers Explained</title>
      <dc:creator>ogc16</dc:creator>
      <pubDate>Fri, 28 Mar 2025 08:43:28 +0000</pubDate>
      <link>https://dev.to/ogc16/mcp-servers-explained-4p7a</link>
      <guid>https://dev.to/ogc16/mcp-servers-explained-4p7a</guid>
      <description>&lt;p&gt;MCP Servers are systems that provide context, tools, and prompts to AI clients. &lt;a href="https://mcp.so/" rel="noopener noreferrer"&gt;See&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MCP is a standard open-source protocol developed for AI to securely access external data and tools, enabling consistent and interoperable interactions&lt;br&gt;
using a client-server system with standardized requests and secure OAuth authorization, allowing AI to access external tools and data sources.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>oauth</category>
      <category>automation</category>
    </item>
    <item>
      <title>How are you adapting as a developer?</title>
      <dc:creator>ogc16</dc:creator>
      <pubDate>Fri, 28 Mar 2025 07:20:08 +0000</pubDate>
      <link>https://dev.to/ogc16/how-are-you-adapting-as-a-developer-pc4</link>
      <guid>https://dev.to/ogc16/how-are-you-adapting-as-a-developer-pc4</guid>
      <description>&lt;p&gt;With a few prompts you are able to achieve amazing products like:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Streaming platform&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The objective is to create a streaming service offering a diverse library of content, personalized recommendations, and innovative features that enhance the viewing experience. This platform will differentiate itself through a focus on niche content, community engagement, and flexible pricing models while maintaining affordability and accessibility for users worldwide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Goals and Objectives&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&amp;gt; Primary Goals&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide a vast library of movies, TV shows, documentaries, and original content.&lt;/li&gt;
&lt;li&gt;Offer advanced personalization through AI-driven recommendations based on user behavior and preferences.&lt;/li&gt;
&lt;li&gt;Support community features like live watch parties, discussion forums, and user-generated content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&amp;gt; Secondary Goals&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Introduce flexible pricing models (e.g., à la carte content selection, tiered subscriptions).&lt;/li&gt;
&lt;li&gt;Ensure seamless integration with various devices (smart TVs, mobile apps, gaming consoles).&lt;/li&gt;
&lt;li&gt; Offer high-quality video streaming with options for 4K, HDR, and Dolby Atmos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Target Audience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;gt;Primary Users&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Young adults (18–35) seeking diverse content options and social features.&lt;/li&gt;
&lt;li&gt; Niche audiences interested in independent films, documentaries, or international content.&lt;/li&gt;
&lt;li&gt; Families looking for affordable entertainment solutions with parental controls.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&amp;gt;Demographics&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Global reach with a focus on urban, tech-savvy individuals who value content discovery and community engagement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Competitor Analysis&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Netflix:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Strengths: Extensive content library, strong brand recognition, user-friendly interface.&lt;br&gt;
Weaknesses: Increasing costs; limited focus on niche content or community features.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Amazon Prime Video:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Strengths: Integration with Amazon ecosystem; additional benefits like free shipping.&lt;br&gt;
Weaknesses: Confusing interface; less emphasis on social features.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Hulu:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Strengths: Strong focus on TV shows; affordable pricing options.&lt;br&gt;
Weaknesses: Limited international content; fewer original titles compared to Netflix.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Disney+:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Strengths: Exclusive Disney, Pixar, Marvel, and Star Wars content; family-friendly focus.&lt;br&gt;
Weaknesses: Limited content diversity beyond Disney franchises.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&amp;gt; Design Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Functional Needs:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Advanced search and recommendation algorithms based on user viewing history and ratings.&lt;/li&gt;
&lt;li&gt; Community features like live watch parties with real-time chat, user reviews, and ratings.&lt;/li&gt;
&lt;li&gt; Flexible pricing models allowing users to choose specific content bundles or à la carte options.&lt;/li&gt;
&lt;li&gt; High-quality video streaming with support for 4K, HDR, and Dolby Atmos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&amp;gt; Visual Design:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean interface with customizable themes (light/dark mode).&lt;/li&gt;
&lt;li&gt;Dynamic content showcases highlighting new releases, user favorites, and trending titles.&lt;/li&gt;
&lt;li&gt;Intuitive navigation for discovering new content or accessing personalized recommendations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Regards&lt;/em&gt; &lt;a href="//x.com/d4m1n/status/1905285032849129795"&gt;Ref&lt;/a&gt;&lt;/p&gt;

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

</description>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Can AI outsmart Human beings?</title>
      <dc:creator>ogc16</dc:creator>
      <pubDate>Wed, 26 Mar 2025 19:10:42 +0000</pubDate>
      <link>https://dev.to/ogc16/can-ai-outsmart-human-beings-l31</link>
      <guid>https://dev.to/ogc16/can-ai-outsmart-human-beings-l31</guid>
      <description>&lt;h2&gt;
  
  
  Software's Future: Developer's Role Evolves
&lt;/h2&gt;

&lt;p&gt;Software drives our world, from phones to global systems. Developers are key, but tech advances bring change.&lt;br&gt;
The world is increasingly powered by software. From the smartphones in our pockets to the complex systems running global infrastructure, software developers are the architects of our digital reality. But as technology advances at an unprecedented pace, what does the future hold for these vital professionals? It's a landscape of both immense opportunity and evolving challenges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Rise of AI and Automation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Perhaps the most significant shift is the increasing integration of artificial intelligence (AI) and automation into the development workflow. AI-powered tools are already assisting with code generation, bug detection, and testing, streamlining the development process. In the future, we can expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI-assisted coding:&lt;/strong&gt; AI models will become more sophisticated, capable of generating complex code snippets and even entire applications based on high-level specifications. This doesn't mean developers will be replaced, but rather that their role will evolve towards higher-level design and architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated testing and deployment:&lt;/strong&gt; Continuous integration and continuous deployment (CI/CD) pipelines, powered by AI, will become even more prevalent, allowing for faster and more reliable software releases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low-code/no-code platforms:&lt;/strong&gt; These platforms, which enable non-developers to create applications, will become more powerful and user-friendly. Developers will likely work alongside these platforms, integrating them into larger systems and building custom extensions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Expanding Scope of Software Development:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software is permeating every aspect of our lives, leading to a broader range of development domains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Internet of Things (IoT):&lt;/strong&gt; With the proliferation of connected devices, developers will be crucial in building secure and efficient IoT applications, from smart home systems to industrial automation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge computing:&lt;/strong&gt; As data processing moves closer to the source, developers will need to master edge computing technologies to build low-latency and responsive applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantum computing:&lt;/strong&gt; While still in its early stages, quantum computing holds immense potential for solving complex problems. Developers who specialize in quantum algorithms and software will be highly sought after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual and Augmented Reality (VR/AR):&lt;/strong&gt; The metaverse and immersive experiences are rapidly expanding, creating demand for developers who can build engaging and interactive VR/AR applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cybersecurity:&lt;/strong&gt; As software becomes more integrated into critical infrastructure, cybersecurity will become paramount. Developers will need to prioritize security best practices and understand how to build resilient systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Importance of Soft Skills and Adaptability:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Technical skills remain essential, but soft skills are becoming increasingly crucial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Communication and collaboration:&lt;/strong&gt; Developers will need to effectively communicate with stakeholders, collaborate with cross-functional teams, and explain complex technical concepts to non-technical audiences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problem-solving and critical thinking:&lt;/strong&gt; The ability to analyze complex problems, identify root causes, and develop innovative solutions will be highly valued.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous learning and adaptability:&lt;/strong&gt; The technology landscape is constantly evolving, so developers must be lifelong learners, willing to embrace new technologies and adapt to changing requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ethical considerations:&lt;/strong&gt; As software becomes more powerful, developers will need to consider the ethical implications of their work, ensuring that their creations are used responsibly and for the benefit of society.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Rise of Specialized Roles:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As the field of software development becomes more complex, specialization will become increasingly important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI/ML engineers:&lt;/strong&gt; Developers with expertise in machine learning and deep learning will be in high demand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud architects:&lt;/strong&gt; Designing and managing cloud-based infrastructure will require specialized skills.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevOps engineers:&lt;/strong&gt; Streamlining the development and deployment process will remain a critical role.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security engineers:&lt;/strong&gt; Protecting software systems from cyber threats will be a top priority.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data scientists and engineers:&lt;/strong&gt; The ability to process and analyze large datasets will be essential for building data-driven applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The future for software developers is bright, albeit one that requires constant adaptation. While AI and automation may reshape the development process, they will also create new opportunities for developers to focus on higher-level tasks and innovate in emerging fields. The key to success will be a combination of strong technical skills, essential soft skills, and a willingness to embrace continuous learning. By staying ahead of the curve and adapting to the evolving landscape, software developers can continue to play a vital role in shaping the future of technology.&lt;br&gt;
Verdict: There are a lot tasks to be completed by human beings.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>cybersecurity</category>
      <category>futurechallenge</category>
    </item>
    <item>
      <title>Software's Future: Developer's Role Evolves Software drives our world, from phones to global systems. Developers are key, but tech advances bring change. The world is increasingly powered by software. From the smartphones in our pockets to the complex</title>
      <dc:creator>ogc16</dc:creator>
      <pubDate>Wed, 26 Mar 2025 18:56:54 +0000</pubDate>
      <link>https://dev.to/ogc16/-softwares-future-developers-role-evolves-software-drives-our-world-from-phones-to-global-533j</link>
      <guid>https://dev.to/ogc16/-softwares-future-developers-role-evolves-software-drives-our-world-from-phones-to-global-533j</guid>
      <description></description>
      <category>softwaredevelopment</category>
      <category>developer</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
