I'm deploying a Django app in a virtual environment and I'm using supervisor for the app itself and some Celery tasks. When my /etc/supervisor/conf.d/project is like this:
[program:botApp]
command = /home/ubuntu/gunicorn_start.bash;
user = ubuntu;
stdout_logfile = /home/ubuntu/logs/gunicorn_supervisor.log;
redirect_stderr = true;
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8;
it works fine, I do sudo systemctl restart supervisor and I can see it running properly, but when I add my second program in the same configuration file like this:
[program:botApp]
command = /home/ubuntu/gunicorn_start.bash;
user = ubuntu;
stdout_logfile = /home/ubuntu/logs/gunicorn_supervisor.log;
redirect_stderr = true;
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8;
[program:worker]
command=/home/ubuntu/django_env/bin/celery -A botApp worker -l info;
user=ubuntu;
numprocs=1;
stdout_logfile=/home/ubuntu/logs/celeryworker.log;
redirect_stderr = true;
autostart=true;
autorestart=true;
startsecs=10;
stopwaitsecs = 600 ;
killasgroup=true;
priority=998;
it throws the following error:
● supervisor.service - Supervisor process control system for UNIX
Loaded: loaded (/lib/systemd/system/supervisor.service; enabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: exit-code) since Tue 2018-09-04 08:09:26 UTC; 12s ago
Docs: http://supervisord.org
Process: 21931 ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown (code=exited, status=0/SUCCESS)
Process: 21925 ExecStart=/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf (code=exited, status=2)
Main PID: 21925 (code=exited, status=2)
Sep 04 08:09:26 ip-172-31-45-13 systemd[1]: supervisor.service: Unit entered failed state.
Sep 04 08:09:26 ip-172-31-45-13 systemd[1]: supervisor.service: Failed with result 'exit-code'.
I have tried changing the second program to be the same as the first one with different name and log file and it throws the same error. Do I need to do something extra for using 2 programs with supervisor? Many thanks.
Since this question was asked over a year ago, it seems doubtful we'll ever receive the answers to these questions, but the following pieces of information would have been helpful:
what Linux distribution and version are (or were) you using; e.g., Ubuntu 18.04, CentOS 7, etc.?
did you look at the logs generated by systemd? (journalctl -xu supervisord)
what, if any, messages did they contain?
did you look at the individual log files generated by your two supervisord services (e.g., /home/ubuntu/logs/celeryworker.log)?
what, if any, messages did they contain?
My gut feel is that the output of journalctl -xu supervisord will tell you what you need to know. Or at least move you a step in the right direction.
Once the configuration file has been created, you may update the Supervisor configuration and start the processes using the following commands:
sudo supervisorctl reread
sudo supervisorctl update
and then restart your supervisorctl
Related
I'm trying to run a bot on a VPS and im able to get a systemd service create so as to be able to run my python code automatically if the server were to ever reboot for any reason. The service is enabled, the status is showing as active when I check its status, and journalctl shows that the .py file has started, but that's where my progress ends. I receive no other output after the notification that the service has started. And when I check my VPS console there is 0 CPU usage meaning that the script is in fact not running.
The script is located at /home/user/projects/ytbot1/bot/main.py and runs perfectly fine when executed manually through python3 main.py.
both the script and the .service file were given u+x permissions to the root and user, and the service is set to run only when the user is logged in (I think,... all I did was set User=myusername in ytbot1.service)
[Unit]
Description=reiss YT Bot
[Service]
User=reiss
Group=reiss
Type=exec
ExecStart=/usr/bin/python3 "/home/reiss/projects/ytbot1/bot/main.py"
Restart=always
RestartSec=5
PrivateTmp=true
TimeoutSec=900
[Install]
WantedBy=multi-user.target
here's the output from sudo systemctl status ytbot1
● ytbot1.service - reiss YT Bot
Loaded: loaded (/etc/systemd/system/ytbot1.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-05-16 10:34:04 CEST; 9s ago
Main PID: 7684 (python3)
Tasks: 1 (limit: 19141)
Memory: 98.4M
CGroup: /system.slice/ytbot1.service
└─7684 /usr/bin/python3 /home/reiss/projects/ytbot1/bot/main.py
and sudo journalctl -fu ytbot1.service
root#vm1234567:~# journalctl -fu ytbot1.service
-- Logs begin at Mon 2022-05-16 07:41:00 CEST. --
May 16 10:07:18 vm1234567.contaboserver.net systemd[1]: Starting reiss YT Bot...
May 16 10:07:18 vm1234567.contaboserver.net systemd[1]: Started reiss YT Bot.
and it stops there. the log doesn't update or add new information.
desired output:
-- Logs begin at Mon 2022-05-16 07:41:00 CEST. --
May 16 10:07:18 vm1234567.contaboserver.net systemd[1]: Starting reiss YT Bot...
May 16 10:07:18 vm1234567.contaboserver.net systemd[1]: Started reiss YT Bot.
Handling GoogleAPI
2022 5 15 14 38 2
./APR_2022_V20 MAY_2022_V15.mp4
DOWNLOADING VIDEOS...
[...] *Script runs, you get the picture*
Any help? Could it be that I have my .py file in the wrong place or maybe something's wrong with the .service file/working directory? Maybe I should use a different version of python? The script i'm trying to run is pretty complex so maybe forking could be an issue (the code calls on a couple google apis but setting Type=forking just forces the service startup to infinitely load then time-out for some reason)? I don't know mayn... I appreciate feedback. Thanks!
Try using /usr/bin/python3 -u and then the file path.
The -u option tells Python not to fully buffer output.
By default, Python uses line buffering if the output is a console, otherwise full buffering. Line buffering means output is saved up until there's a complete line, and then flushed. Full buffering can buffer many lines at a time. And the systemd journal is probably not detected as a console.
I tried to run a Python script as a system service, but the service is not starting. Here is my configuration:
pyntp.service:
[Unit]
Description=Python NTP Service
After=multi-user.target
[Service]
Type=forking
ExecStart=/usr/bin/python $HOME/ntp/ntpservice.py
[Install]
WantedBy=multi-user.target
ntpservice.py:
#!/usr/bin/python
import os
import time
import json
pid = os.fork()
if pid == 0:
print 'parent'
else:
print 'child'
while True:
print('123')
time.sleep(1)
The step to start the service is as follows:
cp pyntp.service /etc/systemd/system/
cp ntpservice.py /usr/local/bin/
systemctl daemon-reload
systemctl enable pyntp.service
systemctl start pyntp.service
The thing is, when I try to see the status of pyntp service, it is always like this:
● pyntp.service - Python NTP Service
Loaded: loaded (/usr/lib/systemd/system/pyntp.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Wed 2018-11-14 22:27:56 CST; 34min ago
Process: 801 ExecStart=/usr/bin/python $HOME/ntp/ntpservice.py (code=exited, status=0/SUCCESS)
Main PID: 801 (code=exited, status=0/SUCCESS)
Nov 14 22:27:56 HES1 systemd[1]: Started Python NTP Service.
Nov 14 22:27:56 HES1 systemd[1]: Starting Python NTP Service...
Can any one help me resolve this? Thanks.
Your program is behaving as expected. Just forking isn't enough to make a daemon. What's happening is your code is running as long as its parent process runs, then (both forks are) exiting when the parent process terminates. What you want is to write a daemon (and have that controlled by systemd). You may find this question useful in explaining some easy ways to do that: How do you create a daemon in Python?
fork is an important part of this process but just doing a fork by itself doesn't completely solve the problem. If you'd like to see a more detailed example of how to daemonize your process by hand using fork you can read this: Python code to Daemonize a process?
The following Python script named "tst_script.py" writes in a file. It works when it is launch via command line but fails to create the file when lauch via a systemd service.
#!/usr/bin/python
#-*- coding: utf-8 -*-
import time
if __name__ == '__main__':
with open('test_file', 'a') as fd:
while True:
for i in range(10):
fd.write('test' + str(i) + '\r\n')
time.sleep(3)
break
The service script named "tst_script.service" is the following:
[Unit]
Description=Python test script
[Install]
WantedBy=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/python -O /home/gilles/tst_script.py
The service script is copied in "/lib/systemd/system" folder and activated by:
sudo systemctl daemon-reload
sudo systemctl enable tst_script.service
We check that the service is installed and enabled by: sudo systemctl status tst_script.service
The result is:
tst_script.service - Python test script
Loaded: loaded (/lib/systemd/system/tst_script.service; enabled)
Active: inactive (dead) since ven. 2018-03-02 13:35:00 CET; 16min ago
Main PID: 10565 (code=exited, status=0/SUCCESS)
and we launch the service by: sudo systemctl start tst_script.service
We check that the script is running: sudo systemctl status tst_script.service
The result is:
tst_script.service - Python test script
Loaded: loaded (/lib/systemd/system/tst_script.service; enabled)
Active: active (running) since ven. 2018-03-02 13:51:17 CET; 1s ago
Main PID: 10738 (python)
CGroup: /system.slice/tst_script.service
└─10738 /usr/bin/python -O /home/gilles/tst_script.py
And after 30 seconds, we check that the process is completed:
tst_script.service - Python test script
Loaded: loaded (/lib/systemd/system/tst_script.service; enabled)
Active: inactive (dead) since ven. 2018-03-02 13:51:47 CET; 3s ago
Process: 10738 ExecStart=/usr/bin/python -O /home/gilles/tst_script.py (code=exited, status=0/SUCCESS)
Main PID: 10738 (code=exited, status=0/SUCCESS)
but, as a result, the file "tst_file" doesn't exist...
I googled but don't find any answer who solve my problem. The closest answer I found is running python script as a systemd service.
Have you any idea to solve this problem ?
As Cong Ma mentioned in the comments, the most obvious problem is that you are probably looking in the wrong place. In your code you have the output file as: with open('test_file', 'a') which when you are testing this script appears in the same folder as the script.
The problem is, that Python does not interpret file_name as /path/to/python/script/file_name but instead reads a relative path as relative to the present working directory. If you are kicking off from systemd, your present working directory is not the same as where the script is located.
You can handle this by configuring your service, but easier in this case is to just provide an absolute path to the output file:
import time
if __name__ == '__main__':
with open('/home/gilles/test_file', 'a') as fd:
while True:
for i in range(10):
fd.write('test' + str(i) + '\r\n')
time.sleep(3)
break
If you'd rather fool around with the service, you can change the working directory of systemd. This info might be helpful: Changing Working Directory of systemd service
I added a bottle server that uses python's cassandra library, but it exits with this error: Bottle FATAL Exited too quickly (process log may have details) log shows this: File "/usr/local/lib/python2.7/dist-packages/cassandra/cluster.py", line 1765, in _reconnect_internal
raise NoHostAvailable("Unable to connect to any servers", errors)So I tried to run it manually using supervisorctl start Bottle ,and then it started with no issue. The conclusion= Bottle service starts too fast (before the needed cassandra supervised service does): a delay is needed!
This is what I use:
[program:uwsgi]
command=bash -c 'sleep 5 && uwsgi /etc/uwsgi.ini'
Not happy enough with the sleep hack I created a startup script and launched supervisorctl start processname from there.
[program:startup]
command=/startup.sh
startsecs = 0
autostart = true
autorestart = false
startretries = 1
priority=1
[program:myapp]
command=/home/website/venv/bin/gunicorn /home/website/myapp/app.py
autostart=false
autorestart=true
process_name=myapp
startup.sh
#!/bin/bash
sleep 5
supervisorctrl start myapp
This way supervisor will fire the startup script once and this will start myapp after 5 seconds, mind the autostart=false and autorestart=true on myapp.
I had a similar issue where, starting 64 python rq-worker processes using supervisorctl was raising CPU and RAM alert at every restart. What I did was the following:
command=/bin/bash -c "sleep %(process_num)02d && virtualenv/bin/python3 manage.py rqworker --name %(program_name)s_my-rq-worker_%(process_num)02d default low"
Basically, before running the python command, I sleep for N second, where N is the process number, which basically means I supervisor will start one rq-worker process every second.
I am in a hurry, I can find out how to do this but I need some help to achieve this without loosing too much time.
Currently what I do to run a uWsgi instance along with my ini file is just:
uwsgi --ini /home/myonlinesite/uwsgi.ini --pidfile /var/run/uwsgi_serv.pid
and then to stop:
uwsgi --stop /var/run/uwsgi_serv.pid.
By the way, I have this code inside a uwsgi init file in my /etc/init.d/uwsgi.
so when I run /etc/init.d/uwsgi start it executes the ini config file and when I execute /etc/init.d/uwsgi stop it stops the uwsgi process id.
The problem is that when I start the uWsgi service it runs normally and logs every http request, any debug print and so on, but when I close putty which is where I run my Vps it kills all uWsgi process and quits the site from being displayed.
I do not know if I have to touch the pid file only, or what do I need to do leave the uWsgi process executing and I can close putty.
Thanks in advance.
If you are setting the parameters in the command line, add the flag -d file.log to your command (-d stands for daemonize):
uwsgi --ini /home/myonlinesite/uwsgi.ini --pidfile /var/run/uwsgi_serv.pid -d file.log
If you are setting the parameters in a config file, add the following line in your config:
daemonize = /absolute/path/to/file.log
In both cases, uWsgi will run in the background and log everything in file.log. Given these options, there is no need using nohup et al.
Using nohup to start the uWsgi process should solve your problem of the process stopping when you log out.
A tutorial
Be sure to add
daemon = logfile
to your config