790

I successfully shelled to a Docker container using:

docker exec -i -t 69f1711a205e bash

Now I need to edit file and I don't have any editors inside:

root@69f1711a205e:/# nano
bash: nano: command not found
root@69f1711a205e:/# pico
bash: pico: command not found
root@69f1711a205e:/# vi
bash: vi: command not found
root@69f1711a205e:/# vim
bash: vim: command not found
root@69f1711a205e:/# emacs
bash: emacs: command not found
root@69f1711a205e:/#

How do I edit files?

simhumileco
  • 31,877
  • 16
  • 137
  • 115
Igor Barinov
  • 21,820
  • 10
  • 28
  • 33

24 Answers24

1051

As in the comments, there's no default editor set - strange - the $EDITOR environment variable is empty. You can log in into a container with:

docker exec -it <container> bash

And run:

apt-get update
apt-get install vim

Or use the following Dockerfile:

FROM  confluent/postgres-bw:0.1

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

Docker images are delivered trimmed to the bare minimum - so no editor is installed with the shipped container. That's why there's a need to install it manually.

EDIT

I also encourage you to read my post about the topic.

Opal
  • 81,889
  • 28
  • 189
  • 210
  • Thank you for the VIM note. I am a beginner to docker. I have made some changes to some files with vim on bash, how do I apply these changes to the container? I used docker restart but it did't work – mediaroot Oct 02 '15 at 19:14
  • 7
    What you need is mounting a volume: https://docs.docker.com/userguide/dockervolumes/ – Opal Oct 02 '15 at 19:25
  • 35
    I needed to login as a root to get this done `docker exec -u 0 -it container_name bash`. – Eng.Fouad May 16 '16 at 09:40
  • There's a proposal here to not use multiple FROMs in the dockerfile (https://github.com/docker/docker/issues/13026) so if that comes into fruition, the second solution may not work for everyone, but the non-dockerfile instructions worked for me, appreciated. – joedragons Jul 14 '16 at 21:53
  • 59
    As with docker, better to install `vim-tiny` instead, probably. – ryenus Aug 22 '16 at 13:23
  • 3
    Maybe you could consider not installing an editor in each container you attach to, but rather just once on the docker host machine. As other commentators mentioned you can mount the volume, so you can edit the files that are going to be mounted, or navigate to the container data itself and edit the files in `/var/lib/docker/` – Pitt Dec 30 '16 at 17:18
  • Worked for an image made on a Debbie/Jessie Os.Thanks – Leon Jul 24 '17 at 13:37
  • one should also note that "no apt-update" usually means the apt command breaks, in case anyone is looking to "skip a step" and "save time" like I once did... – Felipe Valdes Jan 30 '18 at 01:59
  • This just thought me how to install vim at the same time, use EXEC to get into the container. Thanks a lot! – Vince Banzon Mar 01 '18 at 03:26
  • 8
    I just wanted to change one configuration from true to false in container. `apt-get` was not working due to permission issue inside container,so I tried `sed -i 's/texttobechanged/textwanted/g' filename` . It worked for me. – Amreesh Tyagi Sep 20 '18 at 10:09
  • Can anyone suggest me the best option so i do not need to copy manually the file – Faris Rayhan Jan 13 '19 at 16:10
  • 1
    @AmreeshTyagi good solution. my container is in kubernetes so I don't have root access. sed looks like the way to go. thx – TecHunter Jul 17 '19 at 08:01
  • 1
    Great answer. It worked for me in 2017 and I have ever since been referring many guys to this post https://blog.softwaremill.com/editing-files-in-a-docker-container-f36d76b9613c – Ole S Apr 12 '20 at 16:52
  • heureka, finally a good answere! still worth gold in 2021, but a tipp: try with nano, never use vim, you can't close the editor anymore and have to restart the container unfortunately :_( – clockw0rk Mar 24 '21 at 13:36
  • bash: apt-get: command not found is what I get after trying your solution – Adarsh Balu Jan 05 '22 at 07:25
  • @AdarshBalu, sińce you have a different distro with different package manager. – Opal Jan 05 '22 at 08:03
679

If you don't want to add an editor just to make a few small changes (e.g., change the Tomcat configuration), you can just use:

docker cp <container>:/path/to/file.ext .

which copies it to your local machine (to your current directory). Then edit the file locally using your favorite editor, and then do a

docker cp file.ext <container>:/path/to/file.ext

