165

Trying to fix errors and debug problems with my application that is split over several containers, I frequently edit files in containers:

  • either I am totally lazy and install nano and edit directly in container or

  • I docker cp the file out of the container, edit it, copy it back and restart the container

Those are intermediate steps before coming to new content for container build, which takes a lot longer than doing the above (which of course is only intermediate/fiddling around).

Now I frequently break the starting program of the container, which in the breaking cases is either a node script or a python webserver script, both typically fail from syntax errors.

Is there any way to save those containers? Since they do not start, I cannot docker exec into them, and thus they are lost to me. I then go the rm/rmi/build/run route after fixing the offending file in the build input.

How can I either edit files in a stopped container, or cp them in or start a shell in a stopped container - anything that allows me to fix this container?

(It seems a bit like working on a remote computer and breaking the networking configuration - connection is lost "forever" this way and one has to use a fallback, if that exists.)

How to edit Docker container files from the host? looks relevant but is outdated.

Community
  • 1
  • 1
Andreas Reiff
  • 7,961
  • 10
  • 50
  • 104
  • This one also might be a workaround http://stackoverflow.com/a/32353134/586754 - hoping for a better solution yet. – Andreas Reiff Sep 24 '15 at 09:52
  • 1
    maybe you should consider mounting a volume so you can edit files on your host instead of inside the container. Once happy with your code, you are free to `docker cp` the files to the container (or build a new image) – Thomasleveil Sep 24 '15 at 22:31
  • Yes, this would be a little late though if I have not set things up like this from the beginning. This does not work for recovery, I think. – Andreas Reiff Sep 28 '15 at 16:56
  • Many readers will only want to __view__ files rather than edit them. In these cases you can use the `docker commit` command to break a new image. `name=$(docker commit); docker run -it $name /bin/sh` will do what you want. – Att Righ Mar 06 '17 at 16:04
  • so it seems that the file systems of stopped containers are relatively permanents at end ? – Webwoman Sep 13 '18 at 14:25
  • Seems like some kind of fuse mount of the stopped container's contents is what we want. – mcr May 15 '19 at 20:58

5 Answers5

281

I had a problem with a container which wouldn't start due to a bad config change I made. I was able to copy the file out of the stopped container and edit it. something like:

docker cp docker_web_1:/etc/apache2/sites-enabled/apache2.conf .

(correct the file)

docker cp apache.conf docker_web_1:/etc/apache2/sites-enabled/apache2.conf
tomurie
  • 2,821
  • 2
  • 7
  • 2
  • Perfect. I copied a file from the container (I knew its path) and then edited it, and then copied back to the container to the same location. Worked for me! Thanks! – Nawaz Apr 24 '20 at 10:29
  • 2
    Is there a way to remove a file? – kodlan May 24 '20 at 15:44
  • 1
    @kodlan Only if it only appears in the `UpperDir` you get from `docker container inspect` - you'd have to experiment to see how the overlay system represents files in the underlying structure which have been deleted in the upper layer. – Tim Baverstock Jun 02 '20 at 08:51
  • Thanks, this helped me fix my MySQL container running in docker on macOS. – mazedlx Oct 09 '20 at 07:16
  • Note that if the source file you are trying to move is a symlink you might get a `invalid symlink "/root/apache2.conf" -> "../sites-available/apache2.conf` error (this is shown up with Apache 2 because of the sites-enabled/sites-available links). So instead, make sure you copy the original file. – Dan Gravell Nov 14 '22 at 14:50
  • Awesome reply. Make sure to commit the image afterwards, or your mods will be lost after container restart. – Orsiris de Jong Apr 17 '23 at 23:48
  • @tomurie, you saved my a$$ today; thank you so much! – Alyas Jul 05 '23 at 13:54
70

Answering my own question.. still hoping for a better answer from a more knowledgable person!!

There are 2 possibilities.

1) Editing file system on host directly. This is somewhat dangerous and has a chance of completely breaking the container, possibly other data depending on what goes wrong.

2) Changing the startup script to something that never fails like starting a bash, doing the fixes/edits and then changing the startup program again to the desired one (like node or whatever it was before).

More details:

1) Using

docker ps

to find the running containers or

docker ps -a

to find all containers (including stopped ones) and

docker inspect (containername)

look for the "Id", one of the first values.

This is the part that contains implementation detail and might change, be aware that you may lose your container this way.

Go to

