How to edit files within docker containers

How to edit files within docker containers

Disclaimer

You have probably heard countless times that you should never edit a docker container’s state, or editing container state is an anti-pattern, or if you need to edit a container’s state you should use volumes. That advice is good advice and so this article starts with a disclaimer.

If you really need to edit file(s) within a docker container you most likely should do it in one of two ways:

  1. Use a docker volume; or
  2. Make any edits to the file(s) part of the image’s DOCKERFILE

I would recommend never editing a file in production unless the file is part of a mounted docker volume (and even then you should exercise caution not to inadvertently affect the production system). That being said, making minor, ephemeral edits to files within a development environment outside of production can be a quick and easy way to test a change and/or aid in debugging. If the edits you make are not minor consider using the one of the two methods listed above to make changes to your files.

Our running example

With the disclaimer out-of-the way we can move on to our running example:

  • We have an Apache web server (httpd) container that we are having problems with.
  • We would like to edit the server’s configuration file to increase the LogLevel  so that more logging information is output and debugging (hopefully) becomes easier.
  • The configuration file in question is not part of a volume so we will edit it from within the container.

There are two ways in which we can get inside the running container to edit the configuration file:

  1. Open a shell and edit the file from the command line.
  2. Remote into the container and make the changes with our editor.

This article covers the first method but in practice it is a lot easier and much more convenient to use the second method. This is because containers usually do not have text editors installed within them (even vi and nano  will usually not be present) and as a result we have to either install a text editor or use a tool such as sed.

Click here to read an article exploring how you can utilise the second method by remoting into you container using Emacs’ as your editor.

Opening a shell and editing the httpd.conf file from the command line

Remember our running example: we would like to edit the httpd.conf  file to increase the LogLevel of our Apache server (httpd) container. In order to make the change to the file within the container we take the following steps:

1. Run the Apache web server container

  • We are running version 2.4 of the Apache web server (httpd).

2. Get the id of the running container

  • A simple docker ps  will list the running containers and from there you can get the container id.
  • You can see that the id of the container we want begins with c460...

3. Open a shell in the running container

  • Remember from our previous article, how to start a shell in a running Docker container, the command for opening a shell in a running container has the syntax: docker exec -it <container-id> /bin/bash.
  • You only need to enter the first few characters of the container id – not the whole thing!
  • Once the command is executed you enter a root shell within the container (shown by the presence of ‘root’ and ‘#’).

4. Check the current value of the LogLevel directive within the configuration file

  • Explanation of the command:
    • cat conf/httpd.conf | grep -i loglevel.
      • cat conf/httpd.conf  prints the content of the file conf/httpd.conf.
      • The |  (pipe) redirects the output printed by  cat  to the next command which is grep.
      • grep  is called with the argument loglevel  and the flag -i.
      • The -i  flag makes sure the loglevel  string is treated in a case-insensitive way by grep.
    • The command results in all lines with any occurrence of loglevel  (case-insensitive) being printed to the screen.
  • From the output we can see that the LogLevel  is set to warn  – whereas we would like it set to debug.

5. Use sed to search and replace the line with what we want

  • Most likely, as is in this case, the container will not have a text editor installed – even vi  and nano will not present. As a result we use sed (which is installed) to make the change.
    •  An alternative would be to use your container’s package manager to install an editor. For example if the container is Debian based you could run  apt-get update && apt-get install vim  to install vim . Once installed you could use vim to edit the file.
  • Explanation of the command:
    •   sed 's/LogLevel warn/LogLevel debug/' conf/httpd.conf ...
      • Substitute LogLevel warn  with LogLevel debug  in the contents of the file conf/httpd.conf. Note sed just streams this substitution to stdout so it still needs to be written to disk to persist.
    • ... > conf/httpd.conf.changed && mv conf/httpd.conf.changed conf/httpd.conf
      • Write the output from the substitution to the file conf/httpd.conf.changed (it could be called anything) and then rename (move) the file so it overwrites the original. This is done to avoid the issue of creating an empty file as output (as would be the case if we wrote to the same file we read in from).
    • Essentially this just replaces the occurrence of LogLevel warn  with LogLevel debug  in the conf/httpd.conf file .

6. Check that your file change has been made correctly

  • We can see from the output the LogLevel has been changed from warn to debug as we wanted.

7. Exit the shell (also exits the container)

8. Restart the container for the changes to take effect

  • The actual file change occurs immediately within the container but the global configuration file for the Apache server (httpd.conf) is only read when the server starts.
  • As a result we need to restart the server/container for the changes to take effect.

Conclusion

That’s it – you’re done! This article walked you through how to edit a file within a docker container by opening a shell within the container and using sed to replace the line which we wanted to change. This is definitely not the most convenient way and so is probably only appropriate for quick, ephemeral changes that would be discarded later.

A more convenient method of making changes to files within a container is to remote into the container and make changes with your favourite editor. Click here to read an article which explains exactly how to do that using Emacs.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *