Vibe Coding Infrastructure: How I Orchestrated a Modern Tech Stack with Gemini CLI in 3 Hours

By Michael Elias on January 1, 2026

·

85 views

I’m an infrastructure guy. My coding chops are limited to Bash and Perl. Okay, let’s be honest—I’m an old infrastructure guy.

But that’s exactly the point. I wanted a place for my colleagues and me to blog about our AI journeys, but I didn't want to spend months learning a modern JavaScript stack. So, I figured I’d take my infrastructure experience and try some "vibe coding" with the Gemini CLI to build a modern blog site from scratch.

"I can't go back to yesterday because I was a different person then." — Lewis Carroll

It took me 7 days of trial and error, changing personas, and battling dependencies to figure it out initially. But once I had a working app, I asked the LLM to write a prompt that could replicate the build.

Here is the payoff: I wiped the server and ran that AI-generated prompt. It rebuilt the entire end-to-end application in just 3 hours.

Was the prompt precise? No. Did I still have to intervene? Yes. But it turned a week of frustration into a single afternoon of work.

Here is how I went down the rabbit hole so you don't have to, and the prompt that does the heavy lifting for you.

The Goal: Orchestration Over Code Generation

I know I could have used tools like Replit Agent, Cursor Composer, or Lovable. But as an infrastructure engineer, I wanted to see what Gemini could orchestrate if it had access to my terminal, my cloud environment, and the right tools.

I didn't just want code snippets; I wanted the LLM to execute shell commands, satisfy dependencies, and deploy infrastructure.

The Architecture: This isn't a simple static site. We are building a fully decoupled architecture:

  • Host: RHEL 9 (Google Cloud Compute Engine)
  • CMS: Sanity.io (Headless CMS)
  • Frontend: Next.js
  • Backend Services: Google Cloud Run (for email triggers)
  • Web Server: Nginx with Let’s Encrypt SSL
"Architecture diagram showing Gemini CLI orchestrating a full-stack deployment: RHEL 9 server, Sanity.io CMS, Google Cloud Run for email services, and Next.js frontend."

Caption: The high-level architecture orchestrated by the Gemini CLI.

The Prompt: Alice in the Rabbit Hole

I started by spinning up a fresh RHEL 9 machine in GCP. Before we could even start the journey, I needed to install the gemini-cli.

Installing Node.js:

Bash

curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo dnf install -y nodejs

Installing & Logging into Gemini:

Bash

sudo npm install -g @google/gemini-cli
gemini login

Once logged in, I pasted the prompt generated from my previous week of work and let the agent take the wheel.

Terminal screenshot showing Gemini CLI listing the project phases for building a Next.js blog.

Caption: Gemini accepts the mission and begins outlining the project phases.

Step 1: The CMS (Sanity.io) & Connectivity

The first challenge we tackled together was installing Sanity.io. We worked through the initial setup, but eventually hit a connectivity issue.

Sanity requires you to log in via a browser callback to localhost. Since I was using PuTTY to access a remote RHEL server, the browser on my laptop couldn't see the callback on the server.

The Fix: I set up an SSH tunnel on port 4321 to support the login.

Then came the schema creation. I asked Gemini:

"Can you create the basic schemas to support categories, authors, posts, subscribers, and comments?"

Gemini built the schemas successfully.

Console Output:

√ ReadFolder ./

Listed 11 item(s).

♦ Okay, I see the schemaTypes directory. I will now create the schema files inside it.

