Merge pull request #4174 from vbatts/vbatts-env_file
support for `docker run` environment variables file
This commit is contained in:
commit
b45c1061bf
3 changed files with 120 additions and 1 deletions
|
@ -1152,6 +1152,7 @@ image is removed.
|
|||
--cidfile="": Write the container ID to the file
|
||||
-d, --detach=false: Detached mode: Run container in the background, print new container id
|
||||
-e, --env=[]: Set environment variables
|
||||
--env-file="": Read in a line delimited file of ENV variables
|
||||
-h, --hostname="": Container host name
|
||||
-i, --interactive=false: Keep stdin open even if not attached
|
||||
--privileged=false: Give extended privileges to this container
|
||||
|
@ -1284,6 +1285,54 @@ This exposes port ``80`` of the container for use within a link without
|
|||
publishing the port to the host system's interfaces. :ref:`port_redirection`
|
||||
explains in detail how to manipulate ports in Docker.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash
|
||||
|
||||
This sets environmental variables in the container. For illustration all three
|
||||
flags are shown here. Where ``-e``, ``--env`` take an environment variable and
|
||||
value, or if no "=" is provided, then that variable's current value is passed
|
||||
through (i.e. $MYVAR1 from the host is set to $MYVAR1 in the container). All
|
||||
three flags, ``-e``, ``--env`` and ``--env-file`` can be repeated.
|
||||
|
||||
Regardless of the order of these three flags, the ``--env-file`` are processed
|
||||
first, and then ``-e``/``--env`` flags. This way, the ``-e`` or ``--env`` will
|
||||
override variables as needed.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cat ./env.list
|
||||
TEST_FOO=BAR
|
||||
$ sudo docker run --env TEST_FOO="This is a test" --env-file ./env.list busybox env | grep TEST_FOO
|
||||
TEST_FOO=This is a test
|
||||
|
||||
The ``--env-file`` flag takes a filename as an argument and expects each line
|
||||
to be in the VAR=VAL format, mimicking the argument passed to ``--env``.
|
||||
Comment lines need only be prefixed with ``#``
|
||||
|
||||
An example of a file passed with ``--env-file``
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cat ./env.list
|
||||
TEST_FOO=BAR
|
||||
|
||||
# this is a comment
|
||||
TEST_APP_DEST_HOST=10.10.0.127
|
||||
TEST_APP_DEST_PORT=8888
|
||||
|
||||
# pass through this variable from the caller
|
||||
TEST_PASSTHROUGH
|
||||
$ sudo TEST_PASSTHROUGH=howdy docker run --env-file ./env.list busybox env
|
||||
HOME=/
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
HOSTNAME=5198e0745561
|
||||
TEST_FOO=BAR
|
||||
TEST_APP_DEST_HOST=10.10.0.127
|
||||
TEST_APP_DEST_PORT=8888
|
||||
TEST_PASSTHROUGH=howdy
|
||||
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run --name console -t -i ubuntu bash
|
||||
|
|
54
opts/envfile.go
Normal file
54
opts/envfile.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package opts
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
Read in a line delimited file with environment variables enumerated
|
||||
*/
|
||||
func ParseEnvFile(filename string) ([]string, error) {
|
||||
fh, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
defer fh.Close()
|
||||
|
||||
lines := []string{}
|
||||
scanner := bufio.NewScanner(fh)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
// line is not empty, and not starting with '#'
|
||||
if len(line) > 0 && !strings.HasPrefix(line, "#") {
|
||||
if strings.Contains(line, "=") {
|
||||
data := strings.SplitN(line, "=", 2)
|
||||
|
||||
// trim the front of a variable, but nothing else
|
||||
variable := strings.TrimLeft(data[0], whiteSpaces)
|
||||
if strings.ContainsAny(variable, whiteSpaces) {
|
||||
return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' has white spaces", variable)}
|
||||
}
|
||||
|
||||
// pass the value through, no trimming
|
||||
lines = append(lines, fmt.Sprintf("%s=%s", variable, data[1]))
|
||||
} else {
|
||||
// if only a pass-through variable is given, clean it up.
|
||||
lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), os.Getenv(line)))
|
||||
}
|
||||
}
|
||||
}
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
var whiteSpaces = " \t"
|
||||
|
||||
type ErrBadEnvVariable struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e ErrBadEnvVariable) Error() string {
|
||||
return fmt.Sprintf("poorly formatted environment: %s", e.msg)
|
||||
}
|
|
@ -52,6 +52,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
|
|||
flVolumesFrom opts.ListOpts
|
||||
flLxcOpts opts.ListOpts
|
||||
flDriverOpts opts.ListOpts
|
||||
flEnvFile opts.ListOpts
|
||||
|
||||
flAutoRemove = cmd.Bool([]string{"#rm", "-rm"}, false, "Automatically remove the container when it exits (incompatible with -d)")
|
||||
flDetach = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: Run container in the background, print new container id")
|
||||
|
@ -78,6 +79,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
|
|||
cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
|
||||
cmd.Var(&flLinks, []string{"#link", "-link"}, "Add link to another container (name:alias)")
|
||||
cmd.Var(&flEnv, []string{"e", "-env"}, "Set environment variables")
|
||||
cmd.Var(&flEnvFile, []string{"-env-file"}, "Read in a line delimited file of ENV variables")
|
||||
|
||||
cmd.Var(&flPublish, []string{"p", "-publish"}, fmt.Sprintf("Publish a container's port to the host (format: %s) (use 'docker port' to see the actual mapping)", nat.PortSpecTemplateFormat))
|
||||
cmd.Var(&flExpose, []string{"#expose", "-expose"}, "Expose a port from the container without publishing it to your host")
|
||||
|
@ -199,6 +201,20 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
|
|||
}
|
||||
}
|
||||
|
||||
// collect all the environment variables for the container
|
||||
envVariables := []string{}
|
||||
for _, ef := range flEnvFile.GetAll() {
|
||||
parsedVars, err := opts.ParseEnvFile(ef)
|
||||
if err != nil {
|
||||
return nil, nil, cmd, err
|
||||
}
|
||||
envVariables = append(envVariables, parsedVars...)
|
||||
}
|
||||
// parse the '-e' and '--env' after, to allow override
|
||||
envVariables = append(envVariables, flEnv.GetAll()...)
|
||||
// boo, there's no debug output for docker run
|
||||
//utils.Debugf("Environment variables for the container: %#v", envVariables)
|
||||
|
||||
config := &Config{
|
||||
Hostname: hostname,
|
||||
Domainname: domainname,
|
||||
|
@ -213,7 +229,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
|
|||
AttachStdin: flAttach.Get("stdin"),
|
||||
AttachStdout: flAttach.Get("stdout"),
|
||||
AttachStderr: flAttach.Get("stderr"),
|
||||
Env: flEnv.GetAll(),
|
||||
Env: envVariables,
|
||||
Cmd: runCmd,
|
||||
Dns: flDns.GetAll(),
|
||||
DnsSearch: flDnsSearch.GetAll(),
|
||||
|
|
Loading…
Add table
Reference in a new issue