Docker 17.05 предоставляет долгожданные многоступенчатые сборки, это открывает возможность оптимизировать наши производственные образы, чтобы не включать наши зависимости сборки / компиляции и создавать меньшие образы только с самими артефактами.
Это также помогает еще больше автоматизировать процесс сборки, так как упрощает его запуск на сервере CI и отправку образа докера непосредственно из CI.
Представьте себе небольшое одностраничное приложение Angular.js со следующим форматом репозитория:
. ├── Dockerfile ├── bower.json ├── gulpfile.js ├── index.js ├── package.json ├── src │ ├── components │ ├── scss │ ├── index.html │ ├── js │ └── views └── yarn.lock
Теперь мы могли бы использовать Gulp, Grunt или Webpack в качестве инструмента для сборки, это не имеет особого значения для целей этой публикации.
У нас есть файл basicbower.json
, давайте запустим небольшой проект Angular.js внутри,
{ "name": "docker-build", "version": "0.0.1", "description": "", "main": "index.js", "author": "Guy Maliar", "license": "UNLICENSED", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "angular": "^1.5.8", "angular-ui-router": "^0.3.1", "lodash": "4.17.4" } }
И наш package.json
будет выглядеть так,
{ "name": "docker-build", "version": "0.0.1", "description": "", "main": "index.js", "author": "Guy Maliar", "license": "UNLICENSED", "scripts": { "build": "gulp build" }, "dependencies": {}, "devDependencies": { "babel-preset-es2015": "^6.13.2", "eslint": "^3.19.0", "eslint-config-airbnb-base": "^11.2.0", "eslint-plugin-import": "^2.2.0", "gulp": "^3.9.1", "gulp-babel": "^6.1.2", "gulp-image": "^2.4.1", "gulp-clean-css": "^3.4.2", "gulp-minify-html": "^1.0.6", "gulp-rev": "^7.1.0", "gulp-uglify": "^2.0.0", "gulp-usemin": "^0.3.23", "gulp-sass": "^3.1.0", "run-sequence": "^1.2.2" } }
обратите внимание, что мы сохраняем все зависимости сборки в нашем devDependencies
, как и предполагалось.
Настоящая магия начинается с нашего Dockerfile
:
FROM node:8 ENV NODE_ENV=development RUN mkdir -p /app WORKDIR /app RUN yarn global add bower gulp ADD package.json /app ADD bower.json /app RUN yarn install && bower install --allow-root COPY . /app RUN npm run buildFROM kyma/docker-nginx
COPY --from=0 /app/dist/var/www
CMD ["nginx"]
Как видите, мы используем новую функцию многоэтапной сборки Docker.
COPY --from=0
Это позволяет нам собрать наш проект в одном образе Docker, а затем скопировать его в следующий образ Docker, не сохраняя и не удаляя оставшиеся сборки node_modules
и bower_components
!
Мы можем иметь все, что захотим, внутри нашего рабочего образа, поскольку мы копируем только встроенные статические файлы из образа, это может быть изображение Node.js, изображение Golang или, как я выбрал, простое изображение nginx.