├── .gitignore ├── Dockerfile ├── README.md ├── app.go ├── go.sh ├── lib └── Dockerfile └── wrapper.sh /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | /app 3 | static 4 | /static 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM treeder/go-dind 2 | 3 | ADD go.sh /scripts/ 4 | ADD lib/* /scripts/lib/ 5 | 6 | # Just for demo and having something here if the user doesn't pass it in 7 | ADD app.go /app/app.go 8 | WORKDIR /app 9 | 10 | ENTRYPOINT ["sh", "/scripts/go.sh"] 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## MOVED: I've created a new follow on project for Go and other languages here: https://github.com/treeder/dj 2 | 3 | This is a Docker image to help you develop in Go (golang). The great thing is you don't need 4 | to have anything installed except Docker, you don't even need Go installed. See [this post about developing with Docker](https://medium.com/iron-io-blog/why-and-how-to-use-docker-for-development-a156c1de3b24). 5 | 6 | This image can perform the following functions: 7 | 8 | * vendor - vendors your dependencies into a /vendor directory. 9 | * build - builds your program using the vendored dependencies, with no import rewriting. 10 | * remote - this one will produce a binary from a GitHub repo. Equivalent to cloning, vendoring and building. 11 | * image - this will build and create a Docker image out of your program. 12 | * cross - cross compile your program into a variety of platforms. Based on [this](https://medium.com/iron-io-blog/how-to-cross-compile-go-programs-using-docker-beaa102a316d#95d9). 13 | * static - statically compile your program. This is great for making the [tiniest Docker image possible](http://www.iron.io/blog/2015/07/an-easier-way-to-create-tiny-golang-docker-images.html). 14 | 15 | ## Usage 16 | 17 | ### Vendor dependencies: 18 | 19 | ```sh 20 | docker run --rm -it -v "$PWD":/app -w /app treeder/go vendor 21 | ``` 22 | 23 | You may need to add more options if you have subdirectory imports: 24 | 25 | ```sh 26 | docker run --rm -it -v "$PWD":/app -w /app -e "SRCPATH=github.com/username/reponame" treeder/go vendor 27 | ``` 28 | 29 | The SRCPATH should match your local import statements. Only required if you have subdirectories in the current repository 30 | that you are using in imports. 31 | 32 | ### Build: 33 | 34 | ```sh 35 | docker run --rm -v "$PWD":/app -w /app treeder/go build 36 | ``` 37 | 38 | ### Run: 39 | 40 | This is just a normal Docker run. I'm using iron/base here because it's a tiny image that has 41 | everything you need to run your Go binary on. 42 | 43 | ```sh 44 | docker run --rm -v "$PWD":/app -w /app -p 8080:8080 iron/base ./app 45 | ``` 46 | 47 | ### Format: 48 | 49 | ```sh 50 | docker run --rm -v "$PWD":/app -w /app treeder/go fmt 51 | ``` 52 | 53 | ## Advanced Commands 54 | 55 | ### Build a remote git repo: 56 | 57 | This produces a binary given a remote git repo containing a Go program. 58 | 59 | ```sh 60 | docker run --rm -v "$PWD":/app -w /app treeder/go remote https://github.com/treeder/hello-app.go.git 61 | ``` 62 | 63 | You'll end up with a binary called `app` which you can run with the same command as above. 64 | 65 | ### Build a Docker image out of your program: 66 | 67 | This will build a Docker image with your program inside it. 68 | 69 | The argument after image is `IMAGE_NAME:tag`. Also, note the extra mount here, that's required to talk to the Docker host. 70 | 71 | ```sh 72 | docker run --rm -v "$PWD":/app -w /app -v /var/run/docker.sock:/var/run/docker.sock treeder/go image username/myapp:latest 73 | ``` 74 | 75 | Boom, creates a small Docker image for you. Run `docker images` to check it out, should be about ~12MB total. 76 | 77 | Test your new image: 78 | 79 | ```sh 80 | docker run --rm -v "$PWD":/app -w /app -p 8080:8080 username/myapp 81 | ``` 82 | 83 | ### Cross compile: 84 | 85 | This uses a different image, treeder/go-cross, to do a cross compile. 86 | 87 | ```sh 88 | docker run --rm -v "$PWD":/app -w /app treeder/go-cross cross 89 | ``` 90 | 91 | ### Build static binary: 92 | 93 | This is great for making the [tiniest Docker image possible](http://www.iron.io/blog/2015/07/an-easier-way-to-create-tiny-golang-docker-images.html) 94 | 95 | ```sh 96 | docker run --rm -v "$PWD":/app -w /app treeder/go static 97 | ``` 98 | 99 | ### Check Go version: 100 | 101 | ```sh 102 | docker run --rm treeder/go version 103 | ``` 104 | 105 | ## Wrapper Script 106 | 107 | We've provided a [`wrapper.sh` script](./wrapper.sh) to make running each command 108 | more convenient. 109 | 110 | To use it, download it and put it in your `$PATH`. Then, create an alias for it 111 | by pasting the following into your shell config file (e.g. `.bashrc`, `.zshrc`, etc...): 112 | 113 | `alias dgo='wrapper.sh'` 114 | 115 | Now you're ready to run the wrapper. It supports the following commands: 116 | 117 | * `dgo build` 118 | * `dgo cross` 119 | * `dgo static` 120 | * `dgo vendor` 121 | * `dgo image` 122 | * `dgo run` 123 | * `dgo run-static` 124 | 125 | 126 | ## TODO: 127 | 128 | ... 129 | 130 | ## Building this image 131 | 132 | ```sh 133 | docker build -t treeder/go:latest . 134 | ``` 135 | 136 | Tag it with Go version too (can check with `docker run --rm treeder/go version`): 137 | 138 | ```sh 139 | docker tag treeder/go:latest treeder/go:1.4.2 140 | ``` 141 | 142 | Push: 143 | 144 | ```sh 145 | docker push treeder/go 146 | ``` 147 | -------------------------------------------------------------------------------- /app.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | 8 | "github.com/gorilla/mux" 9 | ) 10 | 11 | func main() { 12 | r := mux.NewRouter() 13 | r.HandleFunc("/", Hello) 14 | http.Handle("/", r) 15 | fmt.Println("Starting up on 8080") 16 | log.Fatal(http.ListenAndServe(":8080", nil)) 17 | } 18 | 19 | func Hello(w http.ResponseWriter, req *http.Request) { 20 | fmt.Fprintln(w, "Hello world!") 21 | } 22 | -------------------------------------------------------------------------------- /go.sh: -------------------------------------------------------------------------------- 1 | # To test this script before building an image: 2 | # docker run --rm -v $PWD:/app -w /app treeder/go-dind sh go.sh version 3 | 4 | # Original command to vendor 5 | # docker run --rm -it -v "$PWD":/go/src/x/y/z -w /go/src/x/y/z -e "GOPATH=/go/src/x/y/z/vendor:/go" golang go get 6 | # Original command to build 7 | # docker run --rm -it -v $PWD:/go/src/x/y/z -w /go/src/x/y/z -e "GOPATH=/go/src/x/y/z/vendor:/go" golang go build -o hello 8 | # Original command to cross compile: 9 | 10 | set -e 11 | 12 | cmd="$1" 13 | # echo "Go Args: $*" 14 | if [ "$#" -lt 1 ] 15 | then 16 | echo "No command provided." 17 | exit 1 18 | fi 19 | 20 | if [ -n "$GITCRED" ]; then 21 | echo "creds defined" 22 | echo $GITCRED >> ~/.git-credentials 23 | ls -al ~ 24 | cat ~/.git-credentials 25 | fi 26 | 27 | if [ -n "$GITCONFIG" ]; then 28 | echo "gitconfig defined" 29 | echo $GITCONFIG >> ~/.gitconfig 30 | ls -al ~ 31 | cat ~/.gitconfig 32 | fi 33 | 34 | # echo $PWD 35 | wd=$PWD 36 | defSrcPath="x/y/z" 37 | if [ -z "$SRCPATH" ]; then 38 | SRCPATH=$defSrcPath 39 | fi 40 | # echo "srcpath $SRCPATH ---" 41 | p=/go/src/$SRCPATH 42 | mkdir -p $p 43 | # ls -al 44 | if [ "$(ls -A $wd)" ] 45 | then 46 | # only if files exist, errors otherwise 47 | cp -r * $p 48 | fi 49 | cd $p 50 | # Add vendor to the GOPATH so get will pull it in the right spot 51 | export GOPATH=$p/vendor:/go 52 | 53 | # Pass in: $# MIN_ARGS 54 | validate () { 55 | if [ "$1" -lt $2 ] 56 | then 57 | echo "No command provided." 58 | exit 1 59 | fi 60 | } 61 | vendor () { 62 | go get 63 | cp -r $1/vendor $2 64 | chmod -R a+rw $2/vendor 65 | # cd $wd 66 | } 67 | build () { 68 | # echo "build: $1 $2" 69 | go build $1 70 | cp app $2 71 | chmod a+rwx $wd/app 72 | } 73 | 74 | case "$1" in 75 | vendor) echo "Vendoring dependencies..." 76 | vendor $p $wd 77 | ;; 78 | build) echo "Building..." 79 | build "-o app" $wd 80 | ;; 81 | fmt) echo "Formatting..." 82 | cd $wd 83 | go fmt 84 | ;; 85 | cross) echo "Cross compiling..." 86 | for GOOS in darwin linux windows; do 87 | for GOARCH in 386 amd64; do 88 | echo "Building $GOOS-$GOARCH" 89 | export GOOS=$GOOS 90 | export GOARCH=$GOARCH 91 | go build -o bin/app-$GOOS-$GOARCH 92 | done 93 | done 94 | cp -r bin $wd 95 | chmod -R a+rw $wd/bin 96 | # ls -al $wd/bin 97 | ;; 98 | static) echo "Building static binary..." 99 | CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags="-s" -o static 100 | cp static $wd 101 | chmod a+rwx $wd/static 102 | ;; 103 | remote) echo "Building binary from $2" 104 | validate $# 2 105 | userwd=$wd 106 | cd 107 | git clone $2 repo 108 | cd repo 109 | wd=$PWD 110 | # Need to redo some initial setup here: 111 | cp -r * $p 112 | cd $p 113 | vendor $p $wd 114 | build "-o app" $wd 115 | cp $wd/app $userwd 116 | chmod a+rwx $userwd/app 117 | ;; 118 | image) echo "Building Docker image '$2'..." 119 | validate $# 2 120 | ls -al /usr/bin/docker 121 | build "-o app" $wd 122 | /usr/bin/docker version 123 | cp /scripts/lib/Dockerfile $p 124 | /usr/bin/docker build -t $2 . 125 | # perhaps an alternative to this would be to do dind, replace the FROM with treeder/go-dind for example: 126 | # cp /scripts/lib/Dockerfile $p 127 | # /usr/bin/dockerlaunch /usr/bin/docker -d -D & 128 | # sleep 3 129 | # docker build -t $2 . 130 | ;; 131 | version) 132 | go version 133 | ;; 134 | *) echo "Invalid command, see https://github.com/treeder/dockers/tree/master/go for reference." 135 | ;; 136 | esac 137 | exit 0 138 | -------------------------------------------------------------------------------- /lib/Dockerfile: -------------------------------------------------------------------------------- 1 | # This is for the `image` command. 2 | 3 | FROM iron/base 4 | 5 | WORKDIR /app 6 | 7 | # copy binary into image 8 | COPY app /app/ 9 | 10 | ENTRYPOINT ["./app"] 11 | -------------------------------------------------------------------------------- /wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $TRACE ]] && set -x 3 | 4 | main() { 5 | case "$1" in 6 | build) 7 | docker run --rm -v "$PWD":/app -w /app treeder/go build 8 | ;; 9 | cross) 10 | docker run --rm -v "$PWD":/app -w /app treeder/go cross 11 | ;; 12 | static) 13 | docker run --rm -v "$PWD":/app -w /app treeder/go static 14 | ;; 15 | vendor) 16 | docker run --rm -v "$PWD":/app -w /app treeder/go vendor 17 | ;; 18 | fmt) 19 | docker run --rm -v "$PWD":/app -w /app treeder/go fmt 20 | ;; 21 | run) 22 | docker run --rm -v "$PWD":/app -w /app -p 8080:8080 iron/base ./app 23 | ;; 24 | run-static) 25 | docker run --rm -v "$PWD":/app -w /app -p 8080:8080 iron/base ./static 26 | ;; 27 | image) 28 | local image="$2" 29 | if [[ -z "$image" ]]; then 30 | echo "Missing image name" 31 | exit 1 32 | fi 33 | docker run --rm -v "$PWD":/app -w /app -v /var/run/docker.sock:/var/run/docker.sock treeder/go image "$image" 34 | ;; 35 | *) 36 | echo "Invalid command" 37 | exit 1 38 | ;; 39 | esac 40 | } 41 | 42 | main "$@" 43 | --------------------------------------------------------------------------------