Docker
Pliki dokerów
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 instrukcjiRUN
powoduje problemy z buforowaniem, a następnie instrukcjeapt-get install
mogą się nie powieść . Załóżmy, że później zmodyfikujeszapt-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 polecenieapt-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żnaCOPY
../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/*