Using Emacs to edit files within Docker containers
by Liger Learn
This article explores how you can use an Emacs package docker-tramp, which extends the built-in TRAMP mode, to remote into your Docker containers and make changes to files from within Emacs. In a previous article, how to edit files within docker containers, we discussed how you could make changes to files within a running container by opening a shell and using the command line program sed.
If you are an Emacs user you will find the method in this article much more convenient than opening a shell within a running container as you retain the full power of your Emacs configuration and are presented with familiar interfaces in the form of Dired and TRAMP. But before we begin you should familiarise yourself with the disclaimer from the previous article so you know when it makes sense to actually edit files within containers and the alternative options available ( docker volumes and DOCKERFILEs). Essentially you should use Emacs to make changes to files within containers only when those changes are ephemeral and outside of production environments.
The running example from the previous article is reused in this one and repeated below.
Our running example is as follows:
- 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.
Using Emacs to change a file within a running docker container
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. Install the docker-tramp package
- M-x list-packages.
- Find the docker-tramp package.
- Mark the package for installation by pressing i .
- Execute the mark by pressing x and confirming yes to install the docker-tramp package.
Note: you need to make sure the MELPA repository is part of your package-archives variable in your emacs configuration otherwise the package will not appear in the list. See the ELPA Emacs wiki page for further information on how to do this.
2. Run your docker container
$ docker run -d httpd:2.4
- In this case we want to run the Apache Web Server version 2.4 which is the official docker container labelled as httpd (see DockerHub).
- The output of the command will be the container ID – you will need that later.
3. Get your container ID
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e18d9f6fd49e httpd:2.4 "httpd-foreground" 2 seconds ago Up 1 second 80/tcp confident_kalam
- The output from the command in the previous step would have been the container ID.
- In case you closed that terminal and no longer have the output, you can run
- This will give you the container ID in the first column.
4. Connect to your container through TRAMP in emacs
- Enter the Emacs key binding to find a file:
- This is usually written as C-x C-f by people who use Emacs (where the C is short for CTRL).
/docker: – it is important to start with the slash even if the path shown in the minibuffer ends with one.
- For example in the minibuffer in the image the path ends with a slash ( ~/) but we still start typing with one anyway ( /docker:).
TAB after the colon (
:) and your path will autocomplete to the container ID and another colon (e.g. in the above image
/docker:TAB autocompleted to
- If you have multiple containers running, when you hit TAB a Completion List buffer will pop up listing the IDs of all available containers.
- In that case since you know the container ID you wish to connect to you can either click on the correct one in the buffer or type it in.
- Hit RETURN and you will enter a Dired buffer for a location within the container ( /docker:e18d9f6fd49e:/root:)
5. Open the file you wish to edit, make your changes and save them
- You can see that the file we wish to edit is found within the container at path:
- If you do not know the location of the file you can play around and navigate inside the container through DirEd buffers.
- You can navigate to the file by going through Dired buffers or just by typing the path directly into the minibuffer after entering the find file command ( C-x C-f).
- Once you have opened the file we can navigate to the correct line and change the LogLevel to be the value we want ( debug instead of warn).
- Save the file ( C-x C-s) from Emacs so that the change is reflected within the container.
- You can now exit Emacs having committed your file change to the container.
5. Restart the container for the changes to take effect
$ docker restart e18d9f
- 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.
That’s it – you’re done! In this article we walked through how you can use Emacs’ docker-tramp mode to open a file within a running container in Emacs, edit it, and save it so that the changes are reflected within the container. Although our running example was to edit a particular configuration file you can use the same steps to edit any file within a running container.
This method is much more convenient for Emacs users than the one discussed in the previous article (opening a shell inside the container and using sed). Of course, as mentioned before, if the file change you are making is not intended to be ephemeral then consider making it part of an image’s DOCKERFILE or using docker volumes .
March 11, 2017
March 2, 2017
June 7, 2020