Библиотека Go-разработчика | Golang
24K subscribers
2.57K photos
48 videos
88 files
5.1K links
Все самое полезное для Go-разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/32d20779

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0

#WXSSA
Download Telegram
🤯 QA в 2026 — это уже не «нажми кнопку»

Архитектура микросервисов, SQL, Kafka, логи, автотесты. Именно это работодатели хотят видеть сейчас — и слово «желательно» в вакансиях давно сменилось на «обязательно».

➡️ С чего начать без IT-бэкграунда

Спойлер: из бэка переход почти не требует усилий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4🤔1
⭐️ Проверка интерфейсов на этапе компиляции

В Go тип реализует интерфейс неявно, никаких implements не нужно. Это элегантно, но создаёт тихую ловушку: вы думаете, что тип реализует интерфейс, но из-за несовпадения сигнатуры метода — не реализует. Узнаёте об этом только в рантайме, когда присвоение падает.

Лечится одной строкой, которая ничего не стоит в рантайме:
var _ io.Reader = (*MyReader)(nil)


Что здесь происходит

Объявляется переменная типа io.Reader, ей присваивается nil-указатель на MyReader, результат выбрасывается. Если *MyReader не реализует интерфейс, то компилятор отклонит код. Если реализует, то строка компилируется и не генерирует никакого кода.

Такой же приём используется в стандартной библиотеке Go и в крупных open-source проектах.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍263
📎 Анализатор и инъекции 802.11 на Go

Gapcast — это инструмент для аудита WiFi-сетей: перехват пакетов, инъекции, Evil Twin с Captive Portal и оценка дистанции до точки доступа по RSSI. Написан на Go, лицензия GPL-2.0.

Что умеет

Сканирование 2.4 и 5 ГГц одновременно, запись в .pcap, восстановление данных из файла — в том числе от Wireshark. Deep Scan по одному BSSID проходит три фазы: определение канала, сбор пакетов, расчёт дистанции.

Установка

git clone https://github.com/ANDRVV/gapcast.git
cd gapcast && go build -buildvcs=false
./gapcast -i <interface>


Сканирование сетей:
# 2.4 ГГц
./gapcast -i wlan0

# 5 ГГц
./gapcast -i wlan0 -5g

# Оба диапазона + радар дистанции
./gapcast -i wlan0 -2.4+5g -radar

# Только точки доступа, без клиентов
./gapcast -i wlan0 -2.4+5g -beacon

# Долгое сканирование без пропуска неактивных устройств
./gapcast -i wlan0 -2.4+5g -d


➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
👨‍💻 Markdown-CMS на Go без базы данных

Markdown-CMS — это система управления контентом, где вместо базы данных и визуального редактора используются обычные .md файлы с текстом.

Foundry это свежий проект как раз про такой подход.

Пайплайн простой: конфиг → загрузка контента → граф сайта → маршруты → рендеринг → public/. Два графа в памяти: SiteGraph: документы, роуты, таксономии; и DependencyGraph для инкрементальных пересборок. При изменении файла пересобираются только затронутые страницы.

Что есть из коробки

Плагины с хуками на загрузку/сборку/раздачу, темы с layout-слотами, RSS и sitemap, импорт из WordPress и legacy-Markdown, JS SDK для фронтенда и админки. Валидация битых ссылок, осиротевших медиафайлов и дублирующихся URL — командой foundry validate.

Быстрый старт:
go install github.com/sphireinc/foundry/cmd/foundry@latest
foundry serve # dev-сервер с live reload
foundry build # статика в public/


➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2🤔1
💬 Топ-вакансий для Go-разработчиков за неделю

Golang Developer, Middle+ — до 300 000 ₽, удаленно

Go-разработчик (Мониторинг) — до‍ 585 000 ₽, удаленно по Москве

Бэкенд-разработчик (Storage) — до 500 000 ₽, в офисе/гибрид в Москве

➡️ Еще больше топовых вакансий — в нашем канале Go jobs

🐸 Библиотека Go-разработчика

#GoWork
Please open Telegram to view this post
VIEW IN TELEGRAM
3
🛠 Go Fiber v3: как мигрировать с v2

Fiber v3 вышел в стабильный релиз. Если вы используете v2 в продакшене, вот что нужно знать перед миграцией и зачем она вообще нужна.

Что поменялось

Три изменения, которые влияют на код

1️⃣ fiber.Ctx теперь реализует context.Context

