<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Чевопс?</title><subtitle>Девопс глазами программиста 👨‍💻
Практические примеры работы с Docker 🐳, Kubernetes ☸️ и облаками ☁️
Доступно, по делу, с юмором 🤡</subtitle><author><name>Чевопс?</name></author><id>https://teletype.in/atom/chevops</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/chevops?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@chevops?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=chevops"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/chevops?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-05T08:11:21.528Z</updated><entry><id>chevops:localhost-direct</id><link rel="alternate" type="text/html" href="https://teletype.in/@chevops/localhost-direct?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=chevops"></link><title>Localhost в опасности, или на Кинг-Стрит опять раздают SSL-сертификаты</title><published>2023-01-25T23:01:47.301Z</published><updated>2023-03-17T17:38:00.263Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/fa/b1/fab197a0-847d-4e1a-b648-8ceb07418b59.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/43/cb/43cbafe3-829b-497a-a9d4-e88e4767c2d1.png&quot;&gt;Дело было в феврале 2019 года, когда некто сэр Нова Альтэс из Манчестера, его величества Соединенного Королевства, в одно воскресное и, непременно, дождливое британское утро, обзавелся новеньким SSL-сертификатом на имеющийся в его распоряжении домен localhost.direct. Однако приобретенный набор криптографических последовательностей сэр Альтэс намеревался использовать отнюдь не в целях безопасности личной коллекции Интернет-ресурсов, а в целях весьма благородных — пожертвовать приватный ключ мировому сообществу веб-разработчиков. И вот уже три года подряд сэр Альтэс исправно вносит весьма приличную для обычного программиста из северной Англии сумму фунтов стерлингов на счет центра сертификации Google Trust Services LLC, который, в свою...</summary><content type="html">
  &lt;figure id=&quot;1rno&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/43/cb/43cbafe3-829b-497a-a9d4-e88e4767c2d1.png&quot; width=&quot;2000&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;hPvL&quot;&gt;Дело было в феврале 2019 года, когда некто сэр Нова Альтэс из Манчестера, его величества Соединенного Королевства, в одно воскресное и, непременно, дождливое британское утро, обзавелся новеньким SSL-сертификатом на имеющийся в его распоряжении домен &lt;em&gt;localhost.direct. &lt;/em&gt;Однако приобретенный набор криптографических последовательностей сэр Альтэс намеревался использовать отнюдь не в целях безопасности личной коллекции Интернет-ресурсов, а в целях весьма благородных — пожертвовать приватный ключ мировому сообществу веб-разработчиков. И вот уже три года подряд сэр Альтэс исправно вносит весьма приличную для обычного программиста из северной Англии сумму фунтов стерлингов на счет центра сертификации &lt;em&gt;Google Trust Services LLC&lt;/em&gt;, который, в свою очередь, с большой охотой продлевает срок действия сертификата еще на 12 месяцев, после чего мистер Нова загружает свежий приватный ключ в &lt;a href=&quot;https://github.com/Upinel/localhost.direct#download&quot; target=&quot;_blank&quot;&gt;открытый доступ&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;Ke34&quot;&gt;Что же такого особенного заключается в этом самом сертификате, и чем он может быть полезен сообществу IT? Для ответа на этот вопрос давайте обратим внимание на домен, для которого искомый сертификат, предназначается, а именно — &lt;em&gt;localhost.direct&lt;/em&gt;:&lt;/p&gt;
  &lt;pre id=&quot;p5ia&quot;&gt;$ nslookup localhost.direct
...
Non-authoritative answer:
Name:	localhost.direct
Address: 127.0.0.1&lt;/pre&gt;
  &lt;p id=&quot;S0RC&quot;&gt;Аналогичный ответ от DNS мы получаем при проверке любого сабдомена следующего уровня:&lt;/p&gt;
  &lt;pre id=&quot;WBRw&quot;&gt;$ nslookup whatever.localhost.direct
