This probably fits in very well with the "nuts" part of the golang-nuts group, so here we go: in some of my projects I typically build and deploy locally in a container to see that the service work correctly at least locally. Now, these projects tend to depend on several of my own separate Go modules. Unit testing locally is easy, but in several cases my services depend on more stuff that is unwieldy to build so I prefer having this all done in a staged container image build.
Can I get my workspace "somehow" into my multi-stage build...? Well, looks like it is doable, albeit with some limitations due to the Dockerfile syntax. So, here we are and I would like to ask kindly for kind feedback ... also available as a gist <https://gist.github.com/thediveo/0d8b6ae7f88918c2571890e508468b23>. The illustrative example assumes a filesystem setup as follows: - foobar-ws/ - bar/ - bar.go - go.mod - foo/ - foo.go - go.mod - foobar/ - deployments/foobar/ - *Dockerfile* - go.mod - go.sum - main.go - *Makefile* The Makefile: MAINUSE:=./foobar EMPTYCONTEXT:=.emptyctx NUMCONTEXTS:=9 SHELL:=/bin/bash build: @# find out if we are in workspace mode -- and it we are, then the list of @# modules actually used. @mkdir -p $(EMPTYCONTEXT); \ trap 'rm -rf -- "$(EMPTYCONTEXT)"' EXIT; \ contexts=(); \ workspace_details=$$(go work edit --json); \ if [[ $${workspace_details} ]]; then \ goworkdir=$$(dirname $$(go env GOWORK)); \ echo "found workspace" $${goworkdir}; \ diskpaths=$$(echo $${workspace_details} | jq --raw-output '.Use | .[]? | .DiskPath'); \ echo "modules used in workspace:" $${diskpaths}; \ while IFS= read -r module; do \ if [[ "$${module}" == "$(MAINUSE)" ]]; then \ echo " ๐ " $${module}; \ else \ relcontext=$$(realpath --relative-to="." $${goworkdir}/$${module}); \ contexts+=( $${relcontext} ); \ echo " ๐งฉ" $${module} "ยป ๐" $${relcontext}; \ fi \ done <<< $${diskpaths}; \ else \ diskpaths="$(MAINUSE)"; \ fi; \ buildctxargs=(); \ buildargs=(); \ ctxno=1; \ for ctx in "$${contexts[@]}"; do \ buildctxargs+=( "--build-context=bctx$${ctxno}=$${ctx}" ); \ buildargs+=( "--build-arg=MOD$${ctxno}=./$$(basename ./$${ctx})/" ); \ ((ctxno=ctxno+1)); \ done; \ for ((;ctxno<=$(NUMCONTEXTS);ctxno++)); do \ buildctxargs+=( "--build-context=bctx$${ctxno}=$(EMPTYCONTEXT)" ); \ done; \ echo "args:" $${buildctxargs[*]} $${buildargs[*]}; \ echo "build inside:" $${CWD}; \ docker build \ -f ./deployments/foobar/Dockerfile \ $${buildargs[@]} \ $${buildctxargs[@]} \ --build-arg=WSDISKPATHS="$$(echo $${diskpaths})" \ . The Dockerfile: FROM golang:1.20-alpine AS builder ARG WSDISKPATHS ARG MOD1=./ ARG MOD2=./ ARG MOD3=./ ARG MOD4=./ ARG MOD5=./ ARG MOD6=./ ARG MOD7=./ ARG MOD8=./ ARG MOD9=./ WORKDIR /ws # Copy the additionally used modules into the soon-to-be workspace. COPY --from=bctx1 . ${MOD1} COPY --from=bctx2 . ${MOD2} COPY --from=bctx3 . ${MOD3} COPY --from=bctx4 . ${MOD4} COPY --from=bctx5 . ${MOD5} COPY --from=bctx6 . ${MOD6} COPY --from=bctx7 . ${MOD7} COPY --from=bctx8 . ${MOD8} COPY --from=bctx9 . ${MOD9} # Finally copy in the main module containing a main package to be build. WORKDIR /ws/foobar COPY go.mod go.sum ./ RUN go mod download COPY *.go ./ # Establish the Go workspace WORKDIR /ws RUN go work init ${WSDISKPATHS} RUN go build -v -o /foobar ./foobar A "make" inside foobar-ws/foobar will take over the current local workspace "use" configuration and then build the "main" application. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/e6c8064b-2373-44e8-b439-1f4c71f150f3n%40googlegroups.com.