Szukaj…


Wprowadzenie

Pliki Docker to pliki używane do programowego tworzenia obrazów Docker. Pozwalają na szybkie i powtarzalne tworzenie obrazu Docker, a więc są przydatne do współpracy. Pliki Docker zawierają instrukcje dotyczące budowania obrazu Docker. Każda instrukcja jest zapisana w jednym wierszu i jest podana w formie <INSTRUCTION><argument(s)> . Dockerfiles są wykorzystywane do budowania obrazów dokowane pomocą docker build polecenia.

Uwagi

Pliki dokerów mają postać:

# This is a comment
INSTRUCTION arguments
  • Komentarze zaczynają się od #
  • Instrukcje są tylko dużymi literami
  • Pierwszą instrukcją pliku Docker musi być FROM aby określić obraz podstawowy

Podczas budowania pliku Docker klient Docker wyśle „kontekst kompilacji” do demona Docker. Kontekst kompilacji obejmuje wszystkie pliki i foldery w tym samym katalogu, co plik Docker. Operacje COPY i ADD mogą wykorzystywać tylko pliki z tego kontekstu.


Niektóre pliki Docker mogą zaczynać się od:

# escape=`

Służy to poinstruowaniu parsera Docker, aby używał ` jako znaku zmiany znaczenia zamiast \ . Jest to szczególnie przydatne w przypadku plików Windows Docker.

HelloWorld Dockerfile

Minimalny plik Docker wygląda następująco:

FROM alpine
CMD ["echo", "Hello StackOverflow!"]

To poinstruuje Dockera, aby zbudował obraz w oparciu o Alpine ( FROM ), minimalną dystrybucję kontenerów i uruchomił określone polecenie ( CMD ) podczas wykonywania obrazu wynikowego.

Zbuduj i uruchom:

docker build -t hello .
docker run --rm hello

Spowoduje to wygenerowanie:

Hello StackOverflow!

Kopiowanie plików

Aby skopiować pliki z kontekstu kompilacji na obrazie Docker, użyj instrukcji COPY :

COPY localfile.txt containerfile.txt

Jeśli nazwa pliku zawiera spacje, użyj alternatywnej składni:

COPY ["local file", "container file"]

Polecenie COPY obsługuje symbole wieloznaczne. Można go na przykład użyć do skopiowania wszystkich zdjęć do katalogu images/ :

COPY *.jpg images/

Uwaga: w tym przykładzie images/ mogą nie istnieć. W takim przypadku Docker utworzy go automatycznie.

Odsłanianie portu

Aby zadeklarować narażonych portów z Dockerfile użyć EXPOSE instrukcję:

EXPOSE 8080 8082

Ujawnione porty można zastąpić z wiersza poleceń Docker, ale dobrą praktyką jest jawne ustawianie ich w pliku Docker, ponieważ pomaga to zrozumieć, co robi aplikacja.

Najlepsze praktyki Dockerfiles

Grupuj wspólne operacje

Docker tworzy obrazy jako zbiór warstw. Każda warstwa może tylko dodawać dane, nawet jeśli dane te wskazują, że plik został usunięty. Każda instrukcja tworzy nową warstwę. Na przykład:

RUN apt-get -qq update
RUN apt-get -qq install some-package

Ma kilka wad:

  • Stworzy dwie warstwy, tworząc większy obraz.
  • Użycie samej apt-get update w instrukcji RUN powoduje problemy z buforowaniem, a następnie instrukcje apt-get install mogą się nie powieść . Załóżmy, że później zmodyfikujesz apt-get install przez dodanie dodatkowych pakietów, a następnie doker interpretuje instrukcje początkowe i zmodyfikowane jako identyczne i ponownie użyje pamięci podręcznej z poprzednich kroków. W rezultacie polecenie apt-get update nie jest wykonywane, ponieważ jego wersja buforowana jest używana podczas kompilacji.

Zamiast tego użyj:

RUN apt-get -qq update && \
    apt-get -qq install some-package

ponieważ tworzy to tylko jedną warstwę.

Wspomnij o opiekunie

Zazwyczaj jest to druga linia pliku Docker. Mówi, kto jest odpowiedzialny i będzie mógł pomóc.

LABEL maintainer John Doe <[email protected]>

Pominięcie go nie spowoduje uszkodzenia obrazu. Ale to też nie pomoże twoim użytkownikom.

Bądź zwięzły

Dbaj, aby Twój plik Docker był krótki. Jeśli konieczna jest złożona konfiguracja, rozważ użycie dedykowanego skryptu lub skonfigurowanie obrazów podstawowych.

Instrukcja UŻYTKOWNIKA

USER daemon

Instrukcja USER ustawia nazwę użytkownika lub identyfikator UID, które mają być używane podczas uruchamiania obrazu oraz dla każdej instrukcji RUN , CMD i ENTRYPOINT która następuje po nim w Dockerfile .

Instrukcja WORKDIR

WORKDIR /path/to/workdir

Instrukcja WORKDIR ustawia katalog roboczy dla wszelkich instrukcji RUN , CMD , ENTRYPOINT , COPY i ADD następujących po nim w pliku Dockerfile. Jeśli WORKDIR nie istnieje, zostanie utworzony, nawet jeśli nie zostanie użyty w żadnej kolejnej instrukcji Dockerfile .

Można go użyć wiele razy w jednym Dockerfile . Jeśli podano ścieżkę względną, będzie ona względna do ścieżki poprzedniej instrukcji WORKDIR . Na przykład:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

Wyjście ostatniego polecenia pwd w tym Dockerfile to /a/b/c .

Instrukcja WORKDIR może rozwiązać zmienne środowiskowe ustawione wcześniej za pomocą ENV . Możesz używać tylko zmiennych środowiskowych ustawionych jawnie w Dockerfile . Na przykład:

ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

Wynik końcowy polecenia pwd w tym pliku Docker to /path/$DIRNAME

GŁOŚNOŚĆ Instrukcja

VOLUME ["/data"]

Instrukcja VOLUME tworzy punkt montowania o określonej nazwie i oznacza go jako trzymający zewnętrznie zamontowane woluminy z macierzystego hosta lub innych kontenerów. Wartością może być tablica JSON, VOLUME ["/var/log/"] lub zwykły ciąg z wieloma argumentami, takimi jak VOLUME /var/log lub VOLUME /var/log /var/db . Aby uzyskać więcej informacji / przykładów i instrukcji montażu za pośrednictwem klienta Docker, zapoznaj się z dokumentacją Udostępnianie katalogów przez woluminy.

Komenda docker run inicjuje nowo utworzony wolumin z wszelkimi danymi istniejącymi w określonej lokalizacji w obrazie podstawowym. Rozważmy na przykład następujący fragment pliku Dockerfile:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

Ten plik Docker powoduje powstanie obrazu, który powoduje uruchomienie dokera, w celu utworzenia nowego punktu montowania w / myvol i skopiowania pliku powitania do nowo utworzonego woluminu.

Uwaga: Jeśli jakiekolwiek kroki kompilacji zmienią dane w woluminie po jego zadeklarowaniu, zmiany te zostaną odrzucone.

Uwaga: Lista jest analizowana jako tablica JSON, co oznacza, że musisz używać podwójnych cudzysłowów („) wokół słów, a nie pojedynczych cudzysłowów (').

Instrukcja KOPIOWANIA

COPY ma dwie formy:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)

Instrukcja COPY kopiuje nowe pliki lub katalogi z <src> i dodaje je do systemu plików kontenera na ścieżce <dest> .

Można podać wiele zasobów <src> ale muszą one być względne w stosunku do budowanego katalogu źródłowego (kontekst kompilacji).

Każdy <src> może zawierać symbole wieloznaczne, a dopasowanie zostanie wykonane przy użyciu filepath.Match . Na przykład:

COPY hom* /mydir/        # adds all files starting with "hom"
COPY hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

<dest> jest ścieżką bezwzględną lub ścieżką względem WORKDIR , do której źródło zostanie skopiowane do kontenera docelowego.

COPY test relativeDir/   # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/  # adds "test" to /absoluteDir/

Wszystkie nowe pliki i katalogi są tworzone z UID i GID równym 0.

Uwaga: Jeśli budujesz używając stdin ( docker build - < somefile ), nie ma kontekstu kompilacji, więc nie można użyć COPY .

COPY przestrzega następujących zasad:

  • Ścieżka <src> musi znajdować się w kontekście kompilacji; nie można COPY ../something / coś, ponieważ pierwszym krokiem kompilacji dokera jest wysłanie katalogu kontekstowego (i podkatalogów) do demona dokera.

  • Jeśli <src> jest katalogiem, cała zawartość katalogu jest kopiowana, w tym metadane systemu plików. Uwaga: sam katalog nie jest kopiowany, tylko jego zawartość.

  • Jeśli <src> jest jakimkolwiek innym rodzajem pliku, jest on kopiowany indywidualnie wraz z metadanymi. W takim przypadku, jeśli <dest> kończy się ukośnikiem /, zostanie uznany za katalog, a zawartość <src> zostanie zapisana w <dest>/base(<src>) .

  • Jeśli podano wiele zasobów <src> , bezpośrednio lub ze względu na użycie znaku wieloznacznego, wtedy <dest> musi być katalogiem i musi kończyć się ukośnikiem / .

  • Jeśli <dest> nie kończy się na ukośniku, zostanie uznany za zwykły plik, a zawartość <src> zostanie zapisana w <dest> .

  • Jeśli <dest> nie istnieje, jest tworzony wraz ze wszystkimi brakującymi katalogami na swojej ścieżce.

Instrukcja ENV i ARG

ENV

ENV <key> <value>
ENV <key>=<value> ...

Instrukcja ENV ustawia zmienną środowiskową <key> na wartość. Ta wartość będzie znajdować się w środowisku wszystkich komend Dockerfile „potomków” i może być zastąpiona również w wielu przypadkach.

Instrukcja ENV ma dwie formy. Pierwsza forma, ENV <key> <value> , ustawi pojedynczą zmienną na wartość. Cały ciąg po pierwszej spacji będzie traktowany jako <value> - łącznie ze znakami, takimi jak spacje i cudzysłowy.

Druga forma, ENV <key>=<value> ... , pozwala na ustawienie wielu zmiennych jednocześnie. Zauważ, że druga forma używa znaku równości (=) w składni, podczas gdy pierwsza forma nie. Podobnie jak parsowanie wiersza poleceń, można stosować cudzysłowy i ukośniki odwrotne w celu uwzględnienia spacji w wartościach.

Na przykład:

ENV myName="John Doe" myDog=Rex\ The\ Dog \
    myCat=fluffy

i

ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy

przyniesie takie same wyniki netto w końcowym pojemniku, ale pierwsza forma jest preferowana, ponieważ tworzy pojedynczą warstwę pamięci podręcznej.

Zmienne środowiskowe ustawione przy użyciu ENV będą zachowane, gdy kontener zostanie uruchomiony z obrazu wynikowego. Możesz wyświetlić wartości za pomocą inspekcji docker run --env <key>=<value> i zmienić je za pomocą docker run --env <key>=<value> .

ARG

Jeśli nie chcesz zachować tego ustawienia, użyj zamiast tego ARG . ARG ustawi środowiska tylko podczas kompilacji. Na przykład ustawienie

ENV DEBIAN_FRONTEND noninteractive

mogą mylić apt-get użytkowników na obrazie opartym na Debianie, kiedy wchodzą do kontenera w interaktywnym kontekście za pomocą docker exec -it the-container bash .

Zamiast tego użyj:

ARG DEBIAN_FRONTEND noninteractive

Alternatywnie możesz ustawić wartość tylko dla jednego polecenia, używając:

RUN <key>=<value> <command>

NARAŻENIE Instrukcja

EXPOSE <port> [<port>...]

Instrukcja EXPOSE informuje Dockera, że kontener nasłuchuje na określonych portach sieciowych w czasie wykonywania. EXPOSE NIE udostępnia portów kontenera hostowi. Aby to zrobić, musisz użyć flagi -p aby opublikować zakres portów lub flagi -P aby opublikować wszystkie odsłonięte porty. Te flagi są używane w oknie docker run [OPTIONS] IMAGE [COMMAND][ARG...] celu udostępnienia portu hostowi. Możesz ujawnić jeden numer portu i opublikować go zewnętrznie pod innym numerem.

docker run -p 2500:80 <image name>

To polecenie utworzy kontener o nazwie <image> i powiąże port 80 kontenera z portem 2500 hosta.

Aby skonfigurować przekierowanie portów w systemie hosta, zobacz użycie flagi -P . Funkcja sieci Docker obsługuje tworzenie sieci bez potrzeby ujawniania portów w sieci, szczegółowe informacje można znaleźć w omówieniu tej funkcji).

Instrukcja ETYKIETY

LABEL <key>=<value> <key>=<value> <key>=<value> ...

Instrukcja LABEL dodaje metadane do obrazu. LABEL to para klucz-wartość. Aby uwzględnić spacje w wartości LABEL , użyj cudzysłowów i ukośników odwrotnych, tak jak podczas analizowania z wiersza poleceń. Kilka przykładów użycia:

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

Obraz może mieć więcej niż jedną etykietę. Aby określić wiele etykiet, Docker zaleca łączenie etykiet w jedną instrukcję LABEL jeśli to możliwe. Każda instrukcja LABEL tworzy nową warstwę, która może spowodować nieefektywny obraz, jeśli użyjesz wielu etykiet. Ten przykład daje pojedynczą warstwę obrazu.

LABEL multi.label1="value1" multi.label2="value2" other="value3"

Powyższe można również zapisać jako:

LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

Etykiety są addytywne tym LABEL s w FROM obrazów. Jeśli Docker napotka etykietę / klucz, który już istnieje, nowa wartość zastępuje wszelkie poprzednie etykiety identycznymi kluczami.

Aby wyświetlić etykiety obrazu, użyj polecenia dokowania inspekcji.

"Labels": {
    "com.example.vendor": "ACME Incorporated"
    "com.example.label-with-value": "foo",
    "version": "1.0",
    "description": "This text illustrates that label-values can span multiple lines.",
    "multi.label1": "value1",
    "multi.label2": "value2",
    "other": "value3"
},

Instrukcja CMD

Instrukcja CMD ma trzy formy:

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)

W Dockerfile może znajdować się tylko jedna instrukcja CMD . Jeśli podasz więcej niż jedną CMD tylko ostatnia CMD zadziała.

Głównym celem CMD jest zapewnienie wartości domyślnych dla wykonującego kontenera. Te wartości domyślne mogą obejmować plik wykonywalny lub mogą pominąć plik wykonywalny, w którym to przypadku należy również podać instrukcję ENTRYPOINT .

Uwaga: Jeśli CMD jest używany do dostarczenia domyślnych argumentów dla instrukcji ENTRYPOINT , zarówno instrukcje CMD , jak i ENTRYPOINT powinny być określone w formacie tablicy JSON.

Uwaga: Formularz exec jest analizowany jako tablica JSON, co oznacza, że musisz używać podwójnych cudzysłowów („) wokół słów, a nie pojedynczych cudzysłowów (').

Uwaga: W przeciwieństwie do formularza powłoki, formularz exec nie wywołuje powłoki poleceń. Oznacza to, że normalne przetwarzanie powłoki nie ma miejsca. Na przykład CMD [ "echo", "$HOME" ] nie będzie zastępować zmiennych w $HOME . Jeśli chcesz przetwarzać powłokę, użyj formularza powłoki lub bezpośrednio uruchom powłokę, na przykład: CMD [ "sh", "-c", "echo $HOME" ] .

W przypadku użycia w formatach powłoki lub exec instrukcja CMD ustawia polecenie do wykonania podczas uruchamiania obrazu.

Jeśli użyjesz powłoki CMD , polecenie zostanie wykonane w /bin/sh -c :

FROM ubuntu
CMD echo "This is a test." | wc -

Jeśli chcesz uruchomić polecenie bez powłoki, musisz je wyrazić jako tablicę JSON i podać pełną ścieżkę do pliku wykonywalnego. Ta forma tablicy jest preferowanym formatem CMD . Wszelkie dodatkowe parametry muszą być indywidualnie wyrażone jako ciągi w tablicy:

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

Jeśli chcesz, aby Twój kontener uruchamiał ten sam plik wykonywalny za każdym razem, powinieneś rozważyć użycie ENTRYPOINT w połączeniu z CMD . Zobacz ENTRYPOINT .

Jeśli użytkownik określi argumenty do uruchomienia okna dokowanego, zastąpi domyślną określoną w CMD .

Uwaga: nie myl RUN z CMD . RUN faktycznie uruchamia polecenie w czasie tworzenia obrazu i zatwierdza wynik; CMD nie wykonuje niczego podczas kompilacji, ale określa zamierzoną komendę dla obrazu.

INSTRUKCJA OBSŁUGI

MAINTAINER <name>

Instrukcja MAINTAINER umożliwia ustawienie pola Autor generowanych obrazów.

NIE UŻYWAJ DYREKTYWY DOTYCZĄCEJ KONSERWACJI

Zgodnie z oficjalną dokumentacją dokera instrukcja MAINTAINER jest nieaktualna. Zamiast tego należy użyć instrukcji LABEL aby zdefiniować autora generowanych obrazów. Instrukcja LABEL jest bardziej elastyczna, umożliwia ustawienie metadanych i można ją łatwo przeglądać za pomocą komendy docker inspect .

LABEL maintainer="[email protected]"

Z instrukcji

FROM <image>

Lub

FROM <image>:<tag>

Lub

FROM <image>@<digest>

Instrukcja FROM ustawia obraz podstawowy dla kolejnych instrukcji. W związku z tym poprawny plik Docker musi mieć FROM jako pierwszą instrukcję. Obraz może być dowolnym prawidłowym obrazem - szczególnie łatwo jest rozpocząć od pobrania obrazu z repozytoriów publicznych.

FROM musi być pierwszą instrukcją bez komentarza w Dockerfile.

FROM może pojawić się wiele razy w jednym pliku Docker, aby utworzyć wiele obrazów. Po prostu zanotuj ostatnie wyjście ID obrazu przez zatwierdzenie przed każdym nowym poleceniem FROM .

Wartości tagu lub skrótu są opcjonalne. Jeśli pominiesz którykolwiek z nich, program budujący domyślnie zakłada najnowszy. Konstruktor zwraca błąd, jeśli nie może dopasować wartości znacznika.

Instrukcja RUN

RUN ma 2 formy:

RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)

Instrukcja RUN wykona wszelkie polecenia w nowej warstwie na wierzchu bieżącego obrazu i zatwierdzi wyniki. Wynikowy zatwierdzony obraz zostanie wykorzystany w następnym kroku w Dockerfile .

Nakładanie RUN instrukcje RUN i generowanie zatwierdzeń jest zgodne z podstawowymi koncepcjami Dockera, w których zatwierdzenia są tanie, a kontenery można tworzyć z dowolnego miejsca w historii obrazu, podobnie jak kontrola źródła.

Formularz exec umożliwia uniknięcie mungowania łańcucha powłoki oraz wykonywanie poleceń RUN przy użyciu obrazu podstawowego, który nie zawiera określonego pliku wykonywalnego powłoki.

Domyślną powłokę dla postaci powłoki można zmienić za pomocą polecenia SHELL .

W postaci powłoki możesz użyć \ (ukośnik odwrotny), aby kontynuować pojedynczą instrukcję RUN w następnym wierszu. Weźmy na przykład te dwie linie:

RUN /bin/bash -c 'source $HOME/.bashrc ;\
echo $HOME'

Razem są równoważne tej jednej linii:

RUN /bin/bash -c 'source $HOME/.bashrc ; echo $HOME'

Uwaga: Aby użyć innej powłoki, innej niż „/ bin / sh”, użyj formularza exec przekazującego żądaną powłokę. Na przykład RUN ["/bin/bash", "-c", "echo hello"]

Uwaga: Formularz exec jest analizowany jako tablica JSON, co oznacza, że musisz używać podwójnych cudzysłowów ( ) wokół słów, a nie pojedynczych cudzysłowów ( ' ).

Uwaga: W przeciwieństwie do formularza powłoki, formularz exec nie wywołuje powłoki poleceń. Oznacza to, że normalne przetwarzanie powłoki nie ma miejsca. Na przykład RUN [ "echo", "$HOME" ] nie spowoduje podstawienia zmiennych w $HOME . Jeśli chcesz przetwarzać powłokę, użyj formularza powłoki lub bezpośrednio uruchom powłokę, na przykład: RUN [ "sh", "-c", "echo $HOME" ] .

Uwaga: W formularzu JSON konieczne jest uniknięcie ukośników odwrotnych. Jest to szczególnie istotne w systemie Windows, w którym odwrotny ukośnik jest separatorem ścieżki. W przeciwnym razie poniższy wiersz byłby traktowany jako formularz powłoki z powodu nieważności JSON i nieoczekiwany błąd: RUN ["c:\windows\system32\tasklist.exe"]

Prawidłowa składnia dla tego przykładu to: RUN ["c:\\windows\\system32\\tasklist.exe"]

Pamięć podręczna dla instrukcji RUN nie jest automatycznie unieważniana podczas następnej kompilacji. Pamięć podręczna dla instrukcji takich jak RUN apt-get dist-upgrade -y zostanie ponownie użyta podczas następnej kompilacji. Pamięć podręczną dla instrukcji RUN można unieważnić, używając flagi --no-cache, na przykład kompilacji dokera - no-cache.

Aby uzyskać więcej informacji, zobacz Przewodnik po najlepszych praktykach Dockerfile.

Pamięć podręczna dla instrukcji RUN może zostać unieważniona przez instrukcje ADD . Szczegóły poniżej.

Instrukcja ONBUILD

ONBUILD [INSTRUCTION]

Instrukcja ONBUILD dodaje do obrazu instrukcję wyzwalającą, która ma zostać wykonana w późniejszym czasie, gdy obraz zostanie użyty jako podstawa do kolejnej kompilacji. Wyzwalacz zostanie wykonany w kontekście kompilacji niższego poziomu, tak jakby został wstawiony natychmiast po instrukcji FROM w dalszym pliku Docker.

Każda instrukcja kompilacji może zostać zarejestrowana jako wyzwalacz.

Jest to przydatne, jeśli budujesz obraz, który będzie używany jako baza do budowania innych obrazów, na przykład środowiska do budowania aplikacji lub demona, który można dostosować za pomocą konfiguracji specyficznej dla użytkownika.

Na przykład, jeśli obraz jest narzędziem do budowania aplikacji w języku Python wielokrotnego użytku, będzie wymagał dodania kodu źródłowego aplikacji do określonego katalogu, a następnie może wymagać wywołania skryptu kompilacji. Nie możesz teraz po prostu wywoływać ADD i RUN , ponieważ nie masz jeszcze dostępu do kodu źródłowego aplikacji, i będzie różny dla każdej kompilacji aplikacji. Możesz po prostu dostarczyć twórcom aplikacji płytę Docker do kopiowania i wklejania do ich aplikacji, ale jest to nieefektywne, podatne na błędy i trudne do aktualizacji, ponieważ miesza się z kodem specyficznym dla aplikacji.

Rozwiązaniem jest użycie ONBUILD do zarejestrowania zaawansowanych instrukcji do uruchomienia później, podczas następnego etapu kompilacji.

Oto jak to działa:

Gdy napotka instrukcję ONBUILD , konstruktor dodaje wyzwalacz do metadanych budowanego obrazu. Instrukcja w inny sposób nie wpływa na bieżącą kompilację.

Pod koniec kompilacji lista wszystkich wyzwalaczy jest przechowywana w manifeście obrazu, pod kluczem OnBuild. Można je sprawdzić za pomocą polecenia docker inspect . Później obraz może być użyty jako podstawa dla nowej kompilacji, przy użyciu instrukcji FROM . W ramach przetwarzania instrukcji FROM dalszy konstruktor szuka wyzwalaczy ONBUILD i wykonuje je w tej samej kolejności, w jakiej zostały zarejestrowane. Jeśli którykolwiek z wyzwalaczy zawiedzie, instrukcja FROM zostaje przerwana, co z kolei powoduje niepowodzenie kompilacji. Jeśli wszystkie wyzwalacze zakończą się powodzeniem, instrukcja FROM zakończy się, a kompilacja będzie kontynuowana jak zwykle.

Wyzwalacze są usuwane z końcowego obrazu po wykonaniu. Innymi słowy, nie są dziedziczone przez kompilacje „wnuków”.

Na przykład możesz dodać coś takiego:

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

Ostrzeżenie: ONBUILD instrukcji ONBUILD za pomocą ONBUILD ONBUILD jest niedozwolone.

Ostrzeżenie: Instrukcja ONBUILD może nie wyzwalać instrukcji FROM lub MAINTAINER .

Instrukcja STOPSIGNAL

STOPSIGNAL signal

Instrukcja STOPSIGNAL ustawia sygnał wywołania systemowego, który zostanie wysłany do kontenera w celu wyjścia. Ten sygnał może być prawidłową liczbą bez znaku, która odpowiada pozycji w tabeli syscall jądra, na przykład 9, lub nazwie sygnału w formacie SIGNAME, na przykład SIGKILL.

Instrukcja HEALTHCHECK

Instrukcja HEALTHCHECK ma dwie formy:

HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)

Instrukcja HEALTHCHECK mówi HEALTHCHECK jak przetestować pojemnik, aby sprawdzić, czy nadal działa. Może to wykryć przypadki, takie jak serwer sieciowy, który utknął w nieskończonej pętli i nie jest w stanie obsłużyć nowych połączeń, nawet jeśli proces serwera nadal działa.

Gdy kontener ma określone sprawdzenie poprawności, oprócz normalnego statusu ma status kondycji. Ten status zaczyna się na początku. Za każdym razem, gdy test zdrowia przechodzi, staje się zdrowy (niezależnie od stanu, w jakim był wcześniej). Po pewnej liczbie kolejnych awarii staje się niezdrowy.

Opcje, które mogą pojawić się przed CMD to:

--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--retries=N (default: 3)

Kontrola poprawności będzie najpierw uruchamiana w odstępach sekund po uruchomieniu kontenera, a następnie ponownie w odstępach sekund po zakończeniu każdego poprzedniego sprawdzania.

Jeśli pojedynczy przebieg testu trwa dłużej niż sekundy, oznacza to, że sprawdzenie się nie powiodło.

Ponowna próba kolejnych niepowodzeń kontroli stanu wymaga, aby kontener został uznany za niezdrowy.

W HEALTHCHECK może znajdować się tylko jedna instrukcja Dockerfile . Jeśli podasz więcej niż jeden, tylko ostatni HEALTHCHECK zacznie działać.

Polecenie występujące po słowie kluczowym CMD może być poleceniem powłoki (np. HEALTHCHECK CMD /bin/check-running ) lub tablicą exec (jak w przypadku innych poleceń Dockerfile; szczegółowe informacje można znaleźć np. ENTRYPOINT ).

Status wyjścia komendy wskazuje status kondycji kontenera. Możliwe wartości to:

  • 0: success - pojemnik jest zdrowy i gotowy do użycia
  • 1: unhealthy - pojemnik nie działa poprawnie
  • 2: starting - pojemnik nie jest jeszcze gotowy do użycia, ale działa poprawnie

Jeśli sonda zwróci 2 („start”), gdy pojemnik już wyszedł ze stanu „start”, wówczas jest traktowany jako „niezdrowy”.

Na przykład, aby sprawdzać co pięć minut lub tak, aby serwer WWW był w stanie wyświetlić stronę główną witryny w ciągu trzech sekund:

HEALTHCHECK --interval=5m --timeout=3s \
  CMD curl -f http://localhost/ || exit 1

Aby pomóc w debugowaniu nieudanych sond, każdy tekst wyjściowy (zakodowany w UTF-8), który polecenie zapisuje na standardowym lub standardowym stderr, zostanie zapisany w stanie zdrowia i można go zapytać podczas docker inspect . Takie wyjście powinno być krótkie (obecnie przechowywane są tylko pierwsze 4096 bajtów).

Gdy status kondycji kontenera się zmienia, zdarzenie health_status jest generowane z nowym statusem.

Funkcja HEALTHCHECK została dodana w Docker 1.12.

Instrukcja SHELL

SHELL ["executable", "parameters"]

Instrukcja SHELL pozwala na zastąpienie domyślnej powłoki używanej w postaci poleceń. Domyślna powłoka w systemie Linux to ["/bin/sh", "-c"] , a w systemie Windows to ["cmd", "/S", "/C"] . Instrukcja SHELL musi być napisana w formacie JSON w pliku Dockerfile.

Instrukcja SHELL jest szczególnie przydatna w systemie Windows, w którym istnieją dwie powszechnie używane i całkiem różne natywne powłoki: cmd i powerhell, a także dostępne alternatywne powłoki, w tym sh.

Instrukcja SHELL może pojawić się wiele razy. Każda instrukcja SHELL zastępuje wszystkie poprzednie instrukcje SHELL i wpływa na wszystkie kolejne instrukcje. Na przykład:

FROM windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

Instrukcje SHELL mogą mieć wpływ na następujące instrukcje, gdy ich forma powłoki jest używana w Dockerfile: RUN , CMD i ENTRYPOINT .

Poniższy przykład jest typowym wzorem występującym w systemie Windows, który można usprawnić za pomocą instrukcji SHELL :

...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...

Poleceniem wywoływanym przez dokera będzie:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

Jest to nieefektywne z dwóch powodów. Po pierwsze, wywoływany jest niepotrzebny procesor poleceń cmd.exe (zwany również powłoką). Po drugie, każda instrukcja RUN w formie powłoki wymaga dodatkowej komendy PowerShell, która poprzedza polecenie.

Aby uczynić to bardziej wydajnym, można zastosować jeden z dwóch mechanizmów. Jednym z nich jest użycie formularza JSON polecenia RUN takiego jak:

...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...

Chociaż formularz JSON jest jednoznaczny i nie używa niepotrzebnego cmd.exe, wymaga większej szczegółowości poprzez podwójne cytowanie i ucieczkę. Alternatywnym mechanizmem jest użycie instrukcji SHELL i formularza powłoki, dzięki czemu użytkownicy systemu Windows stają się bardziej naturalną składnią, szczególnie w połączeniu z dyrektywą parsera Escape:

# escape=`

