Docker Ninja – Telegram
Docker Ninja
1.05K subscribers
35 photos
96 links
По всем вопросам обращаться к @nesudimov_eu
Download Telegram
Ты запустил контейнер с флагом --restart=always, но заметил, что он постоянно перезапускается из-за ошибки в приложении. Какая команда поможет временно остановить автоматические перезапуски?
Anonymous Quiz
22%
docker stop container_name
23%
docker pause container_name
2%
docker kill container_name
53%
docker update --restart=no container_name
👍6
🧶 Все переплетено 🧶

Бывает вылизываешь до кровавых пятен daemon.json на проде, а контейнеры все равно стартуют по 30 секунд каждый. Смотришь в логи. Видишь кучу ошибок от каких-то runc, containerd и dockerd. И понимаешь - ты понятия не имеешь, кто это и почему! Начинаешь рестартить docker, но проблема то возвращается, то исчезает.

До конца года осталось полторы недели, в которые вряд ли кто-то будет серьезно работать, так что лучше разобраться прямо сейчас! Но когда не знаешь самой базы приходится тыкаться как слепой котенок...

Поэтому сегодня рассмотрим с вами что это за звери такие runc, containerd и как они связаны с dockerd.


По сути, когда ты пишешь docker run, запускается целый пайп различных операций:
🔹 Docker Engine (dockerd) - главный босс, который принимает твои команды через REST API
🔹 containerd - менеджер среднего звена, управляет образами и снапшотами
🔹 runc - низкоуровневый работяга, создает изоляцию на уровне ядра
🔹 Linux kernel - предоставляет примитивы namespaces и cgroups

Вот как это выглядит в деле:
docker run -d nginx:latest


Что происходит под капотом:
1. Docker CLI стучится к dockerd через Unix socket
2. dockerd дергает containerd через gRPC API
3. containerd загружает образ, создает снапшот и вызывает runc
4. runc создает namespaces (PID, Network, Mount) и запускает процесс

А вся эта магия описывается в OCI спецификации:
{
"ociVersion": "1.0.0",
"process": {
"args": ["nginx", "-g", "daemon off;"]
},
"linux": {
"namespaces": [
{"type": "pid"},
{"type": "network"},
{"type": "mount"}
]
}
}


runc использует эту конфигурацию для настройки изоляции процессов!

Зачем это знать:
➡️ Отладка проблем - понимаешь, на каком уровне сломалось (dockerd, containerd или runc)
➡️ Оптимизация производительности - настраиваешь containerd snapshotter под свою нагрузку
➡️ Глубокий мониторинг - собираешь метрики на уровне containerd для анализа
➡️ Enterprise безопасность - настраиваешь изоляцию на уровне runc для compliance

Теперь когда в очередной раз контейнер откажется стартовать, ты будешь знать где искать проблему! А не тыкать рестарт docker-а в надежде на чудо.

Как обычно, ставь свои пальчики, сердечки и огонечки, чтобы твой покорный слуга продолжал разбирать внутренности контейнерного мира!

🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
110🔥6👍3🙈1
🧘‍♀️Работа с осознанными🧘‍♀️

Тот кто хоть раз пытался заделать весь обвяз для интеграционных тестов отлично знает, что дело это гиблое и ресурсоемкое. Тут тебе надо и хосты найти свободные, и связность для них настроить, а если тесты слишком долгие, то и вторую такую пачку хостов. А если вы сидите в облаке и терраформ с ансиблой покурить. Хорошо, если вы со своей командой успели пересесть на кубер. Но такое, увы, встретишь не всегда. А если тесты вы запускаете раз в день? Все остальное время твоя инфраструктура будет простаивать? Цены то на оперативу видел??

Так что, тут просится какой-то такой инструмент, который как и докер, позволит нам так же гибко и быстро изолировать пачку сервисов и чтобы поднимать можно было по запросу. Например на жирнющем билд агенте поднимать контейнер, внутри которогу будут крутиться еще куча контейнеров.

А что если я скажу, что такой инструмент есть? И имя ему Docker!

Чиво бл...? Предлагаешь поднять контейнеры внутри контейнера? Linux никогда такого не разрешит - упремся в безопасность!


