# Container base name
NAME := echo
# Image tag
TAG := latest
# Image repo prefix to use for "push"
IMGREPO := tangentsoft
# Versioned names to shorten commands below
VDNAME := $(NAME)-$(TAG)
LVINAME := $(NAME):$(TAG)
RVINAME := $(IMGREPO)/$(LVINAME)
MACHINE := $(shell uname -m)
# Container engine to use; "podman" also works here.
CENGINE := docker
# The list of platforms we build the container for. It should cover 99%
# of all practical use cases.
PLATFORMS := x86_64 i386 arm arm64
TARBALLS := $(addprefix $(VDNAME)-, $(addsuffix .tar,$(PLATFORMS)))
# Create OCI image in build cache and export it to a tarball.
all: $(TARBALLS)
$(TARBALLS): Dockerfile Makefile echo.c
p=$$(echo $@ | cut -f3 -d- | cut -f1 -d.) ; t=$$(mktemp) \
&& $(CENGINE) build \
--platform linux/$$p \
--tag $(NAME):$$p \
$(DBFLAGS) . \
&& $(CENGINE) image save -o $@ $(NAME):$$p \
&& skopeo copy docker-archive:$@ docker-archive:$$t \
&& mv $$t $@
# Remove build outputs
clean:
@-rm -f $(TARBALLS)
@-for p in $(PLATFORMS) ; do \
$(CENGINE) image rm $(NAME):$$p ; \
$(CENGINE) image rm $(RVINAME)-$$p ; \
done
@-$(CENGINE) manifest rm $(RVINAME)
# Build an OCI manifest for the tarballs and push the bundle
push: all
for p in $(PLATFORMS) ; do \
t=$(IMGREPO)/$(LVINAME)-$$p ; \
docker tag $(NAME):$$p $$t && \
docker push $$t ; \
done
-$(CENGINE) manifest rm $(RVINAME)
$(CENGINE) manifest create $(RVINAME) \
$(addprefix $(IMGREPO)/$(NAME):$(TAG)-,$(PLATFORMS))
$(CENGINE) manifest push $(RVINAME)
$(CENGINE) pull $(RVINAME)
$(CENGINE) tag $(RVINAME) $(IMGREPO)/$(NAME):latest
$(CENGINE) push $(IMGREPO)/$(NAME):latest
# Run the native version of the built container locally, for testing
run: $(VDNAME)-$(MACHINE).tar
$(MAKE) PLATFORMS=$(MACHINE) && \
$(CENGINE) run $(DRFLAGS) \
--rm \
--tty \
--interactive \
$(NAME):$(MACHINE) $(EPFLAGS)