Многоступенчатая сборка Docker-образа

Разработка ПО — сложный процесс, результатом которого является работающий «в миру» продукт/сервис. Давайте познакомимся с подходом, позволяющим упростить жизненный цикл разработки.

Реализация

Начиная с версии 17.05, в докере появились многоступенчатые билды. Многоступенчатые сборки полезны для всех, кто пытается оптимизировать Docker-файлы и образы, сохраняя их легкими для чтения и обслуживания. До появления этой фичи применяли подход под названием «Builder Pattern». Подход «Builder Pattern» заключается в создании двух Docker-файлов и sh-скрипта:

  • Dockerfile.build — собирает приложение (вытягивает зависимости, компилирует и т. д.).
  • Dockerfile — запускает приложение.
  • build.sh — копирует артифакт, полученный из Dockerfile.build, в контейнер, собирающийся из Dockerfile.

Пример «Builder Pattern». Исходный код примера можно получить на GitHub.

Dockerfile.build

FROM golang:1.12.4-stretch
# Change worck directory
WORKDIR /go/src/github.com/zhooravell/docker-multi-stage-builds/builder-pattern
# Copy go code & dep files to worck directory
COPY main.go   Gopkg.toml Gopkg.toml ./
# Install dep, packages and build application
RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh \
   && dep version \
   && dep ensure \
   && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

Dockerfile

FROM alpine:latest
# Add ssl support
RUN apk --no-cache add ca-certificates

WORKDIR /root/

COPY app .

CMD ["./app"]

build.sh

#!/usr/bin/env bash
echo Building docker-multi-stage-builds/builder-pattern:build
# Билдим образ с приложение (зависимости, компиляция)
docker build -t docker-multi-stage-builds/builder-pattern:build . -f Dockerfile.build
# Создаем контейнер с коротким именем extract
docker container create --name extract docker-multi-stage-builds/builder-pattern:build
# Копируем артефакт из контейнера на хост-машину
docker container cp extract:/go/src/github.com/zhooravell/docker-multi-stage-builds/builder-pattern/app ./app
# Удаляем контейнер
docker container rm -f extract

echo Building docker-multi-stage-builds/builder-pattern:latest
# Собираем образ с скомпилированным приложением
docker build --no-cache -t docker-multi-stage-builds/builder-pattern:latest .
# Удаляем артефакт
rm ./app

Запустим контейнер и убедимся, что у все работает, как ожидалось:

$ docker run -p 8080:8080 docker-multi-stage-builds/builder-pattern

В результате получается очень маленький образ, с минимальным набором пакетов/зависимостей — только то, что нужно для запуска приложения. Production-образ не содержит инструментов сборки, компиляции, систем управления версиями.

$ docker images
REPOSITORY                                 TAG     IMAGE ID      CREATED         SIZE
docker-multi-stage-builds/builder-pattern  latest  4be00adf69b0  16 seconds ago  13.8MB
docker-multi-stage-builds/builder-pattern  build   3f0177d07175  20 seconds ago  819MB

Что же тогда multi-stage build? И зачем он нужен?

Многоступенчатый билд позволяет достичь того же результата, но без bash-скриптов, без нескольких Docker-файлов. Это достигается за счет использования нескольких инструкций FROM. В результате предыдущий пример будет выглядеть так:

FROM golang:1.12.4-stretch as builder
# Change worck directory
WORKDIR /go/src/github.com/zhooravell/docker-multi-stage-builds/go-multi-stage-build
# Copy go code & dep files to worck directory
COPY main.go Gopkg.toml Gopkg.toml ./
# Install dep, packages and build application
RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh \
    && dep version \
    && dep ensure \
    && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
# Add ssl support
RUN apk --no-cache add ca-certificates

WORKDIR /root/
# Copy just the built artifact from the previous stage into this new stage
# The Go SDK and any intermediate artifacts are left behind, and not saved in the final image.
COPY --from=builder /go/src/github.com/zhooravell/docker-multi-stage-builds/go-multi-stage-build/app ./

EXPOSE 8080

CMD ["./app"]

Вся «хитрость» заключается в конструкции COPY —from=builder. Она копирует артефакт с шага с алиасом builder (FROM golang:1.12.4-stretch as builder). Соберем наш контейнер:

$ docker build --no-cache -t docker-multi-stage-builds/go:latest .

Давайте рассмотрим еще пример использования multi-stage builds.

