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
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 build
in the app directory and use the the COPY
command I have.
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.