la0wei
V2EX  ›  Go 编程语言

请教下 Linux 下 golang 编译的二进制程序开机启动

By la0wei at 2020 年 6 月 24 日 · 5472 次点击
请教下 linux 下 golang 编译的二进制程序开机启动

背景:
需要一个伪装站,最好是视频类的,流量大点,所以想到用 golang 的程序,一般单文件,对我这种 linux 苦手再好不过。
找到这么几个
a https://github.com/wybiral/tube
b https://github.com/prologic/tube 从上一个 fork
c https://github.com/stashapp/stash

现象:
a 程序终端正常运行,rc.localnohup&启动无法运行,打印信息后看到
panic: html/template: pattern matches no files: `templates/*`

goroutine 1 [running]:
html/template.Must(...)
/home/davy/.go/src/html/template/template.go:372
github.com/wybiral/tube/pkg/app.NewApp(0xc000065290, 0xc0000652f0, 0x1, 0x8b8360)
/home/davy/go/src/github.com/wybiral/tube/pkg/app/app.go:54 +0xf06
main.main()
/home/davy/go/src/github.com/wybiral/tube/main.go:17 +0x224
panic: html/template: pattern matches no files: `templates/*`
上面的路径非我本机路径,应该是开发者的

b 程序终端正常运行,单文件,rc.localnohup&记不太清了,似乎是可以的

c 程序终端正常运行,单文件,rc.localnohup&启动无法运行,打印信息后看到
panic: Config File "config" Not Found in "[/ /.stash]"

goroutine 1 [running]:
github.com/stashapp/stash/pkg/manager.initConfig()
/stash/pkg/manager/manager.go:74 +0x2e6
github.com/stashapp/stash/pkg/manager.Initialize.func1()
/stash/pkg/manager/manager.go:43 +0x35
sync.(*Once).Do(0x274f2d8, 0x1cc6c38)
/usr/local/go/src/sync/once.go:44 +0xb3
github.com/stashapp/stash/pkg/manager.Initialize(0xc0001d9f88)
/stash/pkg/manager/manager.go:40 +0x39
main.main()
/stash/main.go:15 +0x22

疑问:rc.local 启动程序和终端启动有啥区别,为何程序启动后有不同的输出?如何开机启动?
第 1 条附言  ·  2020 年 6 月 24 日
我的疏忽,表达不到位。
除了开机启动,另外需要程序在后台运行。
直接在终端运行的话,程序是前台运行,会输出日志。
31 条回复  •  2020-08-24 18:35:28 +08:00
kuro1
   1
kuro1  
   2020 年 6 月 24 日   ❤️ 1
工作路径不同
GeruzoniAnsasu
   2
GeruzoniAnsasu  
   2020 年 6 月 24 日   ❤️ 1
https://github.com/stashapp/stash/blob/develop/docker/build/x86_64/Dockerfile

这不是有 docker 吗
开机把容器拉起来就好了,有这么纠结?
Tink
   3
Tink  
   2020 年 6 月 24 日   ❤️ 1
完整路径
la0wei
   4
la0wei  
OP
   2020 年 6 月 24 日
@kuro1 确实怀疑路径不同,但是我用的绝对路径
@GeruzoniAnsasu docker 编写 dockerfile 还是太麻烦了,go 在 docker 里似乎还有些小 trick,比如 gosu 什么的,不愿意搞
@Tink 使用的绝对路径
RubyJack
   5
RubyJack  
   2020 年 6 月 24 日   ❤️ 2
装一个 supervisor 写一个配置文件搞定
no1xsyzy
   6
no1xsyzy  
   2020 年 6 月 24 日   ❤️ 1
@la0wei #4 可能 pwd 不同导致程序行为不同,或者 uid 不同,或者其他什么什么什么。
建议不要 nohup 而是采用 daemonizer,比如 screen supervisor systemd
zjsxwc
   7
zjsxwc  
   2020 年 6 月 24 日   ❤️ 1
除了 supervisor
还可以 crontab @reboot
逃
kiracyan
   8