Angular и Docker multi-stage builds

На основе docker multi-stage build можно реализовать полный жизненный цикл angular-приложения:

  1. Разработка (npm start).
  2. Сборка (ng build —prod).
  3. Деплой (nginx).

Исходный код примера можно получить на GitHub. Docker-файл будет содержать 3 шага (FROM) сборки и выглядеть будет так:

### STAGE 1: Develop ###
FROM node:11.14.0-alpine as develop

USER node

RUN mkdir /home/node/.npm-global && mkdir /home/node/logs

ENV PATH=/home/node/.npm-global/bin:$PATH
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV HOME=/home/node

WORKDIR $HOME/app

RUN npm i -g npm

RUN npm install -g @angular/cli && npm cache clean --force

EXPOSE 4200

CMD [ "node" ]

### STAGE 2: Build ###
FROM develop as builder

USER root

COPY app .

RUN npm install && ng build --prod --output-path=dist

### STAGE 3: Setup ###
FROM nginx:1.15.12-alpine
# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*
# From 'builder' stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /home/node/app/dist /usr/share/nginx/html

Первый шаг (develop) содержит в себе установку пакета Angular CLI и будет использоваться для разработки. Второй шаг (builder) предназначен для сборки приложения: RUN npm install && ng build —prod —output-path=dist. Третий шаг предназначен для копирования артефакта (сбилдженого приложения) в контейнер с HTTP-сервер.

Для этапа разработки будет использоваться docker-compose. Начиная с версии 3.4, docker-compose поддерживает build.target, что позволяет остановить сборку контейнера на конкретном шаге (в нашем случае этот шаг — develop).

version: "3.4"

services:
  angular:
      build:
        context: .
        target: develop # use stage develop
      ports:
        - 4200:4200
      volumes:
        - ./app:/home/node/app:rw
      command:
          - /bin/sh
          - -c
          - |
              cd /home/node/app && npm install && npm start

Выполнив команду docker-compose up, мы получим полноценно работающее окружение для разработки Angular-приложения (компиляция TypeScript, релоад браузера и т. д.).

Чтобы получить сборку приложения, готовую к деплою, нужно выполнить команду:

$ docker build --no-cache -t docker-multi-stage-builds/go:latest .

Запуск контейнера с HTTP-сервером и Angular-приложением выполняется так:

$ docker run -p 8080:80 docker-multi-stage-builds/angular:latest

Выводы

Docker multi-stage build позволяет оптимизировать сборку образов. Сделать контейнеры более «легкими», а также унифицировать процесс разработки, сборки и деплоя.

Надеюсь, эта информация была вам полезна.

Все про українське ІТ в телеграмі — підписуйтеся на канал DOU

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному1
LinkedIn



43 коментарі

Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.

Вот по теме почитать (оптимизация сборкой через nixpkgs).

Не вистачає на dou кнопочки like.

ехал докер через докер
видит докер — в докер докер
сунул докер докер в докер
докер докер can’t resolve hostname

Статья интересная. Но! Ангуляр билдится в СПА, то есть на выходе мы имеем статику, которую можно смело закидывать на любой статик сервер и не надо возиться с контейнерами. Это как купить велосипед и тоскаться с ним по троллейбусам/трамваям...

docker потрібний для розробників?

А хто за розробника буде писати Докерфайл для потреб розробника щодо налаштувань оточення ?

тобто коли я будую свій будинок, і розставляю меблі, мені потрібно складати план на папірці, на випадок якщо я буду будувати такий же будинок, і розставляти такі ж меблі в тому ж порядку?

яке відношення «план» має до фічі яку ви пишете для проекту, для якої потрібно специфічне оточення, яке вам потрібно для реалізації фвчі ? Докерфайл дає можливість використати готовий продукт під свої потреби, наприклад ви працюєте з проектом на будь якій мові, та для вашої таски потрібно додати модуль якийсь, ви берете самі і додаєте його — це підхід профі, або пишете таску на PMa що вам потрібен модуль у контйенері, PM через день — тижднь — місяць — дає таску тех. ліжу, або девопсу, або адміну щодо переробити оточення від вашу фічу, що стає нудною, гидотною таскаою для всіх. Бо такий примітив як Докерфайл повинен знати навть джун у сучаному IT. Коли ви самі написали докерфайл під свою фічу, відправили до staging, + додали до деплою потрібні кроки — фіча післе тесу запрацювала на staiging, та QA перевірили і фіча пішла на продакшин — бо все автомтизовано, а девелопер не чекає поки хтось, щось зробить для нього — він як профі сам вже зробив, корисутючись наданими йому інструментами....