to replace the old file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hkong
  • 8,222
  • 1
  • 19
  • 15
  • 54
    @Igor This should actuallly be the accepted solution as it is the proper way to do it without adding additional packages to your container, while adding packages should be a secondary solution. – Routhinator Jan 21 '17 at 15:14
  • 7
    For Windows platforms, you can use, for example: `docker cp :C:\inetpub\wwwroot\Web.config .` and `docker cp Web.config :C:\inetpub\wwwroot\Web.config`. – Rosberg Linhares Aug 10 '17 at 21:43
  • 1
    Nice workaround for the testing purpose! I don't recommend doing it in production. – Michal Sipek Mar 08 '18 at 12:53
  • 13
    And what do you recommend for production? Should people be editing files in a container interactively in production? – lucid_dreamer Jun 15 '18 at 03:10
  • 9
    Worth noting this method changes the file ownership. It's possible but a bit fiddly to change it back afterwards by going into the container as root (`docker exec -u 0 -it mycontainer bash`) and then running a `chown` command. – Steve Chambers Sep 20 '18 at 10:00
  • Does not work for me with the nginx container. Command: ```docker cp nginx.conf f2:/etc/nginx/nginx.conf``` Error: ```Error response from daemon: Error processing tar file(exit status 1): remove /nginx.conf: device or resource busy``` – duality_ Oct 04 '19 at 11:34
  • @lucid_dreamer i suggest using shellscript to change stuff, as you said it's in production, so you'd already have finished staging processes and know which lines you have to edit – clockw0rk Mar 24 '21 at 13:40
165

You can use cat if it's installed, which will most likely be the case if it's not a bare/raw container. It works in a pinch, and ok when copy+pasting to a proper editor locally.

cat > file
# 1. type in your content
# 2. leave a newline at end of file
# 3. ctrl-c / (better: ctrl-d)
cat file

cat will output each line on receiving a newline. Make sure to add a newline for that last line. ctrl-c sends a SIGINT for cat to exit gracefully. From the comments you see that you can also hit ctrl-d to denote end-of-file ("no more input coming").

Another option is something like infilter which injects a process into the container namespace with some ptrace magic: https://github.com/yadutaf/infilter

Felix
  • 4,510
  • 2
  • 31
  • 46
meijsermans
  • 1,891
  • 1
  • 12
  • 4
66

To keep your Docker images small, don't install unnecessary editors. You can edit the files over SSH from the Docker host to the container:

