Como edito um arquivo após o shell em um contêiner do Docker?

518

Fiz o shell com êxito para um contêiner do Docker usando:

docker exec -i -t 69f1711a205e bash

Agora preciso editar o arquivo e não tenho nenhum editor dentro:

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:/#

Como edito arquivos?

Igor Barinov
fonte
@Opal eu uso confluent / postgres-bw: 0.1
Igor Barinov
2
O @Opal apt-get install vim funciona. obrigado!
Igor Barinov
3
então por que não criar o Dockerfilecomando include-apt-get install e gerar seu próprio contêiner? O contêiner do Docker foi projetado dessa maneira, não do seu jeito.
BMW
1
docker deve instalar pelo sopro de editor de teste, pelo menos, vim por padrão
Bawantha

Respostas:

725

Como nos comentários, não há editor padrão definido - estranho - a $EDITORvariável de ambiente está vazia. Você pode efetuar login em um contêiner com:

docker exec -it <container> bash

E corra:

apt-get update
apt-get install vim

Ou use o seguinte Dockerfile:

FROM  confluent/postgres-bw:0.1

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

As imagens do Docker são fornecidas cortadas ao mínimo necessário - portanto, nenhum editor é instalado com o contêiner enviado. É por isso que é necessário instalá-lo manualmente.

EDITAR

Também encorajo você a ler meu post sobre o assunto.

Opala
fonte
3
O que você precisa é montar um volume: docs.docker.com/userguide/dockervolumes
Opal
16
Eu precisava fazer login como root para fazer isso docker exec -u 0 -it container_name bash.
Eng.Fouad
34
Como no docker, é melhor instalar vim-tiny, provavelmente.
Ryenus
2
Talvez você deva considerar não instalar um editor em cada contêiner ao qual você se conecta, mas apenas uma vez na máquina host do docker. Como outros comentaristas mencionaram, você pode montar o volume, editar os arquivos que serão montados ou navegar até os dados do contêiner e editar os arquivos em/var/lib/docker/
Pitt
4
Eu só queria alterar uma configuração de true para false no contêiner. apt-getnão estava funcionando devido a um problema de permissão dentro do contêiner, então tentei sed -i 's/texttobechanged/textwanted/g' filename. Funcionou para mim.
Amreesh Tyagi 20/09/19
421

Se você não deseja adicionar um editor apenas para fazer algumas pequenas alterações (por exemplo, alterar a configuração do Tomcat), basta usar:

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

que o copia para a máquina local (para o diretório atual). Em seguida, edite o arquivo localmente usando seu editor favorito e faça um

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

para substituir o arquivo antigo.

hkong
fonte
21
@Igor Na verdade, essa deve ser a solução aceita, pois é a maneira correta de fazê-lo sem adicionar pacotes adicionais ao seu contêiner, enquanto a adição de pacotes deve ser uma solução secundária.
Routhinator
1
Para plataformas Windows, você pode usar, por exemplo: docker cp <container>:C:\inetpub\wwwroot\Web.config .e docker cp Web.config <container>:C:\inetpub\wwwroot\Web.config.
Rosberg Linhares
1
Solução agradável para a finalidade de teste! Eu não recomendo fazê-lo na produção.
Michal Šípek
9
E o que você recomenda para produção? As pessoas devem editar arquivos em um contêiner interativamente na produção?
lucid_dreamer
4
Vale ressaltar que esse método altera a propriedade do arquivo. É possível, mas um pouco complicado, alterá-lo novamente depois, entrando no contêiner como root ( docker exec -u 0 -it mycontainer bash) e executando um chowncomando.
Steve Chambers
91

Você pode usar catse estiver instalado, o que provavelmente será o caso se não for um contêiner vazio / bruto. Ele funciona muito bem, e quando copia e cola em um editor apropriado localmente.

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

catproduzirá cada linha ao receber uma nova linha. Certifique-se de adicionar uma nova linha para essa última linha. ctrl-c envia um SIGINTgato para sair normalmente. Nos comentários, você vê que também pode pressionar ctrl-d para indicar o final do arquivo ("não haverá mais entrada").

Outra opção é algo infilterque injeta um processo no namespace do contêiner com alguma mágica do ptrace: https://github.com/yadutaf/infilter

meijsermans
fonte
3
Isso é incrivelmente útil se houver problemas de permissão de instilação!
Roman
17
ctrl+Dé melhor que ctrl+C. ctrl+Denvia um EOF. Você não precisa adicionar uma nova linha extra no final. Com ctrl+C, se você esquecer de adicionar a nova linha, você perderá a última linha!
wisbucky
1
@wisbucky Nice! Melhor ainda. Pode ser necessário pressionar Ctrl-d duas vezes.
meijsermans
52

Para manter pequenas as imagens do Docker, não instale editores desnecessários. Você pode editar os arquivos por SSH do host do Docker para o contêiner:

