20170820

Change the parameters of a docker container without knowing the docker run command used

I'm not sure how useful this Docker "trick" is, since it happens in a very niche situation.

At work, we have several instances running a suite of Docker containers, with some non-trivial amount of environment variables, port configurations, volumes and links among them. This is set up really easily using ansible: writing link/port/volume mappings in ansible (using the docker, container or docker-container modules, depending how long ago we set it up). The syntax is similar to docker-compose, but scripted for ansible.

The problem arises when you are logged in on one of the machines and you want to change (or add) one parameter to one of the currently running containers. Re-running the ansible script in full is not always an option (for reasons I don't want to get into), so up until now we had to painfully rewrite the docker run command from the ansible set up, by hand. Which is terribly error prone. And a pain. And in general very much a process you don't want to follow, ever. We were very close to writing a short python script to convert the yaml specifications from python into docker run commands when we found out a relatively less painful way of doing it.

We jokingly call it the Indy swap



It's quite easy, and is best described using a checklist to avoid messing up.
  1. First, you figure out what you want to do. For instance, map a port
  2. Change to super-user
  3. Get the container id from docker ps
  4. Use your favourite remote editor to inspect the file /var/lib/docker/containers/{container_id}/config.json to figure out what you need to add
  5. service docker stop
  6. Edit the file in step 4 to add/remove any extra setting
  7. service docker start
  8. VoilĂ 

Steps 5-7 are the actual Indy swap, if we are not fast enough the healthcheks in our elastic load balancers will mark the instance as failing and stop it. Yes, we could disable the check while we do this, but where's the thrill, then?

By the way, the file in 4 will be a JSON file with the settings of the container. Any saved edit needs to be done with the docker service closed (since the file is in use otherwise). The format of adding ports, volumes or links is pretty self-explanatory as long as you have already a port, link or volume set up in the instance. Otherwise, check the configuration of any other running container having that. I suggest opening it in 4 with the editor already so you can up-arrow just after stopping the service without needing to find it, and also having planned the changes beforehand (or having done them in a config.json1 you then swap)

Oh, and don't do this in production. Oh, of course you won't because you are not using Docker in production, are you?
Written by Ruben Berenguel