Яке відношення «докер» має до фічі яку я пишу для проекту, для якого потрібно спеціальне оточення, яке мені потрібно для реалізації фічі ? Я без докеру маю можливість використати готовий продукт під свої потреби, наприклад я працюю з проектом на будь-якій мові, для моєї таски потрібно додати модуль якийсь, я беру сам і додаю його — це підхід профі, або пишу таску на PMа що мені потрібен модуль без докера, PM через день — тиждень — місяць — дає таску тех. ліду, або девопсу, або адміну, щодо переробки оточення під мою фічу, що стає нудною гидотною таскою для всіх. Бо такий примітив як додавання модуля без докера повинен знати навіть джун у сучасному IT. Коли ви самі написали свою фічу без докера, відправили до staging, + додали до деплою потрібні кроки — фіча після тесту запрацювала на staging, та QA перевірили і фіча пішла на продакшин — бо все автоматизовано, а девелопер не чекає поки docker, щось зробить для нього — він як профі сам вже зробив, користуючись наданими йому інструментами...

Имея Dockerfile и/или docker-compose конфигурацию ты одной командой имеешь все необходимые сервисы-зависимости, который тебе нужны для разработки/тестирования твоего компонента. На любом окружении. Без докера каждый разработчик вынужден вручную все эти сервисы устанавливать и конфигурить. Очевидный waste.

Я одною командою роблю це без докера, і не маю проблем з купою безглуздих абстракцій без чітких меж. Вже приводили приклад з ангуларом і статикою. Це п’ята нога зайцю. Будь-який мій деплоймент скрипт має залежності тільки від продукту, я не думаю що розумно додавати залежності від якогось софту, з непрозорими умовами ліцензії, з купою багів і апдейтами які ламають зворотну сумісність. Навіть якщо цей продукт піариться вже не один рік і обіцяє золоті гори і магічно все робити супер однією командою, а по суті ще один EEE ...

Значит ты познал дзен или просто работаешь с небольшими проектами/командами и достаточно низким порогом входа.

Кстати, пример из недавней задачи: написать модуль Puppet для конфигурации HAProxy. Мне HAProxy на локальной машине нафиг не нужен, как и Puppet. Не говоря уже о том, что у меня венда. Выбор или поднимать вируалку или докер. Докер — это одна команда и полноценный линух запущен. И так же бесследно стерт из системы когда он уже не нужен.

А linux який вбудований в windows 10 не підходить? Я запускав наприклад ubuntu без VM нативно.

Не пробовал на него HAProxy ставить, наверное, заработало бы. Тем не менее, он мне там не нужен.

Еще одинм момент: как быстро новый разрабочит сможет поднять себе окружение. Или как быстро восстановить свое окружение после чистой установки системы.

Преимущество докера — повторяемость. Сервис в докере изолирован и не зависит от того, что еще установлено/запущено на хосте.

Не говоря уже о том, что у меня венда. Выбор или поднимать вируалку или докер. Докер — это одна команда и полноценный линух запущен.

Линукс докер контейнер на винде все равно через виртуальный линукс хост только работает. Так что там не или-или. И всякая морока что может выстрелить — типа virtual switch, никуда не уходит.

Виртуалка с линухом под докер уже есть, если докер установлен. А чтобы не засорять систему/существующие виртуалки нужно было бы поднять новую. Да и сколько нужно было бы виртуалок, если нужны изолированные окружения? И под каждую нужно было бы выделять ресурсы.

Я не спорю с очевидными преимуществами контейнеров, но это все работает только как ещё одна прослойка поверх стандартных возможностей виртуализации винды и докер не исключение — хост там hyper-v Linux VM. И кстати оверхед по ресурсам будет больший иметь чем запуск чистой виртуалки. Удобство также фигня , особенно там где идёт речь о взаимодействии вин оси, виртуального линукс хоста и контейнера запущенного на нем.

Никто же и не спорит на счет оверхеад в винде, но для докера — линукс нативная среда, а для разворачивания локального проекта для разработки, это приемлимые накладки, в замен получаешь более удобную вариацию окружения когда не нужно педалить код на локалке, открывать виртуалку и проверять все ли норм и как оно работает... Для продакшин хз, не доводилось в винде подобным заниматься, еще и вот узнал что вроде как в докере уже и винду можна запустить, я пока мозгом не дорос до такого извращения... :) А вообще сравнивать чистый докер с виртуализацией — моветон, докер не технология виртуализации, как многие ошибочно считают.

И кстати оверхед по ресурсам будет больший иметь чем запуск чистой виртуалки.

Мы же про изоляцию сервисов. А значит виртуалка под сервис, а не одна виртуалка под всё.

особенно там где идёт речь о взаимодействии вин оси, виртуального линукс хоста и контейнера запущенного на нем.

Тоже edge-case. Из того, что встречал — проблемы с fsync на примаунченый локальный диск, а значит приходится присать в volume. Не особо критично. И нельзя задавать статические IP контейрам по виндой через macvlan. Для подавляющего большинства задач все работет более чем хорошо.

1. Как тестировать решение локально, особенно если оно завязано на сложные сетапы? Да пусть и не на сложные — в любом случае, зачем захламлять свой комп лишними программами, системными переменными и т.д., если для этого давно есть Докер?
2. В CI окружениях сервера могут использоваться для тестирование многих решений. Насиловать одну и ту же VM под каждый конкретный случай несёт с собой кучу неудобств:
2.1. Пункт 1, только уже для корпоративных машин.
2.2. Приложение может положить VM, а так — просто упадёт запущенный образ.
2.3. Приложение будет загаживать VM, если за этим не следить: левые файлы, утечки памяти, теоретически могут быть даже конфликты конфигов между приложениями. При этом (в общем случае) что запустилось в Докере — осталось в volume, который сам удаляется по заданию ключа —rm. А так программист какую-то дебажную строку не убрал, например, и привет.
2.4. Каждую новую VM нужно настраивать под каждый кейс по новой, либо использовать для этого более сложные инструменты, чем Докер. С Докером же минимальный сетап — и дальше по-барабану, что там кто собрался запускать.

Поэтому Докер — удобно/минималистично/переиспользуемо + ещё и безопасно из-за изоляции и возможности ограничивать ресурсы контейнера при запуске.

1. Навіщо використовувати складні сетапи, потрібно використовувати прості. Що значить захламляти — якщо програма використовується вона є на компі, якщо не вокористовується — її немає. Ви видаляєте її або просто не встановлюєте. Програма яка використовується це не хлам, а корисний софт. Якщо Ви не можете\хочете слідкувати за софтом на компі докер тут не допоможе — Ви захламите його докер чимось там. На рахунок системних змінних — якщо захламляють, я рекомендую їх не використовувати, а використовувати змінні хоста. Якщо не хочете модифікувати PATH системний, або користувача, використовуєте:
SET PATH=%PATH%;c:\whatever\else
Це базова річ і використовується не один десяток років, і ніколи не було з ним проблем. Навіщо для цього використовувати софт, купувати ліцензії, апгрейдити, вчити людей, ловити купу багів ?
2. До чого тут докер?
2.1 До чого тут докер?
2.2 Я пас, але думаю це казочка.
2.3 Звучить як фіча, але вирішитись може на рівні VM. VM не повинна буди загажена якщо все ОК, якщо так сталось — правимо і розгортаємо іншу VM.
2.4 Знову ж, використовувати змінні на рівні хоста, а не ОС або користувача. Це дуже просто.

В теорії докер не потрібен, в реальномо житті все звичайно залежить від ситуації.

Пример: есть продукт, есть для него SDK под разные языки/платформы.

Навіщо використовувати складні сетапи, потрібно використовувати прості

Как тестировать все эти SDK на VM? Спойлер: либо через жэ с настройкой всего этого зоопарка руками, либо многократно упростить себе жизнь Докером.

Що значить захламляти — якщо програма використовується вона є на компі, якщо не вокористовується — її немає. Ви видаляєте її або просто не встановлюєте. Програма яка використовується це не хлам, а корисний софт. Якщо Ви не можете\хочете слідкувати за софтом на компі докер тут не допоможе

Если Вы хотите всё удалять/устанавливать руками, следить за подобным зоопарком и, мало того, считаете это чем-то (sic!) позитивным, то Докер здесь, конечно, не поможет. Я вообще не знаю, что в таком случае может помочь). А говорят, что программисты чего-то там автоматизируют...

Ви захламите його докер чимось там.

