簡體   English   中英

Docker 構建中的多個 go 文件

[英]Multiple go files in Docker build

我正在構建一個 Dockeried 應用程序,在其中將 go 文件拆分為兩個文件。

嘗試運行它時出現以下錯誤:

# command-line-arguments 
./server.go:86:63: undefined: indexHandler

indexHandler 位於 server.go 中時工作正常,但我收到錯誤,它位於 handlers.go 中。

有什么建議么?

//server.go
package main

import (
    "database/sql"
    "fmt"
    "log"
    "net"
    "net/http"
    "os"
    "os/exec"
    "strconv"
    "strings"

    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "github.com/jimlawless/whereami"
    "github.com/rs/cors"
)

type FileSystem struct {
    fs http.FileSystem
}

type dbConnection struct {
    conn *sql.DB
}

var dbx dbConnection
var Config Configs

type Configs struct {
    cookieName     string
    cookieValue    string
    cookieMaxAge   int
    cookieHTTPOnly bool
    cookiePath     string
    domain         string
    port           string
    apiKey         string
    apiVersion     string
    apiPath        string
    protocol       string
}

func setConfig() {
    Config = Configs{}
    Config.cookieName = os.Getenv("COOKIE_NAME")
    Config.cookieValue = os.Getenv("COOKIE_VALUE")
    age, err := strconv.Atoi(os.Getenv("COOKIE_MAX_AGE"))
    if err != nil {
        log.Println(whereami.WhereAmI(), err.Error())
    }
    Config.cookieMaxAge = age

    Config.cookieHTTPOnly, err = strconv.ParseBool(os.Getenv("COOKIE_HTTP_ONLY"))
    if err != nil {
        log.Println(whereami.WhereAmI(), err.Error())
    }

    Config.cookiePath = os.Getenv("COOKIE_PATH")
    Config.domain = os.Getenv("DOMAIN")
    Config.port = os.Getenv("PORT")
    Config.apiKey = os.Getenv("APP_KEY")
    Config.apiVersion = os.Getenv("API_VERSION")
    Config.apiPath = os.Getenv("API_PATH")
    Config.protocol = os.Getenv("PROTOCOL")
}

func main() {
    defer recoverPanic()
    setConfig()
    //db()
    fmt.Println(Config)
    target := Config.protocol + Config.domain + Config.port
    corsOpts := cors.New(cors.Options{
        AllowedOrigins: []string{target}, //you service is available and allowed for this base url
        AllowedMethods: []string{
            http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete, http.MethodOptions, http.MethodHead,
        },
        AllowedHeaders: []string{
            "*", //or you can your header key values which you are using in your application
        },
    })

    router := mux.NewRouter()
    router.HandleFunc(Config.apiPath+Config.apiVersion+"/index", indexHandler).Methods("GET")
    router.PathPrefix("/").Handler(http.FileServer(http.Dir("./")))
    http.ListenAndServe(Config.port, corsOpts.Handler(router))
}

/*
func indexHandler(w http.ResponseWriter, req *http.Request) {
    addCookie(w, Config.cookieName, Config.cookieValue)
    cookie, err := req.Cookie(Config.cookieName)
    if err != nil {
        log.Println(whereami.WhereAmI(), err.Error())
    }

    log.Println("Cookie: ", cookie)
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "hola")
}
*/
func addCookie(w http.ResponseWriter, name, value string) {
    cookie := http.Cookie{
        Name:     Config.cookieName,
        Value:    Config.cookieValue,
        Domain:   Config.domain,
        Path:     Config.cookiePath,
        MaxAge:   Config.cookieMaxAge,
        HttpOnly: Config.cookieHTTPOnly,
    }
    http.SetCookie(w, &cookie)
    log.Println("Cookie added")
}

func (fs FileSystem) Open(path string) (http.File, error) {
    f, err := fs.fs.Open(path)
    if err != nil {
        return nil, err
    }

    s, err := f.Stat()
    if s.IsDir() {
        index := strings.TrimSuffix(path, "/") + "/index.html"
        if _, err := fs.fs.Open(index); err != nil {
            return nil, err
        }
    }

    return f, nil
}

func db() error {
    db, err := sql.Open("mysql", "root:root@tcp(192.168.0.33:4200)/mysql")

    if err != nil {
        log.Print(err.Error())
    } else {
        log.Println("DB connected successfully")
    }
    defer db.Close()

    err = db.Ping()
    if err != nil {
        log.Println("Ping Error: " + err.Error())
    } else {
        dbx.conn = db
    }

    return err
}

func recoverPanic() {
    if rec := recover(); rec != nil {
        err := rec.(error)
        log.Println(whereami.WhereAmI(), err.Error())

        var l *net.TCPListener
        file, err := l.File()
        if err != nil {
            log.Println(whereami.WhereAmI(), err.Error())
        }

        path := os.Args
        args := []string{"-graceful"}

        cmd := exec.Command(path[0], args...)
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        cmd.ExtraFiles = []*os.File{file}

        err2 := cmd.Start()
        if err2 != nil {
            log.Println(whereami.WhereAmI(), err2.Error())
        } else {
            log.Println(whereami.WhereAmI(), "Restarted...")
        }
    }
}
//handlers.go
package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/jimlawless/whereami"
)

func indexHandler(w http.ResponseWriter, req *http.Request) {
    addCookie(w, Config.cookieName, Config.cookieValue)
    cookie, err := req.Cookie(Config.cookieName)
    if err != nil {
        log.Println(whereami.WhereAmI(), err.Error())
    }

    log.Println("Cookie: ", cookie)
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "hola")
}

注釋掉的行是我嘗試過但失敗的東西。

#Dockerfile
FROM golang:alpine AS builder

RUN mkdir /app
RUN rm -f go.mod go.sum
RUN go mod init xyz.com
RUN rm -f $GOPATH/go.mod

ADD . /app/
WORKDIR /app
COPY ./handlers.go .
COPY ./server.go .
COPY ./favicon.ico .
COPY ./assets /assets
COPY ./go.mod . 
COPY ./go.sum .

RUN go mod download

COPY . .

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build $(ls -1 *.go)

# command-line-arguments
#./server.go:86:63: undefined: indexHandler

#RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .
#RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build $(ls -1 *.go)
#RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o server.go handlers.go
#RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o server.go handlers.go
#RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build *.go

EXPOSE 9000
#stat /app/*.go: no such file or directory
#CMD ["go", "run", "/app/*.go"]

CMD ["go", "run", "/app/server.go"]

問題在於您的 Dockerfile,特別是 CMD(最后一行)。

我測試了這個,它工作..

# ~ Dockerfile ~
# ...
# CMD ["go", "run", "/app/server.go"] # <- Remove this
CMD ["go", "run", "."] # <- Add this

編輯:發生這種情況的原因是因為您專門運行server.go 意思是, handlers.go沒有與server.go一起編譯,指定句點告訴go構建/運行當前目錄中的所有文件。 我不確定你是如何使用go run server.go在本地工作的(我無法讓它工作,我不得不使用go run.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM