2016-10-31 20 views
5

Tôi đang cố gắng chạy một vùng chứa docker với nhà cung cấp. Đây là Dockerfile tôinhà cung cấp godep với docker

FROM golang:alpine 
EXPOSE 8080 

RUN mkdir /app 
ADD . /app/ 
WORKDIR /app 
RUN go build -o myapp . 
CMD ["/app/myapp"] 

và main.go tôi

package main 

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

    "github.com/gorilla/mux" 
) 

func main() { 

    r := mux.NewRouter() 
    r.HandleFunc("/", Hello) 

    http.Handle("/", r) 
    fmt.Println("Starting up on 8080") 
    log.Fatal(http.ListenAndServe(":8080", nil)) 
} 

func Hello(w http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(w, "Hello world!") 
} 

Tôi đang sử dụng godep cho vendoring libs, nó làm việc trong máy tính cục bộ của tôi, nhưng khi tôi đang cố gắng để chạy nó với Docker với:

docker build -t myapp-img . 
docker run -p 8080:8080 --name myapp-cnt myapp-img 

tôi có lỗi sau:

main.go:8:2: cannot find package "github.com/gorilla/mux" in any of: 
     /usr/local/go/src/github.com/gorilla/mux (from $GOROOT) 
     /go/src/github.com/gorilla/mux (from $GOPATH) 

Tôi không hiểu những gì còn thiếu.

Trả lời

4

Lỗi là chính xác. Đó là nói cho bạn tất cả mọi thứ một Gopher mong muốn nhu cầu.

tôi sẽ giả định rằng bạn đã sao chép Gorilla Mux vào thư mục/nhà cung cấp ứng dụng của bạn trong máy tính cục bộ của bạn, như vậy:

./main.go # this is your myapp code you are coping 
./vendor/github.com/gorilla/mux # for vendoring, this must exist 

Nếu bạn muốn tìm hiểu thêm về vendoring, xem câu trả lời phổ biến của tôi ở đây :

How should I use vendor in Go 1.6?

Bây giờ, để khắc phục điều đó lỗi giả sử bạn đã làm ở trên ...

Một Gopher cần se t hợp lệ $GOPATH trước khi bạn có thể tạo. Điều này bị thiếu trong Dockerfile của bạn.

FROM golang:1.7-alpine 
EXPOSE 8080 

# setup GOPATH and friends 
# 
# TECHNICALLY, you don't have to do these three cmds as the 
# golang:alpine image actually uses this same directory structure and 
# already has $GOPATH set to this same structure. You could just 
# remove these two lines and everything below should continue to work. 
# 
# But, I like to do it anyways to ensure my proper build 
# path in case I experiment with different Docker build images or in 
# case the #latest image changes structure (you should really use 
# a tag to lock down what version of Go you are using - note that I 
# locked you to the docker image golang:1.7-alpine above, since that is 
# the current latest you were using, with bug fixes). 
# 
RUN mkdir -p /go/src \ 
    && mkdir -p /go/bin \ 
    && mkdir -p /go/pkg 
ENV GOPATH=/go 
ENV PATH=$GOPATH/bin:$PATH 

# now copy your app to the proper build path 
RUN mkdir -p $GOPATH/src/app 
ADD . $GOPATH/src/app 

# should be able to build now 
WORKDIR $GOPATH/src/app 
RUN go build -o myapp . 
CMD ["/go/src/app/myapp"] 

Ở đây nó đang làm việc ...

$ tree 
. 
├── Dockerfile 
├── main.go 
└── vendor 
    └── mydep 
     └── runme.go 

Nguồn tập tin của ứng dụng của tôi:

$ cat main.go 
package main 

import (
     "fmt" 

     "mydep" 
) 

func main() { 
     fmt.Println(mydep.RunMe()) 
} 

sự phụ thuộc của tôi trong thư mục vendor/ tôi:

$ cat vendor/mydep/runme.go 
package mydep 

// RunMe returns a string that it worked! 
func RunMe() string { 
     return "Dependency Worked!" 
} 

Bây giờ , xây dựng và chạy hình ảnh:

$ docker build --rm -t test . && docker run --rm -it test 
(snip) 
Step 8 : WORKDIR $GOPATH/src/app 
---> Using cache 
---> 954ed8e87ae0 
Step 9 : RUN go build -o myapp . 
---> Using cache 
---> b4b613f0a939 
Step 10 : CMD /go/src/app/myapp 
---> Using cache 
---> 3524025080df 
Successfully built 3524025080df 
Dependency Worked! 

Lưu ý dòng cuối cùng in đầu ra từ bảng điều khiển, Dependency Worked!.

Nó hoạt động vì:

  1. bạn nói bạn đang sử dụng Vendoring, có nghĩa là bạn có một thư mục địa phương gọi là ./vendor trong thư mục gốc của mã ứng dụng của bạn.
  2. khi bạn ADD . /go/src/app, bạn cũng đang sao chép ./vendor địa phương vào mã ứng dụng của mình.
  3. bạn đã sao chép tệp của mình vào cấu trúc thiết lập phù hợp theo yêu cầu của công cụ Xây dựng để tìm gói (và trong trường hợp này, thư mục ./vendor trong thư mục gốc của mã nguồn của bạn).
+0

Thx cho phản hồi, tôi đã cố gắng sử dụng Dockerfile của bạn, nhưng khi tôi chạy lệnh docker run, có vẻ như GOPATH chưa được đặt. 'Lỗi phản hồi từ daemon: lỗi thời gian chạy oci: exec:" $ GOPATH/src/app/myapp ": stat $ GOPATH/src/app/myapp: không có tệp hoặc thư mục nào như vậy.' – sbouaked

+0

sửa Dockerfile ($ GOPATH isn ' t có sẵn cho CMD). cũng đã thêm một ví dụ làm việc hoàn chỉnh (bây giờ tôi đang làm việc với một máy tính xách tay). – eduncan911