«Його» — чей? И что имеется в виду под «захламлением Докера»?

Якщо не хочете модифікувати PATH системний, або користувача, використовуєте:
SET PATH=%PATH%;c:\whatever\else

...или написать это в Докерфайле один раз и юзать на любой машине, а не страдать лишними настройками VM.

Навіщо для цього використовувати софт, купувати ліцензії, апгрейдити, вчити людей, ловити купу багів ?

Странно, почему не пишем на асме или плюсах до сих пор все, ну на самом-то деле, а? Проверенные решения, по 100500 лет каждому). И какие лицензии имеются в виду? Докер бесплатен.

2. До чого тут докер?
2.1 До чого тут докер?

Вы вообще понимаете, что это такое и зачем?) Пишем Докерфайл с сетапом, и вуаля, образ у Вас собирается или пуллится, и контейнер запускается везде, где установлен Докер на той же платформе. Всё нужное находится в образе, и VM-система остаётся чистой. Изоляция в подарок.

2.4 Знову ж, використовувати змінні на рівні хоста, а не ОС або користувача. Це дуже просто.

Кроме этого нужно устанавливать вагон разного софта, шэрить и апдейтить конфиги на все VM. Но зачем, если этого можно НЕ делать, используя Докер? Изменился конфиг для конкретного окружения/проекта/команды etc — сделали апдейт Докерфайла/Докер образа, и VM даже не трогаем.

Поэтому Докер стал де-факто стандартом для решения проблем использования разных окружений на одной машине, а один и тот же Докер образ даёт при запуске идентичный результат на любой машине, исключая ошибки настройки окружения.

Как тестировать все эти SDK на VM? Спойлер: либо через жэ с настройкой всего этого зоопарка руками, либо многократно упростить себе жизнь Докером.

Запускаючи тести. Наприклад перший-ліпший SDK : Android SDK. Копіюєте 2 версії SDK в 2 різні папочки. Встановлюєте параметр ANDROID_HOME для першого тесту на першу папку, для другого на другу. І т.д. Ну звісно, простіше інсталювати в дефолтний шлях на 2 різних докер образах. Не потрібно встановлювати ніякі змінні. Дуже професійно. Що значить руками? А з докером це буде ногами робитись, чи якимось іншим органом? Ви маєте прослідкувати щоб було 2 версії SDK які Ви підтримуєте. Докер магічним чином дозволить Вам це не перевіряти, чи принципово користуватись копіюванням папочок в 2к19 вже не модно і потрібно «закатумбрити тумбаюнбник оверкуратор». Це справді звучить як багатократне спрощення життя.

Если Вы хотите всё удалять/устанавливать руками, следить за подобным зоопарком и, мало того, считаете это чем-то (sic!) позитивным, то Докер здесь, конечно, не поможет. Я вообще не знаю, что в таком случае может помочь). А говорят, что программисты чего-то там автоматизируют...

Я хочу мати контроль над тим що в мене встановлено, де це знаходиться і якої версії. В ідеалі я хочу копіювати папочки, або запускати інсталлер. Я вважаю що позитивно використовувати прості сценарії і інструменти в порівняні зі складними. При автоматизації програмісти намагаються позбутися непотрібних залежностей, а не додали нових.

«Його» — чей? И что имеется в виду под «захламлением Докера»?

Я маю на увазі, що якщо в розробника виникає хаос при копіюванні і видаленні папочок, то в нього точно буде хаос і з купою докер контейнерів. І він не зможе розібратись, який для чого використовується.

...или написать это в Докерфайле один раз и юзать на любой машине, а не страдать лишними настройками VM.

Або написати в .bat, .ps1, .sh файл без докера один раз і використовувати на будь-якій машині.

Странно, почему не пишем на асме или плюсах до сих пор все, ну на самом-то деле, а? Проверенные решения, по 100500 лет каждому). И какие лицензии имеются в виду? Докер бесплатен.

Тобто докер корисний тому що асм або плюси застаріли?)

Вы вообще понимаете, что это такое и зачем?) Пишем Докерфайл с сетапом, и вуаля, образ у Вас собирается или пуллится, и контейнер запускается везде, где установлен Докер на той же платформе. Всё нужное находится в образе, и VM-система остаётся чистой. Изоляция в подарок.

