Docker golang包导入错误:导入路径不以主机名开头

huangapple go评论110阅读模式
英文:

Docker golang package import error : import path does not begin with hostname

问题

我正在尝试测试Docker和Go项目。这是我的Dockerfile:

FROM golang

ARG app_env
ENV APP_ENV $app_env

COPY ./ /go/src/github.com/user/myProject/app
WORKDIR /go/src/github.com/user/myProject/app

RUN go get ./
RUN go build

CMD if [ ${APP_ENV} = production ]; \
	then \
	app; \
	else \
	go get github.com/pilu/fresh && \
	fresh; \
	fi

EXPOSE 8080

它可以正常运行。然后我向我的Go程序添加了一个包"testpack"。

package main

import(
	"fmt"
	"time"
	"testpack"
)

var now = time.Now()
var election = time.Date(2016, time.November, 8, 0, 0, 0, 0, time.UTC)

func main() {
	//获取选举日期与当前日期之间的持续时间
	tillElection := election.Sub(now)
	//获取持续时间的纳秒数
	toNanoseconds := tillElection.Nanoseconds()
	//从toNanoseconds计算小时数
	hours := toNanoseconds/3600000000000
	remainder := toNanoseconds%3600000000000
	//从小时的余数中计算分钟数
	minutes := remainder/60000000000
	remainder = remainder%60000000000
	//从分钟的余数中计算秒数
	seconds := remainder/1000000000 
	//计算天数,并从小时的余数中获取剩余的小时数
	days := hours/24
	hoursLeft := hours%24

	fmt.Printf("\nHow long until the 2016 U.S. Presidential election?\n\n%v Days %v Hours %v Minutes %v Seconds\n\n", days, hoursLeft, minutes, seconds)
}

然后我运行了docker build ./,但是出现了错误:

package testpack: unrecognized import path "testpack" (import path does not begin with hostname)

我尝试了这个解决方法stackoverflow链接,但是没有解决。

感谢任何帮助。

英文:

I am trying to test docker and go project. Here is my dockerfile

FROM golang

ARG app_env
ENV APP_ENV $app_env

COPY ./ /go/src/github.com/user/myProject/app
WORKDIR /go/src/github.com/user/myProject/app



RUN go get ./
RUN go build

CMD if [ ${APP_ENV} = production ]; \
then \
app; \
else \
go get github.com/pilu/fresh && \
fresh; \
fi	
EXPOSE 8080

It runs fine. Then i added a package "testpack" to my go program.

package main

import(
"fmt"
"time"
"testpack"
)

var now = time.Now()
var election = time.Date(2016, time.November, 8, 0, 0, 0, 0, time.UTC)
func main() {
 //get duration between election date and now
tillElection := election.Sub(now)
//get duration in nanoseconds
toNanoseconds := tillElection.Nanoseconds()
//calculate hours from toNanoseconds
hours := toNanoseconds/3600000000000
remainder := toNanoseconds%3600000000000
//derive minutes from remainder of hours
minutes := remainder/60000000000
remainder = remainder%60000000000
//derive seconds from remainder of minutes
seconds := remainder/1000000000 
//calculate days and get hours left from remainder
days := hours/24
hoursLeft := hours%24

fmt.Printf("\nHow long until the 2016 U.S. Presidential election?\n\n%v Days %v Hours %v Minutes %v Seconds\n\n", days, hoursLeft, minutes, seconds)

}

Now i ran=> docker build ./

I am getting an error

package testpack: unrecognized import path "testpack" (import path does not begin with hostname)

I tried this https://stackoverflow.com/questions/29774786/error-import-path-does-not-begin-with-hostname-when-building-docker-with-local but couldn't resolve

Any help is appreciated.

答案1

得分: 2

显然,它正在尝试从互联网加载它,因为在你的GOPATH中找不到"testpack"。

你没有向我们展示你的GOPATH设置或者你将"testpack"复制到哪里,所以除了说"它丢失了",我无法告诉你更多。

请阅读https://golang.org/cmd/go/#hdr-Relative_import_paths

尝试以下两种方法之一:

  • import "./testpack"
  • 在你的Dockerfile中将GOPATH设置为"/go"
    import "github.com/user/myProject/app/testpack"
英文:

It is obviously trying to load it from the Internet because it isn't finding "testpack" in your GOPATH.

You didn't show us your GOPATH setting or where you copied "testpack" to, so other than saying "It's missing" that's all I can tell you.

Read https://golang.org/cmd/go/#hdr-Relative_import_paths

Try either

  • import "./testpack"
  • Set GOPATH to "/go" in your Dockerfile
    import "github.com/user/myProject/app/testpack"

答案2

得分: 0

听起来你在docker build过程中遇到了一个问题,这很可能是一个依赖性问题(你在本地的$GOPATH上安装了一个依赖项,但在镜像的go环境中没有安装)。你可以在Dockerfile中的构建命令之前安装依赖项,但我强烈建议在Dockerfile之外构建应用程序,并在构建过程中将可执行文件复制到镜像中。

Golang的最大优势之一是静态编译的可执行文件。一旦编译完成,你应该能够在任何等效的架构上运行它。默认情况下,go会尝试编译一个静态可执行文件,但如果你想强制执行它(并且没有使用CGO进行任何复杂操作),你可以设置CGO_ENABLED环境变量为0进行构建,例如:CGO_ENABLED=0 go build -o <output.name> <file.to.build>

这样,你的Dockerfile就会变得简单得多(而且更小,检查生成的镜像的大小),类似于:

FROM scratch

#将可执行文件复制到容器中
ADD <output.name> <output.name>

#设置入口点
ENTRYPOINT [./<output.name>]

#设置暴露的端口
EXPOSE 8080

这样应该解决你的依赖性问题,并使你的运行时容器更小(可能小于20MB),从而减少构建时间并提高部署速度。

英文:

It sounds an awful lot like you're having a problem building your app inside the docker build process. This is likely a dependency issue (you have a dependency installed on your local $GOPATH that is not installed inside the image's go environment). You could install the dependency before the build command in the Dockerfile, but I would pretty seriously consider building the app outside of the Dockerfile, and copying the executable into the image on build.

One of the biggest advantages of Golang is the statically compiled executables. Once it is compiled, you should be able to run it in any equivalent architecture. By default, go will try to compile a static executable but if you would like to enforce it (and you are not doing anything fancy with CGO) you can build with the CGO_ENABLED env var set to 0 like so: CGO_ENABLED=0 go build -o &lt;output.name&gt; &lt;file.to.build&gt;

At this point, your Dockerfile becomes much simpler (and SMALLER, check the image size of the resulting images), something like:

FROM scratch

#copy executable into container
ADD &lt;output.name&gt; &lt;output.name&gt;

#set entrypoint
ENTRYPOINT [./&lt;output.name&gt;]

#set exposed port
EXPOSE 8080

This should solve your dependency issue, and make your runtime container much smaller (probably < 20MB), which will decrease build times and increase deployment speed.

huangapple
  • 本文由 发表于 2017年9月14日 00:23:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/46202487.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定