И тут на помощь приходит флаг --privileged - оружие массового поражения для изоляции контейнеров!

По сути, эта штука превращает твой контейнер в полного властелина хост-системы. Docker при использовании --privileged отключает большую часть своей защиты со словами: "Это все твое, Симба".

Вот как это выглядит в деле:
# Контейнер получает доступ ко всем устройствам хоста
docker run --privileged -it ubuntu:20.04 /bin/bash


А вот сравнение обычного и привилегированного контейнера:
# Обычный контейнер - ограниченный список устройств
docker run -it ubuntu:20.04 ls /dev
console core fd full mqueue null ptmx pts random shm stderr stdin stdout tty urandom zero

# Привилегированный контейнер - полный доступ к /dev хоста
docker run --privileged -it ubuntu:20.04 ls /dev
autofs core fd hvc2 hvc7 loop1 loop6 net ptp0 ram11 ram2 ram7 sda sg0 shm tty0 tty13 tty18 tty22 tty27 tty31 tty36 tty40 tty45 tty5 tty54 tty59 tty63 ttyS1 vcs1 vfio zero
bsg cpu_dma_latency full hvc3 kmsg loop2 loop7 null pts ram12 ram3 ram8 sdb sg1 stderr tty1 tty14 tty19 tty23 tty28 tty32 tty37 tty41 tty46 tty50 tty55 tty6 tty7 ttyS2 vcsa vhost-net
btrfs-control cuse fuse hvc4 kvm loop3 mapper nvram ram0 ram13 ram4 ram9 sdc sg2 stdin tty10 tty15 tty2 tty24 tty29 tty33 tty38 tty42 tty47 tty51 tty56 tty60 tty8 ttyS3 vcsa1 vport0p0
bus dri hvc0 hvc5 loop-control loop4 mem ppp ram1 ram14 ram5 random sdd sg3 stdout tty11 tty16 tty20 tty25 tty3 tty34 tty39 tty43 tty48 tty52 tty57 tty61 tty9 urandom vcsu vport0p1
console dxg hvc1 hvc6 loop0 loop5 mqueue ptmx ram10 ram15 ram6 rtc0 sde sg4 tty tty12 tty17 tty21 tty26 tty30 tty35 tty4 tty44 tty49 tty53 tty58 tty62 ttyS0 vcs vcsu1 vsock


При запуске контейнера с этим ключем внутри происходит следующее:
🔹 Контейнер получает все 40+ Linux capabilities - от CAP_SYS_ADMIN до CAP_NET_ADMIN
🔹 Доступ ко всем устройствам в /dev (а их там немало!)
🔹 AppArmor и SELinux профили идут лесом
🔹 Seccomp фильтры тоже отдыхают

Кейсы использования:
➡️ Docker-in-Docker для CI/CD пайплайнов (классика жанра!)
➡️ Работа с блочными устройствами - монтирование дисков, LVM
➡️ Системное администрирование из контейнера
➡️ Отладка и мониторинг системных ресурсов

Чтобы не раскуривать capabilities и namespaces, просто юзаем этот флаг и получаем троянского коня полнофункциональный linux процесс, который и швец, и жнец, и коня на скаку, и козу на возу!

Но помни, такой сетап юзаем только во внутренней сети и очень осознанно! Пусть твои контейнеры будут мощными, но управляемыми! А то потом будешь разбираться, кто тебе всю систему перелопатил 😅

Попробовал в деле? Ставь 🔥! А если есть вопросы - пиши в директ или личку, разберем!

🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍2🔥2
В твоем проекте есть docker-compose.yml для разработки и docker-compose.prod.yml для продакшена. Как правильно объединить эти конфигурации при деплое?
Anonymous Quiz
30%
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
24%
docker compose --override docker-compose.prod.yml up
35%
docker compose merge docker-compose.yml docker-compose.prod.yml
11%
docker compose --config docker-compose.prod.yml up
🔥2
📖Смотришь в книгу, видишь фигу👎

Бывает сидишь такой, никого не трогаешь, спокойно доживаешь последнюю недельку на работе и тут бац - прилетает алерт, что супер важный микросервис на проде упал. Лезешь в docker logs, но ничего не можешь увидеть, потому что контейнер лежит. Лезешь за ними в заведомо настроенный ELK/Opensearch и ничего не понимаешь. Никакой ошибки или баги не было. Сервис как будто просто вырубили руками.

