我有一个 python 脚本,我想在 Freenas 监狱中运行。它无需服务守护程序即可工作,但我想将其作为服务启动。我创建了以下服务脚本/etc/rc.d/出勤
#!/bin/sh
# PROVIDE: attendance
# REQUIRE: DAEMON
# KEYWORD: shutdown
. /etc/rc.subr
name=attendance
rcvar=attendance_enable
load_rc_config $name
: ${attendance_enable="NO"}
pidfile="/var/run/${name}.pid"
command="/root/Zkteco/app.py"
command_interpreter=/usr/local/bin/python
run_rc_command "$1"
我还添加了attend_enable =“是”在/etc/rc.conf下
当我跑步时,服务出勤开始我收到
Starting attendance
limits: /root/Zkteco/app.py: No such file or directory
/etc/rc.d/attendance: WARNING: failed to start attendance
尽管该目录存在,但我尝试将其从 /etc/rc.d/attendance 移动到 /usr/local/etc/rc.d/attendance ,它似乎可以工作,但它也永远不会作为后台进程,而且我有CTRL+C 来停止它。
有什么推荐吗?该脚本是一个使用fastapi和uvicorn的webapp,与它有什么关系吗?如何查看尝试启动的服务错误的日志。
我尝试过的事情
我使用脚本中的 pyinstaller --onefile 创建了一个二进制文件。并改变了
#!/bin/sh
.
.
.
command="/usr/local/bin/app"
run_rc_command "$1
此更改使服务启动,但它永远不会进入后台。
答案1
中的文件/etc/rc.d
被视为操作系统的一部分并由操作系统管理。你应该仅有的正在与/usr/local/etc/rc.d
.请注意,这也是放置所有包的 rc 脚本的位置。
rc.d 是一个服务管理框架。但它对创建“服务”或更准确地说“对进程进行守护进程”没有任何作用。它的存在是为了提供统一的方式来处理“服务”。
您注意到,由于您的应用程序没有按照您的预期下降到后台,因此您需要按 CTRL-C 退出。你的期望与应该发生的事情不符。您的脚本/程序/应用程序有责任自行守护进程(转到后台等)。 rc 脚本只是应用程序的包装器。
我不太了解你的应用程序和 uvicorn。但从文档来看 uvicorn 似乎并不支持守护进程本身。当指定命令行参数时,通常会发生这种情况。您对此的基本测试是:您是否能够从命令行运行您的应用程序并使其自行与控制台分离?
如果你想要一个纯 Python 的方法来做到这一点,那么看看PEP 3143 – 标准守护进程库。
简单的 FreeBSD 方法是利用守护进程(8)。一个非常简单的例子是:
#!/bin/sh
# REQUIRE: LOGIN
. /etc/rc.subr
name=attendance
rcvar=`set_rcvar`
pidfile="/var/run/${name}.pid"
attendance_user="somenotrootuser"
command="/usr/sbin/daemon"
command_args="-c -f -P ${pidfile} -u ${attendance_user} -r /usr/local/bin/app"
load_rc_config $name
run_rc_command "$1"
(看有没有一种简单的方法来创建 FreeBSD rc 脚本?和FreeBSD rc.d 脚本不作为守护进程启动)
我注意到您将您的应用程序放置在/root
.闻起来就像你正在以 root 身份运行东西一样。以非特权用户身份运行是一个很好的做法。
这应该适用于您的简单情况。如果这是一个适当的生产部署,您需要做更多的事情,但这是由于 uvicorn 而不是 FreeBSD。如果您阅读了https://www.uvicorn.org/deployment/您会注意到,在生产中您经常会使用 gunicorn,也许还会使用 nginx。
以上是 FreeBSD 的“正确”做事方式。如果您喜欢使用 FreeBSD,那么这是一个很好的学习和使用工具。
但是,如果您是一名 Python/Web 程序员,并且发现设置 Gunicorn 等令人畏惧,那么您可能会发现安装起来更容易监督者。它很容易作为一个包安装sysutils/py-supervisor/。这可以被视为 rc/daemon 的替代方案,您会在网上找到更多专门用于 Python Web 项目的示例。