В v2 приходилось вызывать c.UserContext(), чтобы передать контекст в стандартные библиотеки. В v3 fiber.Ctx удовлетворяет интерфейсу context.Context напрямую.
// v2
ctx := c.UserContext()
rows, err := db.QueryContext(ctx, "SELECT ...")

// v3
rows, err := db.QueryContext(c, "SELECT ...")


2️⃣ Статика переехала в middleware

Метод app.Static() убран. Его функциональность перенесена в отдельный static middleware.
// v2
app.Static("/", "./public")

// v3
import "github.com/gofiber/fiber/v3/middleware/static"

app.Use("/", static.New("./public"))


3️⃣ Изменился метод Listen

Метод Listen объединён с конфигурацией. Настройки теперь передаются напрямую в вызов. Если у вас есть кастомная конфигурация запуска сервера, придётся поправить.

Как мигрировать

Команда Fiber выпустила CLI с встроенным инструментом миграции:
go install github.com/gofiber/cli/fiber@latest
fiber migrate --to v3


После запуска обязательно проверяйте весь diff вручную. Инструмент иногда меняет код, который к Fiber не относится.

Что ещё появилось в v3

Drop() — тихий сброс соединения без ответа клиенту, удобно для DDoS-защиты.

End() — немедленный сброс ответа.

SendEarlyHints() — поддержка HTTP 103.

Пакет extractors с единым API для извлечения значений из заголовков, кук, query-параметров и форм. Раньше каждый middleware дублировал эту логику по-своему.

RouteChain для Express-стиля объявления маршрутов. HEAD-маршруты теперь регистрируются автоматически для каждого GET.

Нативная поддержка context.Context убирает целый класс бойлерплейта. Основные breaking changes — это статика и конфигурация Listen, они чинятся быстро. Запустите CLI-инструмент, прогоните тесты, вручную проверьте diff.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥5
❗️ Kafka выстрелила в прод в 7 утра в январские праздники

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

Архитектор собрал 5 типичных ошибок при работе с Kafka, тех, что не проявляются сразу, а в самый неподходящий момент.

➡️ Читать статью

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111
📎 Cтоимость сборщика мусора

Сборщик мусора в Go потребляет два ресурса: память и CPU. Чтобы понять, как им управлять, разберём простую модель.

Память

GC нужно помнить две вещи: что осталось живым после прошлого цикла и что выделила программа с тех пор. Сложите эти два числа и получите размер кучи на момент следующего запуска GC.

CPU

Основная работа GC состоит в том, чтобы пройтись по всей живой памяти и пометить, что ещё нужно, а что можно выбросить. Чем больше живой памяти, тем дольше это занимает. Чем больше указателей и связанных списков, тем медленнее обход.

Компромисс на пальцах

Представьте уборщика в офисе. Убирается каждый час — мусора почти нет, но он постоянно мешает работать. Убирается раз в день — мусор накапливается, зато никто не отвлекается.

GC работает так же. Допустим, программа постоянно выделяет 10 МБ/с, а живая куча занимает 10 МБ.

GC запускается каждую секунду: успевает накопиться ещё 10 МБ, куча вырастает до 20 МБ, CPU-нагрузка составляет 10%.

GC запускается каждые 2 секунды: успевает накопиться 20 МБ, куча вырастает до 30 МБ, CPU-нагрузка падает до 5%.

Реже запускаем — меньше грузим CPU, но тратим больше памяти. Чаще запускаем — экономим память, но платим процессорным временем.
Это и есть главный компромисс GC: память vs CPU.

В Go частота запуска GC является единственным параметром, которым разработчик управляет напрямую. Всё остальное GC решает сам.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2👏2🥱1
😱 Если ваш продукт не умеет отдавать данные в формате, понятном AI-агенту, то вас просто не существует

Скрипт не будет кликать по красивым кнопкам в браузере, он уйдёт к конкуренту с нормальным API. Перестроить архитектуру под машинных клиентов — это уже не хайп, а необходимое условие сохранения конкурентоспособности.

Как адаптировать продукт и не исчезнуть из выдачи:

— интегрировать MCP и A2A-взаимодействие, чтобы агенты могли вас читать;
— научиться контролировать стоимость (лимиты, кэш, роутинг между моделями);
— настроить AgentOps: трейсинг, логирование и отлов регрессий.

Всё это ждёт вас на обновлённом курсе «Разработка AI-агентов». Мы специально сделали фокус на утилитарном инжиниринге и production-ready решениях.

Кстати, до 29 марта можно забрать курс с большой скидкой, и стоит поторопиться — мест на потоке всё меньше.

