我编写了简单的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...
创建的二进制文件)
答案 0 :(得分:5)
您创建的服务很可能与其他用户一起运行(很可能root
是默认设置),其中可能没有GOPATH
env变量集(或者可能指向不同的文件夹) )。
您不应该使用go run
来运行go中编写的服务。首先使用go build
或go 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
这是一个非常不寻常的设置,但是,您通常在其他地方构建应用程序,并将服务指向现有的二进制文件,并且没有服务编译并运行您的代码以及可能带来的所有潜在问题(当前代码无法编译,服务器意外暴露其源代码等的可能性增加。)