A dockerized workflow that decouples the go runtime and tools from the developer's OS.
Enables completely dockerized Go development workflows:
- Bind-mounted
goruntime files on Host - Dockerized
go - Dockerized go debug tools (E.g.
dlv,gopls,bingo) - Standalone
<any go tool you like>
With this, a developer machine becomes ephemeral, containing no development state. Also, a developer only needs to change one variable, to switch to a different go runtime version.
-
Install
bindfs-1.13.10or higher. Required for Step 2. -
Start a
godaemon container,bindfs-mounting the go runtime files onto the host. Requiressudoprivilege.make start-go-daemon
-
Build go and go tool wrappers and their docker images
make
E.g. A docker image named
goplsis built. A wrappergoplsis generated in./bin -
Add this repo's
./binto$PATH.gowrapper is now available$ which go /path/to/docker-go-tools/bin/go $ go
Dockerized go tool wrappers should be used in the scope of a repo
$ which dlv /path/to/docker-go-tools/bin/dlv # Ensure we are in the scope of a git repo $ cd /path/to/your/repo $ dlv
-
Get standalone (non-dockerized) go tools
# Ensure we are not in the scope of a git repo cd ~ $ go get github.com/golangbot/hello $ which hello /home/user/go/bin/hello $ hello Hello World
You are now ready to start developing.
go, go tool wrappers (dlv,gopls,bingoetc), and standalone go tools will work as intended. All without dependency on the Host system.
Let's build a dockerized golint
-
In
Makefile:- Add
golinttoALL_BINSinMakefile. E.g.dlv gopls bingo golint - Add
golintpackage as a variable. E.g.golint_PACKAGE := golang.org/x/lint/golint
- Add
-
Run
make.
make all-remove
We create daemon go container, and bindfs its GOROOT (/usr/local/go) onto the Host at the same path (/usr/local/go). Read more here.
This allows the user to access Go runtime / native files as though it were installed on the Host.
More importantly, it allows a local debugger (e.g. dlv) or go-to-definition tool (e.g. gopls or godef) to open the necessary Go native files.
When called outside of the folder of a git repository, the GOPATH is $HOME/go, and GOCACHE is $HOME/.cache/go-build, as defined in Makefile.
When called within the folder of a git repository, the GOPATH and GOCACHE are /path/to/repo/.go and /path/to/repo/.go/.cache/go-build, as defined in the Makefile. Your workspace environment may want to define these variables to override the wrapper's defaults just to be sure they are set correctly.
These must be used in the folder of a git repository. The GOPATH and GOCACHE are /path/to/repo/.go and /path/to/repo/.go/.cache/go-build.
The binaries will still reside in $GOPATH/bin as defined in Makefile.
You need to have at least bindfs-1.13.10 or higher. More information here
Q: bindfs of the Go daemon container's GOROOT does not work on Docker for Windows or Docker for Mac?
Yes. The bindfs approach only works on Linux at the moment. This is because Docker for Windows/Mac both use a separate VM for the container space, and the host is unable to see the container's files. Read more details here