Change one server variable
$ grim env:set MAIL_HOST=smtp.example.com
One value on the server is wrong, or missing: a mail host, an API key that was rotated, APP_DEBUG for ten minutes while you chase a bug. Pulling the whole file, editing it and pushing it back is a lot of ceremony for one line, and it leaves production credentials on your disk. grim env:set changes that one line where it lives and restarts what reads it.
For several values at once, or to remove a line, use the round trip instead: grim env:pull, edit, grim env:push.
Usage
$ grim env:set MAIL_HOST=smtp.example.com # production
$ grim env:set APP_DEBUG=true staging # only staging's .env
$ grim env:set "MAIL_FROM_NAME=Shop Support" # quote it for your shellRun it from the project directory. The pair comes first and the environment second; with no environment it is production. There is no confirmation: the command acts as soon as you press Enter.
Arguments and options
Set an .env variable on remote server
Usage
grim env:set <pair> [<environment>]Arguments
| Argument | Description |
|---|---|
pair |
KEY=VALUE pair to set (required) |
environment |
Target environment (optional, default: production) |
What it actually does
- Splits the pair at the first
=, so a value may contain=itself. Spaces around the key and the value are trimmed. - Finds the server.
deploy.environments.<environment>ingrim.json, thendeployitself, then your registration in~/.grim/servers.json. The path falls back to/opt/<project>, or/opt/<project>-<environment>for anything but production: the directorygrim server:add-projectmakes. A top-leveldeploy.pathis production's and is skipped for any other environment. - Reads the server's
.envas thedeployuser. - Changes one line. The first line that sets the key is replaced,
export KEY=lines included. When there is none,KEY=VALUEis added at the end. Every other line stays as it was. - Uploads the file over the old one.
- Recreates the PHP services.
app,horizon,schedulerandreverb, whichever the project has, because each caches its configuration at start. It printsRecreating PHP services (app, horizon, scheduler)...and the site is away for a few seconds. - Prints a summary. Project, host, key, and whether the key was
updatedoradded. The value is not printed.
How the value is written
You do not have to think about .env quoting. A value with a space, a #, a quote or a backslash is wrapped in double quotes and escaped; anything else is written as it is. URLs and ampersands pass through untouched.
| You type | The server's .env gets |
|---|---|
APP_DEBUG=true |
APP_DEBUG=true |
"MAIL_FROM_NAME=Shop Support" |
MAIL_FROM_NAME="Shop Support" |
CACHE_PREFIX= |
CACHE_PREFIX= |
Your own shell still reads the line first. Put the pair in quotes whenever the value has a space, a $, a & or a !.
Pitfalls
It always restarts
There is no flag to skip the recreation. To stage a value for the next release without touching the running app, use the round trip and grim env:push without --restart.
The key has to look like a variable
Invalid .env key: mail-host means the key has a character other than letters, digits and underscores, or starts with a digit. Nothing was changed on the server. Invalid format. Use: grim env:set KEY=VALUE means there was no = at all.
-v shows the whole file
With -v every SSH command prints its output, and one of them reads the server's .env. Every production credential scrolls through your terminal. Leave verbose off here unless you are alone with the screen.
The value stays in your shell history
A secret typed on the command line is saved by the shell. For a password or a key, the round trip through an editor keeps it out of the history file.
After it finishes
The app is running on the new value. Your local .env.<environment> from an earlier pull knows nothing about it, so pull again before the next push, or that push puts the old value back.
Questions
Can it remove a variable?
No. grim env:set KEY= sets it to an empty value, which is not the same: the app then sees an empty string instead of the default from its config file. To delete the line, pull, edit and push.
Does a commented-out line count as set?
No. # MAIL_HOST=old is left alone and a new MAIL_HOST= line is added at the end of the file.
Related spells
grim env:pull
Fetch a server's .env
Copy the .env of a deployed environment into the project as .env.<environment>, to read it or to edit and push back.
grim env:push
Send a .env back
Upload your edited .env.<environment> over the .env of a deployed environment, and optionally recreate the containers that read it.
grim remote:artisan
Run artisan on the server
Run one artisan command inside the app container of the deployed project, from your own terminal.
Recipes that use it
Staging to production, one image
Register a staging environment next to production, name both in grim.json, release to staging, look at it, then send the same tag to production without building again.
Debug production
Look at the server, read what the app logged, search the log on the server, question the app through artisan, turn the log level up for a while, and go inside the container when nothing else answers.
Change config on a live app
Set one value in a server's .env, confirm the app reads it, change many values through a pull and a push, rotate a secret the whole team shares, and apply an edit on a stack you run yourself.