Mở rộng câu trả lời của Peter Grainger Tôi đã có thể sử dụng bản dựng nhiều giai đoạn có sẵn kể từ Docker 17.05. Trang chính thức nêu rõ:
Với các bản dựng nhiều giai đoạn, bạn sử dụng nhiều FROM
câu lệnh trong Dockerfile của mình. Mỗi FROM
hướng dẫn có thể sử dụng một cơ sở khác nhau và mỗi hướng dẫn bắt đầu một giai đoạn mới của quá trình xây dựng. Bạn có thể sao chép có chọn lọc các tạo tác từ giai đoạn này sang giai đoạn khác, bỏ lại mọi thứ bạn không muốn trong hình ảnh cuối cùng.
Ghi nhớ điều này ở đây là ví dụ của tôi Dockerfile
bao gồm ba giai đoạn xây dựng. Nó có nghĩa là để tạo ra một hình ảnh sản xuất của ứng dụng web khách.
# 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
lặp lại nội dung của .gitignore
tệp (nó ngăn chặn node_modules
và dẫn đến các dist
thư mục của dự án bị sao chép):
.idea
dist
node_modules
*.log
Ví dụ lệnh để xây dựng một hình ảnh:
$ docker build -t ezze/geoport:0.6.0 \
--build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
--build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
./
Nếu khóa SSH riêng của bạn không có cụm mật khẩu, chỉ cần xác định SSH_KEY_PASSPHRASE
đối số trống .
Đây là cách nó hoạt động:
1). Chỉ ở giai đoạn đầu tiên package.json
,yarn.lock
các tệp và khóa SSH riêng được sao chép sang hình ảnh trung gian đầu tiên có tên sources
. Để tránh nhắc nhở mật khẩu khóa SSH, nó sẽ tự động được thêm vào ssh-agent
. Cuối cùng, yarn
lệnh sẽ cài đặt tất cả các phụ thuộc cần thiết từ NPM và sao chép kho git riêng từ Bitbucket qua SSH.
2). Giai đoạn thứ hai xây dựng và thu nhỏ mã nguồn của ứng dụng web và đặt nó vào dist
thư mục của hình ảnh trung gian tiếp theo có tên production
. Lưu ý rằng mã nguồn đã cài đặt node_modules
được sao chép từ hình ảnh có tênsources
được tạo ở giai đoạn đầu tiên bởi dòng này:
COPY --from=sources /app/ /app/
Có lẽ nó cũng có thể là dòng sau:
COPY --from=sources /app/node_modules/ /app/node_modules/
Chúng tôi chỉ có node_modules
thư mục từ hình ảnh trung gian đầu tiên ở đây, không SSH_KEY
và SSH_KEY_PASSPHRASE
đối số nữa. Tất cả phần còn lại cần thiết để xây dựng được sao chép từ thư mục dự án của chúng tôi.
3). Ở giai đoạn thứ ba, chúng tôi giảm kích thước của hình ảnh cuối cùng sẽ được gắn thẻ ezze/geoport:0.6.0
bằng cách chỉ bao gồmdist
thư mục từ hình ảnh trung gian thứ hai có tên production
và cài đặt Node Express để khởi động máy chủ web.
Danh sách hình ảnh cung cấp một đầu ra như thế này:
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
trong đó các hình ảnh không được gắn thẻ sẽ chuyển sang giai đoạn xây dựng trung gian thứ nhất và thứ hai.
Nếu bạn chạy
$ docker history ezze/geoport:0.6.0 --no-trunc
bạn sẽ không thấy bất kỳ đề cập nào SSH_KEY
và SSH_KEY_PASSPHRASE
trong hình ảnh cuối cùng.