Using Emacs to edit files within Docker containers

Using Emacs to edit files within Docker containers


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.

Running Example

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

Installing docker-tramp

  1. M-x list-packages.
  2. Find the docker-tramp package.
  3. Mark the package for installation by pressing i .
  4. 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

  • 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

  • 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 docker ps.
    • This will give you the container ID in the first column.

4. Connect to your container through TRAMP in emacs

Entering the id of the docker container in Emacs

  1. Enter the Emacs key binding to find a file: CTRL-x CTRL-f.
    • This is usually written as C-x C-f by people who use Emacs (where the C is short for CTRL).
  2. Type /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:).
  3. Hit 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 /docker:e18d9f6fd49e:).
    • 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.
  4. Hit RETURN and you will enter a Dired  buffer for a location within the container ( /docker:e18d9f6fd49e:/root:)

Entering a typical dired buffer within a docker container

5. Open the file you wish to edit, make your changes and save them

Navigate to the file we want to edit through the usual Dired interface

  • You can see that the file we wish to edit is found within the container at path: /usr/local/apache2/conf/httpd.conf.
    • 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).

Edit the file so that the LogLevel value changes from warn (top) to debug (bottom)

  • 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

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


Leave a Reply

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