/var/lib/docker/aufs/diff/9bc343a9..(long container id)/

and there you will find all files that are changed towards the image the container is based upon. You can overwrite files, add or edit files.

Again, I would not recommend this.

2) As is described at https://stackoverflow.com/a/32353134/586754 you can find the configuration json config.json at a path like

/var/lib/docker/containers/9bc343a99..(long container id)/config.json

There you can change the args from e. g. "nodejs app.js" to "/bin/bash". Now restart the docker service and start the container (you should see that it now correctly starts up). You should use

docker start -i (containername)

to make sure it does not quit straight away. You can now work with the container and/or later attach with

docker exec -ti (containername) /bin/bash

Also, docker cp is rather useful for copying files that were edited outside of the container.

Also, one should only fall back to those measures if the container is more or less "lost" anyway, so any change would be an improvement.

Community
  • 1
  • 1
Andreas Reiff
  • 7,961
  • 10
  • 50
  • 104
  • Still hoping for better answer - so feel free to give one, I will move "ansered" tag as well. – Andreas Reiff Nov 16 '15 at 20:38
  • I used the second way and I had to restart docker service in order to force overwriting of ```config.json``` files every time I edited them – Vitaly Isaev Dec 08 '15 at 11:15
  • 2
    I have config.v2.json and every time I start the zombie container, it reverts my Path/EntryPoint update and dies once again. Using "docker cp" to update the entrypoint.sh script to just run bash fixed it. – Curtis Yallop Apr 21 '17 at 17:01
  • @CurtisYallop I'm experiencing the same thing. How did you resolve it? – Brett McLain Sep 07 '17 at 22:01
  • 1
    @BrettMcLain I used docker cp rather than editing it on the host. Like this: Find entry point script location: "docker inspect container_name | grep Entry". Get script: "docker cp container_name:/entrypoint.sh ./". (Edit it) Put script back in container: "docker cp entrypoint.sh container_name:/entrypoint.sh". You can make entry point run bash or run a sleep loop eg "while :; do sleep 10; done". First script line needs to be "#!/bin/bash". – Curtis Yallop Sep 21 '17 at 17:05
  • Thanks Curtis!! You saved the day for me..... I am so relieved, thought that i have lost my work ..... – mayank Sep 25 '17 at 10:28
13

You can edit container file-system directly, but I don't know if it is a good idea. First you need to find the path of directory which is used as runtime root for container. Run docker container inspect id/name. Look for the key UpperDir in JSON output.

That is your directory.

Tejas Sarade
  • 1,144
  • 12
  • 17
  • Found the directory, but that didn't contain all the files. – aioobe Nov 13 '18 at 17:38
  • It is OverlayFS, so your files must be in one on those directories. – Tejas Sarade Nov 26 '18 at 14:41
  • Directory name could be different than "UpperDir", for example, in my case it is Source. But it worked! – user Nov 10 '20 at 13:02
  • You can work on the "MergedDir", it's going to contain all the files from lower dirs and diff on top of that. If you modify something, it will end up in diff, so just like on the container... – p0358 Sep 07 '22 at 08:23
2

Docker Desktop has a option for that but not all versions of it support this feature.

Using Docker Desktop version 4.17.0 (99724) there is a option available to edit files on stopped containers : Container edit dropdown

After that a view should appear where you can edit the file. Just make sure you have the permissions to edit the file you want.

Edit

Also make sure you save it afterwards.

Making file changes

Makusium
  • 201
  • 1
  • 2
  • 15
0

If you are trying to restart an stopped container and need to alter the container because of misconfiguration but the container isn't starting you can do the following which works using the "docker cp" command (similar to previous suggestion). This procedure lets you remove files and do any other changes needed. With luck you can skip a lot of the steps below.

  1. Use docker inspect to find entrypoint, (named Path in some versions)
  2. Create a clone of the using docker run
  3. Enter clone using docker exec -ti bash (if *nix container)
  4. Locate entrypoint file location by looking though the clone to find
  5. Copy the old entrypoint script using docker cp : ./
  6. Modify or create a new entrypoint script for instance

    #!/bin/bash tail -f /etc/hosts

  7. ensure the script has execution rights
  8. Replace the old entrypoint using docker cp ./ :
  9. start the old container using start
  10. redo steps 6-9 until the starts
  11. Fix issues in container
  12. Restore entrypoint if needed and redo steps 6-9 as required
  13. Remove clone if needed
user6830669
  • 161
  • 4