[ Citations: https://github.com/chromeos/chromeos.dev https://github.com/realitydesigners/web-app https://stackoverflow.com/questions/74135712/object-object-being-displayed-when-trying-to-render-blockcontent-on-react https://stackoverflow.com/questions/78610656/sanity-cms-definetype-fields-and-of-types-mismatch https://www.sanity.io/answers/setting-page-title-and-description-in-sanity-using-element-previews

? WriteFile Writing to schemaTypes/post.ts

No changes detected.

Apply this change?

● 1. Allow once 2. Allow for this session 3. Modify with external editor 4. No, suggest changes (esc)

□ WriteFile Writing to schemaTypes/author.ts

Caption: The CLI automatically generating the TypeScript schemas for the CMS.

However, when it told me to "check the studio," it neglected to mention that the Sanity dev server listens on http://localhost:3333.

Infrastructure Lesson: If you are running this on a remote VM, you must tunnel port 3333. Also, Sanity defaulted to IPv6, so I had to explicitly force IPv4:

Bash

sanity start host=0.0.0.0

Step 2: Cloud Run & Email Triggers

With the CMS running, we moved to the mailing list functionality. The LLM provided the specific gcloud SDK commands to configure a Cloud Run service for handling email notifications via Mailjet.

I executed the commands it provided, and the deployment went surprisingly smooth. Cloud Run returned a service URL. Note: Keep that URL handy; you need it for the Sanity.io webhook configuration.

Step 3: Next.js & The "Who Did What?" Confusion

Installing Next.js required some back-and-forth. I had to choose a "custom install" to see the options the LLM was assuming I would take.

We launched the app on localhost:3000 (another SSH tunnel required). Initially, I couldn't see the posts I had created in the CMS. It turned out to be a rendering issue in the code, which we resolved by pasting the errors back into the chat.

Browser preview of a raw Next.js blog post successfully fetching content from the Sanity.io backend on localhost.

Caption: The "Hello World" moment—our local dev environment finally pulling content from Sanity.

The "Agent vs. User" Confusion: Sometimes the LLM forgets who executed a task. For example, it asked me to verify that I had created src/app/api/subscribe/route.ts. In reality, the agent had created that file, not me. It’s important to read the "Verify" lists carefully.

Step 4: Production Deployment (Nginx, Certbot & SELinux)

The application was built. Now, it was time to expose it to the world.

When the LLM tried to install Nginx, it assumed I was on an Apt-based system (Debian/Ubuntu). Since I was on RHEL, the commands failed.

Prompting Tip: Be finite. Tell the LLM explicitly what OS you are running (e.g., "I am on RHEL 9").

We compiled the app (npm run build), launched it with PM2 (Process Manager), and configured Nginx as a reverse proxy.

PM2 process list in Linux terminal showing the Next.js application status as online and monitoring memory usage

Caption: PM2 keeping our Next.js application alive in the background.

Finally, we used Certbot for SSL.

Certbot terminal output confirming successful Let's Encrypt SSL certificate deployment for thefactorysystem.ai

Caption: Securing the site with Let's Encrypt.

The 502 Bad Gateway Trap: Nginx was up, SSL was valid, but I got a 502 error. The gateway wasn't talking to the Next.js app. I pasted the error into Gemini. It wasn't a code issue; it was an infrastructure issue. SELinux was blocking the connection.

The LLM correctly identified this and provided the boolean fix:

Bash

setsebool -P httpd_can_network_connect 1

The Payoff: From 7 Days to 3 Hours

After my initial 7-day "learning phase" to get the first version of the site running, I asked the LLM to generate a single prompt that could recreate the entire build.

The prompt below is what I used to achieve the 3-hour build describe above:

Role: You are a Software Engineering Project Orchestrator LLM. Your primary goal is to guide a developer user through the complete setup, configuration, and deployment of a modern, content-driven web application. You will follow a structured, secure, and iterative process.

  Overall Project Goal:
  Orchestrate the build of a full-stack, content-driven website. This involves setting up a Next.js frontend, a headless Sanity.io CMS backend, a serverless notification service on Google Cloud Run, and deploying the
  final application to a Linux server using PM2, Nginx, and Certbot for SSL.

  Core Technology Stack:
   * Frontend: Next.js
   * Backend (CMS): Sanity.io
   * Serverless Function: Node.js on Google Cloud Run
   * Email Provider: Mailjet (or a similar transactional email service)
   * Deployment: Linux Server, PM2, Nginx, Certbot

  Step-by-Step Orchestration Plan:

  Phase 1: Prerequisites & Account Setup
   1. Confirm the user has the necessary accounts:
       * A Sanity.io account.
       * A Google Cloud Platform (GCP) account with a project created and billing enabled.
       * A Mailjet (or similar) account.

This prompt worked, but as I detailed in the blog, we still hit snag points (OS versions, connectivity, specific package names). After this 3-hour execution was complete, I asked the LLM to analyze our session logs and create an enhanced prompt—one that anticipates the RHEL environment, the verify steps, and the troubleshooting we just did.

That's an excellent question. Reflecting on our session, we can definitely make the initial prompt more robust to preemptively handle the issues we encountered. The key is to add more specificity regarding the environment and to build in verification steps.

Here are the improvements we could make to the original prompt, broken down by the problems they would solve:

1. Improved OS/Environment Awareness
This would have solved the apt vs. dnf and Certbot/SELinux issues.

Suggested Prompt Change:

Under Phase 6: Server Deployment, modify the first step:

Guide the user to ssh into their Linux server. Crucially, at the very beginning of this phase, ask the user to identify their Linux distribution and version (e.g., Ubuntu 22.04, RHEL 9). All subsequent server commands must be tailored to the specified distribution.

If the distribution is Debian/Ubuntu, use apt for package management.

If the distribution is RHEL/CentOS/Fedora, use dnf (or yum) and inform the user that you may need to enable the EPEL repository for certain packages.

When instructing the user to install global Node packages, always prepend the command with sudo to prevent permission errors.

2. Proactive Troubleshooting for Common Sticking Points

Caption: Gemini analyzing its own performance to generate a better prompt.

I haven't run this one yet, but if you want to try to beat my 3-hour time, this is the one to use:

Revised Orchestration Prompt

  Role: You are a Software Engineering Project Orchestrator LLM. Your primary goal is to guide a developer user through the complete setup, configuration, and deployment of a modern, content-driven web application. You will follow a
  structured, secure, and iterative process.

  Overall Project Goal:
  Orchestrate the build of a full-stack, content-driven website. This involves setting up a Next.js frontend, a headless Sanity.io CMS backend, a serverless notification service on Google Cloud Run, and deploying the final application
  to a Linux server using PM2, Nginx, and Certbot for SSL.

  Core Technology Stack:
   * Frontend: Next.js
   * Backend (CMS): Sanity.io
   * Serverless Function: Node.js on Google Cloud Run
   * Email Provider: Mailjet (or a similar transactional email service)
   * Deployment: Linux Server, PM2, Nginx, Certbot

  Step-by-Step Orchestration Plan:

  Phase 1: Prerequisites & Account Setup
   1. Confirm the user has the necessary accounts:
Gemini CLI success message confirming the completion of all orchestration phases: CMS setup, Cloud Run deployment, and Nginx configuration.

Caption: The final success message after the rebuild.

We now have:

  • Sanity.io hosting content (CDN).
  • Next.js web app presenting the blog.
  • Cloud Run handling email logic.
  • Nginx serving it all securely.
Final deployed TheFactorySystem.ai blog site running on a custom domain with SSL security

Caption: The final result—a live, secure, content-driven blog.

I entered this project as an infra guy who didn't know React. I left as an infra guy who still doesn't know React—but I have a deployed, functioning, modern blog to show for it.

Michael Elias is a Senior Principal Operations Engineer at Dun & Bradstreet with a history of entrepreneurship in the ISP and consulting spaces. A veteran of the dot-com era with certifications from Cisco, Red Hat, and Fortinet, Michael specializes in high-compliance infrastructure and enterprise architecture.

- Michael Elias (Read full bio)

Subscribe to this Post

Get notified when there are updates or new content related to "Vibe Coding Infrastructure: How I Orchestrated a Modern Tech Stack with Gemini CLI in 3 Hours".

Comments

Loading comments...

Leave a Comment

Note: All comments are moderated and will appear after approval.