Намагаюсь розібратись навіщо мені автоматизувати з зав’язкою на докер, якщо я можу автоматизувати без цієї зав’язки. Якщо все потрібне записати в папочку, це буде рахуватись? Все потрібне в образі це як? А поза образом пустота? Чи операційна система конкретної версії зі своїм API і можливо несумісна з API схожої версії. Докер сам магічним чином знає якщо в мене OS несумісна або якось зможе це поправити? Поки я бачу що в будь якому разі за такими речами маю слідкувати я + слідкувати ще за докером. Якщо все потрібне в образі без врахування залежності від OS, чому я не можу просто снинуте це все в одну папку? Система залишається чистою... з докером, який підмінює системні драйвери, ага. Ізоляція в подарунок. Ізоляція від чого? Якщо софт пише в базу на віддаленому сервері, як ми це можемо ізолювати? Якщо софт захоче записати в папочку, а інший софт захоче прочити з папочки, як докер дізнається це валідний сценарій по задумці розробника чи ні? Викидує монетку? Чому не весь софт працює з докером? Більше питань та невизначеної поведінки яка не піддається логіці.

Кроме этого нужно устанавливать вагон разного софта, шэрить и апдейтить конфиги на все VM. Но зачем, если этого можно НЕ делать, используя Докер? Изменился конфиг для конкретного окружения/проекта/команды etc — сделали апдейт Докерфайла/Докер образа, и VM даже не трогаем.

Знову ж таки, якщо потрібен софт, і розробники дають гарантії правильної його роботи при використанні інсталятору, то використання костилів докера, не гарантує нічого. Помінявся конфіг — скопіюй файл з конфігом. Помінялась змінна оточення — зміни її. Все геніальне просто. VM навіть не торкаємся. Це такий челенж, не торкатись VM?) В чому суть цього і чому це добро?

Поэтому Докер стал де-факто стандартом для решения проблем использования разных окружений на одной машине, а один и тот же Докер образ даёт при запуске идентичный результат на любой машине, исключая ошибки настройки окружения.

Не дає в загальному випадку, зате дає купу невизначеної поведінки. В розробників докера зате є виправдання на всі випадки життя. «В продакшені не юзати.» Геніально. Писати різні деплойменти для продакшена і для дев-середовищ. Докер це не стандарт, і ніколи їм не буде. Стандарт це використання app-get або .msi або як в .NET way, копіювання папочок.

Що значить руками? А з докером це буде ногами робитись, чи якимось іншим органом?

www.linkedin.com/...​-castelo-branco-lourenço

Я хочу мати контроль над тим що в мене встановлено, де це знаходиться і якої версії. В ідеалі я хочу копіювати папочки, або запускати інсталлер.

И Докер подходит для этого гораздо лучше. Полагаться на свою голову вместо процесса — это фейспалм. Докерфайл, очевидно, более детерминирован, чем «контроль», которого в реальности нет.

Я вважаю що позитивно використовувати прості сценарії і інструменти в порівняні зі складними. При автоматизації програмісти намагаються позбутися непотрібних залежностей, а не додали нових.

При этом наваливать в VM и на локальную машину вагон зависимостей вместо добавления, как Вы выражаетесь, «+1 уровня абстракции» — это нормально)). NuGet, npm, packagist — значит, тоже зло, и Вы пакетными менеджерами не пользуетесь, ведь это же так круто — копировать зависимости руками «в одну папку» © ?)

Все потрібне в образі це як?

Та почитайте хоть вводные страницы уже хоть. Есть базовые образы ОС (разные версии Windows Server и Linux дистро) + 100500 готовых контейнеров от соответствующих контор, заточенных под специфические сервисы (Redis и т.д.). Кастомные образы наследуются от того, что Вам нужно, добавляются новые слои (docs.docker.com/...​engine/reference/builder). Запущенный контейнер (инстанс образа) шэрит с хостом ядро OS, всё остальное — изолировано внутри контейнера. Если volume связывается с локальным хранилищем, это задаётся явно при запуске контейнера, т.е. не потеряется.

Чи операційна система конкретної версії зі своїм API і можливо несумісна з API схожої версії. Докер сам магічним чином знає якщо в мене OS несумісна або якось зможе це поправити?

docs.microsoft.com/...​ers/version-compatibility
То есть, берём последнюю версию для виртуалки/обновляем Винду локально и не паримся. А с контейнерами на никсы такой проблемы вообще нет.

з докером, який підмінює системні драйвери, ага

