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:
check_dotenv_file_exists– Verifies thatconfig/application.ymlexists locally.check_git_tracking– Ensures the file is not accidentally committed to git.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.bakand stored next to the.envin the shared folder. - At most 5 backups are retained; older ones are deleted automatically.
dotenv:updatealways creates a backup before writing to the remote file.
Requirements
- Ruby
>= 3.1.4, < 3.4.0 - Capistrano 3.x
Contributing
- Fork it ( https://github.com/zauberware/capistrano-node-dotenv/fork )
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
License
MIT — see LICENSE.txt.