FROM windowsservercore
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'

Wynikające z:

PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 3.584 kB
Step 1 : FROM windowsservercore
 ---> 5bc36a335344
Step 2 : SHELL powershell -command
 ---> Running in 87d7a64c9751
 ---> 4327358436c1
Removing intermediate container 87d7a64c9751
Step 3 : RUN New-Item -ItemType Directory C:\Example
 ---> Running in 3e6ba16b8df9


Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         6/2/2016   2:59 PM                Example


 ---> 1f1dfdcec085
Removing intermediate container 3e6ba16b8df9
Step 4 : ADD Execute-MyCmdlet.ps1 c:\example\
 ---> 6770b4c17f29
Removing intermediate container b139e34291dc
Step 5 : RUN c:\example\Execute-MyCmdlet -sample 'hello world'
 ---> Running in abdcf50dfd1f
Hello from Execute-MyCmdlet.ps1 - passed hello world
 ---> ba0e25255fda
Removing intermediate container abdcf50dfd1f
Successfully built ba0e25255fda
PS E:\docker\build\shell>

Instrukcja SHELL może również służyć do modyfikowania sposobu działania powłoki. Na przykład przy użyciu SHELL cmd /S /C /V:ON|OFF w systemie Windows można zmodyfikować semantykę opóźnionego rozszerzania zmiennych środowiskowych.

Instrukcja SHELL może być również użyta w systemie Linux, jeśli wymagana jest alternatywna powłoka, taka jak zsh, csh, tcsh i inne.

Funkcja SHELL została dodana w Docker 1.12.

Instalowanie pakietów Debian / Ubuntu

Uruchom instalację za pomocą pojedynczego polecenia uruchomienia, aby scalić aktualizację i zainstalować. Jeśli później dodasz więcej pakietów, uruchomi to aktualizację ponownie i zainstaluje wszystkie potrzebne pakiety. Jeśli aktualizacja zostanie uruchomiona osobno, zostanie zapisana w pamięci podręcznej, a instalacje pakietów mogą się nie powieść. Ustawienie frontendu na nieinteraktywne i przekazanie -y do instalacji jest wymagane w przypadku instalacji skryptowych. Czyszczenie i czyszczenie na końcu instalacji minimalizuje rozmiar warstwy.

FROM debian

RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    git \
    openssh-client \
    sudo \
    vim \
    wget \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow