DEV Community

Sabrina Holt
Sabrina Holt

Posted on

GitOps for Basil: Automating an Urban Garden Without Overengineering It

Picture This: Version Control for Your Basil

If you’ve ever tried to keep a basil plant alive on a city balcony while also debugging distributed systems, you’ve probably had a recurring thought: Wouldn’t it be easier if I could just git push my watering schedule? — or maybe that’s just me. Either way, here’s the story of how I used a little GitOps thinking to automate my urban herb garden… without turning it into a DevOps death spiral.

The "Why" (Besides Needing Pesto on Demand)

I’m a big fan of automating the boring stuff. But I’ve seen far too many tech projects (and yes, garden projects!) become so tightly wound around automation that no actual human wants to touch them anymore. My goal here: Let code do the heavy lifting, but always keep a manual override (because maybe I want to water my basil after a tricky deploy—it’s therapeutic, okay?).

What is "GitOps for Basil"?

For the uninitiated, GitOps is a strategy where your system's desired state lives in Git, and automation (usually bots or controllers) brings the actual system in line with what's declared there. Think of it as a way to manage your software—or in this case, your plants—with the careful versioning and review process that developers love.

In garden terms: Define watering patterns and light schedules in a plain text file (garden.yaml), commit to GitHub, and a little Raspberry Pi on my shelf reads those declarations and tells a smart relay to water the basil. If I change the config, commit, and push—the garden follows suit. If I break everything, a quick git revert returns my basil to its (hopefully lush) glory.


The Minimal Viable Automation Stack

I promised not to overengineer. Here’s what I actually used:

  • Raspberry Pi Zero (with Wi-Fi)
  • Moisture sensor (trusty capacitive, thanks Adafruit)
  • Simple peristaltic pump
  • Relay/Power controller
  • LED Grow Light (bonus: makes my living room look like a spaceship)
  • Python Scripts (for pulling from Git, reading YAML, interfacing with GPIO)
  • GitHub Actions (for fun and a little CI/CD flair)

The config file (garden.yaml):

basil:
  moisture_min: 35    # below this, trigger watering
  moisture_max: 60    # stop watering here
  light_on: "07:00"
  light_off: "20:00"
Enter fullscreen mode Exit fullscreen mode

The Sync Script (abridged magic):

import yaml
import requests
from datetime import datetime

def load_garden_config(git_raw_url):
    resp = requests.get(git_raw_url)
    config = yaml.safe_load(resp.text)
    return config['basil']
# ... logic to read sensors, control relays, etc
Enter fullscreen mode Exit fullscreen mode

Nerd note: Python is intentional here—it’s fast to hack, easy to debug after midnight, and plays nicely with Pi GPIO.

The Manual Override

There’s a big red button. No, really. It waters everything when pressed. Felt important.


Keeping it Human-Scale

Here’s where I draw the line: No Kubernetes. No web UIs (except the garden’s readme on GitHub). If I found myself writing a Helm chart for this setup, I’d know I’d gone too far.

The goal is reliability and tweakability. If I go on vacation, my plants survive. If I have a wild idea ("Does basil like jazz at night?"), it’s a one-line config change. And if my neighbor’s dog knocks the pump over, I can still just water the plants with a cup.


Photos! [Insert photo of a Pi nestled between tomato vines, LED aglow, and code open in VSCode on my balcony table.]


Lessons Learned

  • Automate, don’t alienate: Good automation invites you in, doesn’t lock you out.
  • Keep it observable: Logs to the garden GitHub repo keep me honest—and fixable.
  • Never skip the override: Machines are great, but sometimes you just need to press a big red button.

Urban gardening doesn’t have to be another overengineered mess. But a little version control never hurt anyone—except maybe my first batch of parsley, but that’s a story for another post.

Happy growing! 🌱

Top comments (0)