kiracyan  
   2020 年 6 月 24 日   ❤️ 1
systemd
vinsec
   9
vinsec  
   2020 年 6 月 24 日   ❤️ 1
用 systemd 守护 资源文件路径用绝对路径
la0wei
   10
la0wei  
OP
   2020 年 6 月 24 日
@RubyJack @no1xsyzy
抱歉,工作走开很久。刚刚试了下,supervisor 确实简单好用,不过又遇到问题了。
补充一点,stash 这个程序会占据终端输出,所以要放在后台。然而使用 supervisor 启动后,程序不停的启动退出,pid 一直在变,这有可能是啥原因

@zjsxwc crontab 不知道能否把程序放在后台运行,supervisor 遇到程序一直启动退出的循环问题

@kiracyan @vinsec systemd 要写 service 文件,还不确定能成功,我太懒了,想先把 supervisor 搞定再说
54007
   11
54007  
   2020 年 6 月 24 日   ❤️ 1
我这里有一个例子吧 golang 程序注册成服务,开机启动 https://github.com/hellojukay/systemd-demo
fanpei0121
   12
fanpei0121  
   2020 年 6 月 24 日   ❤️ 1
pm2 管理进程
simple2025
   13
simple2025  
   2020 年 6 月 24 日   ❤️ 1
@la0wei 你这程序不能前台运行?
kiracyan
   14
kiracyan  
   2020 年 6 月 24 日   ❤️ 1
@la0wei 其实 supervisor 是用 systemd 来管理的 启动退出可能是你程序崩了触发了重启机制
la0wei
   15
la0wei  
OP
   2020 年 6 月 24 日
@54007 谢谢,晚上试试看
@fanpei0121 谢谢,这个没有试过,先尝试已掌握的知识上解决
@chenqh 谢谢,正是因为前台运行,会占用终端,在终端输出内容。我想转到后台,不用一直占着终端,以前我都是用 tmux 来解决的,但是不能重启,而且 ssh 你也知道这网络情况,上去一次真不容易
ruanimal
   16
ruanimal  
   2020 年 6 月 24 日   ❤️ 1
@la0wei 你用 supervisor 就不会占用终端了, 用 supervisor 的程序不要以 daemon 模式运行,直接前台启动就好了
keepeye
   17
keepeye  
   2020 年 6 月 24 日   ❤️ 1
systemd 最优
supervisor 次之
其他的不建议
caola
   18
caola  
   2020 年 6 月 24 日   ❤️ 1
systemd 最好,
默认的 supervisor 进程还得靠 systemd 来守护。。。。
no1xsyzy
   19
no1xsyzy  
   2020 年 6 月 24 日   ❤️ 1
@la0wei #10 我试了下 wybiral/tube 在 screen 下和 supervisor 下都正常……
具体你应该 supervisorctl 进去用 tail 、tail <program> stderr 之类看看 log 。
la0wei
   20
la0wei  
OP
   2020 年 6 月 24 日
@ruanimal 我也是这个想法,但是没有成功,一个参数都没敢加,如果我的配置文件没错的话,效果和终端运行应该是差不多的,奈何总是退出

@keepeye systemd 总是要学的,现在偷懒,想先把服务跑起来,以后再完善些

@caola supervisor 还是要简单一点的

@no1xsyzy 我的 vps 用的 root,supervisor 配置文件如下
[program:stash]
command=/root/stash/stash-linux
directory=/root/stash/
user=root
numprocs=1
screen 一定是没问题的。以前都用 screen 或 tmux 来运行 golang 的程序,现在想要进步一点

tail -100 stash 后提示
Warning: sys.stdout.encoding is set to iso8859-1, so Unicode output may fail. Check your LANG and PYTHONIOENCODING environment settings.

正在搜索解决方案
no1xsyzy
   21
no1xsyzy  
   2020 年 6 月 24 日   ❤️ 1
