Начнем неделю с полезных советов: Три простых приема для уменьшения Docker-образов 💻
Образы, которые используют одни и те же слои и весят меньше — быстрее переносятся и деплоятся.
Но как контролировать размер, когда каждое выполнение оператора RUN создает новый слой? Плюс, еще нужны промежуточные артефакты до создания самого образа...
1️⃣ Объединяем несколько слоев в один с помощью поэтапной сборки Docker-образов
Когда Git-репозиторий разрастается, можно просто свести всю историю изменений в один commit и забыть о нем. Оказалось, что нечто подобное можно реализовать и в Docker — посредством поэтапной сборки.
Давайте создадим контейнер Node.js.
Начнем с index.js:
const express = require('express')
const app = express()
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(3000, () => {
console.log(Example app listening on port 3000!)
})
и package.json:{
"name": "hello-world",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"express": "^4.16.2"
},
"scripts": {
"start": "node index.js"
}
}
Упакуем приложение со следующим Dockerfile:FROM node:8Создадим образ:
EXPOSE 3000
WORKDIR /app
COPY package.json index.js ./
RUN npm install
CMD ["npm", "start"]
$ docker build -t node-vanilla .Проверим, что все работает:
$ docker run -p 3000:3000 -ti --rm --init node-vanillaТеперь можно пройти по ссылке: http://localhost:3000 и увидеть там «Hello World!».
В Dockerfile теперь у нас есть операторы COPY и RUN, так что фиксируем увеличение как минимум на два слоя, по сравнению с исходным образом:
$ docker history node-vanilla
Как видим, итоговый образ возрос на пять новых слоев: по одному для каждого оператора в нашем Dockerfile. Давайте теперь опробуем поэтапную Docker-сборку. Используем тот же самый Dockerfile, состоящий из двух частей:
FROM node:8 as buildПервая часть Dockerfile создает три слоя. Затем слои объединяются и копируются на второй и заключительный этапы. Сверху в образ добавляются еще два слоя. В итоге имеем три слоя.
WORKDIR /app
COPY package.json index.js ./
RUN npm install
FROM node:8
COPY --from=build /app /
EXPOSE 3000
CMD ["index.js"]
Давайте пробовать. Сначала создаем контейнер:
$ docker build -t node-multi-stage .Проверяем историю:
$ docker history node-multi-stageСмотрим, изменился ли размер файла:
$ docker images | grep node-Да, он стал меньше, но пока не значительно. Есть способы уменьшить его сильнее.
node-multi-stage 331b81a245b1 678MB
node-vanilla 075d229d3f48 679MB
*️⃣2 и 3 приемы будут чуть позже :)
#лонгрид