Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow environment variables to be injected into the docker build map #4

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ A Leiningen plugin to build and deploy [Docker](https://www.docker.com/) images.
Add docker-deploy to your plugin list in your `project.clj`:

```clojure
:plugins [[gorillalabs/lein-docker "1.3.0"]]
:plugins [[gorillalabs/lein-docker "1.6.0"]]
```

(see version badge above for newest release)

Available commands:

$ lein docker build
$ lein docker push
$ lein docker rmi
$ lein docker build [image-name [additional-arguments ... ]]
$ lein docker push [image-name]
$ lein docker rmi [image-name]

## Configuration

Expand All @@ -38,6 +38,27 @@ Defaults:
* `:dockerfile` points to `Dockerfile`
* `:build-dir` points to the project's root

### Injecting environment variables into configuration

With a CI/CD pipeline such as Jenkins, you may want to generate Docker artifacts tagged
against specific properties of a build run. The values in the :docker configuration options
may contain bash-like references to environment variables, which will be replaced with
values from the environment. For example:

```clojure
:docker {:image-name "myregistry.example.org/myimage"
:tags ["%s-${BUILD_NUMBER:-unknown}"]}
```

Running `lein docker build` command under Jenkins line will generate an image tagged with the
project number and build number (e.g., 1.6.0-306). If BUILD_NUMBER is undefined, as when
outside of Jenkins, then the default value ("unknown") will be spliced in instead. If the
environment variable expression does not contain a default string and the referenced
environment variable is not defined, the expression is replaced with the empty string.

Environment variable injection is supported for the `:image-name`, `:tags`, `:dockerfile`,
and `:build-dir` entries in the project's `:docker` map.

## Releasing your docker images

You can use Leiningen to handle your technical release process.
Expand Down
27 changes: 22 additions & 5 deletions src/leiningen/docker.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
(ns leiningen.docker
(:require [leiningen.core.eval :as eval]
[leiningen.core.main :as main]
[clojure.java.shell :as shell]))
[clojure.java.shell :as shell]
[clojure.string :as str]))

(def var-matcher-pattern #"\$\{(?<varname>[A-Za-z0-9_]+)(?::-(?<default>[^}]+))?\}")

(defn inject-environment-variables
"Given a string, replace text of the form ${NAME} or ${NAME:-default}
with the environment variable value corresponding to NAME.
In the second form, if NAME is not defined, use the default string.
If the default string is not provided and NAME is not defined, replace
the expression with the empty string."
[string]
(reduce (fn [s [match environment-variable default]]
(let [replacement (or (System/getenv environment-variable) default "")]
(str/replace s match replacement)))
string
(re-seq var-matcher-pattern string)))

(defn- exec [& args]
(apply main/debug "Exec: docker" args)
Expand Down Expand Up @@ -63,6 +79,7 @@
(main/warn "Docker image could not be removed.")
(main/exit exit-code))))))


(def valid-command? #{:build :push :rmi})

(defn docker
Expand All @@ -82,16 +99,16 @@

(let [config (:docker project)
image-name (or image-name
(:image-name config)
(inject-environment-variables (:image-name config))
(str (:name project)))
tags (or (:tags config)
["%s"])
images (map
#(str image-name ":" (format % (:version project)))
#(str image-name ":" (format (inject-environment-variables %) (:version project)))
tags)
build-dir (or (:build-dir config)
build-dir (or (inject-environment-variables (:build-dir config))
(:root project))
dockerfile (or (:dockerfile config)
dockerfile (or (inject-environment-variables (:dockerfile config))
"Dockerfile")]

(case command
Expand Down