Структура каталогов 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