การขยายคำตอบของ Peter Graingerฉันสามารถใช้โครงสร้างหลายขั้นตอนที่มีให้ตั้งแต่ Docker 17.05 รัฐหน้าอย่างเป็นทางการ:
ด้วยการสร้างหลายขั้นตอนคุณใช้หลายFROM
ข้อความใน Dockerfile ของคุณ แต่ละFROM
คำสั่งสามารถใช้ฐานที่แตกต่างกันและแต่ละคนเริ่มขั้นตอนใหม่ของการสร้าง คุณสามารถคัดลอกสิ่งประดิษฐ์จากขั้นตอนหนึ่งไปอีกขั้นหนึ่งทิ้งทุกสิ่งที่คุณไม่ต้องการในภาพสุดท้าย
เก็บสิ่งนี้ไว้ในใจที่นี่เป็นตัวอย่างของการDockerfile
รวมสามขั้นตอนการสร้าง มันหมายถึงการสร้างภาพการผลิตของโปรแกรมประยุกต์บนเว็บของลูกค้า
# Stage 1: get sources from npm and git over ssh
FROM node:carbon AS sources
ARG SSH_KEY
ARG SSH_KEY_PASSPHRASE
RUN mkdir -p /root/.ssh && \
chmod 0700 /root/.ssh && \
ssh-keyscan bitbucket.org > /root/.ssh/known_hosts && \
echo "${SSH_KEY}" > /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa
WORKDIR /app/
COPY package*.json yarn.lock /app/
RUN eval `ssh-agent -s` && \
printf "${SSH_KEY_PASSPHRASE}\n" | ssh-add $HOME/.ssh/id_rsa && \
yarn --pure-lockfile --mutex file --network-concurrency 1 && \
rm -rf /root/.ssh/
# Stage 2: build minified production code
FROM node:carbon AS production
WORKDIR /app/
COPY --from=sources /app/ /app/
COPY . /app/
RUN yarn build:prod
# Stage 3: include only built production files and host them with Node Express server
FROM node:carbon
WORKDIR /app/
RUN yarn add express
COPY --from=production /app/dist/ /app/dist/
COPY server.js /app/
EXPOSE 33330
CMD ["node", "server.js"]
.dockerignore
ทำซ้ำเนื้อหาของ.gitignore
ไฟล์ (จะป้องกันnode_modules
และทำให้ไดเร็กตอรี่dist
ของโปรเจ็กต์ถูกคัดลอก):
.idea
dist
node_modules
*.log
ตัวอย่างคำสั่งเพื่อสร้างภาพ:
$ docker build -t ezze/geoport:0.6.0 \
--build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
--build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
./
หากคีย์ SSH ส่วนตัวของคุณไม่มีวลีรหัสผ่านเพียงระบุSSH_KEY_PASSPHRASE
อาร์กิวเมนต์ว่าง
นี่คือวิธีการทำงาน:
1) บนเวทีแรกเท่านั้นpackage.json
, yarn.lock
ไฟล์และที่สำคัญ SSH sources
ส่วนตัวจะถูกคัดลอกไปยังภาพกลางชื่อแรก เพื่อหลีกเลี่ยงการแจ้งข้อความรหัสผ่าน SSH ssh-agent
สำคัญต่อไปนั้นจะถูกเพิ่มโดยอัตโนมัติ สุดท้ายyarn
คำสั่งจะติดตั้งการพึ่งพาที่จำเป็นทั้งหมดจาก NPM และที่เก็บส่วนตัว git จากที่เก็บ Bitbucket บน SSH
2) ขั้นตอนที่สองสร้างและรหัส minifies แหล่งที่มาของโปรแกรมประยุกต์บนเว็บและสถานที่ในไดเรกทอรีของภาพกลางต่อไปที่มีชื่อdist
production
โปรดทราบว่าซอร์สโค้ดของการติดตั้งnode_modules
ถูกคัดลอกจากอิมเมจที่sources
สร้างขึ้นในระยะแรกโดยบรรทัดนี้:
COPY --from=sources /app/ /app/
อาจเป็นไปได้ว่ามันอาจจะเป็นบรรทัดต่อไปนี้:
COPY --from=sources /app/node_modules/ /app/node_modules/
เรามีเฉพาะnode_modules
ไดเรกทอรีจากรูปภาพระดับกลางแรกที่นี่ไม่มีSSH_KEY
และSSH_KEY_PASSPHRASE
อาร์กิวเมนต์อีกต่อไป ส่วนที่เหลือทั้งหมดที่จำเป็นสำหรับการสร้างจะถูกคัดลอกจากไดเรกทอรีโครงการของเรา
3) ในขั้นตอนที่สามเราลดขนาดของอิมเมจสุดท้ายที่จะถูกแท็กezze/geoport:0.6.0
โดยการรวมเฉพาะdist
ไดเร็กทอรีจากอิมเมจระดับกลางที่สองที่ชื่อproduction
และติดตั้ง Node Express เพื่อเริ่มต้นเว็บเซิร์ฟเวอร์
รายชื่อรูปภาพให้ผลลัพธ์เช่นนี้:
REPOSITORY TAG IMAGE ID CREATED SIZE
ezze/geoport 0.6.0 8e8809c4e996 3 hours ago 717MB
<none> <none> 1f6518644324 3 hours ago 1.1GB
<none> <none> fa00f1182917 4 hours ago 1.63GB
node carbon b87c2ad8344d 4 weeks ago 676MB
ที่ภาพที่ไม่ติดแท็ก correpsond ไปที่ขั้นตอนการสร้างขั้นกลางขั้นที่หนึ่งและที่สอง
ถ้าคุณวิ่ง
$ docker history ezze/geoport:0.6.0 --no-trunc
คุณจะไม่เห็นการกล่าวถึงSSH_KEY
และSSH_KEY_PASSPHRASE
ในภาพสุดท้าย