И тут до тебя доходит, а вдруг кто-то еще не успел оклематься после новогоднего корпоратива и случайно удалил тот самый супер важный сервис? А что если это диверсия!??!?!?! Ужас!😱

В такие моменты хорошо бы узнать какие именно операции проводили с dockerd за последнее время. Какой контейнер падает, какой образ пуллится, какая сеть создается?


И тут на помощь приходит docker events! Эта команда подключается напрямую к потоку событий и показывает в реальном времени каждый чих происходящий на хосте с dockerd.

По сути, эта штука как логгер всех операций Docker daemon-а. Создал контейнер - событие. Остановил - событие. Скачал образ - тоже событие. Весь lifecycle твоих контейнеров как на ладони!

Базовый синтаксис такой:
# Мониторинг всех событий в реальном времени
docker events

2025-12-21T21:48:54.964163622+03:00 container kill f0770ec141f769b7330e1ff5fd206096c5ccc50a215803e75920a2cdc62bd080 (image=nginx, maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=elated_jepsen, signal=9)
2025-12-21T21:48:55.465756543+03:00 network disconnect 0a0d7305d434379c8336fc51f51e2a1bacd1065b0a24c18ec65eb53c1e061c63 (container=f0770ec141f769b7330e1ff5fd206096c5ccc50a215803e75920a2cdc62bd080, name=bridge, type=bridge)
2025-12-21T21:48:55.499566110+03:00 container die f0770ec141f769b7330e1ff5fd206096c5ccc50a215803e75920a2cdc62bd080 (execDuration=12, exitCode=137, image=nginx, maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=elated_jepsen)

Хоба! Кто-то из любимых коллекг кильнул этот контейнер!

А вот как это выглядит в деле:
# События за последний час = perfect для дебага
docker events --since "1h"

# События конкретного контейнера
docker events --filter container=webapp --filter type=container


Что умеет фильтровать:
Событий у докера может быть много и в них легко закопаться до следующего года. Так что полезно знать, что конкретно можно там увидеть.
⚙️ Типы объектов: container, image, network, volume - каждый тип живет своей жизнью
⚙️ События контейнеров: create, start, restart, stop, die, destroy, pause, unpause, kill, oom
⚙️ События образов: pull, push, delete, import, load, save, tag, untag
⚙️ По времени: устанавливаем интересующий нас диапазон


Зачем это надо?
➡️ Дебаг падающих сервисов - отслеживаешь последовательность start/die и понимаешь, где все пошло по причинному месту
➡️ Аудит в shared-окружении - видишь кто что делает через события create/destroy/pull, полезно для соблюдения политик ИБ
➡️ Автоматизация реакций - запускаешь скрипты или уведомления при определенных событиях
➡️ Отладка Docker Compose - смотришь порядок создания сетей и томов при сложных multi-service развертываниях
➡️ Мониторинг ресурсных проблем - ловишь OOM events раньше чем они убьют продакшен

Теперь ты можешь читать Docker daemon как открытую книгу без всяких фиг! Больше никаких тыканий пальцем в небо при дебаге. Попробовал docker events в деле? Ставь реакт!

🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍5🔥31
При сборке образа ты заметил, что Docker повторно скачивает зависимости при каждом изменении исходного кода. Какой подход оптимизирует кэширование слоев в Dockerfile?
Anonymous Quiz
9%
Копировать весь проект командой COPY . /app в начале Dockerfile
30%
Использовать флаг --no-cache при каждой сборке
45%
Сначала копировать файлы зависимостей, установить их, затем копировать исходный код
15%
Добавить все файлы в .dockerignore кроме исходного кода
🤣1
🤫Secret Room🤭

Сидишь ты такой, делаешь ревью нового сервиса, а там в Dockerfile видишь шедевр: ENV POSTGRES_PASSWORD=supersecret123 прямо в переменных окружения! Ладно бы это был dev, так нет - продакшен! И еще этот Dockerfile валяется в гите, доступном всей команде из 30 человек, а образ запушен в публичный registry. А потом воздыхают, почему ИБ-шники постоянно закручивают гайки...

