Skip to content

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 machine

Run 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

  1. Finds the server. The host and path come from deploy.environments.<environment> in grim.json, or from deploy itself when it is not split by environment. Where grim.json names no host, the registration grim server:add-project left in ~/.grim/servers.json is used. The path falls back to /opt/<project>, or /opt/<project>-<environment> for anything but production, which is the directory grim server:add-project makes. A top-level deploy.path is production's and is skipped for any other environment.
  2. Reads the file. Connects as the deploy user and reads .env from that path. Nothing on the server is changed.
  3. Writes .env.<environment>. Into the project directory, replacing a copy from an earlier pull without asking.
  4. 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 --restart

Questions

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.

Recipes that use it