Skip to content

Instantly share code, notes, and snippets.

@denzuko
Last active September 5, 2019 15:13
Show Gist options
  • Save denzuko/249370806b170257de0ad7699ae7b8b4 to your computer and use it in GitHub Desktop.
Save denzuko/249370806b170257de0ad7699ae7b8b4 to your computer and use it in GitHub Desktop.
Basecamp for Go apps

Codebase for Go applications with docker based work flow

Born out of the need to deploy function to a heterogeneous serverless cluster via raspberry pi and other commondity off the shelf hardware.

This Repo helps one get started to build and deploy applications, serverless functions, and/or restful apis. If one can write it in go then exeute it securely via docker. The end docker image is based on scratch and would contain a multi-arch image with just the application that has full multi arch and multi os support is baked in.

Dependancies

  • docker
  • docker hub account
  • good ide (e.g. vim/emacs)
  • gnu make
  • knowledge of Go

Usage

Drop these three files into your project folder and use make to build/test/exec go commands

make all - Builds linux arm and amd64 versions of application and bundles a multi arch docker image make EXEC=... gocmd - pass values to go via EXEC='...' to run go command (e.g. make EXEC="run main.go" gocmd) make docs - Runs godoc on port 6060, open/xdg-open/start/pipe http://localhost:6060 to read make test - Run unit tests with code coverage output make release - Builds all images defined with IMAGES='...' then pushes to docker hub (defaults to linux-armv7 and linux-amd64)

Roadmap

  • Support label-schema.org/rc1
  • Support matrix.dapla.net/schema
  • Add matrix.dapla.net/stack.yml
  • bundle for python cookiecutter (or nodejs/go equivalents)
FROM golang:1.13-alpine as base
ARG GOOS=linux
ARG GOARCH=amd64
ARG GOARM
ENV GOARCH=$GOARCH
ENV GOOS=$GOOS
ENV GOARM=$GOARM
ENV CGO_ENABLED=0
WORKDIR /app
COPY . /app
RUN apk add --update --no-cache ca-certificates git tzdata && \
adduser -S -D -H svcrunner && \
go get -d -v . && \
go mod download && \
go mod verify
FROM base as test
RUN go test -coverage ./...
FROM base as builder
RUN go build -a -ldflags='-w -s' -o build/service .
FROM scratch
ENV TZ=Etc/UTC
ENV LANG=en_US.utf8
ENV LC_LANG=en_US.utf8
ENV LC_ALL=en_US.utf8
COPY --from=base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs
COPY --from=base /etc/passwd /etc/group /etc/shadow /etc/
COPY --from=base /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=builder /app/build/service /service
USER svcrunner
ENTRYPOINT ["/service"]
EXPOSE 8080
FROM golang:1.13-alpine
WORKDIR /app
COPY . /app
EXPOSE 6060
RUN go install golang.org/x/tools/cmd/godoc
CMD go exec godoc -http=:6060
IMAGE := $(shell basename "$(shell pwd)")
OS := linux
ARCH := amd64
IMAGES := linux-arm7 linux-amd64
DOCKER := $(shell basename "$(shell which winpty 2>/dev/null)")
DOCKER += docker
.PHONY : all $(IMAGES) release docs build gocmd
all: release
clean:
@-docker image ls --format '{{.Repository}} {{.ID}}' | awk '/$(IMAGE)/ { system("docker image rm "$$2') }'
release: $(IMAGES)
@-$(DOCKER) manifest push $(IMAGE):latest
build:
@$(DOCKER) image build $(BUILD_OPTS) -t $(TAG) .
gocmd:
@$(DOCKER) run --rm -ti \
-v /$(shell pwd)://app \
--workdir=//app \
--entrypoint=go \
-e CGO_ENABLED=0 \
golang:1.13-alpine $(EXEC)
test: EXEC := test -cover ./...
test: gocmd
docs: TAG := "$(IMAGE):docs"
docs: Dockerfile.doc build
@$(DOCKER) run --rm -ti -p 6060:6060/tcp $(IMAGE):docs
$(IMAGE): BUILD_OPTS := --build-arg GOARCH=$(ARCH)
$(IMAGE): BUILD_OTPS += --build-arg GOOS=$(OS)
$(IMAGE): BUILD_OPTS += --build-arg GOARM=$(ARM)
$(IMAGE): TAG := $(IMAGE):$(OS)-$(ARCH)$(ARM)
$(IMAGE): Dockerfile build
arm:
@$(DOCKER) manifest create -a $(IMAGE):latest $(TAGE) --os $(OS) --arch $(ARCH) --variant $(ARM)
intel:
@$(DOCKER) manifest create -a $(IMAGE):latest $(TAGE) --os $(OS) --arch $(ARCH)
linux-arm64: OS=linux
linux-arm64: ARCH=arm64
linux-arm64: $(IMAGE) arm
linux-arm7: OS=linux
linux-arm7: ARCH=arm
linux-arm7: ARM=7
linux-arm7: $(IMAGE) arm
linux-arm6: OS=linux
linux-arm6: ARCH=arm
linux-arm6: ARM=6
linux-arm6: $(IMAGE) arm
linux-arm5: OS=linux
linux-arm5: ARCH=arm
linux-arm5: ARM=5
linux-arm5: $(IMAGE) arm
linux-amd64: OS=linux
linux-amd64: ARCH=amd64
linux-amd64: $(IMAGE) intel
windows-amd64: OS=windows
windows-amd64: ARCH=amd64
windows-amd64: $(IMAGE) intel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment