1+ FROM docker.io/lalyos/upx AS upx
2+
3+ FROM node:8 AS asset-builder
4+ RUN mkdir -p /usr/src/app
5+ WORKDIR /usr/src/app
6+ ARG NODE_ENV=development
7+ ENV NODE_ENV=$NODE_ENV
8+ COPY package.json /usr/src/app/
9+ COPY package-lock.json /usr/src/app/
10+
11+ RUN npm install && npm cache clean --force
12+
13+ COPY .angular-cli.json /usr/src/app/
14+ COPY build.js /usr/src/app/
15+ COPY tsconfig.json /usr/src/app/
16+ COPY tslint.json /usr/src/app/
17+
18+ COPY src /usr/src/app/src
19+
20+ RUN npm run build
21+
22+ FROM golang AS asset-compiler
23+ RUN go get github.com/elazarl/go-bindata/...
24+ RUN go get github.com/elazarl/go-bindata-assetfs/...
25+
26+ COPY --from=asset-builder /usr/src/app/dist /dist
27+ RUN go-bindata-assetfs -nomemcopy -nocompress /dist/... \
28+ && ( grep -q '"os"' bindata_assetfs.go \
29+ || sed -e 's|"github.com/elazarl/go-bindata-assetfs"|"github.com/elazarl/go-bindata-assetfs"\n\t "os"|' -i bindata_assetfs.go ) \
30+ && cp bindata_assetfs.go /bindata_assetfs.go
31+
32+
33+ FROM golang AS server-builder
34+
35+ RUN go get github.com/heptiolabs/healthcheck/...
36+ RUN go get github.com/gorilla/handlers/...
37+ RUN go get github.com/hkwi/h2c/...
38+ RUN go get github.com/elazarl/go-bindata-assetfs/...
39+ RUN go get github.com/heptiolabs/healthcheck/...
40+
41+ COPY --from=upx /bin/upx /bin/upx
42+ RUN ( \
43+ echo 'package main' ; \
44+ echo '' ; \
45+ echo 'import (' ; \
46+ echo ' "github.com/gorilla/handlers"' ; \
47+ echo ' "github.com/hkwi/h2c"' ; \
48+ echo ' "log"' ; \
49+ echo ' "net/http"' ; \
50+ echo ' "os"' ; \
51+ echo ')' ; \
52+ echo '' ; \
53+ echo 'func getEnv(key, fallback string) string {' ; \
54+ echo ' if value, ok := os.LookupEnv("SERVER_" + key); ok {' ; \
55+ echo ' return value' ; \
56+ echo ' }' ; \
57+ echo ' return fallback' ; \
58+ echo '}' ; \
59+ echo '' ; \
60+ echo 'type hookedResponseWriter struct {' ; \
61+ echo ' http.ResponseWriter' ; \
62+ echo ' ignore bool' ; \
63+ echo '}' ; \
64+ echo '' ; \
65+ echo 'func (hrw *hookedResponseWriter) WriteHeader(status int) {' ; \
66+ echo ' if status == 404 {' ; \
67+ echo ' hrw.ignore = true' ; \
68+ echo ' fallbackDocument, err := Asset("dist/index.html")' ; \
69+ echo ' if err != nil {' ; \
70+ echo ' log.Fatal("cannot process 404-handler", err)' ; \
71+ echo ' }' ; \
72+ echo ' hrw.ResponseWriter.Header().Set("Content-Type", "text/html; charset=utf-8");' ; \
73+ echo ' hrw.ResponseWriter.WriteHeader(200)' ; \
74+ echo ' hrw.ResponseWriter.Write(fallbackDocument)' ; \
75+ echo ' } else {' ; \
76+ echo ' hrw.ResponseWriter.WriteHeader(status)' ; \
77+ echo ' }' ; \
78+ echo '}' ; \
79+ echo '' ; \
80+ echo 'func (hrw *hookedResponseWriter) Write(p []byte) (int, error) {' ; \
81+ echo ' if hrw.ignore {' ; \
82+ echo ' return len(p), nil' ; \
83+ echo ' }' ; \
84+ echo ' return hrw.ResponseWriter.Write(p)' ; \
85+ echo '}' ; \
86+ echo '' ; \
87+ echo 'type NotFoundHook struct {' ; \
88+ echo ' h http.Handler' ; \
89+ echo '}' ; \
90+ echo '' ; \
91+ echo 'func (nfh NotFoundHook) ServeHTTP(w http.ResponseWriter, r *http.Request) {' ; \
92+ echo ' nfh.h.ServeHTTP(&hookedResponseWriter{ResponseWriter: w}, r)' ; \
93+ echo '}' ; \
94+ echo '' ; \
95+ echo 'func main() {' ; \
96+ echo ' http.Handle("/", handlers.ProxyHeaders(handlers.LoggingHandler(os.Stdout, NotFoundHook{http.FileServer(assetFS())})))' ; \
97+ echo ' log.Fatal(http.ListenAndServe(getEnv("BIND", ":8080"), &h2c.Server{}))' ; \
98+ echo '}' ; \
99+ ) > web.go
100+ COPY --from=asset-compiler /bindata_assetfs.go bindata_assetfs.go
101+ ARG GOOS=linux
102+ ENV GOOS=$GOOS
103+
104+ ARG CGO_ENABLED=0
105+ ENV CGO_ENABLED=$CGO_ENABLED
106+
107+ RUN go build -o /server bindata_assetfs.go web.go
108+
109+ ARG UPX_ARGS=-6
110+ RUN upx ${UPX_ARGS} /server
111+
112+ FROM scratch
113+ ENTRYPOINT ["server" ]
114+ COPY --from=server-builder /server /bin/server
0 commit comments