Sign inSign up

zephinzer/golang-dev

By zephinzer

•Updated over 7 years ago

A set of scripts/tools packaged in a Docker image to quickly get up-and-writing with Golang.

Image
8

7.0K

zephinzer/golang-dev repository overview

View the canonical documentation at https://github.com/zephinzer/golang-dev⁠


⁠Go Develop 🤓

A set of scripts/tools packaged in a Docker image to quickly get up-and-writing with Golang.

⁠Scope of Work

  • ✅ Use Docker to provision an environment for a Golang 1.x application
  • ✅ Live-reload of application using go build
  • ✅ Live-updating of application's dependenices (go mod used here)
  • ✅ Live-reload of tests using go test
  • ✅ Statically link production binary using go build
  • ✅ Docker image building using the scratch image
  • ✅ Still be able to run things like go (mod|build|run|test) on the host system

⁠System Requirements

You don't need Go installed or a GOPATH for this 🥂

⁠Usage

⁠TL;DR

The quickest way to try this out is to copy the following into a Makefile in your target directory and run make init:

GOLANG_DEV_VERSION=latest

# initialises this directory - use once only
init:
	@$(MAKE) _dev ARG="init"
# builds the application - outputs an `app` binary
build: 
	@$(MAKE) _dev ARG="build"
# runs tests in watch-mode
test: build
	@$(MAKE) _dev ARG="test"
# runs tests once
test.once: build
	@$(MAKE) _dev ARG="test -coverprofile c.out"
# runs the application on the host network
start: build
	@$(MAKE) _dev ARG="start"
# creates a shell in a fresh container generated from the image, usable for development on non-linux machines
shell:
	$(MAKE) dev ARG="shell"
# retrieves the latest version we are at
version.get:
	@docker run -v "$(CURDIR):/app" zephinzer/vtscripts:latest get-latest -q
# bumps the version by 1: specify VERSION as "patch", "minor", or "major", to be specific about things
version.bump: 
	@docker run -v "$(CURDIR):/app" zephinzer/vtscripts:latest iterate ${VERSION} -i
# base command to run other scripts (do not use alone)
_dev:
	@docker run \
    -it \
    --network host \
    -u $$(id -u) \
    -v "$(CURDIR)/.cache/pkg:/go/pkg" \
    -v "$(CURDIR):/go/src/app" \
    zephinzer/golang-dev:$(GOLANG_DEV_VERSION) ${ARG}

Check out the documentation below on how to bundle your application into a scratch Docker image⁠.

⁠Getting Started With Just The golang-dev Image

If you already have a Makefile/don't want a Makefile (but why?), running the following in any directory should get you up and running:

docker run -it \
  -u ${UID} \
  -v "$(pwd)/.cache/pkg:/go/pkg" \
  -v "$(pwd):/go/src/app" \
  zephinzer/golang-dev:latest init;

The script should ask a series of questions which if you agree to all, will create a Git repository, add an appropriate .gitignore file, initialise go mod, and provision a Dockerfile you can use to build your own image.

Notes:

  • The -u parameter sets the guest user to use your host user ID so that new files aren't created as root, causing problems on your host machine when you attempt to delete them.
  • The mapping of the .cache directory allows for faster subsequent dependency processing by go mod.
⁠Live-Reload, Live-Dependency-Update, Live-Testing Development

Assuming you've completed the above step, create a main.go if there isn't already one, and run the following to start development:

docker run -it \
  -u ${UID} \
  --network host \
  -v "$(pwd)/.cache/pkg:/go/pkg" \
  -v "$(pwd):/go/src/app" \
  zephinzer/golang-dev:latest start;

To start the tests, create a new terminal in the smae directory and run:

docker run -it \
  -u ${UID} \
  --network host \
  -v "$(pwd)/.cache/pkg:/go/pkg" \
  -v "$(pwd):/go/src/app" \
  zephinzer/golang-dev:latest start;