Зафиксировать цену и начать деплоить агентов без слива бюджета 👈
🥱17😁3🤔2👍1
🔄 GoLand 2026.1 вышел

С пылу с жару — GoLand 2026.1. Несколько полезных обновлений для Go-разработчиков.

Синтаксические обновления для Go 1.26. IDE теперь сама находит устаревший код и предлагает перейти на новый синтаксис. Поддерживаются два паттерна: создание указателей через new() и типобезопасное разворачивание ошибок через errors.AsType. Применить изменения можно сразу по всему проекту через меню Refactor → Update Syntax или через Search Everywhere. Перед применением показывается diff-превью каждого изменения.

Git worktrees. Теперь можно работать с несколькими ветками одновременно без переключения контекста. Удобно для hotfix-ов или когда AI-агенту нужна отдельная ветка.

Больше AI-агентов. Помимо Junie и Claude Agent, добавлена поддержка GitHub Copilot, Cursor и других агентов через Agent Client Protocol (ACP). Устанавливаются в один клик через новый ACP Agent Registry.

Terraform Stacks. Базовая поддержка работы со стеками прямо в IDE: навигация по компонентам, автодополнение, создание деплойментов.
Wayland по умолчанию на Linux. Улучшены рендеринг и обработка ввода. Если Wayland недоступен, IDE автоматически переходит на X11.

Code With Me уходит. Начиная с 2026.1 плагин исключён из поставки IDE. Он доступен в JetBrains Marketplace как отдельный плагин, но 2026.1 станет последней версией с официальной поддержкой сервиса.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13🥱3👍1
🤨 Молчаливый баг, который не падает и ничего не говорит

Есть парсер логов. Работает месяцами. Однажды в лог прилетает одна аномальная строка: 100 КБ без символа переноса.

bufio.Scanner читает файл в цикле. Программа не паникует, не выбрасывает ошибку в stderr, не зависает. Просто эта строка не попадает в обработку.

По умолчанию Scanner не обработает токен длиннее bufio.MaxScanTokenSize, но какое ожидаемое поведение при переполнении?

➡️ Ответ тут

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92
👀 Go 1.27: вывод типов для дженерик-функций станет последовательным

В Go 1.21 вывод типов заметно улучшился: компилятор научился автоматически подбирать типовые параметры дженерик-функции, когда она используется в присваивании или возвращается из другой функции. Но, как оказалось, это работало не везде одинаково.

Но, присваивание дженерик-функции полю структуры через = компилятор обрабатывает корректно, а то же самое через литерал структуры нет.

Вот конкретный пример:
type S struct{ f func(int) }

func g[T any](T) {}

func _(s S) {
s.f = g // ok
s = S{f: g} // error: cannot use generic function g without instantiation
s = S{f: g[int]} // ok — но зачем, если тип и так известен?
}


То же самое касается элементов массивов, слайсов, мап и отправки в каналы — паттерн одинаковый: через индекс работает, через литерал — нет.

Во всех этих случаях тип левой стороны присваивания полностью известен во время компиляции, так что вывод типового параметра однозначен. Отсутствие вывода это неожиданное поведение, заставляющее разработчика писать лишний шум вроде g[int] там, где он очевиден.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍63
🤩 15 способов склеить строки в Go

Разработчик сравнил практически все распространённые подходы к конкатенации строк в Go и прогнал их через бенчмарки. Два сценария: фиксированное число аргументов (например, сборка cache key) и переменное (динамические SQL-условия и т.п.).

Что тестировалось

+, +=, fmt.Sprintf, fmt.Sprint, strings.Join, bytes.Buffer, strings.Builder — последние два с предварительной аллокацией через .Grow() и без.

Фиксированные аргументы

В сценарии с фиксированным числом аргументов победителем оказался strings.Builder с предварительной аллокацией, следом + оператор и strings.Join. Все трое с минимальным числом аллокаций и низким потреблением памяти. Проще говоря, привычный + здесь вполне нормален и не нужно его усложнять.

// Просто и быстро для фиксированных аргументов
func BuildCacheKey(id, name, region string) string {
return id + "#" + name + "#" + region
}


Переменные аргументы

При переменном числе аргументов лидируют strings.Builder с .Grow() и strings.Join — оба показали одинаково хорошие результаты по времени, памяти и числу аллокаций. += в цикле оказался катастрофически медленным: на 256 аргументах он требует 255 аллокаций против 1 у Join.

