Chapter 1 of 14

What a Local Environment Actually Is

Before installing anything, it is worth naming the parts. A local development environment is not one thing — it is five jobs that happen to run on the same laptop, and almost every problem you have had with yours came from the seams between them.

The problem

A working machine is invisible. You type myapp.test, a page appears, and no part of your attention goes to how. That is exactly as it should be — and it is why, when something breaks, nobody has any idea where to look. The environment was never designed; it accumulated.

So here are the five jobs, because knowing them is what turns “it doesn't work” into a question with an answer.

  1. A name resolver. Something must decide that myapp.test means your machine. That is DNS, and it is the first thing that breaks.
  2. A web server. Something must accept the request on port 80 or 443, work out which project it belongs to, and hand it to the right runtime.
  3. Language runtimes. PHP, Node — and not one of each, but the specific versions each project needs, at the same time.
  4. Backing services. A database, a cache, a queue, somewhere for outgoing mail to land instead of a real inbox.
  5. Certificates. Because half of what you build now refuses to work over plain HTTP.

The hard way

The traditional answer is one tool per job, assembled over years by different people with different opinions: Homebrew for PHP, nvm for Node, Docker for the database, a line in /etc/hosts for the name, nginx or Apache configured by hand, mkcert for a certificate, and MailHog because somebody once sent a test email to a real customer.

Each piece is fine. The seams are where you lose the days:

  • Nothing knows about anything else. You upgrade PHP with Homebrew and your nginx config still points at the old socket. Nothing warns you; the site just stops.
  • Versions are global. One PHP at a time, so the client project on 8.1 and the new one on 8.5 cannot both run — and switching is a ceremony you perform several times a day.
  • Nothing is reproducible. A new colleague spends two days recreating your machine from a README nobody has updated since the last time someone new joined.
  • Everything is a little bit root. A dozen installers have each asked for your password for their own reasons, and no one process is accountable for the result.

The /etc/hosts line deserves a paragraph of its own, because it is the most common approach and the worst. It maps exactly one name. Every new project is another manual edit with sudo, wildcards are impossible, and the file is invisible from inside any project — so the reason a site stopped resolving is in a system file nobody thinks to open.

What changes with one supervisor

Grove does all five jobs in one supervised process, and the difference is not convenience. It is that the parts can know about each other.

  • It answers DNS for your TLD, so a new project needs no file edited anywhere — the name exists because the folder does.
  • It is the web server, so it knows which PHP version a site is pinned to and routes to that runtime without a config file to keep in sync.
  • It installs the runtimes and the databases, so upgrading one does not break another's idea of where it lives.
  • It owns the certificate authority, so a new HTTPS site is one command rather than a ceremony.
  • It sees every request, which is why chapters 10 and 12 are possible at all — nothing assembled from separate tools can show you the timeline of a request with the queries it caused.

What we are building

By chapter 14 you will have this, and every part of it will be something you chose rather than something that accumulated:

  • Every project in one folder served at https://<name>.test with a trusted padlock, no config per project.
  • Several PHP versions at once, pinned per site, with the extensions you need — including ones no prebuilt binary has.
  • Databases, cache and a mail-catcher that Grove installs and supervises, with snapshots you can roll back.
  • A terminal whose php and composer follow the project you are standing in.
  • A grove.toml in the repository, so a new colleague goes from git clone to a running identical environment with one command.
One honest note before we start. Grove replaces a stack you may have spent years arranging, and that is worth doing deliberately rather than all at once. Chapter 7 is where Herd and Valet come off, and it comes after the chapters that make sure everything you relied on is in place. Nothing here asks you to burn the boats early.

What you learned

  • A local environment is five jobs: a name resolver, a web server, runtimes, services and certificates.
  • The seams are where the days go — one tool per job means nothing knows about anything else.
  • /etc/hosts maps one name and hides the reason a site stopped working in a system file.
  • One supervisor lets the parts know about each other, which is what makes per-site PHP and a request timeline possible at all.
  • Replace deliberately. Herd and Valet come off in chapter 7, after everything you relied on is in place.
Next: in Chapter 2 you install Grove — and find out precisely what the two commands that ask for your password are doing with it.