Переспрошу: что здесь конкретно имелось в виду, и откуда такая информация? Потому что вряд ли Вы правы.

Ізоляція від чого?

От хоста.

Якщо софт пише в базу на віддаленому сервері, як ми це можемо ізолювати?

Мне тоже интересно). Это здесь при чём вообще?

Або написати в .bat, .ps1, .sh файл без докера один раз і використовувати на будь-якій машині.

Nope, писал же

Изменился конфиг для конкретного окружения/проекта/команды etc — сделали апдейт Докерфайла/Докер образа, и VM даже не трогаем.

Со скриптами будет беготня, с Докером — нет, т.к. есть один source of truth, который хранится в общем случае в репо вместе с решением. На пальцах разница между скриптами и Докер образами:
1. Сам Докерфайл — по сути, тот же скрипт, который содержит сетап окружения + в общем случае запуск какого-то софта (напр., вытягивание и сборка сорсов + тесты при CI, либо запуск сервера при деплое). Плюс возможность наследования образов.
2. Запуск скрипта — беготня по VM’ам, вероятность где-то что-то забыть и т.д. Сделал ошибку в скрипте — разгребай на VM, что-то уже не надо — удаляй везде руками.
Докерфайлы детерминированы, образы собираются/пуллятся каждый раз (если их ещё нет) и их слои кэшируются, поэтому если образа нет — он спуллится/соберётся, если есть — слои, в которых не было изменений, подтянутся из локального кэша. Есть ошибка в Докерфайле или его нужно обновить — ОДИН мейнтейнер правит свой докерфайл, образ автоматически обновляется, и на VM мы вообще не идём.
3. Нужно удалить ненужные image’и? Одна команда в cmd, которая удалит их из локального кэша.

Якщо софт захоче записати в папочку, а інший софт захоче прочити з папочки, як докер дізнається це валідний сценарій по задумці розробника чи ні? Викидує монетку?

Первый вопрос: опишите полностью кейс, второй: как Вы этот кейс решаете без Докера.

Чому не весь софт працює з докером?

Какой софт Вам нужен, который не работает с Докером?

Хороший, кстати, пример был выше — Android SDK. Виртуалка Андроида AVD — это единственная вещь, которую я не смог поднять в контейнере из-за ограничений нашей инфраструктуры, но сам AVD — настолько забагованная и зависимая от конкретного железа хрень, что Докер там уже где-то сбоку.

Більше питань та невизначеної поведінки яка не піддається логіці

Логике не поддаётся лень читать доки, а потом писать такое).

Це такий челенж, не торкатись VM?) В чому суть цього і чому це добро?

Суть такая же, как слабая связность в ООП. Вот прям идентичная. Каждое окружение детерминировано и нам всё равно, какое оно конкретно.

Не дає в загальному випадку, зате дає купу невизначеної поведінки.

С какой недетерминированностью Вы сталкивались, если не пользовались Докером?

В розробників докера зате є виправдання на всі випадки життя. «В продакшені не юзати.» Геніально.

Про продакшен — просто лол, что-то все (и мы в том числе) юзают и не знают. Amazon давным-давно ECS запустил, а нужно было читать ДОУ и не делать этого, оказывается).

Писати різні деплойменти для продакшена і для дев-середовищ.

Вообще-то, они и без Докера разные — Ваш кэп.

Я так понимаю, все Ваши суждения о Докере базируются на написанном на заборе на данный момент...

Та почитайте хоть вводные страницы уже хоть. Есть базовые образы ОС (разные версии Windows Server и Linux дистро) + 100500 готовых контейнеров от соответствующих контор, заточенных под специфические сервисы (Redis и т.д.). Кастомные образы наследуются от того, что Вам нужно, добавляются новые слои (docs.docker.com/...​engine/reference/builder). Запущенный контейнер (инстанс образа) шэрит с хостом ядро OS, всё остальное — изолировано внутри контейнера. Если volume связывается с локальным хранилищем, это задаётся явно при запуске контейнера, т.е. не потеряется.
docs.microsoft.com/...​ers/version-compatibility
То есть, берём последнюю версию для виртуалки/обновляем Винду локально и не паримся. А с контейнерами на никсы такой проблемы вообще нет.

Ви мене переконали. Спробую що за штука.

Если будут какие-то вопросы — пишите.

