Docker
Dockerfiles
Zoeken…
Invoering
Dockerfiles zijn bestanden die worden gebruikt om Docker-afbeeldingen te maken. Hiermee kunt u snel en reproduceerbaar een Docker-afbeelding maken en zijn ze dus handig voor samenwerking. Dockerbestanden bevatten instructies voor het bouwen van een Docker-afbeelding. Elke instructie is op één rij geschreven en wordt gegeven in de vorm <INSTRUCTION><argument(s)>
. Dockerbestanden worden gebruikt om Docker-afbeeldingen te maken met de opdracht docker docker build
.
Opmerkingen
Dockerbestanden zijn van de vorm:
# This is a comment
INSTRUCTION arguments
- Opmerkingen beginnen met een
#
- Instructies zijn alleen hoofdletters
- De eerste instructie van een Dockerfile moet
FROM
zijn om de basisafbeelding op te geven
Bij het bouwen van een Docker-bestand stuurt de Docker-client een "build-context" naar de Docker-daemon. De build-context omvat alle bestanden en mappen in dezelfde map als het Docker-bestand. COPY
en ADD
bewerkingen kunnen alleen bestanden uit deze context gebruiken.
Sommige Docker-bestanden kunnen beginnen met:
# escape=`
Dit wordt gebruikt om de Docker-parser te instrueren om `
als een escape-teken te gebruiken in plaats van \
. Dit is vooral handig voor Windows Docker-bestanden.
HelloWorld Dockerbestand
Een minimale Dockerfile ziet er zo uit:
FROM alpine
CMD ["echo", "Hello StackOverflow!"]
Dit geeft Docker de opdracht om een afbeelding te maken op basis van Alpine ( FROM
), een minimale distributie voor containers, en om een specifieke opdracht ( CMD
) uit te voeren bij het uitvoeren van de resulterende afbeelding.
Bouw en voer het uit:
docker build -t hello .
docker run --rm hello
Dit levert het volgende op:
Hello StackOverflow!
Bestanden kopiëren
Gebruik de instructie COPY
om bestanden uit de build-context in een Docker-afbeelding te kopiëren:
COPY localfile.txt containerfile.txt
Als de bestandsnaam spaties bevat, gebruikt u de alternatieve syntaxis:
COPY ["local file", "container file"]
De opdracht COPY
ondersteunt jokertekens. Het kan bijvoorbeeld worden gebruikt om alle afbeeldingen naar de images/
map te kopiëren:
COPY *.jpg images/
Opmerking: in dit voorbeeld bestaan images/
mogelijk niet. In dit geval maakt Docker het automatisch aan.
Een poort blootleggen
Om te verklaren blootgesteld poorten van een Dockerfile gebruik maken van de EXPOSE
instructie:
EXPOSE 8080 8082
De instelling voor zichtbare poorten kan worden genegeerd via de Docker-opdrachtregel, maar het is een goede gewoonte om ze expliciet in het Docker-bestand in te stellen, omdat dit helpt te begrijpen wat een toepassing doet.
Dockerfiles best pratices
Groep gemeenschappelijke operaties
Docker maakt afbeeldingen als een verzameling lagen. Elke laag kan alleen gegevens toevoegen, zelfs als deze gegevens aangeven dat een bestand is verwijderd. Elke instructie creëert een nieuwe laag. Bijvoorbeeld:
RUN apt-get -qq update
RUN apt-get -qq install some-package
Heeft een paar nadelen:
- Het zal twee lagen creëren, waardoor een grotere afbeelding wordt geproduceerd.
- Het gebruik van
apt-get update
alleen in eenRUN
instructie veroorzaakt cacheproblemen en vervolgens kunnenapt-get install
instructies mislukken . Stel dat u laterapt-get install
wijzigt door extra pakketten toe te voegen, dan interpreteert docker de initiële en gewijzigde instructies als identiek en hergebruikt de cache van vorige stappen. Als gevolg hiervan wordt de opdrachtapt-get update
niet uitgevoerd omdat de versie in de cache wordt gebruikt tijdens de build.
Gebruik in plaats daarvan:
RUN apt-get -qq update && \
apt-get -qq install some-package
omdat dit slechts één laag oplevert.
Noem de onderhouder
Dit is meestal de tweede regel van het Docker-bestand. Het vertelt wie de leiding heeft en zal kunnen helpen.
LABEL maintainer John Doe <[email protected]>
Als u het overslaat, wordt uw afbeelding niet verbroken. Maar het zal ook uw gebruikers niet helpen.
Wees beknopt
Houd uw Dockerfile kort. Als een complexe configuratie nodig is, overweeg dan om een speciaal script te gebruiken of basisafbeeldingen in te stellen.
GEBRUIKER Instructie
USER daemon
De USER
instructiesets de gebruikersnaam of UID te gebruiken bij het uitvoeren van het beeld en voor elke RUN
, CMD
en ENTRYPOINT
volgende instructies in de Dockerfile
.
WORKDIR Instructie
WORKDIR /path/to/workdir
De WORKDIR
instructie stelt de werkmap in voor alle instructies RUN
, CMD
, ENTRYPOINT
, COPY
en ADD
die volgen in de Dockerfile. Als de WORKDIR
niet bestaat, wordt deze gemaakt, zelfs als deze niet in een volgende Dockerfile
instructie wordt gebruikt.
Het kan meerdere keren in één Dockerfile
worden gebruikt. Als een relatief pad wordt opgegeven, is dit relatief ten opzichte van het pad van de vorige WORKDIR
instructie. Bijvoorbeeld:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
De uitvoer van het laatste pwd
commando in dit Dockerfile
zou /a/b/c
.
De WORKDIR
instructie kan omgevingsvariabelen oplossen die eerder zijn ingesteld met ENV
. U kunt alleen omgevingsvariabelen gebruiken die expliciet in het Dockerfile
. Bijvoorbeeld:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
De uitvoer van het laatste pwd
commando in dit Dockerfile zou /path/$DIRNAME
VOLUME Instructie
VOLUME ["/data"]
De VOLUME
instructie maakt een koppelpunt met de opgegeven naam en markeert dit als extern gemonteerde volumes van native host- of andere containers. De waarde kan een JSON-array zijn, VOLUME ["/var/log/"]
of een gewone string met meerdere argumenten, zoals VOLUME /var/log
of VOLUME /var/log /var/db
. Raadpleeg de documentatie bij Share Directories via Volumes voor meer informatie / voorbeelden en montage-instructies via de Docker-client.
De opdracht docker run
initialiseert het nieuw gemaakte volume met alle gegevens die zich op de opgegeven locatie in de basisafbeelding bevinden. Overweeg bijvoorbeeld het volgende Dockerfile-fragment:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
Deze Dockerfile resulteert in een afbeelding die ervoor zorgt dat Docker wordt uitgevoerd, om een nieuw koppelpunt op / myvol te maken en het begroetingsbestand naar het nieuw gemaakte volume te kopiëren.
Opmerking: als buildstappen de gegevens binnen het volume wijzigen nadat deze zijn gedeclareerd, worden deze wijzigingen genegeerd.
Opmerking: de lijst wordt geparseerd als een JSON-array, wat betekent dat u dubbele aanhalingstekens (“) moet gebruiken rond woorden, niet enkele aanhalingstekens (').
KOPIE Instructie
COPY
heeft twee vormen:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
De COPY
instructie kopieert nieuwe bestanden of mappen van <src>
en voegt deze toe aan het bestandssysteem van de container op het pad <dest>
.
Er kunnen meerdere <src>
-bronnen worden opgegeven, maar deze moeten relatief zijn ten opzichte van de brondirectory die wordt gebouwd (de context van de build).
Elke <src>
kan jokertekens bevatten en het matchen wordt gedaan met behulp van Go's filepath.Match
regels. Bijvoorbeeld:
COPY hom* /mydir/ # adds all files starting with "hom"
COPY hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
De <dest>
is een absoluut pad, of een pad relatief ten opzichte van WORKDIR
, waarnaar de bron wordt gekopieerd in de WORKDIR
.
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/ # adds "test" to /absoluteDir/
Alle nieuwe bestanden en mappen worden gemaakt met een UID en GID van 0.
Opmerking: Als u bouwt met stdin ( docker build - < somefile
), is er geen buildcontext, dus COPY
kan niet worden gebruikt.
COPY
aan de volgende regels:
Het pad
<src>
moet zich binnen de context van de build bevinden; u kunt nietCOPY
../iets / iets, omdat de eerste stap van een docker-build is om de contextmap (en submappen) naar de docker-daemon te sturen.Als
<src>
een map is, wordt de volledige inhoud van de map gekopieerd, inclusief metadata van het bestandssysteem. Opmerking: de map zelf wordt niet gekopieerd, alleen de inhoud ervan.Als
<src>
een ander soort bestand is, wordt het afzonderlijk gekopieerd met de bijbehorende metagegevens. Als in dit geval<dest>
eindigt met een slash /, wordt dit beschouwd als een map en wordt de inhoud van<src>
geschreven op<dest>/base(<src>)
.Als er meerdere
<src>
-bronnen zijn opgegeven, rechtstreeks of vanwege het gebruik van een jokerteken, moet<dest>
een map zijn en moet deze eindigen op een schuine streep/
.Als
<dest>
niet eindigt met een slash, wordt dit als een normaal bestand beschouwd en wordt de inhoud van<src>
op<dest>
.Als
<dest>
niet bestaat, wordt deze samen met alle ontbrekende mappen in het pad gemaakt.
De ENV- en ARG-instructie
ENV
ENV <key> <value>
ENV <key>=<value> ...
De ENV
instructie stelt de omgevingsvariabele <key>
op de waarde. Deze waarde bevindt zich in de omgeving van alle "afstammende" Dockerfile-opdrachten en kan in vele ook inline worden vervangen.
De ENV
instructie heeft twee vormen. De eerste vorm, ENV <key> <value>
, stelt een enkele variabele in op een waarde. De hele tekenreeks na de eerste spatie wordt behandeld als de <value>
- inclusief tekens zoals spaties en aanhalingstekens.
Met het tweede formulier, ENV <key>=<value> ...
, kunnen meerdere variabelen tegelijkertijd worden ingesteld. Merk op dat de tweede vorm het isgelijkteken (=) in de syntaxis gebruikt, terwijl de eerste vorm dat niet doet. Net als het parseren van opdrachtregels kunnen aanhalingstekens en backslashes worden gebruikt om spaties in waarden op te nemen.
Bijvoorbeeld:
ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy
en
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
levert dezelfde netto resultaten op in de laatste container, maar de eerste vorm heeft de voorkeur omdat deze een enkele cachelaag produceert.
De omgevingsvariabelen die zijn ingesteld met ENV
blijven bestaan wanneer een container wordt uitgevoerd vanuit de resulterende afbeelding. U kunt de waarden bekijken met docker run --env <key>=<value>
en ze wijzigen met docker run --env <key>=<value>
.
ARG
Gebruik in plaats daarvan ARG
als u de instelling niet wilt behouden. ARG
stelt omgevingen alleen tijdens de build in. Bijvoorbeeld instelling
ENV DEBIAN_FRONTEND noninteractive
kan apt-get
gebruikers verwarren met een op Debian gebaseerde afbeelding wanneer ze de container in een interactieve context binnenkomen via docker exec -it the-container bash
.
Gebruik in plaats daarvan:
ARG DEBIAN_FRONTEND noninteractive
U kunt ook een waarde voor een enkele opdracht instellen door alleen te gebruiken:
RUN <key>=<value> <command>
BLOOTSTELLING Instructie
EXPOSE <port> [<port>...]
De instructie EXPOSE
informeert Docker dat de container tijdens runtime naar de opgegeven netwerkpoorten luistert. EXPOSE
maakt de poorten van de container NIET toegankelijk voor de host. Om dat te doen, moet u de vlag -p
gebruiken om een reeks poorten te publiceren of de vlag -P
om alle zichtbare poorten te publiceren. Deze vlaggen worden gebruikt in de docker run [OPTIONS] IMAGE [COMMAND][ARG...]
om de poort zichtbaar te maken voor de host. U kunt het ene poortnummer vrijgeven en extern publiceren onder een ander nummer.
docker run -p 2500:80 <image name>
Met deze opdracht wordt een container met de naam <image> gemaakt en wordt poort 80 van de container gekoppeld aan poort 2500 van de hostmachine.
Zie de vlag -P
gebruiken om -P
op het hostsysteem in te stellen. De Docker-netwerkfunctie ondersteunt het maken van netwerken zonder dat poorten binnen het netwerk moeten worden blootgelegd, zie voor gedetailleerde informatie het overzicht van deze functie).
LABEL Instructie
LABEL <key>=<value> <key>=<value> <key>=<value> ...
De LABEL
instructie voegt metagegevens toe aan een afbeelding. Een LABEL
is een sleutel / waarde-paar. Als u spaties in een LABEL
waarde wilt opnemen, gebruikt u aanhalingstekens en backslashes zoals u zou doen bij het parseren van de opdrachtregel. Enkele gebruiksvoorbeelden:
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."
Een afbeelding kan meer dan één label hebben. Om meerdere labels op te geven, raadt Docker aan waar mogelijk labels te combineren in een enkele LABEL
instructie. Elke LABEL
instructie produceert een nieuwe laag die kan resulteren in een inefficiënt beeld als u veel labels gebruikt. Dit voorbeeld resulteert in een enkele afbeeldingslaag.
LABEL multi.label1="value1" multi.label2="value2" other="value3"
Het bovenstaande kan ook worden geschreven als:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
Labels zijn additief inclusief LABEL
s in FROM
afbeeldingen. Als Docker een label / sleutel tegenkomt die al bestaat, vervangt de nieuwe waarde eerdere labels met identieke sleutels.
Gebruik de opdracht docker inspect om de labels van een afbeelding te bekijken.
"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"
},
CMD-instructie
De CMD
instructie heeft drie vormen:
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)
Er kan slechts één CMD
instructie in een Dockerfile
. Als u meer dan één CMD
wordt alleen de laatste CMD
van kracht.
Het hoofddoel van een CMD
is het bieden van standaardwaarden voor een uitvoerende container. Deze standaardwaarden kunnen een uitvoerbaar bestand bevatten of het uitvoerbare bestand weglaten. In dat geval moet u ook een ENTRYPOINT
instructie opgeven.
Opmerking: Als CMD
wordt gebruikt om de standaard argumenten voor de ENTRYPOINT
instructie, zowel de CMD
en ENTRYPOINT
instructies moeten worden opgegeven met de JSON-array-formaat.
Opmerking: het exec-formulier wordt geparseerd als een JSON-array, wat betekent dat u dubbele aanhalingstekens (“) moet gebruiken rond woorden, niet enkele aanhalingstekens (').
Opmerking: in tegenstelling tot het shell-formulier, roept het exec-formulier geen opdrachtshell op. Dit betekent dat normale shell-verwerking niet gebeurt. CMD [ "echo", "$HOME" ]
zal bijvoorbeeld geen variabele substitutie uitvoeren op $HOME
. Als je shell-verwerking wilt, gebruik dan de shell-vorm of voer een shell rechtstreeks uit, bijvoorbeeld: CMD [ "sh", "-c", "echo $HOME" ]
.
Bij gebruik in de shell- of exec-indeling stelt de CMD
instructie de opdracht in die moet worden uitgevoerd bij het uitvoeren van de afbeelding.
Als u de shell-vorm van de CMD
, wordt de opdracht uitgevoerd in /bin/sh -c
:
FROM ubuntu
CMD echo "This is a test." | wc -
Als u uw opdracht zonder shell wilt uitvoeren, moet u de opdracht uitdrukken als een JSON-array en het volledige pad naar het uitvoerbare bestand opgeven. Deze matrixvorm is het voorkeursformaat van CMD
. Eventuele aanvullende parameters moeten afzonderlijk als tekenreeksen in de array worden uitgedrukt:
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
Als u wilt dat uw container elke keer hetzelfde uitvoerbare bestand uitvoert, moet u overwegen ENTRYPOINT
in combinatie met CMD
. Zie ENTRYPOINT
.
Als de gebruiker argumenten opgeeft voor het uitvoeren van het koppelvenster, overschrijven deze de standaardinstelling die is opgegeven in CMD
.
Opmerking: verwar RUN
met CMD
. RUN
voert in feite een opdracht uit op het moment dat de afbeelding wordt opgebouwd en legt het resultaat vast; CMD
voert tijdens het bouwen niets uit, maar geeft de beoogde opdracht voor de afbeelding aan.
ONDERHOUD Instructie
MAINTAINER <name>
Met de instructie MAINTAINER
kunt u het veld Auteur van de gegenereerde afbeeldingen instellen.
GEBRUIK DE ONDERHOUDSRICHTLIJN NIET
Volgens officiële Docker Documentation de MAINTAINER
instructie wordt afgeraden. In plaats daarvan moet men de LABEL
instructie gebruiken om de auteur van de gegenereerde afbeeldingen te definiëren. De LABEL
instructie is flexibeler, maakt het mogelijk metagegevens in te stellen en kan eenvoudig worden bekeken met de opdracht docker inspect
.
LABEL maintainer="[email protected]"
VAN Instructie
FROM <image>
Of
FROM <image>:<tag>
Of
FROM <image>@<digest>
Met de FROM
instructie wordt de basisafbeelding ingesteld voor volgende instructies. Als zodanig moet een geldige Dockerfile FROM
als eerste instructie hebben. De afbeelding kan elke geldige afbeelding zijn - het is vooral gemakkelijk om te beginnen met het ophalen van een afbeelding uit de openbare opslagplaatsen.
FROM
moet de eerste instructie zonder commentaar in het Dockerfile zijn.
FROM
kan meerdere keren binnen één Dockerfile verschijnen om meerdere afbeeldingen te maken. Maak eenvoudig een notitie van de laatste afbeeldings-ID-uitvoer door de commit vóór elke nieuwe FROM
opdracht.
De tag- of digest-waarden zijn optioneel. Als u een van beide weglaat, gaat de bouwer standaard uit van een laatste. De builder retourneert een fout als deze niet kan overeenkomen met de tagwaarde.
RUN Instructie
RUN
heeft 2 vormen:
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)
De RUN
instructie zal alle opdrachten in een nieuwe laag bovenop de huidige afbeelding uitvoeren en de resultaten vastleggen. De resulterende Dockerfile
afbeelding wordt gebruikt voor de volgende stap in het Dockerfile
.
Het uitvoeren van RUN
instructies en het genereren van commits voldoet aan de kernconcepten van Docker, waarbij commits goedkoop zijn en containers kunnen worden gemaakt vanuit elk punt in de geschiedenis van een afbeelding, net als bronbeheer.
De exec vorm maakt het mogelijk om shell koord vervormen vermijden en RUN
commando een basisafbeelding die de gespecificeerde schaal uitvoerbare bevat gebruikt.
De standaardshell voor de shellvorm kan worden gewijzigd met de opdracht SHELL
.
In de shell-vorm kunt u een \
(backslash) gebruiken om een enkele RUN
instructie op de volgende regel voort te zetten. Overweeg bijvoorbeeld deze twee regels:
RUN /bin/bash -c 'source $HOME/.bashrc ;\
echo $HOME'
Samen zijn ze equivalent aan deze enkele regel:
RUN /bin/bash -c 'source $HOME/.bashrc ; echo $HOME'
Opmerking: als u een andere shell dan '/ bin / sh' wilt gebruiken, gebruikt u het exec-formulier dat in de gewenste shell wordt ingevoerd. Bijvoorbeeld RUN ["/bin/bash", "-c", "echo hello"]
Opmerking: het exec-formulier wordt geparseerd als een JSON-array, wat betekent dat u dubbele aanhalingstekens ( “
) moet gebruiken rond woorden, niet enkele aanhalingstekens ( '
).
Opmerking: in tegenstelling tot het shell-formulier, roept het exec-formulier geen opdrachtshell op. Dit betekent dat normale shell-verwerking niet gebeurt. RUN [ "echo", "$HOME" ]
zal bijvoorbeeld geen variabele substitutie uitvoeren op $HOME
. Als je shell-verwerking wilt, gebruik dan de shell-vorm of voer een shell rechtstreeks uit, bijvoorbeeld: RUN [ "sh", "-c", "echo $HOME" ]
.
Opmerking: in het JSON-formulier is het noodzakelijk om backslashes te ontsnappen. Dit is met name relevant op Windows, waarbij de backslash het padscheidingsteken is. De volgende regel zou anders worden behandeld als shell-vorm omdat deze niet geldig is JSON, en mislukt op een onverwachte manier: RUN ["c:\windows\system32\tasklist.exe"]
De juiste syntaxis voor dit voorbeeld is: RUN ["c:\\windows\\system32\\tasklist.exe"]
De cache voor RUN
instructies wordt niet automatisch ongeldig gemaakt tijdens de volgende build. De cache voor een instructie als RUN apt-get dist-upgrade -y
wordt tijdens de volgende build opnieuw gebruikt. De cache voor RUN
instructies kan worden ongeldig gemaakt met de vlag --no-cache, bijvoorbeeld docker build --no-cache.
Raadpleeg de Dockerfile Best Practices-gids voor meer informatie.
De cache voor RUN
instructies kan worden ongeldig gemaakt door ADD
instructies. Zie hieronder voor details.
ONBUILD Instructie
ONBUILD [INSTRUCTION]
De ONBUILD
instructie voegt aan de afbeelding een triggerinstructie toe die op een later tijdstip moet worden uitgevoerd, wanneer de afbeelding wordt gebruikt als basis voor een andere build. De trigger wordt uitgevoerd in de context van de downstream-build, alsof deze direct na de FROM
instructie in de downstream Dockerfile was ingevoegd.
Elke build-instructie kan worden geregistreerd als een trigger.
Dit is handig als u een afbeelding bouwt die wordt gebruikt als basis voor het maken van andere afbeeldingen, bijvoorbeeld een applicatie-buildomgeving of een daemon die kan worden aangepast met een gebruikersspecifieke configuratie.
Als uw afbeelding bijvoorbeeld een herbruikbare Python-applicatiebuilder is, moet de broncode van de applicatie worden toegevoegd aan een bepaalde map en kan het zijn dat daarna een build-script moet worden aangeroepen. U kunt nu niet alleen ADD
en RUN
aanroepen, omdat u nog geen toegang hebt tot de broncode van de toepassing en deze verschilt voor elke build van de toepassing. Je zou applicatieontwikkelaars eenvoudig een boilerplate Dockerfile kunnen geven om in hun applicatie te kopiëren en plakken, maar dat is inefficiënt, foutgevoelig en moeilijk bij te werken omdat het zich vermengt met applicatiespecifieke code.
De oplossing is om ONBUILD
te gebruiken om voorafgaande instructies te registreren om later te worden uitgevoerd, tijdens de volgende bouwfase.
Dit is hoe het werkt:
Wanneer het een ONBUILD
instructie tegenkomt, voegt de bouwer een trigger toe aan de metagegevens van de afbeelding die wordt gebouwd. De instructie heeft verder geen invloed op de huidige build.
Aan het einde van de build wordt een lijst van alle triggers opgeslagen in het afbeeldingsmanifest, onder de sleutel OnBuild. Ze kunnen worden geïnspecteerd met de opdracht docker inspect
. Later kan de afbeelding worden gebruikt als basis voor een nieuwe build, met behulp van de instructie FROM
. Als onderdeel van de verwerking van de FROM
instructie, zoekt de downstream-builder naar ONBUILD
triggers en voert deze uit in dezelfde volgorde als waarin ze zijn geregistreerd. Als een van de triggers mislukt, wordt de FROM
instructie afgebroken waardoor de build op zijn beurt mislukt. Als alle triggers slagen, wordt de FROM
instructie voltooid en gaat de build door zoals gewoonlijk.
Triggers worden uit de definitieve afbeelding verwijderd nadat ze zijn uitgevoerd. Met andere woorden, ze worden niet geërfd door bouwwerken van "kleinkinderen".
U kunt bijvoorbeeld zoiets toevoegen:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
Waarschuwing: Chaining ONBUILD
instructies met ONBUILD
ONBUILD
is niet toegestaan.
Waarschuwing: De ONBUILD
instructie kan niet trekker FROM
of MAINTAINER
instructies.
STOPSIGNAL Instructie
STOPSIGNAL signal
De STOPSIGNAL
instructie stelt het systeemoproepsignaal in dat naar de container wordt verzonden om af te sluiten. Dit signaal kan een geldig niet-ondertekend nummer zijn dat overeenkomt met een positie in de syscall-tabel van de kernel, bijvoorbeeld 9, of een signaalnaam in de indeling SIGNAME, bijvoorbeeld SIGKILL.
HEALTHCHECK Instructie
De HEALTHCHECK
instructie heeft twee vormen:
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
De instructie HEALTHCHECK
vertelt Docker hoe een container moet worden getest om te controleren of deze nog werkt. Dit kan gevallen detecteren, zoals een webserver die vastloopt in een oneindige lus en geen nieuwe verbindingen kan verwerken, hoewel het serverproces nog steeds actief is.
Wanneer voor een container een gezondheidscontrole is opgegeven, heeft deze naast de normale status een gezondheidsstatus. Deze status begint aanvankelijk. Wanneer een gezondheidscontrole slaagt, wordt deze gezond (in welke staat dan ook). Na een bepaald aantal opeenvolgende mislukkingen wordt het ongezond.
De opties die vóór CMD
kunnen verschijnen zijn:
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--retries=N (default: 3)
De gezondheidscontrole zal eerst intervalseconden uitvoeren nadat de container is gestart, en vervolgens opnieuw intervalseconden nadat elke vorige controle is voltooid.
Als een enkele controle langer duurt dan de time-out seconden, wordt de controle als mislukt beschouwd.
Het vergt opnieuw opeenvolgende mislukkingen van de gezondheidscontrole om de container als ongezond te beschouwen.
Er kan slechts één HEALTHCHECK
instructie in een Dockerfile
. Als u er meer dan één HEALTHCHECK
wordt alleen de laatste HEALTHCHECK
van kracht.
De opdracht achter het CMD
sleutelwoord kan een shell-opdracht zijn (bijv. HEALTHCHECK CMD /bin/check-running
) of een exec-array (zoals bij andere Dockerfile-opdrachten; zie bijv. ENTRYPOINT
voor details).
De exitstatus van het commando geeft de gezondheidsstatus van de container aan. De mogelijke waarden zijn:
-
0: success
- de container is gezond en klaar voor gebruik -
1: unhealthy
- de container werkt niet correct -
2: starting
- de container is nog niet klaar voor gebruik, maar werkt correct
Als de sonde 2 retourneert ("starten") wanneer de container al uit de "start" -status is gegaan, wordt deze in plaats daarvan als "ongezond" behandeld.
Om bijvoorbeeld elke vijf minuten te controleren of een webserver de hoofdpagina van de site binnen drie seconden kan bedienen:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
Om falende sondes te helpen debuggen, wordt alle uitvoertekst (UTF-8 gecodeerd) die door de opdracht op stdout of stderr wordt geschreven, opgeslagen in de gezondheidsstatus en kan worden opgevraagd met docker inspect
. Een dergelijke uitvoer moet kort worden gehouden (alleen de eerste 4096 bytes worden momenteel opgeslagen).
Wanneer de gezondheidsstatus van een container verandert, wordt een gebeurtenis health_status
gegenereerd met de nieuwe status.
De HEALTHCHECK
functie is toegevoegd in Docker 1.12.
SHELL-instructie
SHELL ["executable", "parameters"]
Met de instructie SHELL
kan de standaardshell die wordt gebruikt voor de shell-vorm van opdrachten worden overschreven. De standaard shell op Linux is ["/bin/sh", "-c"]
, en op Windows is ["cmd", "/S", "/C"]
. De SHELL
instructie moet in JSON-vorm in een Dockerfile worden geschreven.
De SHELL
instructie is met name handig op Windows waar er twee algemeen gebruikte en heel verschillende native shells zijn: cmd en powershell, evenals alternatieve shells beschikbaar waaronder sh.
De SHELL
instructie kan meerdere keren verschijnen. Elke SHELL
instructie vervangt alle eerdere SHELL
instructies en heeft invloed op alle volgende instructies. Bijvoorbeeld:
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
De volgende instructies kunnen worden beïnvloed door de SHELL
instructie wanneer de shell-vorm ervan wordt gebruikt in een Dockerfile: RUN
, CMD
en ENTRYPOINT
.
Het volgende voorbeeld is een veel voorkomend patroon op Windows dat kan worden gestroomlijnd met behulp van de SHELL
instructie:
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
De opdracht die wordt aangeroepen door Docker is:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
Dit is om twee redenen inefficiënt. Ten eerste wordt er een niet-noodzakelijke cmd.exe-opdrachtprocessor (aka shell) aangeroepen. Ten tweede vereist elke RUN
instructie in de shell-vorm een extra powershell -commando dat de opdracht voorafgaat.
Om dit efficiënter te maken, kunnen twee mechanismen worden gebruikt. Een daarvan is om de JSON-vorm van de opdracht RUN
gebruiken, zoals:
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
Hoewel het JSON-formulier ondubbelzinnig is en niet de niet-noodzakelijke cmd.exe gebruikt, vereist het meer uitgebreidheid door dubbele aanhalingstekens en escapen. Het alternatieve mechanisme is om de SHELL
instructie en de shell-vorm te gebruiken, waardoor een meer natuurlijke syntaxis voor Windows-gebruikers ontstaat, vooral in combinatie met de escape parser-richtlijn:
# 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'
Met als resultaat:
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>
De SHELL
instructie kan ook worden gebruikt om de manier waarop een shell werkt te wijzigen. Als u bijvoorbeeld SHELL cmd /S /C /V:ON|OFF
op Windows, kan de semantiek van de vertraagde omgevingsvariabele-uitbreiding worden gewijzigd.
De SHELL
instructie kan ook op Linux worden gebruikt als een alternatieve shell vereist is, zoals zsh, csh, tcsh en andere.
De SHELL
functie is toegevoegd in Docker 1.12.
Debian / Ubuntu-pakketten installeren
Voer de installatie uit met een enkele opdracht om de update samen te voegen en te installeren. Als u later meer pakketten toevoegt, wordt de update opnieuw uitgevoerd en worden alle benodigde pakketten geïnstalleerd. Als de update afzonderlijk wordt uitgevoerd, wordt deze in de cache opgeslagen en kunnen pakketinstallaties mislukken. Het instellen van de frontend op niet-interactief en het doorgeven van de -y voor installatie is nodig voor installaties met scripts. Reinigen en spoelen aan het einde van de installatie minimaliseert de grootte van de laag.
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/*