Fetch a server's .env
$ grim env:pull
The .env of a deployed app lives on the server and nowhere else. It is not in the image and not in the repository, so the day you need to know what production is really running with, you have to go and get it. grim env:pull does that over SSH and leaves a copy next to your own .env, named after the environment it came from.
It is the first half of a round trip. Pull, edit the copy, send it back with grim env:push. For one value there is a shorter road: grim env:set changes it in place and you never hold the file at all.
Usage
$ grim env:pull # production, saved as .env.production
$ grim env:pull staging # saved as .env.staging
$ diff .env .env.production # what differs from your machineRun it from the project directory. With no argument the environment is production.
Arguments and options
Pull .env from remote server
Usage
grim env:pull [<environment>]Arguments
| Argument | Description |
|---|---|
environment |
Target environment (optional, default: production) |
What it actually does
- Finds the server. The host and path come from
deploy.environments.<environment>ingrim.json, or fromdeployitself when it is not split by environment. Wheregrim.jsonnames no host, the registrationgrim server:add-projectleft in~/.grim/servers.jsonis used. The path falls back to/opt/<project>, or/opt/<project>-<environment>for anything but production, which is the directorygrim server:add-projectmakes. A top-leveldeploy.pathis production's and is skipped for any other environment. - Reads the file. Connects as the
deployuser and reads.envfrom that path. Nothing on the server is changed. - Writes
.env.<environment>. Into the project directory, replacing a copy from an earlier pull without asking. - Prints a summary. Project, host, file name and the number of variables, so a suspiciously short file shows at once.
The file you now hold carries production credentials in plain text. A project made by grim ignores it in git, because its .gitignore lists what is tracked and nothing else. If you have replaced that .gitignore with your own, check before the next git add.
Pitfalls
A second pull throws your edits away
The local copy is overwritten every time. If you pulled, edited and then pulled again to "refresh", the edits are gone. Push first, or rename the copy.
The copy goes stale
grim env:set and a colleague's grim env:push change the server, not your file. Pull again right before you edit, not from memory of last week. Pushing a stale copy puts the old values back.
No host for the environment
No host for "shop" (staging) means neither grim.json nor servers.json knows a server for that environment. Name it under deploy.environments.staging.host, and everyone who clones the project can pull without registering anything.
After it finishes
Read it, or edit it and send it back. The push asks before it overwrites, and the app only reads the new values once its containers are recreated.
$ grim env:push --restartQuestions
Why not keep .env.production in the repository?
Because it holds the database password, the mail credentials and the app key. The server is the one place that must have them, so it is the one place they are kept. Pull when you need to look.
Does pulling restart or touch the app?
No. It reads one file. The app never notices.
Can I pull from a server I did not set up myself?
Yes, when grim.json names the host for that environment and your SSH key is accepted for the deploy user there. Your own servers.json can be empty.
Related spells
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 env:set
Change one server variable
Set a single KEY=VALUE in the .env of a deployed environment and recreate the containers so the app runs on it at once.
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.
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.
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.