Dockerfile directory structure for Go Webapp

8/15/2018

I'm developing a test hello app in Go, which will have access to a Postgres DB. This will use a statefulset to release in kubernetes and has one pod with two container images (one for pgsql & one for goapp).

├── hello-app
|   ├── templates
|       ├── file1.gohtml
|       ├── file2.gohtml
|       └── file3.gohtml
|   ├── Dockerfile
|   └── hello-app.go
├── psql
|   ├── Dockerfile
|   ├── createUser.sh
|   └── createDB.sql
├── yaml
|   └── statefulset.yaml

I am stuck getting the Dockerfile and Go app to tie up. In my first bit of Go code I use the 'template.Must' function to reference the 'templates' directory. Obviously when I run this up as a container the directory structure is different.

I've not quite worked out how to do this in the Dockerfile yet and was looking for some guidance.

/app/hello-app.go

package main

import (

        "database/sql"
        "fmt"
        "os"
        _ "github.com/lib/pq"
        "html/template"
        "net/http"
        "strconv"
)

var db *sql.DB
var tpl *template.Template

func init() {
        host := os.Getenv("VARIABLE")
        var err error
        db, err = sql.Open("postgres", "postgres://user:password@"+host+"/dbname?sslmode=disable")
        if err != nil {
                panic(err)
        }

        if err = db.Ping(); err != nil {
                panic(err)
        }
        fmt.Println("You connected to your database.")

        tpl = template.Must(template.ParseGlob("templates/*.gohtml"))

/app/Dockerfile

FROM golang:1.8-alpine
RUN apk add --update go git
RUN go get github.com/lib/pq/...
ADD . /go/src/hello-app
RUN go install hello-app
Add templates templates/
ENV USER=username \
    PASSWORD=password \
    DB=dbname \
    HOST=hostname \
    PORT=5432

FROM alpine:latest
COPY --from=0 /go/bin/hello-app/ .
ENV PORT 4040
CMD ["./hello-app"]

When I run this up as is in kubernetes (GCP) I get the following log entry on the hello-app container.

panic: html/template: pattern matches no files: templates/*.gohtml goroutine 1 [running]: html/template.Must

-- Tristan C
docker
dockerfile
go
go-html-template
kubernetes

2 Answers

8/16/2018

That error is because, the template.ParseGlob cannot find any matching files in your templates directory. Instead of COPY --from=0 /go/bin/hello-app/ . try copying the entire directory using COPY <YOUR LOCAL GOPATH/src/hello-app> <DOCKER DIR PATH>. Also when you build the app, your templates folder will still be in source folder, so that too might be causing the problem. Solution is to run a go buildin the app directory and use the the COPY command I have.

-- whitespace
Source: StackOverflow

8/15/2018

In the second stage of your Dockerfile, you are only copying your Go binary from the previous stage. You must also copy your templates directory to the second stage as well so the Go binary can reference your HTML templates:

FROM golang:1.8-alpine
RUN apk add --update go git
RUN go get github.com/lib/pq/...
ADD . /go/src/hello-app
RUN go install hello-app
ENV USER=username \
    PASSWORD=password \
    DB=dbname \
    HOST=hostname \
    PORT=5432

FROM alpine:latest
COPY --from=0 /go/bin/hello-app/ .
COPY --from=0 /go/src/hello-app/templates ./templates
ENV PORT 4040
CMD ["./hello-app"]

I'm not sure if this is common practice but when I'm confused about what contents are in what folder within the build process, I simply ls the directory in question to get a better understanding of what might be happening during the build process:

RUN ls

Obviously you can remove these lines once you've finalized your Dockerfile.

-- jkhedani
Source: StackOverflow