How do you build a project with a Dockerfile that has it's own entrypoint

With most of my Go projects I usually specify an entrrypoint in my Dockerfile.
For example:

FROM golang:1.14.1-alpine as build

WORKDIR $GOPATH/src/github.com/rugwirobaker/app
COPY go.mod go.sum  ./
RUN GO111MODULE=on GOPROXY="https://proxy.golang.org" go mod download
COPY . .
RUN GO111MODULE=on CGO_ENABLED=0 go build -o /bin/app ./cmd/app

FROM scratch
WORKDIR /
EXPOSE 8080

COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /bin/app /bin/app

ENTRYPOINT ["/bin/app"]

Correct me if I am wrong but it seems waypoint injects it’s own ENTRYPOINT at build time which conflicts with the one set in the Dockerfile and hence this error:

$ docker logs web-01EMSNTHDCY5TNQA773WZR2V89
standard_init_linux.go:219: exec user process caused: no such file or directory

Perhaps an example for statically compiled languages like Go and Rust would help clear up things,

We wrap the entrypoint but don’t replace your existing one so this should be working. We’ll have to take a closer look do you have an example project we could try?

I currently don’t have one ready without my custom stuff but I can put one together tomorrow.

It may be related to using scratch or an minimal alpine image. When I used @nic go example with buildpacks and switched it to use a Dockerfile, I got it working. Notably when I used an alpine image or scratch, it failed with the same exec failure message. When I used a minimal ubuntu image, it worked. Possibly more of a hint here.

My example with the Dockerfile is here.

1 Like

@mitchellh do you at any point after building the image exec into it? Cause then the exec error would be consistent with @jbayer’s observation and it makes sense since scratch images do not contain a shell.

We do not. We inject the entrypoint by using the Docker APIs directly and performing surgery on the image. You can see the implementation in internal/pkg/epinject And usage in builtin/docker/builder.go

Does that mean we can’t use scratch or alpine images?

I don’t think so, the reactjs example uses alpine. I think there might be certain OS functionality that entrypoint uses to launch the app process that may be minimally required.

I found more of a hint. It looks like waypoint-entrypoint as it is currently built has some dependencies that may not be available on scratch and base alpine images.

This output is from an Ubuntu image:

# ldd waypoint-entrypoint
	linux-vdso.so.1 (0x00007fff1a5af000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f365e059000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f365de67000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f365e080000)

I tried all kinds of gymnastics with both scratch and alpine but in the end I could only make it work when I switched to ubuntu. I hope the issue can be found, minimal images are one of the reasons I like Go.

2 Likes

I was able to confirm the base alpine image works after changing the Makefile to respect CGO_ENABLED. Please see https://github.com/hashicorp/waypoint/pull/586

If you want to try it, use my branch and build the binaries from the main directory with make bin. Then retry the example using the ./waypoint that was built. It worked for me with this example.

3 Likes

Mitchell merged this into main so I would expect 0.1.3 will hopefully address this.