Uczę się Dockera. Wiele razy widziałem, że Dockerfile
ma WORKDIR
polecenie:
FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 3000
CMD [ “npm”, “start” ]
Czy nie mogę po prostu pominąć WORKDIR
i Copy
po prostu mieć mojego Dockerfile
u źródła mojego projektu? Jakie są wady stosowania tego podejścia?
docker
dockerfile
Le garcon
źródło
źródło
WORKDIR
Odpowiedzi:
Zgodnie z dokumentacją :
Ponadto w najlepszych rozwiązaniach dotyczących platformy Docker zaleca korzystanie z niej:
Proponuję go zachować.
Myślę, że możesz refaktoryzować swój plik Dockerfile na coś takiego:
źródło
FROM ubuntu as builder
a potem kolejne użycie obrazuCOPY
, czy „wie”, że użyłem WORKDIR w obrazie „builder”, czy też muszę założyć, że nie (i użyć ścieżki bezwzględnej)?WORKDIR
wartość, ponieważ jest Ran instrukcja w Dockerfile przed uruchomieniemCOPY
jednegoRUN mkdir
polecenie nie jest konieczne; tj. ta linia mogłaby zostać usunięta. Zgodnie z dokumentacją „Jeśli plik WORKDIR nie istnieje, zostanie utworzony, nawet jeśli nie zostanie użyty w żadnej kolejnej instrukcji Dockerfile”. - docs.docker.com/engine/reference/builder/#workdirNie musisz
RUN mkdir -p /usr/src/app
Zostanie to utworzone automatycznie po określeniu pliku
WORKDIR
źródło
Można myśleć o
WORKDIR
niczymcd
wewnątrz pojemnika (wpływa na polecenia, które przychodzą później w Dockerfile, jakRUN
polecenia). Jeśli usunąłeśWORKDIR
w powyższym przykładzie,RUN npm install
nie zadziała, ponieważ nie będziesz w/usr/src/app
katalogu wewnątrz kontenera.Nie widzę, jak to byłoby powiązane z miejscem umieszczenia pliku Dockerfile (ponieważ lokalizacja pliku Dockerfile na maszynie hosta nie ma nic wspólnego z pwd wewnątrz kontenera). Możesz umieścić plik Dockerfile w dowolnym miejscu w swoim projekcie. Jednak pierwszym argumentem
COPY
jest ścieżka względna, więc jeśli przeniesiesz plik Dockerfile, może być konieczne zaktualizowanie tychCOPY
poleceń.źródło
WORKDIR
doda coś podobnegocd
, czy dwaCOPY
w oryginalnym przykładzie nie będą miały tego samego źródła i celu?WORKDIR
ma wpływu na katalog roboczy wewnątrz kontenera . W oryginalnym przykładzie pierwszeCOPY
kopie zpackage.json
na hoście (ścieżka względna do pliku Dockerfile) do/usr/src/app/package.json
w kontenerze . W rzeczywistościWORKDIR
nie ma to wpływu na to konkretne polecenie, ponieważ miejsce docelowe (wewnątrz kontenera) nie używa ścieżki względnej (ścieżka zaczyna się od/
).WORKDIR
działa jak plikcd
. Czy więc dwa poniższe fragmenty są równoważne?WORKDIR /usr/src/app
COPY package.json /usr/src/app/
iWORKDIR /usr/src/app
COPY package.json .
dziękiPrzed zastosowaniem WORKDIR. Tutaj WORKDIR znajduje się w niewłaściwym miejscu i nie jest używany mądrze.
Poprawiliśmy powyższy kod, aby umieścić WORKDIR we właściwej lokalizacji i zoptymalizowaliśmy poniższe instrukcje, usuwając
/Publish
źródło
Uważaj na używanie vars jako nazwy katalogu docelowego,
WORKDIR
co wydaje się skutkować błędem krytycznym „nie można niczego normalizować”. IMO, warto też zwrócić uwagę, żeWORKDIR
zachowuje się tak samo jakmkdir -p <path>
np. Wszystkie elementy ścieżki są tworzone, jeśli jeszcze nie istnieją.AKTUALIZACJA: Napotkałem problem związany ze zmienną (wspomniany powyżej) podczas uruchamiania kompilacji wieloetapowej - teraz wydaje się, że użycie zmiennej jest w porządku - jeśli ona (zmienna) znajduje się w „zakresie”, np. W poniższym, drugie
WORKDIR
odwołanie zawodzi ...podczas gdy to się udaje ...
.oO ( może to jest w dokumentacji i przegapiłem to )
źródło
Zachowaj ostrożność podczas ustawiania,
WORKDIR
ponieważ może to wpłynąć na ciągły przepływ integracji. Na przykład ustawienie go na/home/circleci/project
spowoduje błąd podobny do.ssh
tego, co zdalny cirleci robi w czasie konfiguracji.źródło