Create a project
One command does nearly all of it, and it takes minutes because it builds an image, installs core and migrates a database. What is left to you is small and easy to skip. Copy a password that is shown once, and understand why the first commit holds only three files.
Before you start
The machine is ready: Docker runs, you are logged in, and grim doctor outside any project ends with All checks passed!. If this is a new machine, do the install recipe for your system first.
The install will create the project's database with the mysql client on your machine, as root with no password. When that login does not work, the step is passed over without a word and the run fails later, at the migrations. Try the exact login now.
$ mysql -u root -e "SELECT 1"
$ cd ~/codeStand in the directory that should hold the project. The name you pick becomes the directory, the name in grim.json, the database and the local domain. Use lowercase letters, digits and hyphens. grim does not reject other names, and a domain or a database will.
The ritual, in order
Six steps. The first does nearly all the work, the fourth is optional, and only the last touches git.
Create it
grim create-projectfirst checks that Docker runs and can pull fromghcr.io, then asks two questions.Module preset?offersminimal,allandcustom.Frontend theme?offersblank, an existing theme or a new one. Enter takesminimalandblank, and both can be changed later.$ grim create-project shop Creating project: shop … ✓ Created shop/grim.json 0 modules, theme: blank Running grim install... … Project installed ─────────────────────────────────────── Project shop Core 2.5.0 Modules 0 Themes 2 · · · · · · · · · · · · · · · · · · · · Admin admin@shop.test Password 3f9c1a7e5b2d8046 · · · · · · · · · · · · · · · · · · · · Next cd shop Then grim upBetween the two halves,
grim installprints one line per step with its duration: core, modules, themes, configuration, the lock, the database, the image build, the migrations, the admin. The first failure stops the run.The
Passwordrow is the only place the admin password is ever shown. Copy it before the terminal scrolls. When the two admin rows are missing, the account was not created, and step four makes one.Bring it up
The install leaves the containers running.
grim upadds what is still missing: the certificate forshop.test, and the Vite dev server on your machine.$ cd shop $ grim up … Development ready ─────────────────────────────────────── URL https://shop.test Mailpit https://mail.shop.test Vite HMR https://shop.test:5173Look for
TLS chain verifiedabove the table. It means the certificate that Traefik serves is the one your browser will trust. On Linux and WSL2 expect asudoprompt for/etc/hosts, and on WSL2 a UAC prompt on the Windows desktop.Sign in
Open the login page and use the
AdminandPasswordrows from step one.$ curl -sI https://shop.test/login | head -n 1 $ open https://shop.test/loginThe first line of the answer is the status the app gave. Any mail the app sends lands in Mailpit at
https://mail.shop.test, never in a real inbox. On Linux usexdg-open, and on WSL2cmd.exe /c start.Make an account of your own
Optional.
admin@shop.testis a fine account for a project only you run. For a name of your own, or when the password from step one is gone,grim usercreates another admin.$ grim user anna@example.comThe summary is titled
User createdand carries a new generated password.User (check output above)means it failed. The exit code is 0 either way.Run the suite once
grim testcreates the databaseshop_testnext toshop, migrates it and runs the suite. Run it now, while nothing of yours can be the reason for a failure.$ grim testA red suite on an untouched project is a finding about the train or the machine, not about your code.
Make the first commit
grim does not run
git init. It does write a.gitignore, and that file ignores everything except itself and two others.$ git init $ git add .gitignore grim.json grim.lock $ git status --short A .gitignore A grim.json A grim.lock $ git commit -m "chore: create shop"Three files are the project.
git cloneandgrim installrebuild the rest, at the versions the lock records. The.gitignoreis yours from now on, and grim never rewrites it. For every file or directory the project itself owns, add a line such as!/app/before you expect git to see it.
What you have now
shop/
grim.json, grim.lock what the project is made of, and at which versions
.gitignore the allowlist: itself and the two files above
.env local settings, APP_KEY filled in, DB_HOST=host.docker.internal
docker-compose.yml yours to edit from now on
docker/ Dockerfiles and nginx config, renewed by grim upgrade
src/<Module>/ one git checkout per module
resources/themes/ one checkout per themeOn the machine: the database shop and shop_test, a certificate in ~/.grim/traefik/certs, and a stack that grim down stops and grim up starts. Modules come and go with grim require and grim remove.
When it does not work
“Not authenticated to ghcr.io.”
Docker cannot pull the base image. Answer yes to Run `grim auth:login` now to authenticate? and the run continues. When a 403 follows, the token lacks read:packages or is fine-grained. Make a classic one and run grim auth:login --token <new-pat>.
The migrations fail with an unknown database
The Creating local database step was passed over because mysql -u root did not log in. The project directory is complete up to that point. Create the database with whatever login your server accepts, then run the install again inside the project. Core on disk is left alone and the run goes on to the migrations.
$ mysql -u root -p -e "CREATE DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
$ cd shop
$ grim install
``` When the server wants a password, put `DB_USERNAME` and `DB_PASSWORD` into `.env` before that install. A project named `my-shop` gets the database `my_shop`.
### “Directory shop already exists.”
A failed run leaves its directory behind. When nothing in it is worth keeping, stop its containers with `grim down` inside it, delete it and start again. Otherwise go in and run `grim install`.
### “Could not load module catalog”
You chose `custom` and the registry did not answer, which is nearly always the token. Run `grim auth:login`, or name the modules yourself with `--modules=cart,payments`.
### The browser cannot find shop.test
On macOS nothing on the machine answers the `.test` resolver. On Linux the `sudo` prompt was declined. Add the line by hand, and on WSL2 also run `grim hosts:windows`.
```console
$ echo '127.0.0.1 shop.test mail.shop.test' | sudo tee -a /etc/hostsNext recipe
Bring an existing app onto grim
Convert the instance into a grim.json without installing, read the dry run, settle the modules nobody asked for, point the copied .env at this machine, install, move your own files in, then test and commit.
Read itSpells used here
grim create-project
Conjure a project
Create a project directory with a grim.json on the current train and install it, or write the grim.json for an application that already runs.
grim install
Assemble the whole project
Turn grim.json into a working project by fetching core, every module and theme, writing grim.lock, building the image and starting the stack.
grim up
Raise the stack
Start the project's containers and its Vite dev server, with a trusted certificate and a working address, and say where to open it.
grim user
Create an admin user
Create an administrator account in the app, on your machine or on a deployed server, and print the password once.
grim test
Run the test suite
Run the project's tests in the app container against a separate test database that grim creates and migrates for you.
Related recipes
Install on macOS
Run the installer, open a fresh terminal, prepare the machine with grim setup, check that .test names resolve, and finish on a clean grim doctor.
Add, trace and remove modules
Find a module in the catalogue, require it on the project's train, trace what came along with it, and later remove it, sweep the leftovers and write the lock again.