diff --git a/README.md b/README.md index 62be1d5..2242981 100644 --- a/README.md +++ b/README.md @@ -99,8 +99,10 @@ make docker print-config ## 🎯 Основные возможности ### Docker команды -- `make docker build` - сборка образов -- `make docker push` - публикация в registry +- `make docker build` - сборка образов (двойные теги `TAG1`/`TAG2`) +- `make docker rebuild` - пересборка без кэша (с `TAG1`/`TAG2`) +- `make docker pull` - скачивание/обновление образов по `TAG1`/`TAG2` +- `make docker push` - публикация в registry (оба тега) - `make docker save/load` - работа с архивами - `make docker check` - проверка образов @@ -141,10 +143,16 @@ Dockerfile/ ### Основные операции ```bash # Сборка образа -make docker build IMAGE=myapp TAG=v1.0.0 +make docker build IMAGE=myapp TAG1=latest TAG2=v1.0.0 # Публикация образа -make docker push IMAGE=myapp TAG=v1.0.0 +make docker push IMAGE=myapp TAG1=latest TAG2=v1.0.0 + +# Пересборка без кэша с двумя тегами +make docker rebuild IMAGE=myapp TAG1=latest TAG2=v1.0.0 + +# Скачать/обновить оба тега +make docker pull IMAGE=myapp TAG1=latest TAG2=v1.0.0 REGISTRY=hub.cism-ms.ru/library # Проверка образа make docker check RUN_CMD="lsb_release -a" diff --git a/docs/best-practices.md b/docs/best-practices.md index 999e883..c269051 100644 --- a/docs/best-practices.md +++ b/docs/best-practices.md @@ -4,32 +4,32 @@ ### Семантическое версионирование ```bash -# Основные версии -TAG=v1.0.0 # Стабильная версия -TAG=v1.1.0 # Новая функциональность -TAG=v1.1.1 # Исправления ошибок +# Основной и дополнительный тег (двойное тегирование) +TAG1=latest TAG2=v1.0.0 # Рекомендуемый минимум: стабильный alias + версия +TAG1=stable TAG2=v1.1.0 # Пример для стабильной ветки +TAG1=dev # Разработка без второго тега -# Предварительные версии -TAG=v1.2.0-alpha.1 -TAG=v1.2.0-beta.1 -TAG=v1.2.0-rc.1 +# Предрелизные версии +TAG1=rc TAG2=v1.2.0-rc.1 +TAG1=beta TAG2=v1.2.0-beta.1 +TAG1=alpha TAG2=v1.2.0-alpha.1 -# Специальные теги -TAG=latest # Последняя стабильная -TAG=dev # Разработка -TAG=stable # Стабильная ветка +# Специальные алиасы +TAG1=latest +TAG1=stable +TAG1=dev ``` ### Автоматическое версионирование ```bash # Использование Git commit hash -TAG=$(git rev-parse --short HEAD) +TAG1=$(git rev-parse --short HEAD) # Использование даты -TAG=$(date +%Y%m%d-%H%M%S) +TAG1=$(date +%Y%m%d-%H%M%S) # Использование Git тегов -TAG=$(git describe --tags --always) +TAG1=$(git describe --tags --always) ``` ## 2. Безопасность @@ -92,7 +92,7 @@ coverage # Создание логов с метаданными make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ BUILD_ARGS="--build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ LOG_DIR=./build-logs ``` @@ -116,21 +116,21 @@ docker run --rm -it \ ### Кэширование слоев Docker ```bash # Сборка с использованием кэша -make docker build IMAGE=myapp TAG=v1.0.0 +make docker build IMAGE=myapp TAG1=v1.0.0 # Сборка без кэша (для чистых сборок) -make docker build IMAGE=myapp TAG=v1.0.0 NO_CACHE=1 +make docker rebuild IMAGE=myapp TAG1=v1.0.0 # Принудительное обновление базовых образов -make docker build IMAGE=myapp TAG=v1.0.0 PULL=1 +make docker build IMAGE=myapp TAG1=v1.0.0 PULL=1 ``` ### Параллельная сборка ```bash # Сборка нескольких образов параллельно -make docker build IMAGE=frontend TAG=v1.0.0 & -make docker build IMAGE=backend TAG=v1.0.0 & -make docker build IMAGE=worker TAG=v1.0.0 & +make docker build IMAGE=frontend TAG1=v1.0.0 & +make docker build IMAGE=backend TAG1=v1.0.0 & +make docker build IMAGE=worker TAG1=v1.0.0 & wait # Проверка результатов @@ -142,7 +142,7 @@ docker images | grep -E "(frontend|backend|worker)" # Сборка с минимальным размером make docker build \ IMAGE=myapp \ - TAG=minimal \ + TAG1=minimal \ BUILD_ARGS="--build-arg BUILDKIT_INLINE_CACHE=1" # Сжатие образов @@ -158,13 +158,13 @@ make docker save \ # Сборка базового образа make docker build \ IMAGE=base-image \ - TAG=ubuntu-22.04 \ + TAG1=ubuntu-22.04 \ DOCKERFILE=Dockerfile.base # Использование базового образа make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ BUILD_ARGS="--build-arg BASE_IMAGE=base-image:ubuntu-22.04" ``` @@ -173,7 +173,7 @@ make docker build \ # Обновление базовых образов make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ PULL=1 # Проверка обновлений @@ -211,10 +211,10 @@ docker run -it --rm \ ### Измерение времени сборки ```bash # Время сборки -time make docker build IMAGE=myapp TAG=v1.0.0 +time make docker build IMAGE=myapp TAG1=v1.0.0 # Детальная статистика -make docker build IMAGE=myapp TAG=v1.0.0 2>&1 | tee build.log +make docker build IMAGE=myapp TAG1=v1.0.0 2>&1 | tee build.log ``` ### Мониторинг ресурсов @@ -253,7 +253,7 @@ project/ cat > Makefile.local << EOF REGISTRY=my-registry.com IMAGE=my-project -TAG=dev +TAG1=dev NO_CACHE=0 QUIET=0 EOF diff --git a/docs/examples.md b/docs/examples.md index 046b187..3076a62 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -4,26 +4,26 @@ ### Простая сборка ```bash -# Сборка с минимальными параметрами -make docker build IMAGE=myapp TAG=latest +# Сборка с двойными тегами +make docker build IMAGE=myapp TAG1=latest TAG2=v1.0.0 # Сборка с кастомным registry make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=latest TAG2=v1.0.0 \ REGISTRY=hub.cism-ms.ru/library # Сборка с проверкой -make docker build IMAGE=myapp TAG=v1.0.0 +make docker build IMAGE=myapp TAG1=latest TAG2=v1.0.0 make docker check RUN_CMD="lsb_release -a" ``` ### Полный цикл сборки и публикации ```bash -# 1. Сборка образа +# 1. Сборка образа (двойные теги) make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=latest TAG2=v1.0.0 \ REGISTRY=hub.cism-ms.ru/library # 2. Проверка работоспособности @@ -33,7 +33,7 @@ make docker check \ # 3. Публикация в registry make docker push \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=latest TAG2=v1.0.0 \ REGISTRY=hub.cism-ms.ru/library ``` @@ -56,7 +56,7 @@ docker buildx inspect --bootstrap # Сборка для AMD64 и ARM64 make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=latest TAG2=v1.0.0 \ USE_BUILDX=1 \ PLATFORMS="linux/amd64,linux/arm64" \ PUSH=1 \ @@ -65,7 +65,7 @@ make docker build \ # Сборка для всех популярных платформ make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=latest TAG2=v1.0.0 \ USE_BUILDX=1 \ PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7" \ PUSH=1 @@ -106,7 +106,7 @@ make docker load \ ARCHIVE=images/myapp_v1.0.0.tar.gz \ REGISTRY=hub.cism-ms.ru/library \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ LOGIN=1 \ PUSH_OFFLINE=1 @@ -125,13 +125,13 @@ make docker load \ # Передача переменных окружения make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ BUILD_ARGS="--build-arg VERSION=1.0.0 --build-arg NODE_ENV=production" # Передача пользовательских данных make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ BUILD_ARGS="--build-arg USER_ID=1000 --build-arg GROUP_ID=1000" ``` @@ -279,13 +279,13 @@ make docker check RUN_CMD="env | grep -E 'VERSION|NODE_ENV'" # Сборка с Dockerfile.prod make docker build \ IMAGE=myapp \ - TAG=production \ + TAG1=production \ DOCKERFILE=Dockerfile.prod # Сборка с контекстом в подпапке make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ CONTEXT=./app ``` @@ -294,31 +294,37 @@ make docker build \ # Сборка для локального registry make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ REGISTRY=localhost:5000 # Сборка для Docker Hub make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ REGISTRY=myusername # Сборка для GitLab Registry make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ REGISTRY=registry.gitlab.com/myproject ``` ### Управление тегами ```bash -# Перетегирование образа +# Перетегирование образа (локально) make docker retag NEW_TAG=v2.0.0 # Создание нескольких тегов make docker retag NEW_TAG=latest make docker retag NEW_TAG=stable make docker retag NEW_TAG=2024.01.15 + +# Пулл обоих тегов +make docker pull IMAGE=myapp TAG1=latest TAG2=v2.0.0 REGISTRY=hub.cism-ms.ru/library + +# Пересборка без кэша с двумя тегами +make docker rebuild IMAGE=myapp TAG1=latest TAG2=v2.0.0 ``` ## 9. Очистка и обслуживание diff --git a/docs/faq.md b/docs/faq.md index d0e540d..e1f2eb4 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -6,10 +6,10 @@ **A:** Установите WSL2 или используйте Git Bash: ```bash # В Git Bash -make docker build IMAGE=myapp TAG=latest +make docker build IMAGE=myapp TAG1=latest TAG2=v1.0.0 # Или через WSL2 -wsl make docker build IMAGE=myapp TAG=latest +wsl make docker build IMAGE=myapp TAG1=latest TAG2=v1.0.0 ``` ### Q: Можно ли использовать с Docker Compose? @@ -30,14 +30,14 @@ services: ```bash # .git/hooks/post-commit #!/bin/bash -make docker build IMAGE=myapp TAG=$(git rev-parse --short HEAD) +make docker build IMAGE=myapp TAG1=$(git rev-parse --short HEAD) ``` ### Q: Можно ли использовать с Kubernetes? **A:** Да, после сборки образа: ```bash # Сборка образа -make docker build IMAGE=myapp TAG=v1.0.0 +make docker build IMAGE=myapp TAG1=v1.0.0 # Применение в Kubernetes kubectl apply -f k8s/ @@ -47,7 +47,7 @@ kubectl apply -f k8s/ **A:** Используйте кэширование и .dockerignore: ```bash # Сборка с кэшем -make docker build IMAGE=myapp TAG=v1.0.0 +make docker build IMAGE=myapp TAG1=v1.0.0 # Создание .dockerignore echo "node_modules" >> .dockerignore @@ -86,7 +86,7 @@ make docker push IMAGE=myapp TAG=v1.0.0 REGISTRY=your-private-registry.com # Сборка для ARM64 make docker build \ IMAGE=myapp \ - TAG=v1.0.0 \ + TAG1=v1.0.0 \ USE_BUILDX=1 \ PLATFORMS=linux/arm64 ``` diff --git a/docs/makefile.md b/docs/makefile.md index a279cfe..d21e81a 100644 --- a/docs/makefile.md +++ b/docs/makefile.md @@ -6,9 +6,11 @@ | Команда | Описание | Пример | |---------|----------|--------| -| `make docker build` | Собрать Docker-образ | `make docker build IMAGE=myapp TAG=v1.0` | +| `make docker build` | Собрать Docker-образ (двойные теги) | `make docker build IMAGE=myapp TAG1=latest TAG2=v1.0` | | `make docker check` | Проверить образ | `make docker check RUN_CMD="java -version"` | -| `make docker push` | Собрать + проверить + отправить | `make docker push IMAGE=myapp TAG=v1.0` | +| `make docker push` | Собрать + проверить + отправить (оба тега) | `make docker push IMAGE=myapp TAG1=latest TAG2=v1.0` | +| `make docker rebuild` | Пересобрать без кэша (оба тега) | `make docker rebuild IMAGE=myapp TAG1=latest TAG2=v1.0` | +| `make docker pull` | Скачать/обновить образы по тегам | `make docker pull IMAGE=myapp TAG1=latest TAG2=v1.0` | | `make docker save` | Сохранить образ в архив | `make docker save SRC_IMAGE=myapp:latest` | | `make docker load` | Загрузить из архива | `make docker load ARCHIVE=images/myapp.tar` | | `make docker login` | Авторизация в registry | `make docker login REGISTRY=hub.cism-ms.ru` | @@ -50,15 +52,14 @@ IMAGE=web-frontend IMAGE=api-backend ``` -#### TAG -**Описание:** Тег образа -**По умолчанию:** `latest` +#### TAG1 / TAG2 +**Описание:** Основной и дополнительный тег образа (двойное тегирование) +**По умолчанию:** `TAG1=latest`, `TAG2=v.0.0.1` **Примеры:** ```bash -TAG=latest -TAG=v1.0.0 -TAG=dev -TAG=2024.01.15 +TAG1=latest TAG2=v1.0.0 +TAG1=stable TAG2=v1.0.1 +TAG1=dev # без второго тега ``` #### CONTEXT @@ -344,13 +345,16 @@ GIT_MSG="Обновлены зависимости" ### Служебные переменные -#### FULL_IMAGE -**Описание:** Полное имя образа REGISTRY/IMAGE:TAG -**Формируется автоматически:** `$(REGISTRY)/$(IMAGE):$(TAG)` +#### FULL_IMAGE / FULL_IMAGE_1 / FULL_IMAGE_2 +**Описание:** Полные имена образов +**Формируется автоматически:** +- `FULL_IMAGE` = `$(REGISTRY)/$(IMAGE):$(TAG1)` +- `FULL_IMAGE_1` = `$(REGISTRY)/$(IMAGE):$(TAG1)` +- `FULL_IMAGE_2` = `$(REGISTRY)/$(IMAGE):$(TAG2)` **Примеры:** ```bash -FULL_IMAGE=hub.cism-ms.ru/library/myapp:latest -FULL_IMAGE=registry.local/myapp:v1.0.0 +FULL_IMAGE_1=hub.cism-ms.ru/library/myapp:latest +FULL_IMAGE_2=hub.cism-ms.ru/library/myapp:v1.0.0 ``` #### Цвета вывода diff --git a/makefile b/makefile index 822dec1..991b93f 100644 --- a/makefile +++ b/makefile @@ -10,10 +10,13 @@ # ---- Предустановленные значения под вашу сборку ---- REGISTRY ?= hub.cism-ms.ru/library IMAGE ?= -TAG ?= latest CONTEXT ?= . DOCKERFILE ?= Dockerfile +# Теги образа (двойная маркировка) +TAG1 ?= latest +TAG2 ?= v.0.0.1 + # ---- Режимы сборки ---- USE_BUILDX ?= 0 # 1 -> использовать docker buildx PLATFORMS ?= linux/amd64 # например: linux/amd64,linux/arm64 @@ -66,11 +69,23 @@ SPLIT_SIZE ?= # размер чанка, напр.: 2G (п # ---- Полное имя образа ---- ifneq ($(strip $(REGISTRY)),) - FULL_IMAGE := $(REGISTRY)/$(IMAGE):$(TAG) + FULL_IMAGE := $(REGISTRY)/$(IMAGE):$(TAG1) else - FULL_IMAGE := $(IMAGE):$(TAG) + FULL_IMAGE := $(IMAGE):$(TAG1) endif +# Полные имена образов для двойного тегирования +ifneq ($(strip $(REGISTRY)),) + FULL_IMAGE_1 := $(REGISTRY)/$(IMAGE):$(TAG1) + FULL_IMAGE_2 := $(REGISTRY)/$(IMAGE):$(TAG2) +else + FULL_IMAGE_1 := $(IMAGE):$(TAG1) + FULL_IMAGE_2 := $(IMAGE):$(TAG2) +endif + +# Флаги тегов для docker build (-t tag1 [-t tag2]) +TAGS_FLAGS := -t "$(FULL_IMAGE_1)" $(if $(strip $(TAG2)),-t "$(FULL_IMAGE_2)",) + # ---- Цвета ---- COLOR_RESET := \033[0m COLOR_INFO := \033[1;34m @@ -114,16 +129,18 @@ help: @echo " make git [status|pull|commit|push|sync]" @echo "" @echo "Key vars (override via make VAR=value):" - @echo " REGISTRY=$(REGISTRY) IMAGE=$(IMAGE) TAG=$(TAG) CONTEXT=$(CONTEXT) DOCKERFILE=$(DOCKERFILE)" + @echo " REGISTRY=$(REGISTRY) IMAGE=$(IMAGE) TAG1=$(TAG1) TAG2=$(TAG2) CONTEXT=$(CONTEXT) DOCKERFILE=$(DOCKERFILE)" @echo " USE_BUILDX=$(USE_BUILDX) PLATFORMS=$(PLATFORMS) PUSH=$(PUSH) LOAD=$(LOAD) NO_CACHE=$(NO_CACHE) PULL=$(PULL) QUIET=$(QUIET)" @echo " BUILD_ARGS=$(BUILD_ARGS) ARG_FILE=$(ARG_FILE) RUN_CMD=$(RUN_CMD)" @echo " ARCHIVE=$(ARCHIVE) LOGIN=$(LOGIN) PUSH_OFFLINE=$(PUSH_OFFLINE) KEEP_SRC_TAG=$(KEEP_SRC_TAG)" @echo " IMAGES_DIR=$(IMAGES_DIR)" @echo "" @echo "Examples:" - @echo " make docker build IMAGE=myapp TAG=1.0.0" - @echo " make docker push REGISTRY=registry.local/library IMAGE=myapp TAG=1.0.0" - @echo " make docker save IMAGE=myapp TAG=1.0.0 COMPRESS=1" + @echo " make docker build IMAGE=myapp TAG1=latest TAG2=v0.0.1" + @echo " make docker rebuild IMAGE=myapp TAG1=latest TAG2=v0.0.1" + @echo " make docker push REGISTRY=registry.local/library IMAGE=myapp TAG1=latest TAG2=v0.0.1" + @echo " make docker pull REGISTRY=registry.local/library IMAGE=myapp TAG1=latest TAG2=v0.0.1" + @echo " make docker save IMAGE=myapp TAG1=latest COMPRESS=1" @echo " make docker load ARCHIVE=images/myapp_1.0.0.tar.gz LOGIN=1 PUSH_OFFLINE=1" @echo " make git commit # спросит сообщение" @echo " make git push # commit+push с запросом сообщения" @@ -146,26 +163,29 @@ $(OFFLINE_DIR): # Внутренние цели (не вызывать напрямую) .PHONY: __docker_build __docker_check __docker_push __docker_login __docker_retag __docker_save __docker_load __docker_load_raw __docker_inspect __docker_create_builder __docker_use_builder __docker_clean __docker_print_config +# Доп. внутренние цели +.PHONY: __docker_pull __docker_rebuild + # --- Команды сборки --- define DOCKER_BUILD_CLASSIC - docker build $(CACHE_FLAG) $(PULL_FLAG) $(QUIET_FLAG) \ - -f $(DOCKERFILE) -t "$(FULL_IMAGE)" \ - $(BUILD_ARGS) $(ARG_FILE_FLAGS) \ - "$(CONTEXT)" + docker build $(CACHE_FLAG) $(PULL_FLAG) $(QUIET_FLAG) \ + -f $(DOCKERFILE) $(TAGS_FLAGS) \ + $(BUILD_ARGS) $(ARG_FILE_FLAGS) \ + "$(CONTEXT)" endef define DOCKER_BUILD_BUILDX - docker buildx build $(CACHE_FLAG) $(PULL_FLAG) $(QUIET_FLAG) \ - $(if $(filter 1,$(PUSH)),--push,) \ - $(if $(filter 1,$(LOAD)),--load,) \ - --platform $(PLATFORMS) \ - -f $(DOCKERFILE) -t "$(FULL_IMAGE)" \ - $(BUILD_ARGS) $(ARG_FILE_FLAGS) \ - "$(CONTEXT)" + docker buildx build $(CACHE_FLAG) $(PULL_FLAG) $(QUIET_FLAG) \ + $(if $(filter 1,$(PUSH)),--push,) \ + $(if $(filter 1,$(LOAD)),--load,) \ + --platform $(PLATFORMS) \ + -f $(DOCKERFILE) $(TAGS_FLAGS) \ + $(BUILD_ARGS) $(ARG_FILE_FLAGS) \ + "$(CONTEXT)" endef __docker_build: $(LOG_DIR) - @echo "$(COLOR_INFO)[INFO] Build: $(FULL_IMAGE)$(COLOR_RESET)" + @echo "$(COLOR_INFO)[INFO] Build: $(FULL_IMAGE_1)$(COLOR_RESET)" @echo "$(COLOR_INFO)[INFO] Log: $(LOG_FILE)$(COLOR_RESET)" @{ \ echo "=== Build started: $$(date) ==="; \ @@ -178,20 +198,40 @@ __docker_build: $(LOG_DIR) } | tee $(LOG_FILE) @echo "$(COLOR_OK)[OK] Build success$(COLOR_RESET)" +# Пересборка без кэша (использует двойные теги TAG1/TAG2) +__docker_rebuild: + @$(MAKE) __docker_build NO_CACHE=1 + __docker_check: - @echo "$(COLOR_INFO)[INFO] Check (RUN_CMD) for $(FULL_IMAGE): $(RUN_CMD)$(COLOR_RESET)" - @docker run --rm --entrypoint /bin/sh "$(FULL_IMAGE)" -lc "$(RUN_CMD)" + @echo "$(COLOR_INFO)[INFO] Check (RUN_CMD) for $(FULL_IMAGE_1): $(RUN_CMD)$(COLOR_RESET)" + @docker run --rm --entrypoint /bin/sh "$(FULL_IMAGE_1)" -lc "$(RUN_CMD)" __docker_push: @if [ "$(USE_BUILDX)" != "1" ]; then \ - echo "$(COLOR_INFO)[INFO] Pushing: $(FULL_IMAGE)$(COLOR_RESET)"; \ - docker push "$(FULL_IMAGE)"; \ + echo "$(COLOR_INFO)[INFO] Pushing: $(FULL_IMAGE_1)$(COLOR_RESET)"; \ + docker push "$(FULL_IMAGE_1)"; \ + if [ -n "$(TAG2)" ]; then \ + echo "$(COLOR_INFO)[INFO] Pushing: $(FULL_IMAGE_2)$(COLOR_RESET)"; \ + docker push "$(FULL_IMAGE_2)"; \ + fi; \ else \ - echo "$(COLOR_WARN)[WARN] USE_BUILDX=1: push выполняется при buildx (PUSH=1).$(COLOR_RESET)"; \ - echo "$(COLOR_WARN)[WARN] Пересоберите с PUSH=1 или выполните docker push вручную.$(COLOR_RESET)"; \ + echo "$(COLOR_WARN)[WARN] USE_BUILDX=1: push выполняется при buildx (PUSH=1).$(COLOR_RESET)"; \ + echo "$(COLOR_WARN)[WARN] Пересоберите с PUSH=1 или выполните docker push вручную.$(COLOR_RESET)"; \ fi @echo "$(COLOR_OK)[OK] Push done$(COLOR_RESET)" +# Загрузка/обновление образов (тянет оба тега при наличии TAG2) +__docker_pull: + @if [ -z "$(IMAGE)" ]; then \ + echo "$(COLOR_ERR)[ERR] Укажи IMAGE: make docker pull IMAGE=myapp [REGISTRY=... TAG1=... TAG2=...]$(COLOR_RESET)"; \ + exit 1; \ + fi + @echo "$(COLOR_INFO)[INFO] Pull: $(FULL_IMAGE_1)$(COLOR_RESET)"; docker pull "$(FULL_IMAGE_1)" || true + @if [ -n "$(TAG2)" ]; then \ + echo "$(COLOR_INFO)[INFO] Pull: $(FULL_IMAGE_2)$(COLOR_RESET)"; docker pull "$(FULL_IMAGE_2)" || true; \ + fi + @echo "$(COLOR_OK)[OK] Pull done$(COLOR_RESET)" + __docker_login: @if [ -z "$(REGISTRY)" ]; then \ echo "$(COLOR_ERR)[ERR] REGISTRY не задан. Пример: make docker login REGISTRY=registry.local$(COLOR_RESET)"; \ @@ -212,7 +252,7 @@ __docker_retag: __docker_save: | $(IMAGES_DIR) $(OFFLINE_DIR) @src="$(SRC_IMAGE)"; \ if [ -z "$$src" ]; then \ - if [ -n "$(IMAGE)" ]; then src="$(FULL_IMAGE)"; else echo "$(COLOR_ERR)[ERR] Укажи SRC_IMAGE или IMAGE/TAG$(COLOR_RESET)"; exit 1; fi; \ + if [ -n "$(IMAGE)" ]; then src="$(FULL_IMAGE)"; else echo "$(COLOR_ERR)[ERR] Укажи SRC_IMAGE или IMAGE:TAG1$(COLOR_RESET)"; exit 1; fi; \ fi; \ docker image inspect "$$src" >/dev/null 2>&1 || { echo "$(COLOR_ERR)[ERR] Образ не найден: $$src$(COLOR_RESET)"; exit 1; }; \ safe="$${src//\//_}"; safe="$${safe//:/_}"; out="$(IMAGES_DIR)/$$safe.tar"; \ @@ -248,14 +288,14 @@ __docker_load: | $(OFFLINE_DIR) @awk '/Loaded image:/ { last=$$0 } END { gsub(/^.*Loaded image: /,"",last); print last }' "$(LOAD_LOG)" > "$(SRC_FILE)" @src="$$(cat "$(SRC_FILE)" 2>/dev/null || true)"; \ if [ -z "$$src" ]; then \ - echo "$(COLOR_ERR)[ERR] Не удалось определить repo:tag из docker load. Укажи IMAGE/TAG вручную.$(COLOR_RESET)"; \ + echo "$(COLOR_ERR)[ERR] Не удалось определить repo:tag из docker load. Укажи IMAGE:TAG вручную.$(COLOR_RESET)"; \ exit 1; \ fi; \ echo "$(COLOR_OK)[OK] Загружен исходный образ: $$src$(COLOR_RESET)"; \ repo="$${src%:*}"; srctag="$${src#*:}"; [ "$$repo" = "$$srctag" ] && srctag="latest"; \ src_name="$${repo##*/}"; \ dst_image="$(IMAGE)"; [ -z "$$dst_image" ] && dst_image="$$src_name"; \ - if [ -z "$(IMAGE)" ] && [ "$(KEEP_SRC_TAG)" = "1" ]; then dst_tag="$$srctag"; else dst_tag="$(TAG)"; fi; \ + if [ -z "$(IMAGE)" ] && [ "$(KEEP_SRC_TAG)" = "1" ]; then dst_tag="$$srctag"; else dst_tag="$(TAG1)"; fi; \ if [ -z "$(REGISTRY)" ]; then echo "$(COLOR_ERR)[ERR] REGISTRY пуст$(COLOR_RESET)"; exit 1; fi; \ full_dst="$(REGISTRY)/$$dst_image:$$dst_tag"; echo "$$full_dst" > "$(DST_FILE)"; \ echo "$(COLOR_INFO)[INFO] Тегируем: $$src -> $$full_dst$(COLOR_RESET)"; \ @@ -264,7 +304,7 @@ __docker_load: | $(OFFLINE_DIR) if [ "$(PUSH_OFFLINE)" = "1" ]; then echo "$(COLOR_INFO)[INFO] docker push $$full_dst$(COLOR_RESET)"; docker push "$$full_dst"; echo "$(COLOR_OK)[OK] Пуш завершён$(COLOR_RESET)"; else echo "$(COLOR_WARN)[WARN] PUSH_OFFLINE=0: пуш пропущен$(COLOR_RESET)"; fi __docker_inspect: - @docker image inspect "$(FULL_IMAGE)" || true + @docker image inspect "$(FULL_IMAGE_1)" || true __docker_create_builder: @docker buildx create --name $(BUILDER) --use --bootstrap || docker buildx use $(BUILDER) @@ -284,7 +324,8 @@ __docker_print_config: @echo "FULL_IMAGE : $(FULL_IMAGE)" @echo "REGISTRY : $(REGISTRY)" @echo "IMAGE : $(IMAGE)" - @echo "TAG : $(TAG)" + @echo "TAG1 : $(TAG1)" + @echo "TAG2 : $(TAG2)" @echo "CONTEXT : $(CONTEXT)" @echo "DOCKERFILE : $(DOCKERFILE)" @echo "USE_BUILDX : $(USE_BUILDX)" @@ -309,8 +350,10 @@ docker: @sub="$(word 2,$(MAKECMDGOALS))"; \ case "$$sub" in \ build) $(MAKE) __docker_build ;; \ +rebuild) $(MAKE) __docker_rebuild ;; \ check) $(MAKE) __docker_check ;; \ push) $(MAKE) __docker_build __docker_check __docker_push ;; \ +pull) $(MAKE) __docker_pull ;; \ save) $(MAKE) __docker_save ;; \ load) $(MAKE) __docker_load ;; \ load-raw) $(MAKE) __docker_load_raw ;; \ @@ -323,9 +366,11 @@ docker: print-config) $(MAKE) __docker_print_config ;; \ "") \ echo "$(COLOR_INFO)[INFO] Docker commands:$(COLOR_RESET)"; \ - echo " make docker build — собрать образ"; \ + echo " make docker build — собрать образ (два тега TAG1/TAG2)"; \ + echo " make docker rebuild — пересобрать без кэша (TAG1/TAG2)"; \ echo " make docker check — проверить контейнер (RUN_CMD)"; \ - echo " make docker push — build + check + push"; \ + echo " make docker push — build + check + push (TAG1/TAG2)"; \ + echo " make docker pull — скачать/обновить образы по TAG1/TAG2"; \ echo " make docker save — сохранить образ в ./images/"; \ echo " make docker load — загрузить из архива и (опц.) запушить"; \ echo " make docker load-raw — чистый docker load -i FILE"; \