vim scp://remoteuser@containerip//path/to/document
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matthew
  • 6,351
  • 8
  • 40
  • 53
  • 3
    Thank you. I wanted to leave this link which better explains the `vim scp://` [vim.wikia](http://vim.wikia.com/wiki/Editing_remote_files_via_scp_in_vim). Also, to get your container's IP address, you can use `sudo docker inspect | grep "IPAddress"` – aJetHorn Aug 31 '17 at 14:25
  • 1
    Just wondering, do I literally use "remoteuser", or "docker"? I've tried: `vim scp://docker@172.17.0.17//data/gitea/conf/app.ini` as well as `vim scp://remoteuser@172.17.0.17//data/gitea/conf/app.ini` and both of them just create a new, blank file. – J. Scott Elblein Apr 23 '19 at 13:02
  • 6
    @J.ScottElblein This requires configuring `ssh` on your docker container first. See https://blog.softwaremill.com/editing-files-in-a-docker-container-f36d76b9613c . But you generally don't want to be installing `ssh` in your container. – wisbucky Jul 17 '19 at 01:05
27

You can use cat if installed, with the > caracter. Here is the manipulation :

cat > file_to_edit
#1 Write or Paste you text
#2 don't forget to leave a blank line at the end of file
#3 Ctrl + C to apply configuration

Now you can see the result with the command

cat file
dero
  • 423
  • 4
  • 10
25

You can open existing file with

cat filename.extension

and copy all the existing text on clipboard.

Then delete old file with

rm filename.extension

or rename old file with

mv old-filename.extension new-filename.extension

Create new file with

cat > new-file.extension

Then paste all text copied on clipboard, press Enter and exit with save by pressing ctrl+z. And voila no need to install any kind of editors.

Simply Ged
  • 8,250
  • 11
  • 32
  • 40
xD3ath
  • 350
  • 3
  • 4
23

For common edit operations I prefer to install vi (vim-tiny), which uses only 1491 kB or nano which uses 1707 kB.

In other hand vim uses 28.9 MB.

We have to remember that in order for apt-get install to work, we have to do the update the first time, so:

apt-get update
apt-get install vim-tiny

To start the editor in CLI we need to enter vi.

simhumileco
  • 31,877
  • 16
  • 137
  • 115
  • 1
    For me this was the easier and faster solution, the above solutions could have the advantage of doesn't download apps but this is the easier one. – Ivandez Jul 03 '21 at 02:55
19

Sometime you must first run the container with root:

docker exec -ti --user root <container-id> /bin/bash

Then in the container, to install Vim or something else:

apt-get install vim
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yan
  • 1,382
  • 14
  • 11
10

I use "docker run" (not "docker exec"), and I'm in a restricted zone where we cannot install an editor. But I have an editor on the Docker host.

My workaround is: Bind mount a volume from the Docker host to the container (https://docs.docker.com/engine/reference/run/#/volume-shared-filesystems), and edit the file outside the container. It looks like this:

docker run -v /outside/dir:/container/dir

This is mostly for experimenting, and later I'd change the file when building the image.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ynux
  • 1,280
  • 14
  • 21
9

You can just edit your file on host and quickly copy it into and run it inside the container. Here is my one-line shortcut to copy and run a Python file:

docker cp main.py my-container:/data/scripts/ ; docker exec -it my-container python /data/scripts/main.py
David Dehghan
  • 22,159
  • 10
  • 107
  • 95
9

After you shelled to the Docker container, just type:

apt-get update
apt-get install nano
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dos
  • 2,250
  • 1
  • 29
  • 39
5

If you use Windows container and you want change any file, you can get and use Vim in Powershell console easily.

To shelled to the Windows Docker container with PowerShell:

docker exec -it <name> powershell

  • First install Chocolatey package manager

    Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression;

  • Install Vim

    choco install vim

  • Refresh ENVIRONMENTAL VARIABLE You can just exit and shell back to the container

  • Go to file location and Vim it vim file.txt

Aidar Gatin
  • 755
  • 1
  • 7
  • 9
4

See Stack Overflow question sed edit file in place

It would be a good option here, if:

  1. To modify a large file, it's impossible to use cat.
  2. Install Vim is not allowed or takes too long. My situation is using the MySQL 5.7 image when I want to change the my.cnf file, there is no vim, vi, and Vim install takes too long (China Great Firewall). sed is provided in the image, and it's quite simple. My usage is like

    sed -i /s/testtobechanged/textwanted/g filename

    Use man sed or look for other tutorials for more complex usage.

Shihe Zhang
  • 2,641
  • 5
  • 36
  • 57
4

If you can only shell into container with bin/sh (in case bin/bash doesn't work) and apt or apt-get doesn't work in the container, check whether apk is installed by entering apk in command prompt inside the container. If yes, you can install nano as follows: apk add nano

then nano will work as usual

etemtezcan
  • 41
  • 2
3

It is kind of screwy, but in a pinch you can use sed or awk to make small edits or remove text. Be careful with your regex targets of course and be aware that you're likely root on your container and might have to re-adjust permissions.

For example, removing a full line that contains text matching a regex:

awk '!/targetText/' file.txt > temp && mv temp file.txt

(More)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bbeecher
  • 5,973
  • 2
  • 14
  • 7
2

You can install nano

yum install nano
1

An easy way to edit a few lines would be:

echo "deb http://deb.debian.org/debian stretch main" > sources.list
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

I used a mysql:8.0 container and found there was no text editor installed. There was also no package manager installed??? Luckily I had VS Code installed with the docker extension. With the docker extension you can view all running (and closed) containers and drill down into the file system, just as if it were a local file system.

HTH!

enter image description here

aas4mis
  • 73
  • 6
0

You can also use a special container which will contain only the command you need: Vim. I chose python-vim. It assumes that the data you want to edit are in a data container built with the following Dockerfile:

FROM debian:jessie
ENV MY_USER_PASS my_user_pass
RUN groupadd --gid 1001 my_user
RUN useradd -ms /bin/bash --home /home/my_user \
            -p $(echo "print crypt("${MY_USER_PASS:-password}", "salt")" | perl) \
            --uid 1001 --gid 1001 my_user
ADD src /home/my_user/src
RUN chown -R my_user:my_user /home/my_user/src
RUN chmod u+x /home/my_user/src
CMD ["true"]

You will be able to edit your data by mounting a Docker volume (src_volume) which will be shared by your data container (src_data) and the python-vim container.

docker volume create --name src_volume
docker build -t src_data .
docker run -d -v src_volume:/home/my_user/src --name src_data_1 src_data
docker run --rm -it -v src_volume:/src fedeg/python-vim:latest

That way, you do not change your containers. You just use a special container for this work.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MaxiReglisse
  • 3,093
  • 1
  • 13
  • 14
0

First login as root : docker run -u root -ti bash Type following commands: apt-get update && apt-get install nano

salah
  • 21
  • 1
0

Make sure to update the container before trying to install the editor.

apt-get update
apt-get install nano vi
0

You can view the file content in running container without installing anything

Method 1: if you are using vs code, then install a docker extension. Then when you run the container, click on docker icon on left side bar. It shows the directory structure of running container. you can drill down to your directory from gui, and open the file content.

Method 2: if you want to do it by command line, from powershell, run the command

docker exec -it containerid sh

then go to your directory using cd where your file is.

then use the command "more --lines 10 index.html" (or your file name)

this will allow to view 10 lines at a time. pressing enter will display next 10 lines

0

If you are looking for small, try nano-tiny!

apt-get update
apt-get install nano-tiny

FWIW, the Postgres Docker Image was built with linuxkit.

For info and to compare... My Container reports:

# apt-cache show nano-tiny
Package: nano-tiny
Source: nano
Version: 7.2-1
Installed-Size: 187
Maintainer: Jordi Mallach <jordi@debian.org>
# apt-cache show vim-tiny
Package: vim-tiny
Source: vim
Version: 2:9.0.1378-2
Installed-Size: 1689
Maintainer: Debian Vim Maintainers <team+vim@tracker.debian.org>

If you do not need VI editor features then maybe this version of nano is just right for you.

I hope this helps!

ziff
  • 339
  • 1
  • 3
  • 16
-2

docker comes up with no editors. so simply install vim, 36MB space don't kill your docker!

Siwei
  • 19,858
  • 7
  • 75
  • 95