How to Encrypt a .env File and Run Your App with Dotenvx

Updated

Run dotenvx encrypt to turn your .env values into ciphertext, commit the encrypted file with git, then start your app with dotenvx run -- <your command> so the secrets are decrypted and injected at runtime. This works for any language or framework, and the only thing your infrastructure needs is the private key — not the plaintext secrets.

Before You Start

You need:

  • A project with a .env file containing the values you want to protect.
  • Dotenvx installed (see the Quickstart on dotenvx.com).
  • Git initialized in the project, since the encrypted file is meant to travel with your code.
  • A way to set one private key in your runtime environment. Dotenvx's design is built around a single private key held on your infrastructure.

Step 1: Encrypt the .env File

$ dotenvx encrypt
◈ encrypted (.env)

Input: your existing plaintext .env. Action: dotenvx encrypt converts the values into ciphertext. Expected result: the .env file now holds ciphertext, and only your private key can unlock the values.

After this step, the file is safe to share through git — the values are unreadable without the key.

Step 2: Commit the Encrypted File

$ git add .env
$ git commit -m "encrypt .env"

Input: the encrypted .env. Action: stage and commit it alongside your code. Expected result: the encrypted secrets travel with the repository. Anyone with the repo gets the ciphertext; only holders of the private key can decrypt it.

This is the core shift: instead of coordinating secrets out-of-band, you deliver them the same way you deliver code.

Step 3: Run Your App

$ dotenvx run -- node index.js
⟐ injected env (2) from .env

Input: the encrypted .env plus your private key available to the process. Action: dotenvx run -- <command> decrypts the values and injects them as environment variables just-in-time. Expected result: your app starts with the secrets available as normal environment variables. The injected env (2) line confirms how many variables were loaded.

Swap node index.js for whatever starts your app — the pattern is the same for any language or framework.

How the Pieces Fit

Dotenvx is built from three primitives the site names directly:

Primitive Role
Git Distributes the encrypted file with your code
.env The open standard for loading secrets into code
secp256k1 Asymmetric encryption that keeps values unreadable

The design keeps the decryption key separate from the code, following twelve-factor config: secrets travel with code without becoming part of it. Because only one private key needs to be set on your infrastructure, there's no async coordination of secrets and no centralized service that can go down and take your secret delivery with it.

Common Snags

  • App can't decrypt values. The private key isn't available to the dotenvx run process. Confirm the key is set in the environment where the command executes.
  • You committed plaintext by mistake. Run dotenvx encrypt first, then commit. The commit step is only safe after encryption.
  • You expected a secrets server. Dotenvx deliberately avoids one; delivery happens through git and decryption happens locally at runtime.

When This Approach Fits

Choose Dotenvx if you want secrets to ship with your repository and be decrypted at runtime from a single private key, with no central secrets service in the path. If your workflow depends on a hosted secrets manager with rotation and access auditing, that's a different model — Dotenvx's stated design is to reuse git, .env, and secp256k1 rather than build a new delivery mechanism.