我开发了一个相当大的 django 应用程序。
我已将其部署在连接到 LAN 的服务器计算机(树莓派)上的路径
/var/www/mybig_app/
。
该应用程序使用存储在虚拟环境中的库
/var/www/mybig_app/venv/
。
我配置了一个 .wsgi 文件来指示 Gunicorn 在本地主机的端口 8003 上公开应用程序,并让 nginx 将内容从端口 8003 流式传输到端口 3003。
因此,当前目录为
/var/www/mybig_app/
,我运行
python manage.py runserver localhost:8003
或
/var/www/mybig_app/venv/bin/gunicorn mybig_app.wsgi:application --bind localhost:8003
即使我必须等待大约 5 秒钟,在这两种情况下,我都可以从连接到我的 LAN 地址
localhost:8003
的另一台设备的浏览器访问我的应用程序(我尝试以管理员身份登录,访问所有页面,它有效,没有错误)。
现在我想通过
systemd
将我的应用程序作为服务进行管理。
所以我在
.service
准备了一个 /var/www/mybig_app/infrastructure/systemd/mybig_app.service
文件,与 符号链接
ln -s /var/www/mybig_app/infrastructure/systemd/mybig_app.service /etc/systemd/system/
ln -s /var/www/mybig_app/infrastructure/systemd/mybig_app.service /etc/systemd/system/multi-user.target.wants/
加载了systemd的配置
sudo systemctl daemon-reload
sudo systemctl enable mybig_app.service
(我之前为其他应用程序做过此操作,它有效)
最后我想启动它,但是当从目录
/var/www/mybig_app
我运行
sudo systemctl start mybig_app.service
在达到我设置的 15 秒超时后,我得到了命令,并且我得到了
Job for mybig_app.service failed because a timeout was exceeded.
See "systemctl status mybig_app.service" and "journalctl -xe" for details.
所以我跑步
journalctl -xe
我明白了
--
-- A stop job for unit mybig_app.service has finished.
--
-- The job identifier is 20135 and the job result is done.
May 08 17:48:02 Raspberry100 systemd[1]: Starting service for starting the app mybig_app on RPi...
-- Subject: A start job for unit mybig_app.service has begun execution
-- Defined-By: systemd
-- Support: https://www.debian.org/support
--
-- A start job for unit mybig_app.service has begun execution.
--
-- The job identifier is 20135.
May 08 17:48:05 Raspberry100 sudo[1806]: root : TTY=pts/1 ; PWD=/var/www/mybig_app ; USER=root ; COMMAND=/bin/systemctl daemon-reload
May 08 17:48:05 Raspberry100 sudo[1806]: pam_unix(sudo:session): session opened for user root by pi(uid=0)
May 08 17:48:05 Raspberry100 systemd[1]: Reloading.
May 08 17:48:05 Raspberry100 sudo[1806]: pam_unix(sudo:session): session closed for user root
May 08 17:48:09 Raspberry100 sudo[1838]: root : TTY=pts/1 ; PWD=/var/www/mybig_app ; USER=root ; COMMAND=/bin/systemctl start mybig_app.
May 08 17:48:09 Raspberry100 sudo[1838]: pam_unix(sudo:session): session opened for user root by pi(uid=0)
May 08 17:48:18 Raspberry100 systemd[1]: mybig_app.service: Start operation timed out. Terminating.
May 08 17:48:18 Raspberry100 systemd[1]: mybig_app.service: Failed with result 'timeout'.
-- Subject: Unit failed
-- Defined-By: systemd
-- Support: https://www.debian.org/support
--
-- The unit mybig_app.service has entered the 'failed' state with result 'timeout'.
May 08 17:48:18 Raspberry100 systemd[1]: Failed to start service for starting the app mybig_app on RPi.
-- Subject: A start job for unit mybig_app.service has failed
-- Defined-By: systemd
-- Support: https://www.debian.org/support
--
-- A start job for unit mybig_app.service has finished with a failure.
--
-- The job identifier is 20135 and the job result is failed.
May 08 17:48:18 Raspberry100 sudo[1838]: pam_unix(sudo:session): session closed for user root
这里有什么问题?
我认为它以某种方式链接到我的
mybig_app.service
文件的内容,但我过去使用过相同的过程和其他应用程序,只是更改了项目名称,它总是有效。
另一个问题可能是安装的库,它们相当旧(项目是 2018 年的)。
请注意,由于我通过 python 和 Gunicorn 运行该应用程序需要几秒钟(不超过 5 秒)来设置,因此我在我的 .service 文件中设置了
[Service]
...
# RestartSec=100ms # this is the default
RestartSec=15s
TimeoutStartSec=15s
TimeoutSec=15s
为了让它有更多的时间来设置(默认重启超时是0.1秒)。
我已删除并重新创建虚拟环境。
我已重新启动服务器。
我尝试将超时时间增加到 115 秒。
我注意到,随着启动命令的持续, 我可以从连接到我的 LAN 的另一台设备的浏览器访问并导航我的应用程序。
这个问题与this类似,因为我无法作为服务启动或重新启动我的应用程序,但我可以通过python或gunicorn成功运行它。但就我而言,我没有使用 httpd 作为 Web 服务器,而是使用 nginx,它对于以相同方式配置的其他应用程序运行良好。
mybig_app.service
[Unit]
# the first line must be
# [Unit]
#------------------------------------------------------------------------
# what to do with this file
# this file must be named
# <target_app>.service
# and deployed to
# /etc/systemd/system
# to be ran on boot.
# Once in the folder make the file executable
# sudo chmod +x <target_app>.service
# This will start the service but will not run it on boot.
# sudo systemctl start <target_app>.service
# To make your service automatically run on boot
# sudo systemctl daemon-reload
# sudo systemctl enable <target_app>.service
# Run this in terminal to disable the program on boot
# sudo systemctl daemon-reload
# sudo systemctl disable <target_app>.service
# Documentation https://www.freedesktop.org/software/systemd/man/systemd.service.html
#------------------------------------------------------------------------
Description=service for starting the app mybig_app on RPi
After=network.target
# This will not start execution of this file until the network connection is made
# It can be replaced with other parameters of your choosing
# e.g.
# After=syslog.target
[Service]
WorkingDirectory=/var/www/mybig_app/
ExecStart=/var/www/mybig_app/venv/bin/gunicorn mybig_app.wsgi:application --bind localhost:8003
StandardOutput=file:/var/log/mybig_app/mybig_app-stdout.log
StandardError=file:/var/log/mybig_app/mybig_app-stderr.log
#Optional: Saves the output and error log of the terminal to a .log file in a directory of your choosing.
Restart=always
# Automatically restart on kill
# RestartSec=100ms # this is the default
RestartSec=15s
TimeoutStartSec=15s
TimeoutSec=15s
KillSignal=SIGQUIT
# Optional: To cleanly end the file on stop use this command. This sends a terminal interrupt command on the executable script
# alternatively:
# Restart=on-failure
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target