├── .gitignore ├── Dockerfile ├── Dockerfile.multistage ├── Dockerfile.volume ├── Readme.md ├── go.mod ├── go.sum └── hello_server.go /.gitignore: -------------------------------------------------------------------------------- 1 | hello_server 2 | go-docker 3 | out/ 4 | vendor/ 5 | _vendor-* 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Dockerfile References: https://docs.docker.com/engine/reference/builder/ 2 | 3 | # Start from the latest golang base image 4 | FROM golang:latest 5 | 6 | # Add Maintainer Info 7 | LABEL maintainer="Rajeev Singh " 8 | 9 | # Set the Current Working Directory inside the container 10 | WORKDIR /app 11 | 12 | # Copy everything from the current directory to the Working Directory inside the container 13 | COPY . . 14 | 15 | # Build the Go app 16 | RUN go build -o main . 17 | 18 | # Expose port 8080 to the outside world 19 | EXPOSE 8080 20 | 21 | # Command to run the executable 22 | CMD ["./main"] 23 | -------------------------------------------------------------------------------- /Dockerfile.multistage: -------------------------------------------------------------------------------- 1 | # Dockerfile References: https://docs.docker.com/engine/reference/builder/ 2 | 3 | # Start from the latest golang base image 4 | FROM golang:latest as builder 5 | 6 | # Add Maintainer Info 7 | LABEL maintainer="Rajeev Singh " 8 | 9 | # Set the Current Working Directory inside the container 10 | WORKDIR /app 11 | 12 | # Copy everything from the current directory to the Working Directory inside the container 13 | COPY . . 14 | 15 | # Build the Go app 16 | RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . 17 | 18 | 19 | ######## Start a new stage from scratch ####### 20 | FROM alpine:latest 21 | 22 | RUN apk --no-cache add ca-certificates 23 | 24 | WORKDIR /root/ 25 | 26 | # Copy the Pre-built binary file from the previous stage 27 | COPY --from=builder /app/main . 28 | 29 | # Expose port 8080 to the outside world 30 | EXPOSE 8080 31 | 32 | # Command to run the executable 33 | CMD ["./main"] -------------------------------------------------------------------------------- /Dockerfile.volume: -------------------------------------------------------------------------------- 1 | # Dockerfile References: https://docs.docker.com/engine/reference/builder/ 2 | 3 | # Start from the latest golang base image 4 | FROM golang:latest 5 | 6 | # Add Maintainer Info 7 | LABEL maintainer="Rajeev Singh " 8 | 9 | # Set the Current Working Directory inside the container 10 | WORKDIR /app 11 | 12 | # Build Args 13 | ARG LOG_DIR=/app/logs 14 | 15 | # Create Log Directory 16 | RUN mkdir -p ${LOG_DIR} 17 | 18 | # Environment Variables 19 | ENV LOG_FILE_LOCATION=${LOG_DIR}/app.log 20 | 21 | # Copy everything from the current directory to the Working Directory inside the container 22 | COPY . . 23 | 24 | # Build the Go app 25 | RUN go build -o main . 26 | 27 | # This container exposes port 8080 to the outside world 28 | EXPOSE 8080 29 | 30 | # Declare volumes to mount 31 | VOLUME [${LOG_DIR}] 32 | 33 | # Run the binary program produced by `go install` 34 | CMD ["./main"] 35 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # go-docker 2 | 3 | Several Examples for building docker containers for your Go applications. 4 | 5 | ## Running the app locally 6 | 7 | ```bash 8 | $ go build 9 | $ ./go-docker 10 | 2019/02/03 11:38:11 Starting Server 11 | ``` 12 | 13 | ```bash 14 | $ curl http://localhost:8080?name=Rajeev 15 | Hello, Rajeev 16 | ``` 17 | 18 | ## Building and running the docker image 19 | 20 | Read the tutorial: [Building Docker Containers for Go Applications](https://www.callicoder.com/docker-golang-image-container-example/) -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/callicoder/go-docker 2 | 3 | require ( 4 | github.com/gorilla/context v1.1.1 5 | github.com/gorilla/mux v1.6.2 6 | gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 7 | ) 8 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 2 | github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= 3 | github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 4 | gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI= 5 | gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= 6 | -------------------------------------------------------------------------------- /hello_server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "net/http" 8 | "os" 9 | "os/signal" 10 | "syscall" 11 | "time" 12 | 13 | "github.com/gorilla/mux" 14 | "gopkg.in/natefinch/lumberjack.v2" 15 | ) 16 | 17 | func handler(w http.ResponseWriter, r *http.Request) { 18 | query := r.URL.Query() 19 | name := query.Get("name") 20 | if name == "" { 21 | name = "Guest" 22 | } 23 | log.Printf("Received request for %s\n", name) 24 | w.Write([]byte(fmt.Sprintf("Hello, %s\n", name))) 25 | } 26 | 27 | func main() { 28 | // Create Server and Route Handlers 29 | r := mux.NewRouter() 30 | 31 | r.HandleFunc("/", handler) 32 | 33 | srv := &http.Server{ 34 | Handler: r, 35 | Addr: ":8080", 36 | ReadTimeout: 10 * time.Second, 37 | WriteTimeout: 10 * time.Second, 38 | } 39 | 40 | // Configure Logging 41 | LOG_FILE_LOCATION := os.Getenv("LOG_FILE_LOCATION") 42 | if LOG_FILE_LOCATION != "" { 43 | log.SetOutput(&lumberjack.Logger{ 44 | Filename: LOG_FILE_LOCATION, 45 | MaxSize: 500, // megabytes 46 | MaxBackups: 3, 47 | MaxAge: 28, //days 48 | Compress: true, // disabled by default 49 | }) 50 | } 51 | 52 | // Start Server 53 | go func() { 54 | log.Println("Starting Server") 55 | if err := srv.ListenAndServe(); err != nil { 56 | log.Fatal(err) 57 | } 58 | }() 59 | 60 | // Graceful Shutdown 61 | waitForShutdown(srv) 62 | } 63 | 64 | func waitForShutdown(srv *http.Server) { 65 | interruptChan := make(chan os.Signal, 1) 66 | signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) 67 | 68 | // Block until we receive our signal. 69 | <-interruptChan 70 | 71 | // Create a deadline to wait for. 72 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 73 | defer cancel() 74 | srv.Shutdown(ctx) 75 | 76 | log.Println("Shutting down") 77 | os.Exit(0) 78 | } 79 | --------------------------------------------------------------------------------