英文:
Systemd doesn't detect GOPATH (run without binary file)
问题
我写了一个简单的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...
命令创建的二进制文件)
英文:
I wrote simple systemd service-file goserver.service
:
[Unit]
Description=Goserver
[Service]
ExecStart=/usr/bin/go run /home/denis/goserver/index.go
[Install]
WantedBy=multi-user.target
But when I try to run service and get status:
$ sudo systemctl status goserver.service
I get error:
мар 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)
But $GOPATH
is set with export
command:
$ export GOPATH="/home/denis/goserver/"
$ ls $GOPATH
goserver.log index.go pkg src templates
And this command from command-line works fine:
$ /usr/bin/go run /home/denis/goserver/index.go
But if I use systemd service it doesn't work.
How can I run systemd service with detected $GOPATH
? (without binary file created by command go build...
)
答案1
得分: 6
您创建的服务很可能会以不同的用户身份运行(默认情况下可能是root
),该用户可能没有设置GOPATH
环境变量(或者可能指向不同的文件夹)。
您不应该使用go run
来运行使用Go编写的服务。首先,使用go build
或go install
将它们编译为可执行二进制文件(更多信息请参考:https://stackoverflow.com/questions/30612611/what-does-go-build-build),然后在ExecStart
中启动可执行二进制文件。这样,您就不会依赖于像GOPATH
和已安装的依赖项这样的东西(因为只有在它们存在时,构建/安装才会成功)。
如果您确实想使用go run
,请确保为启动服务的用户设置了GOPATH
,并且该用户对GOPATH
文件夹具有适当的权限(因为它位于用户的主文件夹内)。还请注意,您可以在[Service]
部分中指定User=
和Group=
指令,以便控制服务使用哪个用户启动。
英文:
The service you created will most likely run with a different user (most likely root
is the default), of whom there might not be GOPATH
env variable set (or may point to a different folder).
You shouldn't use go run
to run services written in go. First compile them to executable binaries either with go build
or go install
(more on this: https://stackoverflow.com/questions/30612611/what-does-go-build-build), and start the executable binary in ExecStart
. Then you won't rely on things like GOPATH
and dependencies being installed (because building/installing will only succeed if they do exist).
If you truly want to use go run
, make sure GOPATH
is set for the user your service is started with; and also that the user has proper permissions for the GOPATH
folder (as it's inside a user home folder). Also note that you can specify the User=
and Group=
directives in the [Service]
section, so you can control with what user your service is started.
答案2
得分: 6
一个systemd服务在一个干净的环境中运行,因此不会被用户在启动服务时所处的任意环境所干扰。
所以你需要在你的服务文件中设置GOPATH:
[Service]
Environment=GOPATH=/home/denis/goserver/
ExecStart=/usr/bin/go run /home/denis/goserver/index.go
这是一个非常不寻常的设置,通常你会在其他地方构建你的应用程序,并且让服务指向一个现有的二进制文件,而不是让服务编译和运行你的代码,这样可能会带来各种潜在问题(当前代码无法编译,服务器意外暴露源代码的风险增加等)。
英文:
A systemd service runs with a clean environment, so it is not clobbered by any random environment the user happens to be in when starting a service.
So you need to set the GOPATH in your service file
[Service]
Environment=GOPATH=/home/denis/goserver/
ExecStart=/usr/bin/go run /home/denis/goserver/index.go
This is a very unusual setup though, you normally build your application elsewhere, and have the service point to an existing binary, and don't have the service compile and run your code with all the potential problems that could entail (current code does not compile, increased chance of server accidentally exposes its source code etc.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论