1

我写了简单的 systemd 服务文件goserver.service

[Unit]
Description=Goserver

[Service]
ExecStart=/usr/bin/go run /home/denis/goserver/index.go

[Install]
WantedBy=multi-user.target

但是当我尝试运行服务并获取状态时:

$ sudo systemctl status goserver.service

我得到错误:

мар 02 12:28:04 DV go[13627]: home/denis/goserver/index.go:6:2: cannot find package "gopkg.in/mgo.v2" in any of:
мар 02 12:28:04 DV go[13627]:         /usr/lib/go-1.6/src/gopkg.in/mgo.v2 (from $GOROOT)
мар 02 12:28:04 DV go[13627]:         ($GOPATH not set)

但是$GOPATHexport命令设置:

$ export GOPATH="/home/denis/goserver/"

$ ls $GOPATH
goserver.log  index.go  pkg  src  templates

命令行中的这个命令可以正常工作:

$ /usr/bin/go run /home/denis/goserver/index.go

但是,如果我使用 systemd 服务,它就不起作用。

如何在检测到的情况下运行 systemd 服务$GOPATH?(没有由命令创建的二进制文件go build...

4

2 回答 2

5

您创建的服务很可能会与不同的用户一起运行(很可能root是默认用户),其中可能没有GOPATH设置环境变量(或可能指向不同的文件夹)。

你不应该go run用来运行用 go 编写的服务。go build首先使用或将它们编译为可执行二进制文件go install(更多信息:What does go build build?),然后在ExecStart. 然后,您将不会依赖GOPATH安装的依赖项之类的东西(因为构建/安装只有在它们确实存在时才会成功)。

如果您真的想使用go run,请确保GOPATH为您的服务启动的用户设置;并且用户对该GOPATH文件夹具有适当的权限(因为它位于用户主文件夹中)。另请注意,您可以在该部分中指定User=Group=指令[Service],这样您就可以控制由哪个用户启动您的服务。

于 2017-03-02T09:50:54.027 回答
5

systemd 服务在干净的环境中运行,因此它不会被用户在启动服务时碰巧所处的任何随机环境所破坏。

所以你需要在你的服务文件中设置GOPATH

[Service]
Environment=GOPATH=/home/denis/goserver/
ExecStart=/usr/bin/go run /home/denis/goserver/index.go

这是一个非常不寻常的设置,您通常在其他地方构建您的应用程序,并让服务指向现有的二进制文件,并且没有让服务编译和运行您的代码,并可能带来所有潜在的问题(当前代码没有编译,增加服务器意外暴露其源代码的机会等)

于 2017-03-02T10:21:18.703 回答