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

How to set an enviroment variable on an existing container? #8838

Closed
Boran opened this issue Oct 29, 2014 · 37 comments
Closed

How to set an enviroment variable on an existing container? #8838

Boran opened this issue Oct 29, 2014 · 37 comments

Comments

@Boran
Copy link

Boran commented Oct 29, 2014

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?

@antonbormotov
Copy link

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.

@tiborvass
Copy link
Contributor

@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

@Boran
Copy link
Author

Boran commented Jan 14, 2015

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.

@ghost
Copy link

ghost commented Apr 6, 2015

I find it very usefull. +1

@bletvaska
Copy link

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"

@onbjerg
Copy link

onbjerg commented Jun 4, 2015

@bletvaska How does that work?

@bletvaska
Copy link

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

@onbjerg
Copy link

onbjerg commented Jun 5, 2015

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?

@bletvaska
Copy link

@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.

@nemanjan00
Copy link

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]

@Boran
Copy link
Author

Boran commented Jul 8, 2015

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]

@nemanjan00
Copy link

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

@Boran
Copy link
Author

Boran commented Jul 8, 2015

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).

@doronl
Copy link

doronl commented Nov 11, 2015

This is a very annoying limitation

@thaJeztah
Copy link
Member

For those interested, there's an open PR for changing properties of running/existing containers, but it has not yet been decided on; #15078

@peerasan
Copy link

peerasan commented Aug 8, 2016

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

@pascalandy
Copy link

pascalandy commented Aug 29, 2016

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

@yaitskov
Copy link

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

@derMart
Copy link

derMart commented Mar 10, 2017

I do not understand why this issue is closed?
PR #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.

@nemanjan00
Copy link

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...

@Boran
Copy link
Author

Boran commented Mar 11, 2017

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".

@eddo888
Copy link

eddo888 commented Apr 4, 2017

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

@doronl
Copy link

doronl commented Apr 6, 2017

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.

@michael-wise
Copy link

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.

@Lewiscowles1986
Copy link

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.

@jpic
Copy link

jpic commented Jun 10, 2017

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

@zsly1029
Copy link

@pykiss Thanks for the solution. It is working!

@ntlzz93
Copy link

ntlzz93 commented Apr 27, 2018

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?

@Dahu88
Copy link

Dahu88 commented May 7, 2018

@ntlzz93 hosts is probably a file a not a folder

@ptflp
Copy link

ptflp commented May 30, 2018

@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"]

@willemavjc
Copy link

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: #22490 (comment))

@felipecrs
Copy link

felipecrs commented Aug 26, 2020

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.

@ghost
Copy link

ghost commented Dec 24, 2022

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...

the argument tho is that this shouldn't be the case. you should not have to offline a container completely to update its configuration. its a config file. config files should be adjustable for specific circumstances as needed in my opinion

@nemanjan00
Copy link

There are plenty of good reasons why variables can not be universally changed in the runtime:

  1. Environment variables propagate down the process tree, so, there would be a need for ability to locate processes that need env variables changed

  2. A lot of containers use vars only in entrypoint, to generate config for application before starting it

  3. Most of apps only use env vars, to connect to DBs, set local vars, etc.

  4. Due to 2 and 3, you lose the biggest advantage of docker, the guarantee application will work the same time every time

  5. You lose immutability which is very important for HA

The proper way to change env vars is to deploy new version, by altering docker-compose.yml/dockcer-stack.yml or whatever other mechanism you use for deploying application

@felipecrs
Copy link

One possibility is to allow changing environment variables, but they would only be effective on container restart.

@nemanjan00
Copy link

It would be more of rebuild than restart, since restart does persist storage...

@yangyile1990
Copy link

但是我的容器已经启动,该怎样修改启动容器时的环境变量呢

#首先停止容器
docker stop gitlab
#获取到容器ID
export CONTAINER_ID=`docker inspect --format="{{.Id}}" gitlab`
#检查获取的是否正确
echo $CONTAINER_ID
#修改容器配置所在的位置(默认位置是 sudo vim /var/lib/docker/containers/$CONTAINER_ID/config.v2.json)
sudo vim /media/yangyile/SSDYILE/dockervolume/docker/containers/$CONTAINER_ID/config.v2.json
#在里面搜一下就能找到 "Env" 的配置,编辑即可
#编辑完重启docker服务
sudo systemctl stop docker
sudo systemctl stop docker.socket 
sudo systemctl start docker.socket 
sudo systemctl start docker
#容器再次启动后验证结果
docker exec gitlab bash -c 'echo $GITLAB_OMNIBUS_CONFIG'
#很明显结果已经生效,而看启动日志也是正常的启动
docker logs --tail 100 gitlab
#感谢这个教程
#https://stackoverflow.com/questions/27812548/how-to-set-an-environment-variable-in-a-running-docker-container
#里面的某个人的指导意见恰好能用于我的情况

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests