Dockerfile üzerinde WORKDIR'ın amacı nedir?


115

Docker öğreniyorum. Birçok kez Dockerfilebunun WORKDIRkomuta sahip olduğunu gördüm :

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” ] 

Sadece ihmal edemez WORKDIRve Copysadece gözlerimi sahip DockerfileProjemin kökünde? Bu yaklaşımı kullanmanın dezavantajları nelerdir?


Derleme zamanında dizini şu şekilde değiştirirsinizWORKDIR
Ultraviolet

1
@Ultraviolet bunu açıklar mısınız? Tam anlamıyorum
Le garcon

Yanıtlar:


125

Belgelere göre :

WORKDIR komutu, Dockerfile'da onu izleyen herhangi bir RUN, CMD, ENTRYPOINT, COPY ve ADD komutları için çalışma dizinini ayarlar. WORKDIR yoksa, sonraki Dockerfile komutlarında kullanılmasa bile oluşturulacaktır.

Ayrıca, Docker en iyi uygulamalarında onu kullanmanızı önerir:

... okunması, giderilmesi ve bakımı zor olan RUN cd… && do-something gibi komutları çoğaltmak yerine WORKDIR kullanmalısınız.

Saklamanızı öneririm.

Dockerfile'ınızı aşağıdaki gibi yeniden düzenleyebileceğinizi düşünüyorum:

FROM node:latest
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ “npm”, “start” ] 

2
@MarioGil Lütfen COPY belgelerine
juanlumn

1
Kullandığımda FROM ubuntu as builderve ardışık görüntü kullandığımda COPY, "oluşturucu" görüntüsünde WORKDIR kullandığımı "biliyor mu" yoksa kullanmadığımı (ve mutlak bir yol kullanmam) mı gerekiyor?
Alex 75

Docker belgelerine göre , WORKDIRdeğeri koruduğunu söyleyebilirim çünkü siz COPYbirini çalıştırmadan önce Dockerfile'da çalıştırılan bir talimat
juanlumn

Sizin RUN mkdiremriniz gerekli değildir; yani bu satır silinebilir. Dokümantasyona göre "WORKDIR yoksa, sonraki Dockerfile talimatlarında kullanılmasa bile oluşturulacaktır." - docs.docker.com/engine/reference/builder/#workdir
Purplejacket

@Purplejacket doğru, cevabı güncelleyeceğim
juanlumn

61

Zorunda değilsin

RUN mkdir -p /usr/src/app

Bu, otomatik olarak WORKDIR

FROM node:latest
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ “npm”, “start” ] 

4
Bununla birlikte, bazen RUN mkdir gereklidir çünkü WORKDIR, dizinler oluştururken KULLANICI'ya saygı göstermez - github.com/moby/moby/issues/20295
Joe Bowbeer

24
WORKDIR'in klasörü otomatik olarak oluşturacağını belirttiğiniz gerçeğini beğendim.
GingerBeer

33

Aklınıza gelebilecek WORKDIRbir benzeri cd(bu sanki Dockerfile daha sonra gelip komutları etkiler kabın içine RUNkomuta). WORKDIRYukarıdaki örneğinizden kaldırdıysanız , RUN npm installçalışmaz çünkü /usr/src/appkapsayıcınızın içindeki dizinde olmayacaksınız .

Bunun Dockerfile'ınızı nereye koyduğunuzla nasıl ilişkili olacağını anlamıyorum (ana makinedeki Dockerfile konumunuzun konteynerin içindeki pwd ile hiçbir ilgisi olmadığı için). Dockerfile'ı projenizde istediğiniz yere koyabilirsiniz. Ancak, ilk argüman COPYgöreceli bir yoldur, bu nedenle Dockerfile'ınızı taşırsanız bu COPYkomutları güncellemeniz gerekebilir .


3
Eğer WORKDIRgibi ekler cd, iki olmaz COPYorijinal örnekteki aynı kaynak ve hedef var?
Jonas Rosenqvist

5
Hayır , kapsayıcı içindekiWORKDIR çalışma dizinini etkiler . Orijinal örnekte, ilk ana bilgisayardan (Dockerfile'a giden göreceli yol) konteynere kopyalar . Aslında, hedefin (kabın içinde) göreceli bir yol kullanmaması (yol ile başlar ) nedeniyle, bu belirli komut üzerinde herhangi bir etkisi yoktur . COPYpackage.json /usr/src/app/package.json WORKDIR/
mkasberg

@mkasberg WORKDIRBir cd. Öyleyse aşağıdaki 2 kod parçası eşdeğer mi? WORKDIR /usr/src/app COPY package.json /usr/src/app/ve WORKDIR /usr/src/app COPY package.json . Teşekkürler
kcatstack

1
Evet, bunlar eşdeğerdir.
mkasberg

1

WORKDIR'i uygulamadan önce. Burada WORKDIR yanlış yerdedir ve akıllıca kullanılmamaktadır.

FROM microsoft/aspnetcore:2
COPY --from=build-env /publish /publish
WORKDIR /publish
ENTRYPOINT ["dotnet", "/publish/api.dll"]

WORKDIR'i doğru konuma yerleştirmek için yukarıdaki kodu düzelttik ve aşağıdaki ifadeleri kaldırarak optimize ettik /Publish

FROM microsoft/aspnetcore:2
WORKDIR /publish
COPY --from=build-env /publish .
ENTRYPOINT ["dotnet", "/api.dll"]

1
Api.dll dosyasının önündeki eğik çizgiye sahip olmamalısınız, çünkü bu onu kabın köküne yönlendirecektir
Timothy c

1

WORKDIR"Hiçbir şey normalleştirilemez" ölümcül bir hatayla sonuçlanacak gibi görünen - hedef dizin adı olarak vars kullanmaya dikkat edin . IMO, aynı zamanda , yolun tüm unsurlarının zaten mevcut değilse yaratıldığı WORKDIRgibi aynı şekilde davrandığını da belirtmekte fayda mkdir -p <path>var.

GÜNCELLEME: Çok aşamalı bir yapı çalıştırırken değişkenle ilgili sorunla (yukarıda bahsedilen) karşılaştım - şimdi bir değişken kullanmanın iyi olduğu anlaşılıyor - eğer (değişken) "kapsam dahilindeyse", örneğin aşağıda 2. WORKDIRreferans başarısız olur ...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
WORKDIR $varname

oysa bunda başarılı ...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
ENV varname varval
WORKDIR $varname

.oO ( Belki belgelerde vardır ve kaçırdım )


0

WORKDIRSürekli entegrasyon akışını etkileyebileceğinden, ayarladığınız yere dikkat edin . Örneğin , bunu olarak ayarlamak, kurulum zamanında uzak circleci'nin yaptığı /home/circleci/projectgibi bir şeyde hataya neden olacaktır .ssh.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.