remote-env-file loads one or more remote HTTPS .env files at build runtime and injects the parsed variables into the Jenkins build environment.
It is designed for cases where configuration lives outside Jenkins, for example in GitHub raw files, object storage, or an internal HTTPS endpoint, and you want Jenkins to fetch the current version at run time instead of copying values into job configuration by hand.
- Loads an ordered list of remote dotenv files per invocation.
- Applies sources top to bottom, with later sources overriding earlier remote values.
- Supports per-source auth:
- no credentials: anonymous request
- Secret Text credential:
Authorization: Bearer <token> - Username with password credential: HTTP Basic auth
- Exposes a first-class Pipeline step:
withRemoteEnvFiles(...) - Adds native Job DSL support via
remoteEnvFiles { ... }for Freestyle wrappers and Pipeline job properties - Expands Jenkins environment variables in each
sourceUrlandcredentialsIdbefore resolving them. - Rejects duplicate keys inside a single remote file, including keys that differ only by case such as
FOOandfoo. - Rejects special OS/process-loading variables such as
PATH,PATHEXT,LD_PRELOAD,LD_LIBRARY_PATH,DYLD_LIBRARY_PATH,DYLD_INSERT_LIBRARIES,LIBPATH, andSHLIB_PATH. - Rejects keys that would overwrite existing build environment variables. Collision checks follow Jenkins environment semantics and are case-insensitive.
- Fails the build on fetch, auth, parse, size, blocked-variable, or collision errors.
- Keeps fetched content in memory only.
- No non-HTTPS URLs.
- No Git provider specific APIs or custom headers.
- No multiline dotenv support.
- No
export KEY=valuesupport. - No variable interpolation such as
${HOME}or$HOME. - No support for overriding special OS/process-loading variables such as
PATHorLD_PRELOAD. - No secret masking. Values injected by this plugin are ordinary environment variables.
- No automatic polling or mid-build refresh. Sources are fetched once at wrapper start or once at Pipeline run setup.
Remote values injected by this plugin are normal environment variables.
If a build step prints, echoes, or otherwise exposes those values, Jenkins does not mask or protect them automatically just because they came from this plugin. Treat remote dotenv content accordingly.
This plugin treats the remote dotenv source as trusted job configuration for normal application settings, but it intentionally rejects environment variables that can change how the operating system resolves binaries or loads shared libraries.
Blocked variables are:
PATHPATHEXTLD_PRELOADLD_LIBRARY_PATHDYLD_LIBRARY_PATHDYLD_INSERT_LIBRARIESLIBPATHSHLIB_PATH
These checks are case-insensitive. For example, PATH and Path are treated as the same variable.
Use this when you want the remote variables available for the whole Freestyle build.
In the job configuration:
- Open
Build Environment. - Enable
Load environment variables from a remote HTTPS dotenv file. - Add one or more rows under
Sources. - Put the lowest-precedence source first and the highest-precedence source last.
- Optionally choose a credential per source row.
Use this when you want the variables available to the Pipeline run without wrapping every stage manually.
In the Pipeline job configuration:
- Open
Configure. - In the main job configuration section, enable
Load environment variables from a remote HTTPS dotenv file. - Add one or more rows under
Sources. - Put the lowest-precedence source first and the highest-precedence source last.
- Optionally choose a credential per source row.
This job-level mode applies the fetched values to the Pipeline run after the build starts, fails the run before user steps if loading fails, and caches the merged values for that run.
Use this when only part of the Pipeline should see the variables, or when you explicitly want the fetch to happen from the selected agent workspace context.
The plugin exposes withRemoteEnvFiles(...) directly in Pipeline and in the Jenkins snippetizer.
node {
withRemoteEnvFiles(sources: [
[sourceUrl: 'https://raw.githubusercontent.com/your-org/your-repo/main/config/base.env'],
[sourceUrl: 'https://raw.githubusercontent.com/your-org/your-repo/main/config/prod.env']
]) {
sh 'printenv | sort'
sh './gradlew test'
}
}
Variables loaded through withRemoteEnvFiles(...) exist only inside the wrapped block.
Sources are loaded in the order you configure them.
- Earlier source: lower precedence
- Later source: higher precedence
- Same key in multiple remote files: later source wins
- Same key as an existing Jenkins/build environment variable: the build fails
Example:
base.envsetsAPP_MODE=baseprod.envsetsAPP_MODE=prod- final merged environment uses
APP_MODE=prod
Configure the sources in the job UI, then keep the Jenkinsfile clean:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'test -n "$APP_NAME"'
sh 'test "$APP_MODE" = "prod"'
sh 'echo "Loaded merged remote configuration for this run"'
}
}
}
}
pipeline {
agent any
stages {
stage('Integration Tests') {
steps {
withRemoteEnvFiles(sources: [
[
sourceUrl: 'https://config.example.com/team/service/test.env',
credentialsId: 'config-basic-auth'
]
]) {
sh './scripts/run-integration-tests.sh'
}
}
}
}
}
pipeline {
agent any
stages {
stage('Verify Merged Env') {
steps {
withRemoteEnvFiles(sources: [
[sourceUrl: 'https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/base.env'],
[sourceUrl: 'https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/prod.env']
]) {
sh 'test "$APP_MODE" = "prod"'
sh 'test "$COMMON_VALUE" = "prod-override"'
sh 'test "$RELEASE_CHANNEL" = "stable"'
}
}
}
}
}
This plugin also adds native Job DSL methods named remoteEnvFiles.
- In Jenkinsfiles, the Pipeline step remains
withRemoteEnvFiles(...). - In Job DSL seed scripts, use
remoteEnvFiles { ... }. - In the Job DSL API Viewer, custom closure extensions may only appear as
remoteEnvFiles(Closure closure). That is expected for this style of extension. The full supported syntax is documented below and inexamples/jobdsl/.
freeStyleJob('remote-env-wrapper-job') {
wrappers {
remoteEnvFiles {
source('https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/base.env')
source {
sourceUrl('https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/prod.env')
}
}
}
steps {
shell('''#!/bin/sh -eu
test "$APP_MODE" = "prod"
echo "Job DSL wrapper example passed"
''')
}
}
pipelineJob('remote-env-pipeline-job') {
properties {
remoteEnvFiles {
source('https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/base.env')
source('https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/prod.env')
}
}
definition {
cps {
sandbox(true)
script('''pipeline {
agent any
stages {
stage('Verify') {
steps {
sh 'test "$APP_MODE" = "prod"'
}
}
}
}''')
}
}
}
Supported source declaration styles inside the Job DSL block:
- Nested:
source { sourceUrl('https://...'); credentialsId('cred-id') } - Helper-call:
source('https://...')source('https://...', 'cred-id')
If the Job DSL plugin exposes generated dynamic methods for your installed plugin version, you can inspect them in the Job DSL API Viewer. The native remoteEnvFiles DSL added by this plugin is the recommended, stable option.
If you hit a Job DSL/plugin-version mismatch, use configure {} as the escape hatch. A working fallback example is included in examples/jobdsl/pipeline-configure-fallback.groovy.
The Job DSL API Viewer currently shows the remoteEnvFiles extension method, but it does not render a richer nested example for this custom closure DSL. Improving that viewer experience would require a Job DSL enhancement rather than a plugin-side workaround, so this plugin relies on the README and examples/jobdsl/ as the canonical reference for full syntax.
The plugin supports the following Jenkins credential types:
Secret TextUsername with password
Each source row has its own Credentials ID dropdown, which lists supported credentials visible to that job and applicable to the configured URL.
Use:
Secret Textfor bearer-token style endpoints such as private raw file endpoints backed by an access tokenUsername with passwordfor internal HTTPS services, artifact repositories, or other endpoints protected with HTTP Basic auth
If a source is public or uses a presigned URL, leave Credentials ID empty for that row.
The plugin expects URLs that return plain text dotenv content over HTTPS. The URL must point to the raw file, not a human-facing HTML page.
No credentials required.
https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/public.env
Use two sources to layer shared and environment-specific settings.
https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/base.env
https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/prod.env
Put base.env first and prod.env second so prod.env wins on overlapping keys.
Use a Jenkins Secret Text credential containing a GitHub token with read access to the repository.
https://raw.githubusercontent.com/your-org/private-config-repo/main/environments/prod.env
Pipeline example:
withRemoteEnvFiles(sources: [
[
sourceUrl: 'https://raw.githubusercontent.com/your-org/private-config-repo/main/environments/prod.env',
credentialsId: 'github-pat'
]
]) {
sh './deploy.sh'
}
No Jenkins credential is needed if the URL already contains a time-limited signature.
https://example-config-bucket.s3.eu-west-2.amazonaws.com/app/prod.env?X-Amz-Algorithm=AWS4-HMAC-SHA256&...
Use a Jenkins Username with password credential.
https://config.example.com/jenkins/my-service/test.env
Useful for simple public demos.
https://gist.githubusercontent.com/your-user/0123456789abcdef/raw/0123456789abcdef/example.env
This repository includes ready-to-use fixture files under examples/.
Successful fetches:
https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/public.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/quoted.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/base.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/prod.env
Intentional failure cases:
https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/invalid-export.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/duplicate-keys.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/interpolation.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/duplicate-case.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/blocked-path.envhttps://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/blocked-loader.env
Quick test Jenkinsfile:
pipeline {
agent any
stages {
stage('Verify Remote Env') {
steps {
withRemoteEnvFiles(sources: [
[sourceUrl: 'https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/base.env'],
[sourceUrl: 'https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/prod.env']
]) {
sh 'test "$APP_NAME" = "remote-env-file-demo"'
sh 'test "$APP_MODE" = "prod"'
sh 'test "$COMMON_VALUE" = "prod-override"'
sh 'test "$RELEASE_CHANNEL" = "stable"'
}
}
}
}
}
Use the raw URL:
https://raw.githubusercontent.com/OWNER/REPO/BRANCH/PATH/TO/file.env
Do not use the HTML blob URL:
https://github.com/OWNER/REPO/blob/main/PATH/TO/file.env
If opening the URL in a browser shows a webpage with GitHub or GitLab chrome around it, it is probably the wrong URL. The plugin needs the direct raw file response.
Supported lines:
APP_NAME=my-service
API_BASE_URL=https://api.example.com
QUOTED="two words"
SINGLE='quoted value'
EMPTY=
Ignored:
- blank lines
- full-line comments beginning with
#
Rejected examples:
export BAD=value
MULTILINE="line 1
line 2"
HOME_PATH=${HOME}/bin
1BAD=value
- HTTPS only.
- Redirects are followed.
- Connect timeout: 15 seconds.
- Read timeout: 15 seconds.
- Maximum response size: 131072 bytes.
- The plugin logs the source location and success/failure state, but not resolved credential values or dotenv values.
Use https://..., not http://....
Add at least one row under Sources.
The selected credential is not visible to the job, or the Pipeline script refers to the wrong credential ID.
The chosen credential type is unsupported for this plugin.
The remote file contains a key that Jenkins already set for the build, such as a parameter or another environment variable. Rename the key in the remote file.
The file is not valid under the plugin's strict dotenv parser. Remove export, interpolation, malformed keys, or multiline syntax.
This repository includes a Docker-based Jenkins setup for local development and plugin testing.
Start Jenkins:
.\docker\fixture\generate-certs.ps1
docker compose up --build -d
Jenkins will be available at http://localhost:8080.
Development login:
- username:
admin - password:
admin
Useful commands:
docker compose logs -f jenkins
docker compose down
docker compose down -v
docker compose build
docker compose up -d
Use docker compose down -v when you want to reset Jenkins state completely.
- The plugin is built inside a Maven + JDK 17 container.
- The resulting
.hpiis baked into a Jenkins2.528.3-lts-jdk17image. - The development image creates a local admin user and disables the setup wizard.
- The Docker image also installs the
job-dslplugin and copiesexamples/jobdsl/intoJENKINS_HOME/jobdsl/. - The local Docker init scripts disable Job DSL script security for the seeded development examples so they can regenerate without manual approvals.
- The container startup script recopies the plugin into
JENKINS_HOME/pluginsso rebuilt plugin versions are picked up on restart. - The local HTTPS fixture service uses self-signed certificates generated by
docker/fixture/generate-certs.ps1. - Generated cert/key files under
docker/fixture/certs/are intentionally ignored by Git.
- Start Jenkins with Docker.
- Create a Pipeline job.
- In the job configuration, enable
Load environment variables from a remote HTTPS dotenv file. - Add
https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/base.envas the first source. - Add
https://raw.githubusercontent.com/jenkinsci/remote-env-file-plugin/main/examples/prod.envas the second source. - Save the job.
- Use a Jenkinsfile like this:
pipeline {
agent any
stages {
stage('Verify') {
steps {
sh 'test "$APP_MODE" = "prod"'
sh 'echo "Remote env files loaded"'
}
}
}
}
If the build fails, the console log will tell you whether the problem is URL validation, authentication, dotenv parsing, blocked special variables, size limits, or variable collisions.
The Docker development setup in this repository includes:
- a local Jenkins controller at
http://localhost:8080 - a local HTTPS fixture service for
.envfiles athttps://env-fixture:8443/inside the Docker network - seeded example jobs you can open directly in the Jenkins UI after startup
- a Job DSL seed job that generates additional examples from
examples/jobdsl/
Seeded jobs:
example-remote-env-wrapper-successexample-remote-env-wrapper-multi-source-successexample-remote-env-wrapper-blocked-pathexample-remote-env-wrapper-duplicate-caseexample-remote-env-job-property-successexample-remote-env-job-property-blocked-loaderseed-remote-env-jobdsl-examples
Job DSL generated jobs:
jobdsl-remote-env-wrapper-successjobdsl-remote-env-pipeline-property-successjobdsl-remote-env-configure-fallback
Matching example Jenkinsfiles live under examples/pipelines/. Matching Job DSL scripts live under examples/jobdsl/.
MIT. See LICENSE.