...
Non-authoritative answer:
Name:	whatever.localhost.direct
Address: 127.0.0.1&lt;/pre&gt;
  &lt;p id=&quot;v8ni&quot;&gt;Нетрудно догадаться, что сэр Альтэс позаботился о том, чтобы домен &lt;code&gt;localhost.direct&lt;/code&gt;, ровно как и любой домен, подходящий под маску &lt;code&gt;*.localhost.direct&lt;/code&gt; , вели на &lt;code&gt;127.0.0.1&lt;/code&gt;, то есть на сетевой интерфейс &lt;em&gt;внутренней петли&lt;/em&gt;, он же &lt;code&gt;localhost&lt;/code&gt;. Поскольку соответствующие DNS-записи внесены в публичную базу DNS, а ключ SSL-сертификата находится в свободном доступе, — любой желающий имеет возможность защитить свой собственный &lt;em&gt;localhost&lt;/em&gt; сертификатом, выданным авторитетным центром.&lt;/p&gt;
  &lt;p id=&quot;YOpk&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;iyKd&quot;&gt;Демо&lt;/h3&gt;
  &lt;p id=&quot;BVug&quot;&gt;Скачаем с &lt;a href=&quot;https://github.com/Upinel/localhost.direct#download&quot; target=&quot;_blank&quot;&gt;ресурса&lt;/a&gt; сэра Альтэса подписанный сертификат вместе с ключом и положим их в директорию &lt;code&gt;~/localhost.direct&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;mNC2&quot;&gt;$ mkdir -p ~/localhost.direct
$ curl -o certs.zip -LOs https://aka.re/localhost
$ unzip -P localhost certs.zip
$ rm certs.zip
$ ls
localhost.direct.crt localhost.direct.key&lt;/pre&gt;
  &lt;p id=&quot;ZgJK&quot;&gt;Создадим простой &lt;code&gt;nginx.conf&lt;/code&gt;:&lt;/p&gt;
  &lt;figure&gt;
    &lt;script src=&quot;https://gist.github.com/igops/22c286522e02c008ffc6c59e893603d3.js&quot;&gt;&lt;/script&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;YI1j&quot;&gt;Запустим контейнер &lt;code&gt;nginx:alpine&lt;/code&gt;, подложив внутрь &lt;code&gt;nginx.conf&lt;/code&gt;, подписанный сертификат и его ключ:&lt;/p&gt;
  &lt;pre id=&quot;Ncrx&quot;&gt;$ docker run --rm \