Или вот классика жанра: пароли зашиты прямо в Dockerfile, логи CI пестрят API-токенами, а в docker inspect можно прочитать всю подноготную приложения включая секретные ключи. И все это "потому что так быстрее", "потом переделаем", "да кто на наш тест полезет"...

Знакомо? Тогда давай разберем как делать правильно, чтобы ИБ-ешники не материли хотя бы твою родословную до седьмого колена!


Пароли, ключи и прочие чувствительные данные штука зависящая от конкретного контура где развертывается приложение (test, stage, prod). Не будем же мы юзать одни и те же секреты для прода и для теста (хотя я встречал и такое...). Поэтому, хорошо бы иметь возможность поместить их подстановку на этап деплоя. То есть в Docker Compose.

На такой случай придумали директиву secrets - встроенный сейф для всех твоих паролей, токенов и прочих деликатесов!

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

Вот как это выглядит в деле:
# docker-compose.yml
version: '3.8'

secrets:
db_password:
file: ./secrets/db_password.txt # секрет из файла
api_key:
external: true # секрет берется из внешнего источника

services:
web:
image: nginx
secrets:
- db_password # подключение секрета к сервису
- source: api_key
target: /run/secrets/api_token # монтирование с другим именем


Видишь? Секреты объявляются в отдельной секции, а потом подключаются к нужным сервисам. Никаких паролей в открытом тексте!

Как создаем?
Самые базовые способы - создать секрет из файла или переменной среды.
secrets:
mysql_root_password:
file: ./mysql_root_password.txt # содержимое файла становится секретом

database_url:
environment: DATABASE_CONNECTION_STRING # секрет создается из переменной окружения хоста


External секреты в самом первом примере - это когда секрет уже создан внешними инструментами или через некоторые механизмы Swarm, о которых поговорим в будущих постах.

Зачем это нужно?
➡️ ИБ-шники не кусаются - секреты не попадают в логи CI/CD, Docker registry и остаются изолированными от кода
➡️ Соответствие стандартам - корпоративные политики безопасности запрещают пароли в переменных окружения
➡️ Разные окружения - можешь использовать разные секреты для dev/staging/prod без изменения compose-файлов
➡️ Минимальная attack surface - секреты живут только в памяти контейнера, недоступны через файловую систему хоста
➡️ Ротация через override - можешь менять секреты через docker-compose.override.yml без правки основного файла

Но у встроенного механизма есть ограничения:
⚠️ нет автоматической ротации - привет протухшим сертам
⚠️ нет централизованного аудита - не видим где и что уже утекло, значит не знаем где дыры
⚠️ нет интеграции с enterprise-системами типа HashiCorp Vault или AWS Secrets Manager

Для сложных production-окружений все же лучше переходить на специализированные решения. Зато для большинства задач Docker Compose secrets - это идеальный баланс простоты и безопасности!

Теперь ты знаешь как хранить секреты по-человечески, а не светить ими на всю вселенную!

Полезно - ставь реакт! А теперь предлагаю удалиться на выходнульки, чтобы сделать последний рывок перед 2к26!

🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥8👍7😁21
В твоем Dockerfile используется инструкция ENTRYPOINT ["python", "app.py"]. Ты хочешь передать дополнительные аргументы при запуске контейнера. Что произойдет?
Anonymous Quiz
11%
Аргументы заменят команду ENTRYPOINT полностью
61%
Аргументы будут добавлены к команде ENTRYPOINT как параметры
22%
Аргументы будут проигнорированы
6%
Произойдет ошибка запуска контейнера
🙃Post-Monday brain loading🙃

30.12.2025 Вторник 09:30 🥱. Ты опрокидываешь 4-ю стопку эспрессо и удобно располагаешься в своем рабочем кресле, чтобы сделать 2-минутную передышку перед очередной задачей. Но опухшие веки медленно, но верно смыкаются. Тело рязмякает и ты проваливаешься в объятья Морфея...