// Плохо: O(n) аллокаций
func bad(ss []string) string {
result := ss[0]
for _, s := range ss[1:] {
result += "#" + s // новая аллокация на каждой итерации
}
return result
}

// Хорошо: 1 аллокация
func good(ss []string) string {
return strings.Join(ss, "#")
}

// Хорошо: 1 аллокация, максимум скорости
func best(ss []string) string {
var length int
for _, s := range ss {
length += len(s) + 1
}
var b strings.Builder
b.Grow(length)
b.WriteString(ss[0])
for _, s := range ss[1:] {
b.WriteString("#")
b.WriteString(s)
}
return b.String()
}


Практические рекомендации:

- Фиксированное число строк → просто +, не думайте об этом
- Переменное число строкstrings.Join как дефолт, strings.Builder + .Grow() если критична производительность
- fmt.Sprintf / fmt.Sprint → только для форматирования, не для конкатенации
- bytes.Buffer → медленнее strings.Builder почти везде, смысла нет
- += в цикле → никогда

fmt.Sprintf медленнее всех в фиксированном сценарии, а strings.Join оказался неожиданно быстрым. Сам автор признаётся, что использовал Sprintf по привычке из-за удобной форматной строки — и зря.

Ничего революционного, но полезно иметь под рукой как шпаргалку, когда кто-то в ревью спрашивает «а почему не Sprintf?».

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
17👍8🔥1
🐳 Плавающие теги в Docker

Большинство Dockerfile выглядят примерно так:
FROM golang:1.26.1-alpine


golang:1.26.1-alpine это плавающий тег. Каждый раз, когда upstream обновляет образ: патч безопасности, замена библиотеки, изменение поведения, ваш следующий билд молча подтягивает новую версию. Вы ничего не меняли, а билд сломался.

Решение:
# Было
FROM golang:1.26.1-alpine

# Стало
FROM golang:1.26.1-alpine3.20@sha256:a1b2c3d4e5f6...


Digest это SHA256 конкретного слоя образа. Он не меняется. Ваш билд от сегодня и билд через полгода используют буквально один и тот же образ.

Получить digest просто:
docker pull golang:1.26.1-alpine
docker inspect --format='{{index .RepoDigests 0}}' golang:1.26.1-alpine


Как получать обновления безопасности

Тут в игру входят Dependabot и Renovate: они автоматически обновят digest в вашем Dockerfile и откроют PR. Вы видите, что именно изменилось, и сами решаете, мержить или нет.

Добавьте в .github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"


Добавьте renovate.json в корень репозитория:
{
"extends": ["config:base"],
"docker": {
"pinDigests": true
}
}


После этого обновления приходят сами в виде PR с понятным ченджлогом.

Тег говорит «примерно вот это», digest говорит «именно вот это».

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍96
🤩 Go-обёртка для YottaDB стала читаемой

YottaDB это key-value база данных с ACID-транзакциями. YDBGo её официальная Go-обёртка. Вышла вторая версия, посмотрим что поменялось.

Что было не так с v1

v1 имел два API — SimpleAPI и EasyAPI — оба многословные, с неудобными сигнатурами. Каждый вызов требовал передавать tptoken и errstr, вручную вызывать Alloc и Free, и писать обработку ошибок после каждой операции. Вот как выглядело простое чтение значения:

// v1 EasyAPI
x, err := ValE(tptoken, &errstr, varname, subsarray)
if err != nil { ... }


// v2
x := n.Get()


Что изменилось в v2

Центральная идея это доступ к базе через экземпляры *Conn и *Node. Создаёте соединение, создаёте узел, работаете с ним:
db := yottadb.MustInit()
defer yottadb.Shutdown(db)

conn := yottadb.NewConn()
n := conn.Node("varname", "sub1", "sub2")

n.Set("hello")
x := n.Get()
n.Kill()


tptoken и errstr больше нигде не передаются — они хранятся внутри Conn. Буферы освобождаются автоматически через GC — Alloc/Free ушли.

Итерация раньше её не было вовсе, нужно было вручную вызывать SubNextE. Теперь:
for node := range n.Children() {
println(node)
}

for node := range n.Tree() {
println(node)
}


Транзакции стали лаконичнее:
conn.Transaction("BATCH", nil, func() {
n.Set(value)
})


Вызов M-кода из Go:
// v1 — 6 строк с проверками ошибок
// v2
table := conn.MustImport("calltab.ci")
retval := table.Call("mfunc", "param1", 2, 3)


Производительность