-v $PWD/nginx.conf:/etc/nginx/conf.d/default.conf \
-v $PWD/localhost.direct.crt:/etc/nginx/certs/localhost.direct.crt \
-v $PWD/localhost.direct.key:/etc/nginx/certs/localhost.direct.key \
-p 80:80 \
-p 443:443 \
nginx:alpine&lt;/pre&gt;
  &lt;p id=&quot;nsye&quot;&gt;Откроем &lt;a href=&quot;https://localhost.direct&quot; target=&quot;_blank&quot;&gt;https://localhost.direct&lt;/a&gt; в браузере. Сертификат работает.&lt;/p&gt;
  &lt;p id=&quot;Btff&quot;&gt;&lt;em&gt;— Вы уже скучаете по боли от самоподписанных сертификатов и паническим надписям «Connection is not secure»?&lt;/em&gt;&lt;/p&gt;
  &lt;figure id=&quot;xhAJ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/93/ea/93eab118-1c10-4300-b2c6-602a1cea0b4f.png&quot; width=&quot;1476&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;lcdD&quot;&gt;Пример роутинга по сабдоменам:&lt;/p&gt;
  &lt;figure&gt;
    &lt;script src=&quot;https://gist.github.com/igops/e95d250ab1806e291b01a1c32d3bc292.js&quot;&gt;&lt;/script&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;8owj&quot;&gt;Результат:&lt;/p&gt;
  &lt;figure id=&quot;Rxnp&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a7/68/a768fbdb-453c-4de4-9fce-0b796c59a41a.png&quot; width=&quot;1224&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;Ea1F&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/49/21/4921b1ac-b13d-4dbc-a0aa-aa2b1fa59c53.png&quot; width=&quot;1224&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Q0fj&quot;&gt;Идея проекта &lt;em&gt;localhost.direct &lt;/em&gt;максимально проста и изящна&lt;em&gt;. Kudos&lt;/em&gt;, сэр Альтэс!&lt;/p&gt;
  &lt;p id=&quot;pmJ2&quot;&gt;Официальная страница проекта: &lt;a href=&quot;https://get.localhost.direct&quot; target=&quot;_blank&quot;&gt;https://get.localhost.direct&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;CV5o&quot;&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;C4or&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;Подпишись на телеграм «чевопса»&lt;/strong&gt;&lt;/p&gt;
    &lt;p id=&quot;JQUx&quot; data-align=&quot;center&quot;&gt;&lt;a href=&quot;https://t.me/chevops&quot; target=&quot;_blank&quot;&gt;https://t.me/chevops&lt;/a&gt;&lt;/p&gt;
    &lt;p id=&quot;dJ7K&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Девопс глазами программиста 👨‍💻&lt;/em&gt;&lt;/p&gt;
    &lt;p id=&quot;hDw1&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Практические примеры работы с Docker 🐳, Kubernetes ☸️ и облаками ☁️&lt;/em&gt;&lt;/p&gt;
    &lt;p id=&quot;ZUhH&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Доступно, по делу, с юмором 🤡&lt;/em&gt;&lt;/p&gt;
  &lt;/section&gt;

</content></entry><entry><id>chevops:docker-fast-maven-build</id><link rel="alternate" type="text/html" href="https://teletype.in/@chevops/docker-fast-maven-build?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=chevops"></link><title>Готовим докерфайл для быстрой сборки JAR используя Maven</title><published>2023-01-17T10:16:34.843Z</published><updated>2023-03-08T14:00:09.646Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/35/5a/355ae7cf-fb10-4437-a395-3fc4a7dc8908.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/4d/5f/4d5f0699-2274-40fa-b4c4-1ed2640921d8.png&quot;&gt;Рассмотрим пример maven-проекта из sping guides. Он имеет следующую структуру:</summary><content type="html">
  &lt;figure id=&quot;Osgs&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4d/5f/4d5f0699-2274-40fa-b4c4-1ed2640921d8.png&quot; width=&quot;2000&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;K3rx&quot;&gt;Рассмотрим &lt;a href=&quot;https://github.com/spring-guides/gs-maven/tree/main/complete&quot; target=&quot;_blank&quot;&gt;пример&lt;/a&gt; maven-проекта из &lt;em&gt;sping guides&lt;/em&gt;. Он имеет следующую структуру:&lt;/p&gt;
  &lt;pre id=&quot;cRxE&quot;&gt;├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