vim scp://remoteuser@containerip//path/to/document
Mateus
fonte
2
Obrigado. Eu queria deixar esse link que explica melhor o vim scp:// vim.wikia . Além disso, para obter o endereço IP do seu recipiente, você pode usarsudo docker inspect <container_id> | grep "IPAddress"
aJetHorn
1
Apenas imaginando, eu literalmente uso "remoteuser" ou "docker"? Eu tentei: vim scp://[email protected]//data/gitea/conf/app.iniassim como os vim scp://[email protected]//data/gitea/conf/app.inidois, basta criar um novo arquivo em branco.
J. Scott Elblein
1
@ J.ScottElblein Isso requer a configuração sshprimeiro no contêiner do docker. Consulte blog.softwaremill.com/… . Mas você geralmente não deseja instalar sshno seu contêiner.
19619 wisbucky
14

Em algum momento você deve primeiro executar o contêiner com root:

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

Em seguida, no contêiner, para instalar o Vim ou outra coisa:

apt-get install vim
yan
fonte
7

Eu uso "docker run" (não "docker exec") e estou em uma zona restrita onde não podemos instalar um editor. Mas eu tenho um editor no host do Docker.

Minha solução alternativa é: Vincular a montagem de um volume do host do Docker ao contêiner ( https://docs.docker.com/engine/reference/run/#/volume-shared-filesystems ) e editar o arquivo fora do contêiner. Se parece com isso:

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

Isso é principalmente para experimentar, e mais tarde eu alteraria o arquivo ao criar a imagem.

ynux
fonte
6

Depois de fazer o shell no contêiner do Docker, digite:

apt-get update
apt-get install nano
Dos
fonte
6

Você pode abrir o arquivo existente com

cat filename.extension

e copie todo o texto existente na área de transferência.

Em seguida, exclua o arquivo antigo com

rm filename.extension

ou renomeie o arquivo antigo com

mv old-filename.extension new-filename.extension

Crie um novo arquivo com

cat > new-file.extension

Em seguida, cole todo o texto copiado na área de transferência, pressione Entere saia com salvar pressionando ctrl+z. E pronto, não há necessidade de instalar nenhum tipo de editor.

xD3ath
fonte
5

Você pode simplesmente editar seu arquivo no host e copiá-lo rapidamente e executá-lo dentro do contêiner. Aqui está o meu atalho de uma linha para copiar e executar um arquivo Python:

docker cp main.py my-container:/data/scripts/ ; docker exec -it my-container python /data/scripts/main.py
David Dehghan
fonte
1
Como isso responde à pergunta? - "Como edito arquivos?"
Peter Mortensen
4

Para as operações de edição comuns que preferem instalar vi( vim-tiny ), que usa apenas 1.491 kB ou nanoque usa 1707 kB .

Por outro lado, vimusa 28,9 MB .

Temos que lembrar que, para apt-get installtrabalhar, precisamos fazer updatea primeira vez, então:

apt-get update
apt-get install vim-tiny

Para iniciar o editor na CLI , precisamos entrar vi.

simhumileco
fonte
2

Se você usa o contêiner do Windows e deseja alterar qualquer arquivo, pode obter e usar o Vim no console do Powershell facilmente.

Para o shell do contêiner do Windows Docker com o PowerShell:

docker exec -it <name> powershell

  • Primeiro instale o gerenciador de pacotes Chocolatey

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

  • Instale o Vim

    choco install vim

  • Atualizar VARIÁVEL AMBIENTAL Você pode justar exite voltar ao contêiner

  • Vá para o local do arquivo e vim-o vim file.txt

Aidar Gatin
fonte
1

É meio esquisito, mas com uma pitada você pode usar sedou awkfazer pequenas edições ou remover texto. É claro que tenha cuidado com seus destinos de regex e esteja ciente de que você provavelmente está rootno seu contêiner e pode ter que reajustar as permissões.

Por exemplo, removendo uma linha completa que contém texto que corresponde a uma regex:

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

(Mais)

bbeecher
fonte
1

Uma maneira fácil de editar algumas linhas seria:

echo "deb http://deb.debian.org/debian stretch main" > sources.list
Saubhagya Srivastava
fonte
1

Consulte a pergunta sobre estouro de pilha sed sed file edit in place

Seria uma boa opção aqui, se:

  1. Para modificar um arquivo grande, é impossível usá-lo cat.
  2. Instalar o Vim não é permitido ou leva muito tempo. Minha situação está usando a imagem MySQL 5.7 quando eu quiser mudar o my.cnfarquivo, não há vim, vie instale Vim leva muito tempo (China Great Firewall). sedé fornecido na imagem e é bastante simples. Meu uso é como

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

    Use man sedou procure outros tutoriais para um uso mais complexo.

Shihe Zhang
fonte
1

Você pode usar, catse instalado, com o >caracter. Aqui está a manipulação:

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

Agora você pode ver o resultado com o comando

cat file
dero
fonte
0

Você também pode usar um contêiner especial que conterá apenas o comando necessário: Vim. Eu escolhi o python-vim . Ele pressupõe que os dados que você deseja editar estejam em um contêiner de dados criado com o seguinte 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"]

Você poderá editar seus dados montando um volume do Docker (src_volume) que será compartilhado pelo seu contêiner de dados (src_data) e pelo contêiner python-vim.

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

Dessa forma, você não muda seus contêineres. Você apenas usa um contêiner especial para este trabalho.

MaxiReglisse
fonte