Я якось не зрозумів ваш пост. Якщо ви не знаєте нащо вам докер — він вам непотрібен. У мене в практиці два варіанти підходу до деплою
1. Doсker based
2.Terraform based (без докеру по Packer вирішує багато питань...)
Це я так для себе їх назвав, перший підхід надає можливість в будь якому проекті зробити будь що, наприклад багато девів у моєму оточенні працюють з MacOS ци як там її, мені аби підняти оточення на макбуці це пи...ц або на вінді... Докер вирішує це питання, є декілька образів налаштованих, одна команда і оточення працює не залежно від того вінда то мак чи щось інше...

Я намагаюсь вирішити для себе, чи потрібно мені витрачати час на вивчення докера, чи на щось більш корисне. Поки реальних аргументів за докер малувато. Героїчно долаються вигадані проблеми.

ні — не потрібно, бо як би було потрібно, не було б таких питань.

Героїчно долаються вигадані проблеми.

Рівень вашої компетенції та досвіду — не дозволяє вам зрозуміти що проблеми є реальні а не вигадані. Я вам вище приклад навів — локальне оточення підняти, на сервері, та у мульті ОС середовищі. Це реальна картина — не вигадана.

Я цю реальну картину 5 років успішно щодня успішно вирішую, тут мимо.

Я ж кажу — ще не доросил. ДОкер вирішує такі питання як суміснсть бібліотек, використання ресурсів, залежності, кластеризація та так інше. Звичайно це все можна зробити будь яким іншим методом — шляхом, на то воно і *nix like. Наприклад я написав скрипта який щось робить, на python3, локально у мене стоїть python3.7, на деяких серверах стоїть 3.4 а десь ще 2.7. Як швидко всюди запустит скрипт в роботу — все верно, можна
1. Встановити всюди одну версію python
2. Pyenv
3. Docker
Як на мене запхати скрипта в Docker образ та пушнути в regystry — а потім через Ansible массово на всіх серуверах запустити цього скрипта, оновити так само... Але це мій шлях — який робиться для 100500 серверів за пів години (ну може дещо більше) — але це на 99% автоматизований процес. Можна вириішити через bash чи ще якось. Але це рішення цілком на розробниках, адмінах, опсах... Доке дозволяє зробити сайт з усіма залежностями — віддати його клієнту та розгорнути з мінімумом налаштувань. Просто ви ще не зтикались з такими тасками, коли дуже різні сервери, оточення, ОС, версії та на всьому цьому потрібно швиденько щось запустити )))

PS це я ще не казав про обмеження на ресурси, коли в Докері це набагато простіше ніж руками через croup, limits.conf та таке інше....

Я намагаюсь вирішити для себе, чи потрібно мені витрачати час на вивчення докера, чи на щось більш корисне.

Вы уже потратили времени больше, чем на прочтение базовой документации по Докеру, и до сих пор задаёте по нему элементарные вопросы по кругу.

час на вивчення докера

Це (з власного досвіду) десь години 4 на базову документацію і «на погратися»? Ви дійсно вже більше часу витратили на цю гілку форума.

Думаю было бы неплохо упомянуть про distroless контейнеры гугла...

Можна ж написати власну статтю!

А можно не тратить время на местный сброд и выкатить тул по урезке существующих контейнеров с поддержкой Vuls сигнатур.

Та погугли просто — там нет ничего сложного.

Запуск контейнера с HTTP-сервером и Angular-приложением выполняется так

Ирония в том, что те же SPA-приложения которые являются по сути статическим хтмл+жс+цсс (2мб) нуждаются в хттп-сервере на каждом контейнере (100мб). Люди тупо проксируют нжинкс нжинксом.
Нельзя без костылей(в виде скриптов) сделать образ без рантайма и отдавать статический артефакт внутри него через отдельный нжинкс-контейнер.

отдавать статический артефакт внутри него через отдельный нжинкс-контейнер.

НЯЗ можно используя средства Kubernetes/OpenShift.

Поспрашиваю у коллег. Вроде что-то такое делали — контейнер был тупо как волюм для другого.

подвох в том что неймд волюм берет артефакт из образа только когда этот вольюм создается. Если запускается контейнер, а вольюм уже есть — новый артефакт туда не запишется. Я написал скрипт который вручную копирует артефакт, это и есть решение.
Есть довольно много людей которые столкнулись с той же проблемой и воюют с разрабами докер-компоуза чтоб ее решить (безрезультатно): github.com/...​ocker/compose/issues/5912

Підписатись на коментарі