diff --git a/Dockerfile b/Dockerfile index 3e23f2f..662302a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,39 @@ -# copy build result to a centos base image to match other -# crunchy containers -FROM centos:7 -RUN mkdir /app -ADD ./pg_tileserv /app/ -ADD ./assets /app/assets +ARG GOLANG_VERSION +ARG TARGETARCH +ARG VERSION +ARG BASE_REGISTRY +ARG BASE_IMAGE +ARG PLATFORM +FROM --platform=${PLATFORM} docker.io/library/golang:${GOLANG_VERSION}-alpine AS builder +LABEL stage=tileservbuilder +ARG TARGETARCH ARG VERSION -LABEL vendor="Crunchy Data" \ - url="https://crunchydata.com" \ - release="${VERSION}" \ - org.opencontainers.image.vendor="Crunchy Data" \ - os.version="7.7" +WORKDIR /app +COPY . ./ + +RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -v -ldflags "-s -w -X main.programVersion=${VERSION}" + +FROM --platform=${TARGETARCH} ${BASE_REGISTRY}/${BASE_IMAGE} AS multi-stage + +COPY --from=builder /app/pg_tileserv /app/ +COPY --from=builder /app/assets /app/assets + +VOLUME ["/config"] + +USER 1001 +EXPOSE 7800 + +WORKDIR /app +ENTRYPOINT ["/app/pg_tileserv"] +CMD [] + +FROM --platform=${PLATFORM} ${BASE_REGISTRY}/${BASE_IMAGE} AS local + +RUN mkdir /app +ADD ./pg_tileserv /app/ +ADD ./assets /app/assets VOLUME ["/config"] @@ -23,10 +45,10 @@ ENTRYPOINT ["/app/pg_tileserv"] CMD [] # To build -# make APPVERSION=1.0.2 clean build build-docker +# make APPVERSION=1.0.2 clean docker # To build using binaries from golang docker image -# make APPVERSION=1.0.2 clean bin-docker build-docker +# make APPVERSION=1.0.2 clean multi-stage-docker # To run # docker run -dt -e DATABASE_URL=postgres://user:pass@host/dbname -p 7800:7800 pramsey/pg_tileserv:1.0.2 diff --git a/Makefile b/Makefile index c36d39f..aa36065 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,40 @@ - -APPVERSION := latest -GOVERSION := 1.21 -PROGRAM := pg_tileserv -CONFIG := config/$(PROGRAM).toml -CONTAINER := pramsey/$(PROGRAM) -DATE := $(shell date +%Y%m%d) +##AVAILABLE BUILD OPTIONS - +## APPVERSION - Variable to set the version label +## GOVERSION - Defaults to 1.21.6 but can be overriden, uses alpine go container as base +## PROGRAM - Name of binary, pg_tileserv +## CONTAINER - prefix and name of the generated container +## CONFIG - config file to be used +## DATE - Date String used as alternate tag for generated containers +## BASE_REGISTRY - This is the registry to pull the base image from +## BASE_IMAGE - The base image to use for the final container +## TARGETARCH - The architecture the resulting image is based on and the binary is compiled for +## IMAGE_TAG - The container and tag to be applied to the container + +APPVERSION ?= latest +GOVERSION ?= 1.21.6 +PROGRAM ?= pg_tileserv +CONFIG ?= config/$(PROGRAM).toml +CONTAINER ?= pramsey/$(PROGRAM) +DATE ?= $(shell date +%Y%m%d) +BASE_REGISTRY ?= registry.access.redhat.com +BASE_IMAGE ?= ubi8-micro +SYSTEMARCH = $(shell uname -i) + +ifeq ($(SYSTEMARCH), x86_64) +TARGETARCH ?= amd64 +PLATFORM=amd64 +else +TARGETARCH ?= arm64 +PLATFORM=arm64 +endif + +IMAGE_TAG ?= $(CONTAINER):$(APPVERSION)-$(TARGETARCH) RM = /bin/rm CP = /bin/cp MKDIR = /bin/mkdir -.PHONY: bin-docker build-docker build check clean docs install release test uninstall +.PHONY: bin-docker bin-for-docker build build-docker check clean common-build docker docs install multi-stage-docker release set-local set-multi-stage test uninstall .DEFAULT_GOAL := help @@ -18,36 +42,69 @@ GOFILES := $(wildcard *.go) all: $(PROGRAM) -check: ## This checks the current version of Go installed locally +check: ## This checks the current version of Go installed locally @go version -clean: ## This will clean all local build artifacts +clean: ## This will clean all local build artifacts $(info Cleaning project...) @rm -f $(PROGRAM) @rm -rf docs/* - docker image prune --force + @docker image inspect $(CONTAINER):$(APPVERSION) >/dev/null 2>&1 && docker rmi -f $(CONTAINER):$(APPVERSION) $(CONTAINER):$(DATE) || echo -n "" -docs: ## Generate docs +docs: ## Generate docs @rm -rf docs/* && cd hugo && hugo && cd .. -build: $(GOFILES) ## Build a local binary using APPVERSION parameter or CI as default +build: $(PROGRAM) ## Build a local binary using APPVERSION parameter + +$(PROGRAM): $(GOFILES) go build -v -ldflags "-s -w -X main.programVersion=$(APPVERSION)" -bin-docker: ## Build a local binary based off of a golang base docker image +bin-docker: ## Build a local binary based off of a golang base docker image sudo docker run --rm -v "$(PWD)":/usr/src/myapp:z -w /usr/src/myapp golang:$(GOVERSION) make APPVERSION=$(APPVERSION) build -build-docker: $(PROGRAM) Dockerfile ## Generate a CentOS 7 container with APPVERSION tag, using binary from current environment - docker build -f Dockerfile --build-arg VERSION=$(APPVERSION) -t $(CONTAINER):$(APPVERSION) -t $(CONTAINER):$(DATE) . +bin-for-docker: $(GOFILES) ## Build a local binary using APPVERSION parameter or CI as default (to be used in docker image) +# to be used in docker the built binary needs the CGO_ENABLED=0 option + CGO_ENABLED=0 go build -v -ldflags "-s -w -X github.com/CrunchyData/pg_featureserv/conf.setVersion=$(APPVERSION)" + +build-common: Dockerfile + docker build -f Dockerfile \ + --target $(BUILDTYPE) \ + --build-arg VERSION=$(APPVERSION) \ + --build-arg GOLANG_VERSION=$(GOVERSION) \ + --build-arg TARGETARCH=$(TARGETARCH) \ + --build-arg PLATFORM=$(PLATFORM) \ + --build-arg BASE_REGISTRY=$(BASE_REGISTRY) \ + --build-arg BASE_IMAGE=$(BASE_IMAGE) \ + --label vendor="Crunchy Data" \ + --label url="https://crunchydata.com" \ + --label release="${APPVERSION}" \ + --label org.opencontainers.image.vendor="Crunchy Data" \ + --label os.version="7.7" \ + -t $(IMAGE_TAG) -t $(CONTAINER):$(DATE) . + docker image prune --filter label=stage=tileservbuilder -f + +set-local: + $(eval BUILDTYPE = local) + +set-multi-stage: + $(eval BUILDTYPE = multi-stage) -release: clean docs build build-docker ## Generate the docs, a local build, and then uses the local build to generate a CentOS 7 container +# This is just an alias to keep the existing targets available +docker-build: docker -test: ## Run the tests locally +docker: bin-for-docker Dockerfile set-local build-common ## Generate a BASE_IMAGE container with APPVERSION tag, using a locally built binary + +multi-stage-docker: Dockerfile set-multi-stage build-common ## Generate a BASE_IMAGE container with APPVERSION tag, using a binary built in an alpine golang build container + +release: clean docs docker ## Generate the docs, a local build, and then uses the local build to generate a BASE_IMAGE container + +test: ## Run the tests locally go test -v $(CONFIG): $(CONFIG).example sed 's/# AssetsPath/AssetsPath/' $< > $@ -install: $(PROGRAM) docs $(CONFIG) ## This will install the program locally +install: $(PROGRAM) docs $(CONFIG) ## This will install the program locally $(MKDIR) -p $(DESTDIR)/usr/bin $(MKDIR) -p $(DESTDIR)/usr/share/$(PROGRAM) $(MKDIR) -p $(DESTDIR)/etc @@ -56,14 +113,17 @@ install: $(PROGRAM) docs $(CONFIG) ## This will install the program local $(CP) -r assets $(DESTDIR)/usr/share/$(PROGRAM)/assets $(CP) -r docs $(DESTDIR)/usr/share/$(PROGRAM)/docs -uninstall: ## This will uninstall the program from your local system +uninstall: ## This will uninstall the program from your local system $(RM) $(DESTDIR)/usr/bin/$(PROGRAM) $(RM) $(DESTDIR)/etc/$(PROGRAM).toml $(RM) -r $(DESTDIR)/usr/share/$(PROGRAM) -help: ## Prints this help message +help: ## Prints this help message + @echo "" @echo "" + @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | fgrep -v : | sed -e 's/\\$$//' | sed -e 's/.*##//' @echo "" - @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/:.*##/:/' + @echo "BUILD TARGETS:" + @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | fgrep : | sed -e 's/\\$$//' | sed -e 's/:.*##/:/' @echo "" @echo ""