<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Vadim Rutkovsky</title><generator>teletype.in</generator><description><![CDATA[Vadim Rutkovsky]]></description><image><url>https://teletype.in/files/54/547c3746-ed20-49bb-861b-64798c613b5c.png</url><title>Vadim Rutkovsky</title><link>https://teletype.in/@vrutkovs</link></image><link>https://teletype.in/@vrutkovs?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vrutkovs</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/vrutkovs?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/vrutkovs?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Thu, 21 May 2026 22:47:47 GMT</pubDate><lastBuildDate>Thu, 21 May 2026 22:47:47 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@vrutkovs/HysWqaPLH</guid><link>https://teletype.in/@vrutkovs/HysWqaPLH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vrutkovs</link><comments>https://teletype.in/@vrutkovs/HysWqaPLH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vrutkovs#comments</comments><dc:creator>vrutkovs</dc:creator><title>Remember - no Dockerfiles</title><pubDate>Thu, 12 Sep 2019 13:37:07 GMT</pubDate><description><![CDATA[Многие разработчики разочарованы в магии современного контейнерного подхода.]]></description><content:encoded><![CDATA[
  <p>Многие разработчики разочарованы в магии современного контейнерного подхода.</p>
  <p>Кроме дополнительных требований к приложению (см. <a href="https://12factor.net/" target="_blank">The Twelve-Factor Apps</a>) им зачастую приходится еще и учить новый формат для сборки контейнеров - Dockerfile. Изначально формат был достаточно простым - <code>FROM</code>, <code>RUN</code> да <code>COPY</code>, но затем этот формат оброс дополнительными конструкциями - <code>COPY --from</code> и <code>FROM foo as bar</code> для multistage builds, <code>ONBUILD</code> и так далее. Кроме того, формат не стандартизирован никак и управляется целиком и полностью желаниями Docker Inc.</p>
  <p>Но Dockerfile - не единственный способ сборки контейнерных образов. Рассмотрим некоторые из них.</p>
  <h2>Buildah</h2>
  <p><a href="https://buildah.io/" target="_blank">Buildah</a> - это инструмент, который специально создан только для сборки контейнерных образов. В отличие от <code>docker</code> он не требует демона, может быть <a href="https://developers.redhat.com/blog/2019/08/14/best-practices-for-running-buildah-in-a-container" target="_blank">запущен в другом контейнере</a> и позволяет более гибко собирать контейнерные образы.</p>
  <p>Рассмотрим пример:</p>
  <pre>echo &quot;--- Сборка приложения, никаких контейнеров ---&quot;
./configure --with-feature=a
make
echo &quot;Приложение собрано в ./output/bin/my-app&quot;

echo &quot;--- Сборка контейнера ---&quot;

echo &quot;Создаем пустой контейнер и смонтируем его&quot;
newcontainer=$(buildah from scratch)
scratchmnt=$(buildah mount $newcontainer)

echo &quot;Устанавливаем bash и coreutils из репозиториев Fedora 30 в контейнер используя dnf из хоста&quot;
dnf install --installroot $scratchmnt --releasever 30 bash coreutils --setopt install_weak_deps=false -y

echo &quot;Копируем бинарный файл в /usr/bin/ контейнера&quot;
cp ./output/bin/my-app $scratchmnt/usr/bin

