How to edit file within Docker container or edit a file after I shell into a Docker container?

While working on my Spring Boot Microservices with Docker I felt a need to edit some of the files present under my docker container.

But when I tried to edit the file nano application.yaml it throws me an error bash: nano: command not found. So I was not able to edit the file which is present inside my running docker container.

After spending some time on google and thinking about the issue I realized docker never encourages you to edit or change anything present inside the docker container.

Docker has the principle of keeping the things lightweight so that we can easily ship the containers to any environment due to that fact you will never find utilities such as nano, tree etc by default installed. You have to install it manually inside your docker container.

Here are the steps for editing files in a container

  1. Find the container id of a running container
  2. Login inside the docker container using CONTAINER ID
  3. Update the package manager
  4. Install the required package vi, nano, vim etc.
  5. Edit the file using either vim or nano
  6. Install vim editor along with dockerfile
  7. Using remote editor by exposing the port 22
  8. Best practices for editing the file


1. Find the container id of a running container

First, we need to find the CONTAINER ID of the running container. Use the following command to list all the running containers -

1docker ps -a

The above command will list out all the running containers.

Look at the CONTAINER ID in which you want to edit the file.

Note down or COPY the CONTAINER ID because we are going to use it to go inside the docker container.



2. Login inside the docker container using CONTAINER ID

In the previous step-1 we have to fetch the CONTAINER ID of the running container. Now we need to login into the container using the following command -

1docker exec -u 0 -it 8662ea2fa000 /bin/bash

If the above command fails with the message - OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown then you should replace the /bin/bash with /bin/sh

Here is the command -

1docker exec -u 0 -it 8662ea2fa000 /bin/sh

Note - The above command will help you to log in as root user so that you will have all the privileges.

After executing the above command you will be inside your running container.

If you do not put the -u 0 flag inside your docker container then you will be logged as appuser and you will not have root privileges and you will not be able to install any new utility inside your docker container.



3. Update the package manager

Once you are logged into the docker container the first thing which you need to do is to update the package manager so that it will have all the latest repository URLs updated.

Run the following command to update the package manager -

  1. For CentOS -
1yum update
  1. For Ubuntu
1apt-get update


4. Install the required package vi, nano, vim etc.

Now after updating the package repository you can install your favorite editor (vi, nano, vim) inside your docker container so that you can edit the file.

Here is the command for installing the editor -

  1. For CentOs
1yum install vim-enhanced -y
2yum install nano -y
3yum install vim-minimal -y
4
5or
6
7dnf install vim-enhanced -y
8dnf install nano -y
9dnf install vim-minimal -y
  1. For Ubuntu
1apt-get install vim
2apt-get install nano


5. Edit the file using either vim or nano

Finally, you can use the command nano application.yaml or vim application.yml to edit/update your file present inside the running docker container.



6. Install vim editor along with dockerfile

This is one of the easiest ways with which you can install your favorite editor along with your docker container. I am using the vim editor but you can choose any Linux editor of your choice.

You can write installation instructions for vim inside your Dockerfile so that whenever you built and run the docker image vim editor will always be installed inside your container.

Here is my docker file where I have installed the vim editor -

 1FROM openjdk:8-jdk-alpine
 2ARG JAR_FILE=build/libs/*.jar
 3COPY ${JAR_FILE} app.jar
 4
 5RUN mkdir destination-dir-for-add
 6ADD sample.tar.gz /destination-dir-for-add
 7
 8RUN ["apt-get", "update"]
 9RUN ["apt-get", "-y", "install", "vim"]
10
11ENTRYPOINT ["java","-jar","/app.jar"]

If you look carefully in the above docker file then you will notice I have added only two lines of code for installing the vim into my container -

1RUN ["apt-get", "update"]
2RUN ["apt-get", "-y", "install", "vim"]

So you can use the above two lines of codes and replace the vim with your favorite editor of your choice.



7. Using remote editor by exposing the port 22

There is one more way by which you can expose the port 22 or in other words if I say enabling the SSH into the running container. I would certainly not recommend this approach because you will start many parallel processes along with your container.

But use this approach only when you are in the development phase and where you need to debug. For a production environment, it is highly discouraged.

So here are the things which we need to do -

  1. Install openssh-server
  2. run ssh process
  3. Expose port 22
  4. Build and run docker image on port 22

We will put all this inside the docker file. Here is the docker file -

 1FROM openjdk:8-jdk-alpine
 2ARG JAR_FILE=build/libs/*.jar
 3COPY ${JAR_FILE} app.jar
 4
 5RUN mkdir destination-dir-for-add
 6ADD sample.tar.gz /destination-dir-for-add
 7
 8RUN ["apt-get", "update"]
 9RUN ["apt-get", "install", "-y", "openssh-server"]
10RUN echo 'root:lollol0' | chpasswd
11RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
12RUN ["/etc/init.d/ssh", "start"]
13
14EXPOSE 22
15
16WORKDIR "/app"
17
18CMD ["/usr/sbin/sshd", "-D"]
19
20ENTRYPOINT ["java","-jar","/app.jar"] 


7.1 Build the docker image

Now we need to build the docker image. Use the following command to build the docker image and substitute the image name as per your need -

1docker build -t myimagewithopenssh . 

7.2 Run docker image on port 22

Now in the previous two steps(Step 7, Step 7.1) we have created a dockerfile and build a docker file. Let’s run the dockerfile on the port 22

Here is the command you should use for running the docker image -

1docker run --rm -p 2222:22 -d --name=myimagewithopenssh myimagewithopenssh 

After starting the container now you can edit the file remotely. Here is the vim command for editing the file present inside your docker container -

1vim scp://root@localhost:2222//app/application.yaml


8. Best practices for editing the file

Editing a file inside a running docker container is not recommended because it goes against the basic principles of containerization. A container should exhibit similar behavior no matter where you running it, so if a container works in your development environment then it should work on stage as well as the production environment.

So the question comes why do you need to edit a file inside the running container?

Answer - You are working on a development environment where you want to test some changes by temporarily editing the files inside the docker container but still the scope is limited to your development environment.

Here are some discussion threads which I found on the development forum -

  1. Stackoverflow - How do I edit a file after I shell to a Docker container?
  2. Docker Forum - How to edit a file in a running container?

Anchor-17-feb-2021