github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/cmd/fns/initialization/base/docker.go (about) 1 /* 2 * Copyright 2023 Wang Min Xiang 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package base 19 20 import ( 21 "context" 22 "fmt" 23 "github.com/aacfactory/errors" 24 "os" 25 "path/filepath" 26 "strings" 27 ) 28 29 const ( 30 dockerfile = `# USAGE 31 # docker build -t $$IMAGE_NAME:latest --build-arg VERSION=${VERSION} . 32 33 FROM golang:$$GO_VERSION-alpine AS builder 34 35 ARG VERSION=v0.0.1 36 ENV GO111MODULE on 37 # Enable goproxy 38 ENV GOPROXY https://goproxy.cn,direct 39 40 WORKDIR /build 41 42 COPY . . 43 44 RUN mkdir /dist \ 45 && go generate \ 46 && go build -ldflags "-s -w -X main.Version=${VERSION}" -o /dist/fapp \ 47 && cp -r configs /dist/configs 48 49 50 FROM alpine 51 52 COPY --from=builder /dist / 53 54 # Note: when use UTC, then discard this. 55 RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.cernet.edu.cn/alpine#g' /etc/apk/repositories && \ 56 apk add tzdata \ 57 && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone 58 59 WORKDIR / 60 61 # Note: expose port which is defined in config 62 EXPOSE 18080 63 64 ENTRYPOINT ["./fapp"] 65 ` 66 ) 67 68 func DockerImageNameFromMod(mp string) (name string) { 69 modItems := strings.Split(mp, "/") 70 modItemsLen := len(modItems) 71 if modItemsLen == 1 { 72 name = mp 73 } else { 74 appName := modItems[modItemsLen-1] 75 domain := modItems[0] 76 if modItemsLen > 2 { 77 for i := modItemsLen - 2; i > 0; i-- { 78 appName = modItems[i] + "-" + appName 79 } 80 } 81 name = fmt.Sprintf("%s:%s", domain, appName) 82 } 83 return 84 } 85 86 func NewDockerFile(goVersion string, path string, dir string, dockerImageName string) (mf *DockerFile, err error) { 87 if !filepath.IsAbs(dir) { 88 dir, err = filepath.Abs(dir) 89 if err != nil { 90 err = errors.Warning("fns: new main file failed").WithCause(err).WithMeta("dir", dir) 91 return 92 } 93 } 94 mf = &DockerFile{ 95 name: dockerImageName, 96 path: path, 97 filename: filepath.ToSlash(filepath.Join(dir, "Dockerfile")), 98 goVersion: goVersion, 99 } 100 return 101 } 102 103 type DockerFile struct { 104 name string 105 path string 106 filename string 107 goVersion string 108 } 109 110 func (f *DockerFile) Name() (name string) { 111 name = f.filename 112 return 113 } 114 115 func (f *DockerFile) Write(_ context.Context) (err error) { 116 content := strings.Replace(dockerfile, "$$IMAGE_NAME", f.name, 1) 117 content = strings.Replace(content, "$$GO_VERSION", f.goVersion, 1) 118 writeErr := os.WriteFile(f.filename, []byte(content), 0644) 119 if writeErr != nil { 120 err = errors.Warning("fns: dockerfile write failed").WithCause(writeErr).WithMeta("filename", f.filename) 121 return 122 } 123 return 124 }