Где то на фоне ты слышишь постоянно повторяющиеся ритмичные звуки: ты ты ты - тыыы тыыы тыыы - ты тыыы тыыы ты. Ты открываешь глаза, а вокруг все черное белое. Ты едешь в трамвае. На старинных часах марки "Заря" стоит дата 6 октября 2025 года. В правой руке ты держишь дискету с надписью nginx.tar.

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


И тут на помощь приходит команда docker load!

Эта команда умеет воскрешать Docker-образы из tar-архивов, созданных через docker save.

Вот как это выглядит в деле:
# На исходном сервере: пакуем образ в архив
docker save -o myapp.tar myapp:latest

# На целевом сервере: распаковываем обратно
docker load -i myapp.tar

# Или через pipe без промежуточного файла
docker save myapp:latest | docker load


Видишь? Ты этими командами говоришь Docker достать из архива не только файлы, но и всю структуру слоев, историю команд, теги - все что было в оригинальном образе. А далее восстановить все как было: слои, метаданные, теги, всю родословную образа.

А чем же docker load отличается от docker import?
Тут как разница между полным бекапом системы и копированием домашней папки. docker load восстанавливает весь образ со всеми потрохами, а docker import создает новый образ из файловой системы, теряя всю историю. Если тебе нужно именно перенести готовый образ, то подходит только load!

Зачем это нужно?
➡️ Air-gapped развертывания: когда интернет - роскошь
➡️ Миграция между дата-центрами через флешки (да, бывает и такое!)
➡️ Disaster recovery: храним критические образы локально, чтобы никто не уволок
➡️ Медленный интернет: лучше один раз скачать и развезти

А вот что мы можем найти внутри tar-архива
📀 blobs/sha256/ - файлы слоев образа
📀 index.json - указатель на манифесты (в папке blobs/sha256/) для разных архитектур образа
📀 manifest.json - это легаси вариант того самого манифеста, который указывает как и в каком порядке соединять слои образа
📀 oci-layout - содержит версию формата oci и помогает инструментам определить, что это OCI-совместимый образ
📀 repositories - содержит соответствие тегов образа хешам манифестов

Docker читает manifest.json, восстанавливает граф зависимостей слоев, проверяет SHA256 хэши и регистрирует все это богатство в локальном хранилище.

Так что теперь ты знаешь как загрузить образы из архива и спасти себя от повторного проживания 3 месяцев до Нового Года! Фухх, сон отпускает. Ты возвращаешься к работе и ставишь реакт на новый пост в канале...

🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
15🔥3👍2
🔫Pullp fiction🔫

31 декабря. Воздух пронизан заливной рыбой и мандаринками. Ты шагаешь в местный магазин за горошком для оливьехи. Но тут тебе на плечо садится почтовый голубь с письмом от коллеги-дежурного на НГ (вот ведь бедолага...):
- Привет! Решил развернуть все наше инфраструктурное окружение (Nginx, PostgreSQL, Redis, RabbitMQ, ELK, Consul, Vault и еще пару штуковин...) у себя на рабочем компе, чтобы потестить кое-какую штуку. Запустил docker compose up -d и положил всю сеть в офисе... Что делать??

- Однако, - думаешь ты. - Ну что же, надо выручать коллегу!

Можно конечно через docker pull каждый образ по отдельности тащить, но когда у тебя полтора десятка сервисов, это превращается в пытку. А docker compose up с таким количеством сервисов, как видим, сразу отъедает большую часть сетевого канала.


Уверен, что команду docker compose pull придумали специально для тех, кто трудится не покладая рук даже по праздникам!

По сути, эта штука парсит твой docker-compose.yml, вытаскивает все образы из секций image и тихо-мирно скачивает их с registry. Никаких остановок сервисов, никаких пересозданий контейнеров, никаких тебе указаний названия и тэга образа - просто обновляет локальный кеш нужных тебе образов и все!

Базовый синтаксис элементарен:
# Загружает образы для всех сервисов из docker-compose.yml
docker compose pull


А если вдруг нужно спуллить что-то конкретное, то делаем так
# Обновляешь образы только для указанных сервисов
docker compose pull web database redis


Представь у тебя такой compose-файл:
version: '3.8'
services:
web:
image: nginx:1.21
api:
image: myapp:latest
database:
image: postgres:14


