Jak edytować pliki w zatrzymanym / nie uruchamiającym się kontenerze docker

94

Próbując naprawić błędy i debugować problemy z moją aplikacją, która jest podzielona na kilka kontenerów, często edytuję pliki w kontenerach:

  • albo jestem totalnie leniwy i instaluję nano i edytuję bezpośrednio w kontenerze lub

  • Dockeruję plik z kontenera, edytuję go, kopiuję z powrotem i restartuję kontener

Są to kroki pośrednie przed przejściem do nowej zawartości do budowania kontenera, co zajmuje dużo więcej czasu niż wykonanie powyższej czynności (co oczywiście jest tylko pośrednie / majsterkowanie).

Teraz często przerywam program startowy kontenera, który w przypadkach zepsutych jest skryptem węzła lub skryptem serwera WWW w języku Python, oba zazwyczaj zawodzą z powodu błędów składniowych.

Czy jest jakiś sposób na uratowanie tych kontenerów? Ponieważ nie uruchamiają się, nie mogę ich dokować, więc są dla mnie stracone. Następnie przechodzę do trasy rm / rmi / build / run po naprawieniu naruszającego pliku w danych wejściowych kompilacji.

Jak mogę edytować pliki w zatrzymanym kontenerze lub cp je w lub uruchomić powłokę w zatrzymanym kontenerze - cokolwiek, co pozwala mi naprawić ten kontener?

(Wygląda to trochę jak praca na zdalnym komputerze i zerwanie konfiguracji sieciowej - w ten sposób połączenie jest tracone „na zawsze” i trzeba użyć rozwiązania awaryjnego, jeśli istnieje).

Jak edytować pliki kontenerów Docker z hosta? wygląda na trafne, ale jest nieaktualne.

Andreas Reiff
źródło
To również może być obejściem stackoverflow.com/a/32353134/586754 - mając nadzieję na jeszcze lepsze rozwiązanie.
Andreas Reiff
1
może powinieneś rozważyć zamontowanie wolumenu, aby móc edytować pliki na swoim hoście zamiast w kontenerze. Gdy już będziesz zadowolony ze swojego kodu, możesz przejść docker cpdo plików do kontenera (lub zbudować nowy obraz)
Thomasleveil
Tak, to byłoby trochę za późno, gdybym nie ustawiał takich rzeczy od początku. Myślę, że to nie działa na wyleczenie.
Andreas Reiff
Wielu czytelników będzie chciało tylko przeglądać pliki, zamiast je edytować. W takich przypadkach możesz użyć docker commitpolecenia, aby złamać nowy obraz. name=$(docker commit); docker run -it $name /bin/shzrobisz, co chcesz.
Att Righ
więc wydaje się, że systemy plików zatrzymanych kontenerów są w końcu stosunkowo trwałe?
Webwoman

Odpowiedzi:

139

Miałem problem z kontenerem, który nie uruchamiał się z powodu złej zmiany konfiguracji, którą wprowadziłem. Udało mi się skopiować plik z zatrzymanego kontenera i edytować go. coś jak:

docker cp docker_web_1:/etc/apache2/sites-enabled/apache2.conf .

(popraw plik)

docker cp apache.conf docker_web_1:/etc/apache2/sites-enabled/apache2.conf
tomurie
źródło
22
To powinna być akceptowana odpowiedź. Z jakiegoś powodu nie sądziłem, że CP pracuje na zatrzymanych kontenerach. Ładny!
Proximo
Idealny. Skopiowałem plik z kontenera (znałem jego ścieżkę), a następnie wyedytowałem go, a następnie skopiowałem z powrotem do kontenera w to samo miejsce. Pracował dla mnie! Dzięki!
Nawaz
Czy istnieje sposób na usunięcie pliku?
kodlan
1
@kodlan Tylko jeśli pojawia się tylko w pliku, z UpperDirktórego otrzymujesz docker container inspect- musisz poeksperymentować, aby zobaczyć, jak system nakładek reprezentuje pliki w podstawowej strukturze, które zostały usunięte w górnej warstwie.
Tim Baverstock
Dzięki, pomogło mi to naprawić mój kontener MySQL działający w Dockerze na macOS.
mazedlx
60

Odpowiadając na moje własne pytanie… wciąż mam nadzieję na lepszą odpowiedź od bardziej kompetentnej osoby !!

Istnieją 2 możliwości.

1) Edycja systemu plików bezpośrednio na hoście . Jest to nieco niebezpieczne i może spowodować całkowite zerwanie pojemnika, prawdopodobnie inne dane w zależności od tego, co pójdzie nie tak.

2) Zmiana skryptu startowego na coś, co nigdy nie zawodzi, jak uruchomienie basha, wykonanie poprawek / edycji, a następnie zmiana programu startowego ponownie na pożądany (jak node lub cokolwiek to było wcześniej).

Więcej szczegółów:

1) Korzystanie

docker ps

aby znaleźć uruchomione kontenery lub

docker ps -a

aby znaleźć wszystkie pojemniki (w tym zatrzymane) i

docker inspect (containername)

poszukaj „Id”, jednej z pierwszych wartości.

To jest część, która zawiera szczegóły implementacji i może ulec zmianie, pamiętaj, że w ten sposób możesz stracić kontener.

