Moby: How to set an enviroment variable on an existing container?

Created on 29 Oct 2014  路  32Comments  路  Source: moby/moby

One can pass environment vars into new containers when building them with "docker run":
docker run -e "FOO=bar" ...

But how can one do that for an existing container, there is no -e option for docker run.
I wish to be able to restart a container with a new environment setting, but do not wish to actually recreate the container (as it has lots of manual changes in there).

One option might be to commit the container to an image and create a new container based on that image. Seems a very roundabout way though.

have I missed something?

Most helpful comment

I found a solution... You just stop docker daemon and change container config in

/var/lib/docker/containers/[container-id]/config.json

I also tried to do this with just docker container reseting but file seems to be rewriten on each start.

This is just a temporary solution (I hope), since, I do not want to stop all containers just to modify one...

You can find container-id by executing

docker inspect [container-name]

All 32 comments

I am looking for that as well,
I can change environment variables, go into container (for example, docker-bash tool), and export vars with export command or unset them. But in this way, when I exit from container, docker recovers old vars and their values.

@Boran @antonbormotov I believe commit is the right way here since you essentially want to keep a modified state of a container.

If your program is smart enough to have a way to source some file upon being notified, you could docker exec sh -c echo 'foo=bar' > /root/.bashrc' and notify the program to source it.

/cc @jfrazelle @tianon

The container name and and hostname within are also cast in stone.
As regards committing and recreating with 'run', one has to be very careful to re-add the same volumes and environments for the new container to really be a clone with just one env change.

Edit: when doing a commit - rm - run, one loses the contents of non bound data volumes, which I just found out the hard way.
From a sysadmin point of view these are real limitations.

I guess it is a conceptual issue that one just has to live with.
One can close this issue from my point of view.

I find it very usefull. +1

Yes. It will be very useful. At the moment, my workaround is this:

docker exec -i CONTAINER_ID /bin/bash -c "export VAR1=VAL1 && export VAR2=VAL2 && run_cmd"

@bletvaska How does that work?

to @onbjerg before the command run_cmd is executed, the environment variables VAR1 and VAR2 are set.

But will this update the env variables "forever"? I mean, if I run this and then 5 days later change some variable in run_cmd, will it still work? Or is it a one-off command?

@onbjerg it is a one-off command. if you want to make this change permanent in the container, you have to commit your changes as was mentioned earlier.

I found a solution... You just stop docker daemon and change container config in

/var/lib/docker/containers/[container-id]/config.json

I also tried to do this with just docker container reseting but file seems to be rewriten on each start.

This is just a temporary solution (I hope), since, I do not want to stop all containers just to modify one...

You can find container-id by executing

docker inspect [container-name]

didn't work for me.

docker run --name test1 busybox echo hello world
docker inspect test1
vi /var/lib/docker/containers/a1942d99c06a3e9d7c2229d2d6e3ab2370ceb427db488326088d615c0e89f8d5/config.json
(change test1 to test2 in the config)
start docker

docker start test2
Error response from daemon: no such id: test2
Error: failed to start containers: [test2]

You did not stop docker daemon before editing config and start it after. :)
Also, I did not test it with name, only enviroment variable. :)

Yes, change an env variable works, confirmed.
But not changing the conatiner name (which is irrelevant since docker now has a rename function any way).

This is a very annoying limitation

For those interested, there's an open PR for changing properties of running/existing containers, but it has not yet been decided on; https://github.com/docker/docker/pull/15078

Thanks /var/lib/docker/containers/[container-id]/config.json
At lease..... We can change

Folks,

Let's close the question. Here is my challenge:
How can I pass an environment variable from the host into a container while running a bash script?

I didn't find the answer easily ... but here it is!
The beauty of this setup is that it runs via a bash script.
We always stays at the remote level and not within the postgresql-master container.


echo Generate a unique file name for this backup
ENV_BKP_NAME="$(date +%Y-%m-%d_%Hh%Mm%S)_pg-master.sql"

echo Transfer the env_var into postgresql-master container
docker exec -it postgresql-master sudo -u postgres bash -c \ export
declare -x VAR_BKP_NAME=$ENV_BKP_NAME

echo Time to backup ... pg_dumpall"
docker exec -it postgresql-master sudo -u postgres bash -c \
    "cd /var/lib/postgresql/backup \
    && pg_dumpall -U postgres --clean --oids --verbose > $VAR_BKP_NAME \
    && echo Message within postgresql-master container... \
    && echo ... backup $VAR_BKP_NAME is completed"

