Структура каталогов Dockerfile для Go Webapp

Я разрабатываю тестовое приложение Hello на Go, которое будет иметь доступ к базе данных Postgres. Он будет использовать набор состояний для выпуска в kubernetes и имеет один модуль с двумя образами контейнеров (один для pgsql и один для goapp).

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

Я застрял, пытаясь связать приложение Dockerfile and Go. В моем первом бите кода Go я использую функцию template.Must для ссылки на каталог templates. Очевидно, что когда я запускаю это как контейнер, структура каталогов отличается.

Я еще не совсем понял, как это сделать в Dockerfile, и искал какое-то руководство.

/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"))

/ приложение /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"]

Когда я запускаю это как в kubernetes (GCP), я получаю следующую запись в журнале hello-app.

паника: html/template: шаблон не соответствует ни одному файлу: templates/*.gohtml goroutine 1 [выполняется]: html/template.Must

2 ответа

Решение

На втором этапе вашего Dockerfile вы копируете только двоичный файл Go с предыдущего этапа. Вы также должны скопировать свой templates перейдите ко второму этапу, чтобы двоичный файл Go мог ссылаться на ваши HTML-шаблоны:

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"]

Я не уверен, является ли это обычной практикой, но когда я запутался в том, что содержимое в какой папке в процессе сборки, я просто ls рассматриваемый каталог, чтобы лучше понять, что может происходить в процессе сборки:

RUN ls

Очевидно, что вы можете удалить эти строки после завершения Dockerfile.

Эта ошибка заключается в том, что template.ParseGlob не могу найти подходящих файлов в вашем каталоге шаблонов. Вместо COPY --from=0 /go/bin/hello-app/ . попробуйте скопировать весь каталог, используя COPY <YOUR LOCAL GOPATH/src/hello-app> <DOCKER DIR PATH>, Кроме того, когда вы создаете приложение, ваша папка с шаблонами будет по-прежнему находиться в исходной папке, что также может быть причиной проблемы. Решение состоит в том, чтобы запустить go buildв каталоге приложения и использовать COPY команда у меня есть.

У меня возникла такая же ошибка с папкой моих шаблонов, но я решил ее, скопировав все файлы из моей корневой папки с помощью этой команды в моем Dockerfile:

COPY . .

Кроме того, когда вы используете внешнюю библиотеку, вы можете включить GO111MODULE.

В вашем терминале (MacOS):

export GO111MODULE=on
go mod init

В вашем Dockerfile:

COPY go.mod .
RUN go mod download
Другие вопросы по тегам