├── main
│   └── java
│       └── hello
│           ├── Greeter.java
│           └── HelloWorld.java
├── test
├── java
├── hello
└── GreeterTest.java&lt;/pre&gt;
  &lt;p id=&quot;WVgz&quot;&gt;Самый банальный Dockerfile «на скорую руку» может выглядеть следующим образом:&lt;/p&gt;
  &lt;figure&gt;
    &lt;script src=&quot;https://gist.github.com/igops/9b6cabcfc9c7601c63b385a073dded51.js&quot;&gt;&lt;/script&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bvme&quot;&gt;Рассмотрим способы оптимизации.&lt;/p&gt;
  &lt;p id=&quot;7VGU&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;joys&quot;&gt;&lt;strong&gt;1. Шаг перый: Кешируем зависимости&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;X4RG&quot;&gt;Как правило, в процессе активной разработки, список зависимостей &lt;strong&gt;меняется реже&lt;/strong&gt; чем бизнес-логика и тесты. Воспользуемся этим знанием: вынесем dependencies в отдельной слой и расположим его до слоя &lt;code&gt;COPY src src&lt;/code&gt;. Согласно идеологии &lt;em&gt;docker layers&lt;/em&gt;, изменение слоя инвалидирует &lt;strong&gt;только те слои, которые расположены после данного&lt;/strong&gt;, поэтому изменение содержимого директории &lt;em&gt;src&lt;/em&gt; не будет инвалидировать слой зависимостей.&lt;/p&gt;
  &lt;p id=&quot;CbxS&quot;&gt;Осталось теперь только придумать, как выделить &lt;em&gt;dependencies&lt;/em&gt; в отдельный слой. В качестве решения, можно сначала скормить мавену голый &lt;em&gt;pom.xml&lt;/em&gt; без директории &lt;em&gt;src&lt;/em&gt;, а позже скопмилировать проект, используя уже имеющиеся зависимости:&lt;/p&gt;
  &lt;figure&gt;
    &lt;script src=&quot;https://gist.github.com/igops/d5daa59984b988a5d9d39c2fd2d28d07.js&quot;&gt;&lt;/script&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ZIP7&quot;&gt;Согласно &lt;em&gt;maven build lifecycle&lt;/em&gt;, &lt;em&gt;mvn verify&lt;/em&gt; выполнит фазы &lt;em&gt;validate&lt;/em&gt;, &lt;em&gt;compile&lt;/em&gt;, &lt;em&gt;test&lt;/em&gt;, &lt;em&gt;package&lt;/em&gt; и сам &lt;em&gt;verify&lt;/em&gt;. Поскольку на данном этапе в директории /build есть только &lt;em&gt;pom.xml&lt;/em&gt; — сам исходный код скомпилирован не будет, но все зависимости из &lt;em&gt;pom.xml&lt;/em&gt; будут установлены в локальный репозиторий &lt;em&gt;~/.m2&lt;/em&gt;.&lt;/p&gt;
  &lt;p id=&quot;oJlh&quot;&gt;Следующими двумя слоями мы копируем директорию src и компилируем jar-файл командой &lt;em&gt;mvn package&lt;/em&gt;. &lt;strong&gt;Большинство&lt;/strong&gt; зависимостей будет зачитано мавеном из локального репозитория.&lt;/p&gt;
  &lt;p id=&quot;xKZw&quot;&gt;Исследуем слои промежуточного stage образа командой &lt;a href=&quot;https://github.com/wagoodman/dive&quot; target=&quot;_blank&quot;&gt;dive&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;m0R9&quot;&gt;       0 B  WORKDIR /build
    1.6 kB  COPY pom.xml .
     18 MB  RUN /bin/sh -c mvn --fail-never verify
     715 B  COPY src src
    682 kB  RUN /bin/sh -c mvn package&lt;/pre&gt;
  &lt;p id=&quot;eStg&quot;&gt;Итого, на данном этапе мы добились следующего поведения:&lt;/p&gt;
  &lt;ul id=&quot;5svM&quot;&gt;
    &lt;li id=&quot;ZbDm&quot;&gt;изменение директории &lt;em&gt;src&lt;/em&gt; (частое действие) приводит к инвалидации только двух последних двух слоев, «тяжелые» слои, расположенные ДО — остаются в кеше&lt;/li&gt;
    &lt;li id=&quot;sIuz&quot;&gt;изменение файла &lt;em&gt;pom.xml&lt;/em&gt; (редкое действие) приводит к инвалидации последних четырех слоев&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;xAgL&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;Iw1d&quot;&gt;&lt;strong&gt;2. Шаг второй: Исключаем тесты&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;FQxa&quot;&gt;Если выполнение тестов при сборке не является частью вашего CI/CD, их можно пропустить, используя флаг &lt;code&gt;-DskipTests&lt;/code&gt;. Наличие этого флага позволяет пропустить выполнение тестов, однако не исключает тесты из &lt;strong&gt;компиляции&lt;/strong&gt;. Полный отказ от тестов реализуется при помощи двух флагов &lt;code&gt;-Dmaven.test.skip -DskipTests&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;5uta&quot;&gt;Теперь, когда тесты исключены, maven больше не нуждается в плагине &lt;em&gt;Maven Surefire Plugin&lt;/em&gt;, который используется на этапе &lt;em&gt;mvn test&lt;/em&gt;. Поскольку, это &lt;strong&gt;единственный артифакт&lt;/strong&gt;, который добавлялся в локальный репозиторий в слое &lt;em&gt;RUN mvn package&lt;/em&gt; (легко проверить командой &lt;em&gt;dive&lt;/em&gt;), теперь мы можем использовать флаг &lt;code&gt;-o&lt;/code&gt;, который запрещает обращение к &lt;em&gt;remote&lt;/em&gt; репозиториям и вынуждает мавен читать локальный репозиторий:&lt;/p&gt;
  &lt;figure&gt;
    &lt;script src=&quot;https://gist.github.com/igops/4c74e1c0c52e89d51fa3d85c4533dd57.js&quot;&gt;&lt;/script&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;YO0U&quot;&gt;Сборка стала заметно быстрее, а размер последнего слоя &lt;em&gt;stage=build&lt;/em&gt; снизился с 682 до 634kB (проверьте ваши слои самостоятельно командой &lt;em&gt;dive&lt;/em&gt; или &lt;em&gt;docker history&lt;/em&gt;). Благодаря флагу &lt;em&gt;&lt;code&gt;-o&lt;/code&gt;&lt;/em&gt;, &lt;strong&gt;все&lt;/strong&gt; зависимости зачитаны мавеном из локального репозитория.&lt;/p&gt;
  &lt;p id=&quot;rGgK&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;e4J9&quot;&gt;&lt;strong&gt;3. Шаг третий: Используем параллельную сборку&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;1uSO&quot;&gt;Maven версии 3+ позволяет использовать &lt;a href=&quot;https://cwiki.apache.org/confluence/display/MAVEN/Parallel+builds+in+Maven+3&quot; target=&quot;_blank&quot;&gt;parallel builds&lt;/a&gt;:&lt;/p&gt;
  &lt;blockquote id=&quot;Kmgi&quot;&gt;&lt;em&gt;mvn -T 4 clean install # Builds with 4 threads&lt;br /&gt;mvn -T 1C clean install # 1 thread per cpu core&lt;br /&gt;mvn -T 1.5C clean install # 1.5 thread per cpu core&lt;/em&gt;&lt;/blockquote&gt;
  &lt;p id=&quot;jSFd&quot;&gt;Распараллелим сборку по 10 потоков на каждое ядро, доступное докеру:&lt;/p&gt;
  &lt;figure&gt;
    &lt;script src=&quot;https://gist.github.com/igops/84e5188f9cd4dfb8502de249bfeb4bb9.js&quot;&gt;&lt;/script&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;fB6Y&quot;&gt;Мы рассмотрели несколько способов оптимизации maven-сборки в экосистеме докера. В промышленных масштабах, подобная оптимизация экономит уйму времени ожидания, как ускоряя CI/CD pipeline, так и уменьшая биллинг за процессорное время.&lt;/p&gt;
  &lt;p id=&quot;byu5&quot;&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;XJqN&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;Подпишись на телеграм «чевопса»&lt;/strong&gt;&lt;/p&gt;
    &lt;p id=&quot;q4Ko&quot; data-align=&quot;center&quot;&gt;&lt;a href=&quot;https://t.me/chevops&quot; target=&quot;_blank&quot;&gt;https://t.me/chevops&lt;/a&gt;&lt;/p&gt;
    &lt;p id=&quot;y1eN&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Девопс глазами программиста 👨‍💻&lt;/em&gt;&lt;/p&gt;
    &lt;p id=&quot;42Gj&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Практические примеры работы с Docker 🐳, Kubernetes ☸️ и облаками ☁️&lt;/em&gt;&lt;/p&gt;
    &lt;p id=&quot;u5wp&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Доступно, по делу, с юмором 🤡&lt;/em&gt;&lt;/p&gt;
  &lt;/section&gt;

