Skip to content

Liber Tertius · Chapter 1 · Getting grim

Install on macOS

The installer brings grim and the tools around it, but not the shared plumbing every project leans on. That is a second command, and its last line says "ready" whatever happened. So the procedure ends with the one command that tells the truth about the machine.

≈8 min 5 steps Docker Desktop or OrbStack running PHP 8.1+ and Composer A GitHub account with access to grimoiry
Source

Before you start

Docker has to be installed and running. The installer does not bring it, and everything after the installer talks to it. Docker Desktop and OrbStack both do, as long as docker is on your PATH.

PHP 8.1 or newer and Composer have to be there too. The installer checks both first and stops when either is missing. grim itself is a PHP program, and it runs on your machine, not in a container.

$ docker info --format '{{.ServerVersion}}'
$ php --version
$ composer --version

Homebrew is not required, but have it. With Homebrew the installer adds mkcert, MariaDB and Node by itself. Without it, MariaDB is left to you.

You will be asked for a classic GitHub token. The installer prints a link with the scopes already selected. A fine-grained token is accepted by GitHub and still cannot pull images.

The ritual, in order

Five steps. The first and the third change the machine, the other three only look.

  1. Run the installer

    One line downloads grim.phar into ~/.local/bin and fills in what is missing around it: mkcert and its certificate authority, MariaDB, Node and Yarn. Expect the macOS password prompt once, when the authority goes into your keychain.

    $ curl -sS https://grim.grimoiry.com/install.sh | bash
    
    GRIM CLI Installer
    
    PHP 8.4 OK
    Composer OK
    
    Generate the token on GitHub, then paste it here (input is hidden).
    Token:
    
    Next steps:
      grim doctor            Check system dependencies

    Green lines are things that were found or installed. Yellow lines are things the installer could not do, each with the command to run yourself. It goes on past them, so read them now. The token prompt says the input is hidden. It is not. Do not paste it on a shared screen. The token is saved to ~/.grim/config.json and to Composer's global auth.json, and the installer finishes by running grim auth:login with it, which logs Docker in to ghcr.io.

  2. Open a fresh terminal

    The installer cannot change the PATH of the shell it was piped into. When ~/.local/bin was not on it, the installer printed the line to add. Add it, open a new terminal, and ask who grim thinks you are.

    $ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
    $ grim auth:whoami

    Authenticated as and your GitHub name mean the token arrived. command not found means the PATH line is missing from the profile of the shell you really use.

  3. Prepare the machine

    Every project answers at https://<name>.test. One Traefik routes all of them and one rule sends .test to your own machine. grim setup puts both in place, once per machine. It asks for sudo once, to write /etc/resolver/test.

    $ grim setup
    Setting up local dev environment...
    
      Creating traefik-public network... OK
      Checking mkcert... installed
      Installing mkcert CA... OK
      SSL certs will be generated per-project on grim up
      Setting up Traefik... running
      Setting up *.test DNS... needs sudo
      Creating /etc/resolver/test (routes *.test to 127.0.0.1)
      DNS configured
    
    Local dev environment ready.

    Read the indented lines, not the last one. Local dev environment ready. is printed, with exit code 0, even when a line above it says failed. The reason is on the line under the failed one.

    Laravel Herd holds ports 80 and 443. When Herd is running, setup stops it with herd stop and does not say so. grim up does the same later. Your Herd sites are down until you start Herd again, and then grim's are.

  4. Check that a .test name resolves

    The resolver file sends every .test lookup to 127.0.0.1. grim starts nothing that answers DNS there. On a Mac that has Herd, Valet or dnsmasq, something already does. On a clean Mac, nothing does. Find out now, not in the browser.

    $ dscacheutil -q host -a name shop.test
    name: shop.test
    ip_address: 127.0.0.1

    An address means something on the Mac answers for .test. No output means nothing does. That is fine too: grim create-project and grim up then add the project's line to /etc/hosts themselves, and sudo asks for your password when they do.

  5. Ask the doctor

    grim doctor checks the tools, the Docker daemon, the ports, the database login and the token, and gives one verdict.

    $ grim doctor
    
      Docker daemon    ✓ running
      Traefik ports    ✓ 80, 443 bound
      Composer         ✓ 2.8.4
      MySQL/MariaDB    ✓ 11.4.2 (root@127.0.0.1, no password)
    
      GitHub auth       ✓ (anna)
      grim.json          - (not found — not in a GRIM project directory)
    
    All checks passed!

    A - is something absent, not something wrong. Outside a project the two manifest lines are always -. The MySQL/MariaDB line matters more than its mark suggests: a - there does not fail the run, but the first project will get no database. Settle it before you go on.

What you have now

~/.local/bin/grim, grim.phar     the tool, updated in place by grim self-update
~/.grim/config.json              your token and the telemetry choice
~/.grim/install.log              what the installer did, for when you ask for help
~/.grim/traefik/                 the shared proxy and, later, one certificate per project
/etc/resolver/test               .test goes to 127.0.0.1

There is also a MariaDB on the machine, outside Docker, that accepts root without a password so the containers can reach it. Keep port 3306 closed to any network you do not trust.

No project yet. That is the next recipe, Create a project. To take a newer grim later, run grim self-update.

When it does not work

“PHP is not installed. Install PHP 8.1+ first.”

The installer stops here, and the same way for Composer is not installed. Install both and run the installer again. It is safe to repeat: everything it finds in place is left alone.

“GitHub token is required. Installation cannot continue without it.”

The prompt offers Press Enter to skip, and skipping ends the install with this message. Every package is private, so there is no install without a token. Create the classic token from the printed link and run the installer again.

“MariaDB/MySQL not reachable on 127.0.0.1:3306 and Homebrew is not installed.”

Without Homebrew the installer has no way to install a database server. Install Homebrew and run the installer again, or point any MySQL or MariaDB you already run at port 3306 with a passwordless root. The check doctor makes is this one:

$ mysql -u root -h 127.0.0.1 -e "SELECT 1"

Doctor runs the mysql client from your machine. A server without the client on your PATH still shows as not reachable.

A .test name does not resolve

The resolver rule is in place, nothing on the Mac answers it, and the hosts line is missing: the sudo prompt was declined, or the run had no terminal. Add the project's names to /etc/hosts, which is read first, or run grim up again in a terminal.

$ echo '127.0.0.1 shop.test mail.shop.test' | sudo tee -a /etc/hosts

“Port(s) 80, 443 are held by a non-Docker process.”

It appears under Setting up Traefik... failed. A local nginx or Apache is listening. Stop it, run grim setup again, and read the Traefik line.

The keychain prompt was dismissed

mkcert -install failed. Re-run manually later: mkcert -install means the authority was never trusted, and browsers will warn on every .test page. Run mkcert -install, answer the prompt, and restart the browser.