Cheers!
Pascal Twitter

Now the config file is overwritten even after docker is stopped. :(

I do not understand why this issue is closed?
PR https://github.com/docker/docker/pull/15078 just supports resource configs for now.
As pointed out by @yaitskov the workaround editing the config file even does not work anymore at all.
The comment by @Boran in Jan 2015 points out a lot of arguments on which I would not conclude to close this issue.

"I _guess_ it is a conceptual issue that one just has to live with." is not a closing argument either.

  1. Is this a conceptual issue hard to change?
  2. Would it be possible and valueable to change even if not easy?

I would answer the second question with yes, so one should not close this issue from my point of view.

ENV variables are not meant to be changed.
If you want to change ENV variables, you deploy or commit and start with new ENV variables...

For me it's ok to close this, it's a conceptual issue.
When working with containers one has to learn to use the "immutability".

docker exec -ti -e LINES=$LINES -e COLUMNS=$COLUMNS $container bash

The problem is that when you stop a container it actually kills all the processes, than when you do start it run the processes again from scratch, reading the old env values from somewhere, why can't I override them? @nemanjan00 this is IMO a pure technical issue and there are some cases when commit to image and run again as new container is very cumbersome and annoying.

I've encountered this roadblock several times. For the more less experienced programmers, docker is a great tool, but I wish containers/configurations were more pliable on-the-fly. In this case, setting environment variables for an existing container. Thanks.

I Just encountered this issue for the nth time. It does seem like a pain but thinking about it, your containers shouldn't contain any state that is not entirely disposable, so docker is helping us help ourselves towards a goal of immutability and documented deploys.

I Suppose it depends what you are using docker for, but I imagine there would be many that would be horrified if their ENV variable for database was changed during runtime without notice to another DB siphoning off user-data.

Just thought I'd put that out there.

Is there a method like kube's edit or something to edit docker inspect ?

@pykiss Thanks for the solution. It is working!

I can't find /var/lib/docker/.....

docker container inspect 503cac788f35
"Id": "503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11", "Created": "2017-09-01T07:14:21.585220331Z", "Path": "/docker-entrypoint.sh", "Args": [ "kibana" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 13405, "ExitCode": 0, "Error": "", "StartedAt": "2018-04-23T14:06:39.160219761Z", "FinishedAt": "2018-04-23T14:01:18.693610061Z" }, "Image": "sha256:8689ff370eef04a1de40fc5242c72a91b6f68e18412692445ad73c9f298b4184", "ResolvConfPath": "/var/lib/docker/containers/503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11/resolv.conf", "HostnamePath": "/var/lib/docker/containers/503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11/hostname", "HostsPath": "/var/lib/docker/containers/503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11/hosts", "LogPath": "/var/lib/docker/containers/503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11/503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11-json.log", "Name": "/kibana", ....... ........

but when i cd to this location , not found location

$ cd /var/lib/docker/containers/503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11/hosts
-bash: cd: /var/lib/docker/containers/503cac788f35b05e54a146272edf4904bea6fc4334cc54585b8c5ee07767ad11/hosts: No such file or directory

What's wrong with me?

@ntlzz93 hosts is probably a file a not a folder

@Boran you can use bash script in entrypoint and receive environments from env file or other your best way, on every start, restart container, entrypoint updates your enviroments.
in dockerfile

...
ENTRYPOINT ["/bin/sh -c", "/path/to/your/bash.sh"]

in bash.sh

#!/bin/bash
# Export from source or other your easy ways
export VAR1=VAL1 && export VAR2=VAL2
# Then start your service e.g. apache2
exec apache2 -DFOREGROUND

im using CMD in dockerfile

CMD ["/root/scripts/boot.sh"]

I know this issue is closed since a while but I'm surprised. Has anyone ever considered using a .profile to solve this?

In case some people still come on this issue which is on Google Search Top10 results, we use .profile here. (See details in this issue: https://github.com/moby/moby/issues/22490#issuecomment-541429688)

In case some people still come on this issue which is on Google Search Top10 results, we use .profile here. (See details in this issue: #22490 (comment))

I don't know how ~/.profile helps since it's not sourced at all unless you use something like sh -l.

Was this page helpful?
0 / 5 - 0 ratings