echo &quot;Устанавливаем CMD [&#x27;/usr/bin/my-app&#x27;]&quot;
buildah config --cmd /usr/bin/my-app $newcontainer
buildah commit $newcontainer my-app:latest</pre>
  <p>(для Debian/Ubuntu систем подход немного сложнее - <code>apt-get download package &amp;&amp; dpkg -i package.deb --force-not-root --root=$scratchmnt</code>)</p>
  <p>В чем приемущество такого подхода? Вот несколько примеров:</p>
  <ul>
    <li><a href="https://github.com/GoogleContainerTools/distroless/blob/master/README.md" target="_blank">Distroless-подход</a> - в образе не будет инструментов для сборки - нет dnf/apt-get</li>
    <li>Для сборки не требуются привилегии для запуска приложений в контейнере -&gt; сборку контейнерного образа можно запускать в другом контейнере без требования флага <code>priviledged</code></li>
    <li>Во всем контейнере создастся три слоя - <code>FROM scratch</code>, <code>COPY &lt;необходимые бинарные файлы из coreutils + bash + my-app&gt;</code> и <code>CMD [&#x27;/usr/bin/app&#x27;]</code></li>
    <li>Кэшированием артефактов для сборки управляет сборочный хост - можно свободно использовать <a href="https://github.com/distcc/distcc" target="_blank">distcc</a>, сетевые диски для кэша и т.д.</li>
  </ul>
  <p>Эти образы совместимы со спецификацией OCI, а значит их можно запускать в docker, docker-compose или Kubernetes так же, как и собранные в docker.</p>
  <h3>buildah bud</h3>
  <p>Кроме того, <code>buildah</code> поддерживает чтение инструкций из Dockerfile: <code>buildah bud -f Dockerfile .</code>. Инструкции из Dockerfile преобразуются в инструкции по созданию новых контейнеров и копированию файлов аналогично предыдущему примеру.</p>
  <p>Этот способ так же позволяет монтировать внешние директории для сборки контейнеров: <code>buildah bud --volume /var/lib/my-build-cache:/cache:ro,Z -t imageName .</code></p>
  <h2>Source2Image</h2>
  <p>Еще в древности люди заметили что фреймворк или целый язык программирования имеет стандартизированный алгоритм для сборки:</p>
  <ul>
    <li><code>golang</code>: <code>go get &amp;&amp; go build</code></li>
    <li><code>rust</code>: <code>cargo build --release</code></li>
    <li><code>python</code>: <code>pip install -r requirements.txt &amp;&amp; pip install .</code></li>
  </ul>
  <p>Кроме того, при переходе на новую версию приходится менять все Dockerfile, убедится что базовый образ в один прекрасный день не обновит golang или python до неподдерживаемой версии и т.д.</p>
  <p>Чтобы избежать копипаста кусков в Dockerfiles и упрощения процесса сборки был создан инструмент под названием <a href="https://github.com/openshift/source-to-image" target="_blank">Source-to-Image</a>.</p>
  <p>После установки <a href="https://github.com/openshift/source-to-image/releases" target="_blank">s2i</a> сборка простого питоновского проекта сокращается до одной команды:</p>
  <pre>s2i build https://github.com/sclorg/django-ex centos/python-36-centos7 hello-python
</pre>
  <p>Это консольное приложение выполняет следующие действия:</p>
  <ul>
    <li> Клонирует репозиторий <code>https://github.com/sclorg/django-ex</code> во временную директорию </li>
    <li> Тянет образ <code>docker.io/centos/python-36-centos7</code> В этом образе хранятся инструкции (подробнее ниже) и необходимые инструменты </li>
    <li> Используя питон и инструкции из <code>python-36-centos7</code> создается новый образ <code>hello-python</code> </li>
  </ul>
  <p>Если требуется собирать приложение с другой версией питона, то при сборке нужно лишь сменить сборочный образ - к примеру <code>docker.io/centos/python-27-centos7</code></p>
  <p>Вся &quot;магия&quot; сборки хранится в сборочном образе. <a href="https://github.com/openshift/source-to-image#anatomy-of-a-builder-image" target="_blank">Краткое описание</a> процесса сборки:</p>
  <ul>
    <li><code>s2i</code> ищет каталог <code>s2i/bin/</code> в сборочном образе</li>
    <li>при сборке образа запускается скрипт из <code>s2i/bin/assemble</code></li>
    <li>при старте собранного образа запускается <code>s2i/bin/run</code></li>
    <li>(опционально) скрипт из <code>s2i/bin/usage</code> добавит описание в контейнерный образ</li>
    <li>(опционально) скрипт из <code>s2i/bin/save-artifact</code> позволяет использовать предыдущие сборки для кэширования артефактов сборки</li>
  </ul>
  <p>Этот простой интерфейс позволяет отделить процедуру сборки приложения от исходников и обновлять их независимо. Source2Image, к примеру, используется в OpenShift (дистрибутиве kubernetes) для быстрого и безопасного создания пайпланов из git-репозиториев.</p>
  <h3>Заключение</h3>
  <p>Существует множество инструментов для сборки контейнерных образов без использования Dockerfile. Многие могут показаться черезчур усложненными (а некоторые - черезчур упрощенными), но фактически Dockerfiles до сих пор остаются неформализированным стандартом. Тем не менее важно знать преимущества других способов сборки - а так же из недостатки.</p>
  <p>Эти и другие способы сборки имаджей предлагаю обсудить в <a href="https://t.me/kubernetes_ru" target="_blank">https://t.me/kubernetes_ru</a> или <a href="https://t.me/ru_podman" target="_blank">https://t.me/ru_podman</a></p>
  <p>---</p>
  <p>Источник: <a href="https://vrutkovs.eu/posts/source2image/" target="_blank">https://vrutkovs.eu/posts/source2image/</a></p>
  <p>К примеру, этот блогпост был собран с помощью <a href="https://github.com/vrutkovs/sti-hugo" target="_blank">vrutkovs/sti-hugo</a></p>

]]></content:encoded></item></channel></rss>