Using a Makefile to Automate Deployments
The two routine tasks in operating a Zend Enterprise Web Platform deployment — building and pushing application images and deploying the chart — both involve long command lines with several flags. Capturing them as Makefile targets turns each into a short, memorable command such as make build-app1 or make deploy, reduces typing errors, and gives your team a single, version-controlled source of truth for how images are built and how the platform is deployed.
This section provides ready-to-adapt Makefile targets for both tasks.
For creating application images
A Makefile is the recommended way to build and tag your PHP application images consistently. The pattern below defines variables for the registry and tag (defaulting the tag to the current date), provides colored output helpers, and exposes a self-documenting help target.
#!make
########################## Variables #####################
HERE := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
SHELL := /bin/bash
TAG := $(shell date +%Y-%m-%d)
CR := cr.example.com/prod
ARCH := linux/amd64
##########################################################
############################### Colors ################################
# Call these using the construct @$(call {VAR},"text to display")
MK_GREEN = echo -e "\e[32m"$(1)"\e[0m"
MK_BLUE = echo -e "\e[34m"$(1)"\e[0m"
MK_CYAN = echo -e "\e[36m"$(1)"\e[0m"
# Semantic names
MK_INFO = $(call MK_BLUE,$1)
MK_SUCCESS = $(call MK_GREEN,$1)
######################################################################
.PHONY: help build-app1
default: help
##@ Help
help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[0-9a-zA-Z_-]+:.*?##/ { printf " \033[36m%-40s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
##@ Container Build Tasks
build-app1: ## Build and push application 1
@$(call MK_INFO,"Building php container for application 1")
docker buildx build --platform $(ARCH) --no-cache -f Dockerfile \
-t "$(CR)/app1:$(TAG)" -t $(CR)/app1:latest \
--build-arg "ARG_NAME=ARG_VALUE" --push .
@$(call MK_SUCCESS,"[DONE] Built php container for application 1 ($(CR)/app1:$(TAG))")
Add as many --build-arg declarations as you need for the Dockerfile build arguments (OS, OS_VERSION, ZENDPHP_VERSION, and so on), or declare those defaults entirely within the Dockerfile itself. Add one build-* target per application.
Usage
# Build "latest" plus a tag named after today's date (the default TAG):
make build-app1
# Build with an explicit tag:
make build-app1 TAG=testing
# Build for a different registry:
make build-app1 CR=private.registry/prod
# Build an ARM image (e.g. to run on an Apple-silicon Mac):
make build-app1 ARCH=linux/aarch64
Because the variables (TAG, CR, ARCH) are overridable on the command line, the same target serves local testing, ARM builds, and production pushes without editing the Makefile.
For deploying your chart
The same approach turns the helm upgrade --install workflow into a one-word command. Because helm upgrade --install both installs and upgrades, a single deploy target works for first deployments and every subsequent change.
Add the following variables and targets to your Makefile:
##########################################################
# Deployment variables
RELEASE := my-release
NAMESPACE := prod
CHART := oci://cr.zend.com/charts/platform/umbrella
VERSION := 1.2.3
# Space-separated list of values override files, in load order
VALUES := 00-infra.values.yaml 01-app1.values.yaml 02-app2.values.yaml
##########################################################
.PHONY: deploy history rollback status uninstall
##@ Deployment Tasks
deploy: ## Install or upgrade the platform release
@$(call MK_INFO,"Deploying $(RELEASE) to namespace $(NAMESPACE)...")
helm upgrade --install \
-n $(NAMESPACE) --create-namespace \
--timeout 10m0s \
$(RELEASE) $(CHART) --version $(VERSION) \
$(addprefix -f ,$(VALUES))
@$(call MK_SUCCESS,"[DONE] Deployed $(RELEASE)")
status: ## Show release status and pod state
helm status $(RELEASE) -n $(NAMESPACE)
kubectl -n $(NAMESPACE) get pods
history: ## Show Helm revision history for the release
helm history $(RELEASE) -n $(NAMESPACE)
rollback: ## Roll back to a revision: make rollback REV=<n>
@$(call MK_INFO,"Rolling back $(RELEASE) to revision $(REV)...")
helm rollback $(RELEASE) $(REV) -n $(NAMESPACE)
@$(call MK_SUCCESS,"[DONE] Rolled back $(RELEASE) to revision $(REV)")
uninstall: ## Uninstall the release
helm uninstall $(RELEASE) -n $(NAMESPACE)
The key trick is $(addprefix -f ,$(VALUES)), which expands your space-separated VALUES list into the repeated -f file1 -f file2 ... arguments Helm expects, in order.
Usage
# Install or upgrade (same command for both):
make deploy
# Deploy a different chart version:
make deploy VERSION=1.3.0
# Inspect what's deployed:
make status
make history
# Roll back to revision 3:
make rollback REV=3
# Tear it down:
make uninstall
Keep the Makefile, your values override files, and (if you consume the chart locally) your Chart.yaml together in version control. Combined with bumping the chart VERSION per change, this gives you a reviewable, reproducible deployment history — and makes the make history / make rollback REV=<n> pair a reliable recovery path.