</content></entry><entry><id>chevops:revealing-docker-entrypoint</id><link rel="alternate" type="text/html" href="https://teletype.in/@chevops/revealing-docker-entrypoint?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=chevops"></link><title>О чем молчат докер-контейнеры, или 4 способа узнать entrypoint</title><published>2023-01-17T09:48:44.559Z</published><updated>2023-03-09T01:01:27.020Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/c9/86/c9860515-8ec5-4762-848d-d88263b73d07.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/82/c3/82c32abc-098e-446b-a5e6-c22a51dcc88e.png&quot;&gt;Часто бывает, что документация по запуску того или иного контейнера либо отсутствует, либо ее качество оставляет желать лучшего. На своей практике я наблюдал множество случаев, когда docker run приводил к многозначительному молчанию консоли, после чего процесс завершался без какого-либо видимого эффекта:</summary><content type="html">
  &lt;figure id=&quot;0bRa&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/82/c3/82c32abc-098e-446b-a5e6-c22a51dcc88e.png&quot; width=&quot;2000&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1t4i&quot;&gt;Часто бывает, что документация по запуску того или иного контейнера либо отсутствует, либо ее качество оставляет желать лучшего. На своей практике я наблюдал множество случаев, когда &lt;em&gt;docker run &lt;/em&gt;приводил к многозначительному молчанию консоли, после чего процесс завершался без какого-либо видимого эффекта:&lt;/p&gt;
  &lt;figure id=&quot;Ef40&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/70/f1/70f14822-a3c3-495c-9b5d-d749ad9963e9.gif&quot; width=&quot;1614&quot; /&gt;
    &lt;figcaption&gt;«Молчаливый» Alpine&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;orZm&quot;&gt;Давайте рассмотрим несколько  техник, которые помогут вам разобраться с запуском любого контейнера.&lt;/p&gt;
  &lt;p id=&quot;vxG8&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;Jfmy&quot;&gt;&lt;strong&gt;1. Найдите Dockerfile&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;mRlV&quot;&gt;Dockerfile представляет собой набор инструкций для сборки образа и последующего запуска контейнера. Лучшим рецептом исследования проблемы «молчаливого» старта является изучение непосредственно самого docker-файла. При запуске контейнера выполняется команда, указанная в инструкции &lt;em&gt;ENTRYPOINT&lt;/em&gt;:&lt;/p&gt;
  &lt;figure id=&quot;mOSx&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/48/af/48afbdc4-7d4c-41ab-ac26-3c09f637b200.gif&quot; width=&quot;1614&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;r74w&quot;&gt;Dockerfile в исходном виде не является частью собранного образа, поэтому проще всего отыскать оригинал. Если автор образа — не вы, то попробуйте найти репозиторий исходного кода, откуда образ был собран. Как правило, помогает гугление запросов из разряда «&lt;em&gt;some-image docker github&lt;/em&gt;». Используйте поиск по гитхаб-репозиторию, чтобы найти искомый Dockerfile.&lt;/p&gt;
  &lt;p id=&quot;8j3W&quot;&gt;Если в docker-файле отсутствует инструкция &lt;em&gt;ENTRYPOINT&lt;/em&gt;, найдите самую последнюю инструкцию &lt;em&gt;FROM&lt;/em&gt;, и далее изучите родительский образ аналогичным способом.&lt;/p&gt;
  &lt;p id=&quot;3fg2&quot;&gt;Если вам не удалось найти &lt;em&gt;ENTRYPOINT&lt;/em&gt;, или у вас нет уверенности, что найденный Dockerfile соответствует искомому контейнеру, переходите к следующим техникам.&lt;/p&gt;
  &lt;p id=&quot;YbvX&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;EoUT&quot;&gt;&lt;strong&gt;2. Зачитайте Entrypoint из конфигурации образа&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;EKZq&quot;&gt;&lt;code&gt;$ docker inspect some-image -f &amp;quot;{{.Config.Entrypoint}}&amp;quot;&lt;/code&gt;&lt;/p&gt;
  &lt;figure id=&quot;Ixkt&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1d/b8/1db82fb2-5d12-414d-9d55-a3a1b85d1adf.gif&quot; width=&quot;1614&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NyAN&quot;&gt;Эта команда дешево и сердито выведет искомый &lt;em&gt;ENTRYPOINT&lt;/em&gt;. Зачем же тогда искать Docker-файл, если есть такая простая и понятная команда? Дело в том, что Dockerfile является наиболее полным представлением о содержимом образа, в то время как &lt;em&gt;docker inspect&lt;/em&gt; просто выдает параметры конфигурации, одним из которых, в том числе, является &lt;em&gt;ENTRYPOINT&lt;/em&gt;:&lt;/p&gt;
  &lt;pre id=&quot;Jhjc&quot;&gt;$ docker inspect nginx -f &amp;quot;{{.Config.Entrypoint}}&amp;quot;
