Skip to content

Commit

Permalink
build: Dockerfile update (#66)
Browse files Browse the repository at this point in the history
* update dockerfile to handle building binary

* inject index info at runtime
  • Loading branch information
mastercactapus authored Jul 24, 2019
1 parent 6825788 commit be59611
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/web/src/node_modules/
/bin/
smoketest_db_dump
13 changes: 7 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export PATH := $(PWD)/bin:$(PATH)
export GOOS = $(shell go env GOOS)
export GOALERT_DB_URL_NEXT = $(DB_URL_NEXT)

ifeq ($(shell test -d vendor && echo -n yes), yes)
export GOFLAGS=-mod=vendor
endif

ifdef BUNDLE
GOFILES += web/inline_data_gen.go
endif
Expand Down Expand Up @@ -131,12 +135,9 @@ web/src/node_modules: web/src/node_modules/.bin/cypress
web/src/node_modules/.bin/cypress: web/src/yarn.lock
(cd web/src && yarn --no-progress --silent --frozen-lockfile && touch node_modules/.bin/cypress)

web/src/build/index.html: web/src/webpack.prod.config.js web/src/node_modules $(shell find ./web/src/app -type f )
(cd web/src && node_modules/.bin/webpack --config webpack.prod.config.js)
echo "" >>web/src/build/index.html
echo "<!-- Version: $(GIT_VERSION) -->" >>web/src/build/index.html
echo "<!-- GitCommit: $(GIT_COMMIT) ($(GIT_TREE)) -->" >>web/src/build/index.html
echo "<!-- BuildDate: $(BUILD_DATE) -->" >>web/src/build/index.html
web/src/build/index.html: web/src/webpack.prod.config.js web/src/yarn.lock $(shell find ./web/src/app -type f )
rm -rf web/src/build/static
(cd web/src && yarn --no-progress --silent --frozen-lockfile && node_modules/.bin/webpack --config webpack.prod.config.js)

web/inline_data_gen.go: web/src/build/index.html $(CFGPARAMS) $(INLINER)
go generate ./web
Expand Down
11 changes: 10 additions & 1 deletion devtools/ci/dockerfiles/goalert/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
FROM node:10 AS UI
COPY . /build
RUN cd /build && make web/src/build/index.html

FROM golang:alpine AS BE
COPY --from=UI /build /build
RUN apk --no-cache add git make
RUN cd /build && make bin/goalert BUNDLE=1

FROM alpine
RUN apk --no-cache add tzdata ca-certificates
COPY goalert /usr/bin/
COPY --from=BE /build/bin/goalert /usr/bin/
CMD ["/usr/bin/goalert"]
ENV GOALERT_LISTEN :8081
62 changes: 44 additions & 18 deletions web/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ package web

import (
"bytes"
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path"
"strings"
"sync"
"time"

"github.com/pkg/errors"
"github.com/target/goalert/version"
)

// NewHandler creates a new http.Handler that will serve UI files
Expand All @@ -27,23 +30,49 @@ func NewHandler(urlStr string) (http.Handler, error) {
return httputil.NewSingleHostReverseProxy(u), nil
}

type memoryHandler map[string]File
type memoryHandler struct {
files map[string]File
loadIndex sync.Once
indexData []byte
}
type memoryFile struct {
*bytes.Reader
file File
name string
size int
}

func (m memoryHandler) Open(file string) (http.File, error) {
if f, ok := m["src/build"+file]; ok {
return &memoryFile{Reader: bytes.NewReader(f.Data()), file: f}, nil
}
func (m *memoryHandler) index() (*memoryFile, error) {
m.loadIndex.Do(func() {
f, ok := m.files["src/build/index.html"]
if !ok {
return
}
stamp := []byte(fmt.Sprintf("\n\n<!-- Version: %s -->\n<!-- GitCommit: %s (%s) -->\n<!-- BuildDate: %s -->\n\n</html>",
version.GitVersion(), version.GitCommit(), version.GitTreeState(), version.BuildDate().UTC().Format(time.RFC3339)))
data := make([]byte, len(f.Data()), len(f.Data())+len(stamp))
copy(data, f.Data())
data = bytes.Replace(data, []byte("</html>"), stamp, 1)
m.indexData = data
})

f, ok := m["src/build/index.html"]
if !ok {
if len(m.indexData) == 0 {
return nil, errors.New("not found")
}

return &memoryFile{Reader: bytes.NewReader(f.Data()), file: f}, nil
return &memoryFile{Reader: bytes.NewReader(m.indexData), name: "src/build/index.html", size: len(m.indexData)}, nil
}

func (m *memoryHandler) Open(file string) (http.File, error) {
if file == "/index.html" {
return m.index()
}

if f, ok := m.files["src/build"+file]; ok {
return &memoryFile{Reader: bytes.NewReader(f.Data()), name: f.Name, size: len(f.Data())}, nil
}

// fallback to loading the index page
return m.index()
}

func (m *memoryFile) Close() error { return nil }
Expand All @@ -53,11 +82,11 @@ func (m *memoryFile) Readdir(int) ([]os.FileInfo, error) {
func (m *memoryFile) Stat() (os.FileInfo, error) {
return m, nil
}
func (m *memoryFile) Name() string { return path.Base(m.file.Name) }
func (m *memoryFile) Size() int64 { return int64(len(m.file.Data())) }
func (m *memoryFile) Name() string { return path.Base(m.name) }
func (m *memoryFile) Size() int64 { return int64(m.size) }
func (m *memoryFile) Mode() os.FileMode { return 0644 }
func (m *memoryFile) ModTime() time.Time {
if strings.Contains(m.file.Name, "/static/") {
if strings.Contains(m.name, "/static/") {
return time.Time{}
}

Expand All @@ -81,14 +110,11 @@ func rootFSFix(h http.Handler) http.Handler {
}

func newMemoryHandler() http.Handler {
if len(Files) > 0 {
// preload
go Files[0].Data()
}
m := make(memoryHandler, len(Files))
m := &memoryHandler{files: make(map[string]File, len(Files))}
for _, f := range Files {
m[f.Name] = f
m.files[f.Name] = f
}
go m.index()

return rootFSFix(http.FileServer(m))
}

0 comments on commit be59611

Please sign in to comment.