Raise the stack
$ grim up
The start of a working day, the first run after a clone, the morning after a reboot. grim up is what you type when the project should answer in a browser and does not yet. It is safe to run on a project that is already up: containers that are running are left as they are, and only what is missing gets started.
That same habit makes it the wrong command after an edit to .env. A running container keeps the values it started with. For that there is grim reload.
Usage
$ grim up # everything, Vite included
$ grim up --build # rebuild the app image first
$ grim up app redis # only these services
$ grim up --no-vite # containers onlyRun it from the project directory or anywhere below it. Docker has to be running, and on your own machine mkcert has to be installed.
Arguments and options
Start Docker services + Vite dev server
Usage
grim up [-b|--build] [--no-vite] [-t|--timeout TIMEOUT] [--] [<services>...]Arguments
| Argument | Description |
|---|---|
services |
Specific services to start (optional, repeatable) |
Options
| Option | Description |
|---|---|
-b, --build |
Rebuild images before starting |
--no-vite |
Skip starting Vite dev server |
-t, --timeout=TIMEOUT |
Docker compose timeout in seconds |
What it actually does
On your own machine, in this order. Each step is printed with its result and the time it took.
- Checks Traefik. The one Traefik that routes every project on the machine is started when it is not running, and ports 80 and 443 are checked. A running Laravel Herd holding those ports is stopped, and a line after the steps tells you so.
- Makes the certificate.
mkcertissues one forshop.testandmail.shop.testinto~/.grim/traefik/certs, and Traefik is restarted to serve it. On later runs the certificate is checked and left alone when it is still good. - Runs
docker compose up -d, with--buildand the service names when you gave them. - Generates translations.
php artisan lang:jsin the app container. A failure here does not stop the run. - Starts Vite on your machine, not in a container. See Vite on the host.
- Installs Composer dependencies, only when the app container has no
vendor/autoload.phpyet. On a fresh clone this is the long step. - Runs
php artisan storage:link. - Copies
vendor/to the host, only when the project directory has none, so your editor can resolve classes. - Probes port 443 on
127.0.0.1, then verifies the certificate chain end to end and printsTLS chain verified. When a link of the chain is broken it restarts or recreates Traefik on its own and says which.
The run ends with a table titled Development ready: the URL, Mailpit, Horizon when the project uses it, the Vite address and the duration.
A project with its own certificate, tls.mode set to custom in grim.json with tls.domain, tls.cert and tls.key, skips mkcert and the hosts entries. The certificate is copied to Traefik as it is, and docker-compose.yml is written again so the routed domain follows tls.domain.
Linux and Windows add steps of their own. On Linux, the line 127.0.0.1 shop.test mail.shop.test is added to /etc/hosts before anything else, and sudo may ask for your password. A Mac where shop.test does not resolve gets the same line; one with Herd, Valet or dnsmasq is left alone. On Windows the same entries go into the Windows hosts file. Both also make storage/ and bootstrap/cache/ writable inside the container.
Vite on the host
Locally the dev server is a process on your machine, started with yarn dev and left running in the background. It is skipped when the project has no package.json or when you pass --no-vite.
| File | What it holds |
|---|---|
.grim/vite.pid |
The process id grim down uses to stop it. |
.grim/vite.log |
Everything Vite printed. Read this when assets do not load. |
public/hot |
The dev server address. While it exists the app loads assets from Vite. |
.env |
Three VITE_DEVELOPMENT_* lines, appended once, pointing Vite at the project's certificate. |
When node_modules is missing, yarn install runs first. A Vite left over from an earlier run of the same project is stopped before the new one starts.
On a shared dev box
A project whose grim.json says deployment.kind is vps-dev takes a different and shorter road. There is no mkcert, no hosts file and no Vite process: certificates come from the box's Traefik, and MySQL and Vite are services in the stack.
| Your machine | Shared dev box | |
|---|---|---|
docker-compose.yml |
Left as it is | Written again from the template on every run |
| Database | On the machine, outside the stack | A mysql container |
| Vite | A process on the host | A vite container |
| Migrations | Not run | php artisan migrate --force on every run |
| Address | https://shop.test |
deployment.domain from grim.json |
It checks that the traefik-public network exists before starting anything, and ends with a table titled Dev environment ready. The box itself is raised by grim server:dev:setup.
Pitfalls
Without yarn on the host, Vite is skipped without a word
No step fails and nothing is printed. The sign is a summary table with no Vite HMR row, and pages that load built assets or none. Install Node and yarn, then run grim up again.
Something else holds port 80 or 443
Port(s) 80, 443 are held by a non-Docker process. Free them before running grim (e.g. stop the conflicting service). Herd is stopped for you; any other web server is not. Stop it and run grim up again.
mkcert is missing
The certificate step fails with mkcert is not installed or not on PATH and the install command for your system. No project container has been started at that point. Install it and run grim up again; the first run also adds the local authority to the system trust store.
The first start times out
docker compose up gets 300 seconds when the app image has to be built and 120 when it exists. On a slow connection the first build can need more. Pass --timeout=600, or set docker.timeout in grim.json to keep it.
On your own machine grim up does not run migrations. A fresh clone with an empty database answers with an SQL error until you run grim artisan migrate.
After it finishes
Open the URL from the table. Mail the app sends lands in Mailpit at https://mail.shop.test. When a page errors, the next stop is the log.
$ grim logs -f appAt the end of the day, grim down stops it all and keeps your data.
Questions
Can two projects be up at once?
Yes. Each has its own containers and its own .test name, and the one Traefik routes to both.
Does grim up app still start Vite?
Yes. Service names only narrow what docker compose up starts. Add --no-vite when you want containers and nothing else.
Related spells
grim down
Lower the stack
Stop the project's containers and its Vite server. Volumes stay unless you say otherwise.
grim reload
Apply a changed .env
Recreate every container of the project and clear the config cache, so the app reads the .env as it is now.
grim logs
Read the logs
Show what the containers have been printing, for one service or all of them, on your machine or on a deployed server.
grim doctor
Check your circle
Check every tool grim expects on this machine, and the project you are standing in, and say what to do about what is missing.
Recipes that use it
Set up a dev box for a client
Raise a shared development server, give it a registry token, put the first project on it, let developers in by key, hand over the access card, and later take a developer or a project off again.
Create a project
Answer two questions, let the install run, bring the stack up, sign in as the generated admin, run the suite once and commit the three files that are the project.