Команда проверяет доступность новых версий для nginx:1.21, myapp:latest и postgres:14 в registry и загружает их в локальное хранилище Docker daemon. Существующие контейнеры продолжают жить на предыдущих версиях до явного пересоздания.

Зачем это нужно?
➡️ Минимизируем downtime при обновлениях - предварительная загрузка образов позволяет быстро перезапускать сервисы без ожидания скачивания
➡️ Валидируем образы перед деплоем - проверяешь существование указанных образов в registry до начала обновления продакшна
➡️ Оптимизируем CI/CD pipeline - разделяешь этапы загрузки образов и их применения для лучшего контроля процесса
➡️ Готовимся к rolling updates - обеспечиваешь наличие новых образов на всех хостах кластера перед началом поэтапного обновления
➡️ Blue-green deployments - подготавливаешь образы для обеих сред заранее

И не забывай про layer sharing - Docker Compose pull эффективно использует общие слои между образами. При обновлении образов с одинаковыми базовыми слоями загружаются только измененные layers!

Ты отправил дежурному его голубя обратно, указав в ответном письме, что можно спуллить необходимые компоненты через docker compose pull по одному ссылку на этот пост, совсем забыв, что сеть в офисе лежит намеренно, ведь в такой день важно замедлиться, отложить рабочие дела и расслабиться за вычиткой постов из любимого канала имя которому...

🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥2😁2
🛻 Синий трактор едет к нам. Pt. 2🛻

Коллеги, вот уже второй год мы с вами встречаем новогодние праздники вместе! И в этом году, как и говорил, я подготовил для вас небольшой подарочек. Его вы найдете завтра под елкой в нашем канале!

Ну и конечно же, мои вам пожелания на новый год:
В новом году хочу пожелать вам энергии, крепкого здоровья, хорошего достатка, ну и конечно же по-больше приятных встреч с родными и близкими! Ведь именно этого не хватает нам ИТ-шникам в загруженные рабочие будни! С праздником вас, друзья!🥳

И не забывайте в новогоднюю ночь слова известного китайского мудреца:
Самогон вина полезней -
Пей без мин трагических!

Он спасет от всех болезней,
Кроме венерических!

Лао-Цзы


🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾5🎄1
🎄Елочка гори!🎄

Коллеги, вот и пришла пора распаковывать наши подарочки!

Примерно в начале ноября передо мной встал вопрос, куда двигаться дальше. Помимо докера, есть еще множество интереснейших тем, о которых очень хочется вам поведать, поэтому на новогодних выходных я со всей силы работаю над новыми каналами по тематике Kubernetes и Linux. Тематика была выбрана не случайно - обе эти темы связаны с тематикой Docker и это дает большой простор для написания перекрестных постов за счет чего можно будет погрузиться в тему более детально.

Но сам подарок состоит не в том.
Новый год это не только обещания похудеть, бросить курить или начать читать по 40 книг в год, но и возможность пересмотреть свой прошлый опыт, чтобы определить вектор для будущего развития. Для меня таким вектором (близким мне по духу) стала идея построения этакого хаба знаний/сообщества для devops/sre - инженеров любого уровня. Поэтому, я принял решение развивать не только этот и озвученные выше каналы, но и Бусти. Это никак не скажется на качестве контента в телеграм каналах, но даст мне большую мотивацию и ресурсы для дальнейшего развития.

Сейчас я уже подготовил для вас на каждый день выходных расширенные версии постов с канала Docker Ninja. Ближе к 15 января вы сможете найти там и расширенные версии постов с каналов по Linux и Kubernetes еще до выхода в свет самих вышеозвученных каналов. Сам доступ к расширенным постам возможен за небольшую плату. Подробнее вы можете ознакомиться на самой странице Boosty. Но, с сегодняшнего дня и по 16 января все читатели канала смогут читать расширенные версии постов бесплатно перейдя по этой ссылке! Поэтому, предлагаю вам ознакомиться на праздниках, пока доступ не закрылся.

Постов на канале Docker Ninja не будет до 12 января включительно.

А на этом у меня все. Спасибо за внимание! И хорошо вам отдохнуть и набраться сил перед новыми карьерными достижениями!💪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥32😍2🎅1