Iść do

/var/lib/docker/aufs/diff/9bc343a9..(long container id)/

i tam znajdziesz wszystkie pliki, które zostały zmienione w kierunku obrazu, na którym oparty jest kontener. Możesz nadpisywać pliki, dodawać lub edytować pliki.

Ponownie, nie polecam tego.

2) Jak opisano na https://stackoverflow.com/a/32353134/586754 , konfigurację json config.json można znaleźć w ścieżce takiej jak

/var/lib/docker/containers/9bc343a99..(long container id)/config.json

Tam możesz zmienić argumenty z np. „Nodejs app.js” na „/ bin / bash”. Teraz zrestartuj usługę dockera i uruchom kontener (powinieneś zobaczyć, że teraz poprawnie się uruchamia). Powinieneś użyć

docker start -i (containername)

aby upewnić się, że nie zakończy się od razu. Możesz teraz pracować z kontenerem i / lub później dołączyć z

docker exec -ti (containername) /bin/bash

Ponadto docker cp jest raczej przydatny do kopiowania plików, które były edytowane poza kontenerem.

Ponadto do tych środków należy wracać tylko wtedy, gdy pojemnik i tak jest mniej więcej „zgubiony”, więc każda zmiana byłaby poprawą.

Andreas Reiff
źródło
Wciąż liczę na lepszą odpowiedź - więc nie krępuj się jej podać, przeniosę też tag „ansered”.
Andreas Reiff
Skorzystałem z drugiego sposobu i musiałem ponownie uruchomić usługę dockera, aby wymusić nadpisywanie config.jsonplików za każdym razem, gdy je edytowałem
Witalij Isajew
2
Mam config.v2.json i za każdym razem, gdy uruchamiam kontener zombie, przywraca moją aktualizację ścieżki / punktu wejścia i ponownie umiera. Użycie "docker cp" do zaktualizowania skryptu entrypoint.sh tak, aby po prostu uruchomić bash, naprawiło to.
Curtis Yallop,
@CurtisYallop Doświadczam tego samego. Jak to rozwiązałeś?
Brett McLain
1
@BrettMcLain Użyłem docker cp zamiast edytować go na hoście. W ten sposób: Znajdź lokalizację skryptu punktu wejścia: "docker inspect nazwa_kontenera | grep Entry". Pobierz skrypt: „docker cp nazwa_kontenera: /entrypoint.sh ./”. (Edytuj) Umieść skrypt z powrotem w kontenerze: "docker cp entrypoint.sh nazwa_kontenera: /entrypoint.sh". Możesz sprawić, że punkt wejścia uruchomi bash lub uruchom pętlę uśpienia, np. „While:; do sleep 10; done”. Pierwsza linia skryptu musi mieć postać „#! / Bin / bash”.
Curtis Yallop
9

Możesz bezpośrednio edytować system plików kontenera, ale nie wiem, czy to dobry pomysł. Najpierw musisz znaleźć ścieżkę do katalogu, który jest używany jako katalog główny w środowisku wykonawczym dla kontenera. Biegnij docker container inspect id/name. Poszukaj klucza UpperDirw danych wyjściowych JSON.

To jest twój katalog.

Tejas Sarade
źródło
Znaleziono katalog, ale nie zawiera on wszystkich plików.
aioobe
To jest OverlayFS, więc twoje pliki muszą znajdować się w jednym z tych katalogów.
Tejas Sarade
Nazwa katalogu może być inna niż „UpperDir”, na przykład w moim przypadku jest to Source. Ale zadziałało!
Rajni Kewlani
0

Jeśli próbujesz ponownie uruchomić zatrzymany kontener i chcesz go zmienić z powodu błędnej konfiguracji, ale kontener się nie uruchamia, możesz wykonać następujące czynności, które działają przy użyciu polecenia „docker cp” (podobnie jak w poprzedniej sugestii). Ta procedura umożliwia usuwanie plików i wprowadzanie wszelkich innych potrzebnych zmian. Przy odrobinie szczęścia możesz pominąć wiele poniższych kroków.

  1. Użyj funkcji Docker inspect, aby znaleźć punkt wejścia (w niektórych wersjach nazwany Path)
  2. Utwórz klon pliku using docker run
  3. Wpisz clone używając docker exec -ti bash (kontener if * nix)
  4. Zlokalizuj lokalizację pliku punktu wejścia, przeglądając klon, aby znaleźć
  5. Skopiuj stary skrypt punktu wejścia za pomocą docker cp: ./
  6. Na przykład zmodyfikuj lub utwórz nowy skrypt punktu wejścia

    #!/bin/bash tail -f /etc/hosts

  7. upewnij się, że skrypt ma uprawnienia do wykonywania
  8. Zastąp stary punkt wejścia za pomocą docker cp ./:
  9. uruchom stary pojemnik za pomocą polecenia start
  10. powtórz kroki 6-9, aż do rozpoczęcia
  11. Napraw problemy w kontenerze
  12. W razie potrzeby przywróć punkt wejścia i powtórz kroki 6-9 zgodnie z wymaganiami
  13. W razie potrzeby usuń klon
user6830669
źródło