capistrano-node-dotenv

A Capistrano plugin for managing .env files on remote servers running Node.js applications. It handles uploading, syncing, backing up, and rolling back the .env file that lives in your deployment's shared folder.

Table of Contents

Click to expand - [How it works](#how-it-works) - [Installation](#installation) - [Configuration](#configuration) - [Tasks](#tasks) - [dotenv:setup](#dotenvsetup) - [dotenv:update](#dotenvupdate) - [dotenv:get](#dotenvget) - [dotenv:init](#dotenvinit) - [dotenv:show](#dotenvshow) - [dotenv:backup](#dotenvbackup) - [dotenv:rollback](#dotenvrollback) - [dotenv:check](#dotenvcheck) - [Automatic symlinking](#automatic-symlinking) - [Backup behaviour](#backup-behaviour) - [Requirements](#requirements) - [Contributing](#contributing) - [License](#license)

How it works

The gem stores your environment configuration locally in config/application.yml — a YAML file where top-level keys are global variables and nested keys are stage-specific variables. On deploy, the relevant keys are extracted, assembled into a proper .env file, and uploaded to the server's shared folder. The .env file is automatically added to Capistrano's linked_files so it gets symlinked into each release.

Local config format (config/application.yml)

# Global variables shared across all stages
DATABASE_URL: postgres://localhost/myapp

# Stage-specific variables
production:
  NODE_ENV: production
  API_KEY: secret-prod

staging:
  NODE_ENV: staging
  API_KEY: secret-staging

Remote .env file format

The generated .env file uses section markers so the gem can parse it back:

# Begin global envs 2026-03-02 10:00:00
DATABASE_URL=postgres://localhost/myapp
# End global envs 2026-03-02 10:00:00
# Begin production envs 2026-03-02 10:00:00
NODE_ENV=production
API_KEY=secret-prod
# End production envs 2026-03-02 10:00:00

Installation

Add to your Gemfile:

gem 'capistrano-node-dotenv'

Then run:

bundle install

Require the gem in your Capfile:

require 'capistrano/node/dotenv'

Make sure config/application.yml is not tracked by git:

git rm --cached config/application.yml
echo 'config/application.yml' >> .gitignore

Configuration

Set these variables in config/deploy.rb or a stage file. All have sensible defaults.

Variable Default Description
dotenv_local_path config/application.yml Path to the local YAML config file
dotenv_remote_path .env Path to the .env file relative to the shared folder
dotenv_env `fetch(:node_env) \ \
dotenv_remote_backup false Whether to automatically back up on deploy

Example:

# config/deploy.rb
set :dotenv_local_path,  'config/application.yml'
set :dotenv_remote_path, '.env'
set :dotenv_env,         -> { fetch(:stage) }

Tasks

cap dotenv:setup      # Upload local config/application.yml to the server (first-time or full overwrite)
cap dotenv:update     # Compare local vs remote .env interactively and push selected changes
cap dotenv:get        # Compare remote vs local .env and optionally pull remote values into local
cap dotenv:init       # Build local config/application.yml by pulling .env files from all stages
cap dotenv:show       # Print the content of the remote .env file for the current stage
cap dotenv:backup     # Create a timestamped backup of the remote .env file (keeps latest 5)
cap dotenv:rollback   # Roll back the remote .env file to the most recent backup
cap dotenv:check      # Run all pre-deploy checks (file exists, not git-tracked, stage config present)

dotenv:setup

Reads config/application.yml, extracts global keys and stage-specific keys, generates a .env file with section markers, and uploads it to shared/<dotenv_remote_path>. Use this the first time you deploy or when you want to fully overwrite the remote file.

cap production dotenv:setup

dotenv:update

Compares your local config/application.yml with the current remote .env. Displays any differences and interactively asks whether to overwrite the remote globals and/or stage section. Automatically creates a backup before writing.

cap production dotenv:update

dotenv:get

The reverse of dotenv:update. Compares the remote .env with your local file and interactively asks whether to pull remote values back into config/application.yml.

cap production dotenv:get

dotenv:init

Iterates over all configured Capistrano stages, downloads each stage's .env file, and merges everything into a local config/application.yml. Useful for bootstrapping a fresh local environment from existing servers.

cap production dotenv:init

dotenv:show

Prints the raw content of the remote .env file to stdout.

cap production dotenv:show

dotenv:backup

Creates a timestamped backup (e.g. .env-2026-03-02-10-00-00.bak) in the shared folder. Automatically removes older backups, keeping only the 5 most recent.

cap production dotenv:backup

dotenv:rollback

Restores the remote .env from the most recent .bak file. Does nothing if no backup exists.

cap production dotenv:rollback

dotenv:check

Runs three pre-deploy checks in sequence:

  1. check_dotenv_file_exists – Verifies that config/application.yml exists locally.
  2. check_git_tracking – Ensures the file is not accidentally committed to git.
  3. check_config_present – Confirms that the current stage's config is not empty.
cap production dotenv:check

Automatic symlinking

The gem hooks into deploy:started and automatically adds the remote .env path to linked_files. No manual configuration in deploy.rb is needed — the file will be symlinked into every release directory.

Backup behaviour

  • Backups are named <filename>-YYYY-MM-DD-HH-MM-SS.bak and stored next to the .env in the shared folder.
  • At most 5 backups are retained; older ones are deleted automatically.
  • dotenv:update always creates a backup before writing to the remote file.

Requirements

  • Ruby >= 3.1.4, < 3.4.0
  • Capistrano 3.x

Contributing

  1. Fork it ( https://github.com/zauberware/capistrano-node-dotenv/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

License

MIT — see LICENSE.txt.