How are developers setting up their dev environments for Golang with Docker? I setup a multi-stage Docker file, but then it seems i have to build the container every time I want to try out my changes. Is this the best practice or is there a better way?
FROM golang:1.9.2 as builder
RUN mkdir -p /go/src/github.com/mycompany/myapp
WORKDIR /go/src/github.com/mycompany/myapp
RUN go get github.com/aws/aws-sdk-go/aws \
github.com/aws/aws-sdk-go/aws/session
COPY app/ .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/mycompany/myapp .
CMD ["./app"]`
**评论:**
ChristophBerger:
SeerUD:I would develop and test as much as I can outside a container and run the Dockerfile only for deploying the tested binary to a staging or production environment.
earthboundkid:I think a lot of people just don't develop in a Docker container. If you are really set on doing it, I'd look into mounting your code in a running container as a volume, and using some kind of file-watcher that triggers a rebuild and a restart of a process, otherwise you're going to be hampering your productivity.
Have tests, run them in your Docker container when you build it, and then otherwise develop locally is what I'd recommend. Unless of course you're testing something that's Linux-specific and you work on a Mac say, then I'd go with what I said in the paragraph above.
People may argue that that would be doing it "wrong" because you wouldn't be using the same image as what you'd use in production. I try to find a balance. Get as close as possible without impacting productivity. So, if possible, I'd use the same base image, same Go version, etc. and the rest would be "close enough" whilst remaining a productive environment to work in.
Redundancy_:No need to
mkdir
. From the docs:If the
WORKDIR
doesn’t exist, it will be created even if it’s not used in any subsequentDockerfile
instruction.
hell_0n_wheel:I don't really like to run "go get" inside a build process, since it's not going to be repeatable, and that slows things down each time.
earthboundkid:i have to build the container every time I want to try out my changes
That just sounds like you aren't using Docker efficiently.
Is this the best practice or is there a better way?
Dunno about best practice, but Docker seems a bit heavyweight for golang. Go does not (yet) reach so far into the OS that you need to partition off a virtual root image just to isolate one installation from another. A directory all one needs for containment; set
$GOPATH
and$GOROOT
accordingly and you're off to the races.GOPATH allows you to specify dependencies that are unique to your project GOROOT allows you to choose a specific golang installation to build and run your project
Easy peasy. Use something like
direnv
to switch your GOPATH / GOROOT as you change projects, and the switching is seamless.
hell_0n_wheel:If you use dep, there's no need to switch GOPATH between projects, because all your dependencies' code is in the vendor subdirectory.
There's never a reason to touch GOROOT unless you're developing Go itself and have multiple versions installed.
earthboundkid:There's never a reason to touch GOROOT...
You're forgetting when one develops services written against multiple versions of Go. Ideally, we'd all run the latest and greatest, but we can't pivot Go versions on a dime...
hell_0n_wheel:But each binary should know where its own root is, no? I thought that was baked into the build.
earthboundkid:Huh? A binary doesn't need a root.
GO_ROOT is baked into
go
AFAIK.