请检查你的 locale,建议优先使用 UTF-8
https://wiki.archlinux.org/index.php/Locale_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
可能导致 encoding/decoding 时 raise
顺便再看下 stderr 吧

有可能 stash 依赖 stdout 是 tty
实在不行还有定时 RunOnce=screen -dmS session_name program argv
但这个做法是邪道。

其实如果不考虑访问日志和 attach 的话 systemd 更简单一点,反正大头早已经配好了。
la0wei
   22
la0wei  
OP
   2020 年 6 月 24 日
@no1xsyzy 谢谢。编码已通过下面问题解决
export PYTHONIOENCODING="UTF-8"$PYTHONIOENCODING
这次 supervisor tail 不报错了,不过内容为空

我也不是头铁硬要用 supervisor,只是好奇为何程序启动后有不同的现象。
la0wei
   23
la0wei  
OP
   2020 年 6 月 24 日
@kuro1 @GeruzoniAnsasu @Tink @RubyJack @no1xsyzy @kiracyan @vinsec @54007 @chenqh @ruanimal @keepeye @caola
谢谢各位,使用 systemd 已经搞定了。
还是想知道出问题的原因,以后大家偶遇类似的问题或者解决方案,欢迎回来留言
askfermi
   24
askfermi  
   2020 年 6 月 24 日   ❤️ 1
除了用 supervisor 之类的,我记得还可以直接把 golang 的程序注册成系统服务: https://github.com/kardianos/service
ttimasdf
   25
ttimasdf  
   2020 年 6 月 24 日   ❤️ 1
好好学学 docker,dockerfile 编写比 systemd unit 要容易的多,且更通用。一个 golang 用 systemd 还能糊一下,一个 python 加一堆依赖用 systemd 咋整?再调个 bash,source 一下 pyenv ?

而且根本就不涉及什么 gosu 啊这这那那的,创建 golang 程序的 docker 容器是最最简单的。直接从 scratch 镜像初始化一个完全空白的容器,把编译好的 binary 丢进去就成了。我手把手教你写 dockerfile 。

FROM scratch
COPY ./your_exe /app/your_exe
COMMAND /app/your_exe

直接一 build 一 run 就完了!什么 screen supervisord pm2 systemd 那都是上世纪的东西了,除了配置复杂,显得很有技术含量之外,没有什么实际的优点,而且完全不 portable 。
la0wei
   26
la0wei  
OP
   2020 年 6 月 26 日
@askfermi systemd 启动也算是服务吧,只不过没有同一名称叫服务
@keepeye docker 白天各种事情,没有及时回复,抱歉。docker 确实是大杀器,我是因为方案看的太多,想一步到位,有时太过追求完美,所以 dockerfile 写的太复杂,反而忘记了解决问题的初衷,docker 确实是最优方案,我换一台 vps 测试看看
askfermi
   27
askfermi  
   2020 年 6 月 26 日
@la0wei 你这么说也没错。用这个的好处是不需要额外的第三方来管理(当然也带来了一些不足)。
keepeye
   28
keepeye  
   2020 年 6 月 26 日
@la0wei docker 学习可以,但 docker 要解决的不是你问的这个问题
julyclyde
   29
julyclyde  
   2020 年 6 月 28 日
@ttimasdf docker 也不 portable 啊 只能 x86linux
ttimasdf
   30
ttimasdf  
   2020 年 7 月 13 日
@julyclyde 这个帖子讨论的是 daemon 化运行,而 docker 带来的额外优点,也就是我前面提的“portable”的意思是,在一台 vps 和另一台 vps 之间,快速迁移部署的能力。

在不同操作系统之间“可移植”某种意义上是个伪命题,这跟这个主题讨论的问题就不一样了,展开来讲也太长了。
revalue
   31
revalue  
   2020 年 8 月 24 日   ❤️ 1
@la0wei 点开 c 项目,发现了不得了的东西,收藏了
The Go Programming Language
› http://golang.org/
› Go Playground
Go Projects
› Revel Web Framework
© 2026 V2EX · 58ms · 3.9.8.5