[/docker-entrypoint.sh]&lt;/pre&gt;
  &lt;p id=&quot;n8Hq&quot;&gt;&lt;em&gt;Образ Nginx выполняет команду &lt;/em&gt;/docker-entrypoint.sh&lt;em&gt; при запуске контейнера.&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;0EcQ&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;1kQo&quot;&gt;3. &lt;strong&gt;Скопируйте Entrypoint-скрипт из контейнера на вашу машину&lt;/strong&gt;&lt;/h3&gt;
  &lt;pre id=&quot;OTqG&quot;&gt;$ docker run \
-v /path/on/host:/mount-dir \
--entypoint cp \
some-image /path/in/container /mount-dir&lt;/pre&gt;
  &lt;p id=&quot;BPos&quot;&gt;&lt;em&gt;Скопирует /path/in/container из образа some-image на хост в директорию /path/on/host (на Windows вместо обратного слеша «\» использовать «^» — здесь и далее).&lt;/em&gt;&lt;/p&gt;
  &lt;pre id=&quot;HjMH&quot;&gt;$ docker run \
-v $PWD:/mount --entypoint cp \
nginx /docker-entrypoint.sh /mount&lt;/pre&gt;
  &lt;p id=&quot;p6kp&quot;&gt;&lt;em&gt;Теперь в вашей рабочей директории есть файл &lt;/em&gt;/docker-entrypoint.sh&lt;em&gt; из образа Nginx&lt;/em&gt; (&lt;em&gt;на Windows вместо $PWD использовать %cmd%)&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;5W43&quot;&gt;Кстати, я использую эту команду для копирования любого файла из образа. Разберем подробнее, как она работает:&lt;/p&gt;
  &lt;ul id=&quot;ln1l&quot;&gt;
    &lt;li id=&quot;Xvz8&quot;&gt;&lt;code&gt;-v /path/on/host:/mount-dir&lt;/code&gt; замаунтить директорию хоста &lt;em&gt;/path/on/host&lt;/em&gt; в контейнер на путь &lt;em&gt;/mount-dir&lt;/em&gt;&lt;/li&gt;
    &lt;li id=&quot;Qinn&quot;&gt;&lt;code&gt;--entypoint cp&lt;/code&gt; при старте контейра использовать команду &lt;em&gt;cp&lt;/em&gt; (сокращение от &lt;em&gt;copy&lt;/em&gt;, то есть &lt;em&gt;скопировать&lt;/em&gt;)&lt;/li&gt;
    &lt;li id=&quot;CVPP&quot;&gt;&lt;code&gt;/path/in/container /mount-dir&lt;/code&gt; параметры запуска контейнера, в данном случае - параметры команды &lt;em&gt;cp&lt;/em&gt; - скопировать &lt;em&gt;откуда&lt;/em&gt; и скопировать &lt;em&gt;куда&lt;/em&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;rsNy&quot;&gt;Как итог, файл &lt;em&gt;/path/in/container&lt;/em&gt; копируется в директорию &lt;em&gt;/path/on/host&lt;/em&gt;.&lt;/p&gt;
  &lt;p id=&quot;rRHm&quot;&gt;Работает гораздо быстрее чем &lt;em&gt;docker save&lt;/em&gt; и не требует запущенного контейнера, как &lt;em&gt;docker copy&lt;/em&gt;.&lt;/p&gt;
  &lt;p id=&quot;w2Jy&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;cjv8&quot;&gt;4. &lt;strong&gt;Запустите контейнер в режиме линукс-терминала&lt;/strong&gt;&lt;/h3&gt;
  &lt;pre id=&quot;Pt0V&quot;&gt;$ docker run -it --entrypoint=sh some-image&lt;/pre&gt;
  &lt;p id=&quot;CVST&quot;&gt;В большинство docker-образов предуставновлен &lt;em&gt;Bourne shell&lt;/em&gt; (/bin/sh), что позволяет вам использовать его в качестве терминала (не забудьте флаги -it, которые инициируют интерактивную консоль контейнера):&lt;/p&gt;
  &lt;p id=&quot;16at&quot;&gt;&lt;em&gt;Запускаем контейнер nginx, используя sh в качестве entrypoint:&lt;/em&gt;&lt;/p&gt;
  &lt;pre id=&quot;JBcR&quot;&gt;$ docker run -it --entrypoint=sh nginx&lt;/pre&gt;
  &lt;p id=&quot;3k8O&quot;&gt;&lt;em&gt;Изучаем оригинальный entrypoint, выявленный предыдущими методами:&lt;/em&gt;&lt;/p&gt;
  &lt;pre id=&quot;pAMl&quot;&gt;$ less /docker-entrypoint.sh&lt;/pre&gt;
  &lt;p id=&quot;QpVg&quot;&gt;&lt;em&gt;Используем другие возможности линукса, находясь внутри контейнера:&lt;/em&gt;&lt;/p&gt;
  &lt;pre id=&quot;XVEA&quot;&gt;$ bash