Notes

  • Making changes to *.go will result in a live-reload
  • Add a new import will cause the script to start downloading the new dependency
  • Removing that import will simply cause the dependency to be removed - simple stuff
  • If you need a port open without using --network host, specify the flag -p "HOSTPORT":"CONTAINERPORT" in the docker run command
  • If a new file is created, you'll need to send an interrupt to the process and start it again to begin watching it. I have no idea how to automatically watch new files but if you do, please submit a pull request. Thanks in advance!
⁠Building a Binary

Assuming you have a main.go, building a binary is as simple as running:

docker run -it \
  -u ${UID} \
  -v "$(pwd)/.cache/pkg:/go/pkg" \
  -v "$(pwd):/go/src/app" \
  zephinzer/golang-dev:latest build;

The binary will appear in your current directory and be named app.$GOOS.$GOARCH. It will be postfixd with a .exe if $GOOS specifies a Windows build.

Notes:

⁠Building Into a Docker Image

If you denied the init script from creating a Dockerfile, you can run it again to get it. Otherwise, the Dockerfile script should be:

FROM zephinzer/golang-dev:latest as development
COPY . /go/src/app
ENTRYPOINT [ "start" ]
FROM development as build
RUN build
ENTRYPOINT [ "/go/src/app/app" ]
FROM scratch as production
COPY --from=build /go/src/app/app /
ENTRYPOINT [ "/app" ]

Copy the above and paste it in a file named Dockerfile in your root directory. After that, you can build your image by running:

docker build -t yourname/yourimage:yourtag .;

⁠Advanced Usage

⁠Usage in a docker-compose.yml

Add the following in your Docker Compose to use this as part of a Docker provisioned environment:

version: "3.5" # or anything you're using
services:
  # ...
  app:
    image: zephinzer/golang-dev:latest
    ports: # if needed
    - "3000:3000"
    user: "${UID}"
    entrypoint: ["start"]
    volumes:
    - "./.cache/pkg:/go/pkg"
    - "./:/go/src/app"
    # ...
  # ...

⁠License

This project is licensed under the MIT license. See the LICENSE file⁠ for the full text.

⁠Footnotes

⁠Why golang-dev Came About
  • Golang requirements. Go's infamous $GOPATH is a pain-in-the-filesystem. Developing via a Docker environment abstracts this away. Also, you no longer have to have Go installed on your system since managing different Go versions is another pain-in-the-filesystem.
  • Live-reload tooling. Realize⁠ works for applications but does not run tests. Same for Gin⁠ which seems . Only GoConvey⁠ does it well, but it uses a browser interface instead of a CLI. Go Convey also only outputs a PASS or FAIL. I wanted to see error logs on FAIL which it didn't provide me.
  • Auto-download dependencies. None of Realize, Gin and GoConvey automatically downloads dependencies either. While this is super useful, it also requires context of which package manager to use. This project enforces the use of go mod which accomodates previous package managers such as glide and go dep.
⁠Personal Use Case

I use this project for information-systems type of work. This may not accomodate your use cases perfectly if you're developing scripts for say big data processing or artificial intelligence works, but it may. Let me know if you have any suggestions via an issue!


⁠Development/Hacking

If you're interested in working on this, read on!

The contribution mechanism is roughly the same as other open-source projects:

  1. Fork this repository
  2. Make your changes on master
  3. Make a pull request
⁠Code

The main logic of how this works is written as shell scripts in the /scripts directory⁠.

The Dockerfile simply copies the /scripts⁠ in and adds it to the $PATH.

⁠Testing

Tests are contained in the ./test directory⁠ but you can run it from the root using make test.

⁠Building

To build the Docker image, run make build.

⁠Versioning

To bump a patch version, run make version.bump.

To bump a minor versoin, run make version.bump VERSION=minor.

To bump a major versoin, run make version.bump VERSION=major.

⁠Publishing

To publish the Docker image, run make publish.

This publishes two images - one with the version as recorded by the Git tags, another with the version of Golang, and a last one with the latest tag.

⁠Projects Using This

⁠Cheers 😎

Leave me a 🌟 or watch this repository to indicate your interest in my sustained development on this. It'll help me decide whether or not I should deprecate this once my own use case for this is over.

Tag summary

Content type

Image

Digest

Size

177.3 MB

Last updated

over 7 years ago

docker pull zephinzer/golang-dev