Systemd没有检测到GOPATH(没有二进制文件运行)

时间:2017-03-02 09:46:17

标签: go systemd systemctl gopath

我编写了简单的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)

$GOPATH使用export命令设置:

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

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

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

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

但是,如果我使用systemd服务,它就无法工作。

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

2 个答案:

答案 0 :(得分:5)

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

您不应该使用go run来运行go中编写的服务。首先使用go buildgo install(更多内容:What does go build build?)将它们编译为可执行二进制文件,然后在ExecStart中启动可执行二进制文件。那么你就不会依赖GOPATH之类的东西和正在安装的依赖项(因为只有当它们存在时,构建/安装才会成功)。

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

答案 1 :(得分:3)

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

因此您需要在服务文件中设置GOPATH

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

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