$ ls -la /etc/nginx/conf.d&lt;/pre&gt;
  &lt;p id=&quot;dkd0&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;9FzW&quot;&gt;&lt;strong&gt;Домашнее задание&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;xFnF&quot;&gt;Объясните, почему &lt;code&gt;$ docker run alpine&lt;/code&gt; завершается сразу после старта.&lt;/p&gt;
  &lt;p id=&quot;T9ma&quot;&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;6IGn&quot; data-align=&quot;center&quot;&gt;&lt;strong&gt;Подпишись на телеграм «чевопса»&lt;/strong&gt;&lt;/p&gt;
    &lt;p id=&quot;Wp5M&quot; data-align=&quot;center&quot;&gt;&lt;a href=&quot;https://t.me/chevops&quot; target=&quot;_blank&quot;&gt;https://t.me/chevops&lt;/a&gt;&lt;/p&gt;
    &lt;p id=&quot;r8II&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Девопс глазами программиста 👨‍💻&lt;/em&gt;&lt;/p&gt;
    &lt;p id=&quot;mXue&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Практические примеры работы с Docker 🐳, Kubernetes ☸️ и облаками ☁️&lt;/em&gt;&lt;/p&gt;
    &lt;p id=&quot;R2dc&quot; data-align=&quot;center&quot;&gt;&lt;em&gt;Доступно, по делу, с юмором 🤡&lt;/em&gt;&lt;/p&gt;
  &lt;/section&gt;

</content></entry></feed>