2

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...)

icza
  • 389,944
  • 63
  • 907
  • 827

2 Answers2

6

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: 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.

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827
6

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.)

nos
  • 223,662
  • 58
  • 417
  • 506
  • Now I use xdg-open in my golang script. It contains: `exec.Command("/bin/sh", "-c", "xdg-open path/to/my/pdf.pdf")` If I use `go run goserver/script.go` it works fine. But If I use systemctl service file I get the Error: no "view" rule for type "application/pdf" passed its test case. What Environment should I use in this case? – Денис Смаль May 31 '18 at 07:16