v2 быстрее v1 за счёт снижения числа аллокаций. Node переиспользует буферы при итерации через Index() вместо создания нового объекта на каждый шаг. Конкретные цифры: базовые операции быстрее EasyAPI в 4–7 раз, SimpleAPI — на 1–4%.

v1 продолжает поддерживаться, v1 и v2 можно использовать в одном приложении одновременно. Для постепенного перехода — есть таблица соответствия синтаксиса в официальном блоге и диффы реальных миграций.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍2
⚡️ Neovim 0.12.0

Вышел Neovim 0.12.0. Разбираем главное.

LSP

Добавлено много новых возможностей:

textDocument/inlineCompletion — inline-подсказки прямо в редакторе

textDocument/linkedEditingRange — одновременное редактирование связанных символов, например, открывающий и закрывающий HTML-тег

textDocument/onTypeFormatting — форматирование во время набора

textDocument/selectionRange — инкрементальное выделение: v_an расширяет выделение, v_in сужает

textDocument/documentColor + colorPresentation — предпросмотр цветов прямо в буфере

• Переработан codeLens — теперь отображается как виртуальные строки

• Новая команда :lsp для интерактивного управления LSP-клиентами

DiagnosticRelatedInformation теперь видна в vim.diagnostic.open_float(), а gf прыгает к проблемному месту

vim.lsp.buf.rename() подсвечивает переименовываемый символ через hl-LspReferenceTarget

Новые команды и плагины

:DiffTool — сравнение директорий и файлов
:Undotree — визуальный навигатор по дереву отмен
:iput — вставка с автовыравниванием отступа
:uniq — дедупликация строк в буфере
:restart — перезапуск Nvim с переподключением текущего UI
:connect — динамическое подключение UI к серверу
:wall ++p — автоматически создаёт отсутствующие родительские директории
gx в help-буферах теперь открывает онлайн-документацию по тегу под курсором

Новые опции

autocomplete — включает встроенное автодополнение при наборе
pumborder — рамка вокруг popup-меню завершения
winborder — кастомный стиль рамки окна, включая "bold"
diffop' теперь включает "indent-heuristic" и "inline:char" по умолчанию
maxsearchcoun' — максимум для searchcount(), по умолчанию 999
busy — статус «занятости» буфера, отображается в статусной строке символом ◐
pummaxwidth — максимальная ширина popup-меню завершения
fillchars получил новый флаг "foldinner"
listchars получил новый флаг "leadtab"

Производительность

Ctrl-R для вставки из регистров стал в 10 раз быстрее — теперь работает как paste, а не как ввод пользователя

vim.glob.to_lpeg() — новая реализация на LPeg, ~50% быстрее для сложных паттернов

• LSP semantic tokens теперь запрашиваются только для видимой области экрана (textDocument/semanticTokens/range) — меньше трафика, быстрее отклик

:packadd больше не инвалидирует кэш Lua-путей — значительный выигрыш при старте для конфигов с множеством :packadd

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥11🔥92🤔2
🐳 Пересборка за секунды вместо минут

Правильный порядок слоёв в Dockerfile решает половину проблемы. go mod download не перезапускается, если go.mod не менялся, то это знают все. Но стоит обновить любую зависимость, даже патч-версию, и Docker пересобирает слой с нуля: скачивает все модули заново, прогоняет полную компиляцию.

BuildKit решает через постоянный кэш, который живёт между билдами независимо от слоёв.

Как это работает:
# syntax=docker/dockerfile:1
FROM golang:1.26.1-alpine AS builder

WORKDIR /build
COPY go.mod go.sum ./

RUN --mount=type=cache,target=/go/pkg/mod \
go mod download

COPY . .

RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux go build -o /app ./cmd/server


/go/pkg/mod это кэш скачанных модулей. Если пакет уже был загружен в предыдущем билде, он не качается снова даже если слой инвалидирован.

/root/.cache/go-build это кэш компилятора Go. Файлы, которые не изменились с прошлой сборки, не перекомпилируются. Именно это даёт наибольший выигрыш при инкрементальных изменениях кода.

Mount-кэш не попадает в финальный образ. Это не слой, а временная точка монтирования, которая существует только во время RUN. Размер образа не растёт, данные не утекают в прод.

В новых версиях Docker BuildKit включён по умолчанию. Если нет, то включить можно двумя способами:
# Переменная окружения
DOCKER_BUILDKIT=1 docker build .

# Или в /etc/docker/daemon.json
{ "features": { "buildkit": true } }


📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍121