I know that I can run the scheduler manually by using
python web2py.py -K myapp
But where should this be specified in production environment? I am using standard web2py deployment script for apache, on ubuntu.
Just to round the picture. Using Debian or other Linux distributions after 2015, the way to go is systemd. For systemd the following steps have to be taken:
Create the file /etc/systemd/system/web2py-sched.service
Containing the following
[Unit]
Description=Web2Py scheduler service
[Service]
ExecStart=/usr/bin/python /home/www-data/web2py/web2py.py -K <yourapp>
Type=simple
[Install]
WantedBy=multi-user.target
Then install the service calling:
sudo systemctl enable /etc/systemd/system/web2py-sched.service
With Ubuntu 12.04 I make it manually:
in /etc/init directory create web2py-scheduler.conf file:
description "Web2py scheduler"
start on filesystem or runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 8 60
exec sudo -u user <path_to_web2py>/web2py.py -K <your_app>
in /etc/init.d exec:
ln -s /lib/init/upstart-job web2py-scheduler
(optional, only if you want manual startup) in /etc/init directory create the web2py-scheduler.override file:
manual
Please see
Web2Py Book
which worked for me running Ubuntu 14:
Start the scheduler as a Linux service (upstart)
To install the scheduler as a permanent daemon on Linux (w/ Upstart), put the following into /etc/init/web2py-scheduler.conf, assuming your web2py instance is installed in user's home directory, running as user, with app myapp, on network interface eth0.
description "web2py task scheduler"
start on (local-filesystems and net-device-up IFACE=eth0)
stop on shutdown
respawn limit 8 60 # Give up if restart occurs 8 times in 60 seconds.
exec sudo -u <user> python /home/<user>/web2py/web2py.py -K <myapp>
respawn
You can then start/stop/restart/check status of the daemon with:
sudo start web2py-scheduler
sudo stop web2py-scheduler
sudo restart web2py-scheduler
sudo status web2py-scheduler
Related
I know how to autostart a python script (or so I thought). But I want a programm or something, if my python script is not running anymore, it should start the script again. Has anyone a idea how to do this?
Edit:
I tried running it as a service but that didnt work.
import bluetooth
import pygame
pygame.mixer.init()
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
port = 22
server_sock.bind(("",port))
server_sock.listen(1)
client_sock,address = server_sock.accept()
print ("Verbindung Hergestellt mit: ", address)
while True:
recvdata = client_sock.recv(1024)
print ("Nachricht bekommen: %s" % recvdata)
pygame.mixer.pause()
if (recvdata == b"h"):
sound = pygame.mixer.Sound('/home/maxi/Desktop/test.wav')
playing = sound.play()
if (recvdata == b"p"):
sound = pygame.mixer.Sound('/home/maxi/Desktop/test2.wav')
playing = sound.play()
if (recvdata == b"k"):
break
client_sock.close()
server_sock.close()
My startscript is:
[Unit]
Description=MaxiTest
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3 /home/maxi/Desktop/btsound1.py
[Install]
WantedBy=multi-user.target
You can search more about how a python script can perform as a service or daemon. There are many solutions in this link:
How to make a Python script run like a service or daemon in Linux
Between all solutions, I prefer 3 of them (I'm not very familiar with raspberry-pi, so check compatibility):
Cronjob: You can create a cronjob for the script and the OS will run it every x seconds/minutes/... automatically and periodically.
Systemctl/Systemd: Create a custom service file for your script and start and enable it in Systemd. A complete guide is here:
https://medium.com/codex/setup-a-python-script-as-a-service-through-systemctl-systemd-f0cc55a42267
You chose systemd (after editing);
In /PATH_project/ create 2 bash scripts like this:
#!/bin/bash
# This is start.sh
cd /home/maxi/Desktop/
/usr/bin/python3 btsound1.py
And create stop.sh:
#!/bin/bash
for KILLPID in `ps ax | grep ‘myservice’ | awk ‘{print $1;}’`; do
kill -9 $KILLPID;
done
Then give execution permission to both files using:
chmod a+x start.sh
chmod a+x stop.sh
Then create a myservice.service file in /etc/systemd/system :
[Unit]
Description=myservice service
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=simple
Restart=always
ExecStart=/bin/bash /home/maxi/Desktop/start.sh
ExecStop=/bin/bash /home/maxi/Desktop/stop.sh
RestartSec=5
TimeoutSec=60
RuntimeMaxSec=infinity
PIDFile=/tmp/mydaemon.pid
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl start myservice.service
sudo systemctl status myservice.service
Benefits of using such bash scripts is that you can handle some more things in this way. For example if you are using a virtual environment, you can use source activate in start.sh file before running the script.py .
Supervisord: Install Supervisor and create a supervisord.conf file for your script. A good guide is here:
https://csjourney.com/managing-processes-with-supervisor-in-depth-tutorial/
I found what was the problem. I used rc.local and started the program 10 seconds after boot. The system needed time first to set up before I could start the script.
I followed multiple tutorials available on stackoverflow about starting a python script at startup but none of them works.
I need to activate a virtualenv then start a flask server
I tried
init.d method
I made an start.sh in /etc/init.d/
#!/bin/sh
### BEGIN INIT INFO
# Provides: skeleton
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $portmap
# Should-Stop: $portmap
# X-Start-Before: nis
# X-Stop-After: nis
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: true
# Short-Description: Example initscript
# Description: This file should be used to construct scripts to be
# placed in /etc/init.d.
### END INIT INFO
cd /home/ion/
source /home/ion/py35/bin/activate
cd /home/ion/Desktop/flask/
nohup python main.py &
echo "Done"
Its permissions are chmod at +x
ion#aurora:/etc/init.d$ ll start.sh
-rwxr-xr-x 1 root root 625 Jun 25 19:10 start.sh*
Went to /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/etc/init.d/start.sh
exit 0
Didn't work
cronjob method
sudo crontab -e
and appended
#reboot sh '/etc/init.d/start.sh'
Didn't worked either , where am I wrong?
Manual triggered logs
(py35) ion#aurora:~/Desktop/flask$ python main.py
WARNING:tensorflow:From /home/ion/Desktop/flask/encoder.py:57: calling l2_normalize (from tensorflow.python.ops.nn_impl) with dim is deprecated and will be removed in a future version.
Instructions for updating:
dim is deprecated, use axis instead
2018-06-25 19:34:05.511943: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://localhost:5505/ (Press CTRL+C to quit)
* Restarting with stat
1) Don't use old "init.d" method. Use something modern. If you have Ubuntu 15.04 and higher, you can use Systemd to create daemon that will be started automatically at startup. If you have for example Ubuntu older than 15.04 - use Upstart.
For Systemd:
Create unit file in /lib/systemd/system/you_service_name.service with the following content (as far as I can see your python script doesn't spawn new process while running, so Type should be simple. More info here):
[Unit]
Description=<your_service_name>
After=network.target network-online.target
[Service]
Type=simple
User=<required_user_name>
Group=<required_group_name>
Restart=always
ExecStartPre=/bin/mkdir -p /var/run/<your_service_name>
PIDFile=/var/run/<your_service_name>/service.pid
ExecStart=/path/to/python_executable /path/to/your/script.py
[Install]
WantedBy=multi-user.target
Save this file and reload systemd:
sudo systemctl daemon-reload
Then add your service to autostart:
sudo systemctl enable you_service_name.service
you should see that Systemd created required symlinks after enable action.
Reboot and see if it's up and running (ps aux | grep python or sudo systemctl status you_service_name.service). If there is something weird - check Systemd journal:
sudo journalctl -xe
UPD:
To launch your python script in desired virtualenv, just use this expression in your service unit file:
ExecStart=/venv_home/path/to/python /venv_home/path/to/your/script.py
2) You can also use crontab, but you need to specify full path for desired shell there, for example:
#reboot /bin/bash /path/to/script.sh
If you need additional help - just let me know here.
The essence:
I have created a daemon to manage some tasks on a remote platform.
It is written in python and accepts start, stop and restart arguments.
While trying to add it to the systemd (so it would start on system startup and be stopped on shutdown, etc.) I encountered a problem:
It seems to see daemon running, but I am not sure if it actually works, because restarting or requesting status returns with an error:
[user#centos ~]# systemctl restart mydaemon
Failed to restart mydaemon.service: Unit mydaemon.service failed to load: No such file or directory.
[user#centos ~]# systemctl status mydaemon
● mydaemon.service
Loaded: not-found (Reason: No such file or directory)
Active: inactive (dead)
The specifics:
The code itself follows the well-known example by Sander Marechal with very few changes. By itself it works without any problems, and properly reacts to all accepted arguments. The pid is saved in /tmp/my-daemon.pid.
The systemd service file is in the user daemons directory: /usr/lib/systemd/user/mydaemon.service, and the code is as follows:
[Unit]
Description=The user daemon
[Service]
Type=forking
ExecStart=/usr/bin/python /home/frcr/mydaemon_v01.py start
ExecStop=/usr/bin/python /home/frcr/mydaemon_v01.py stop
RestartSec=5
TimeoutSec=60
RuntimeMaxSec=infinity
Restart=always
PIDFile=/tmp/my-daemon.pid
[Install]
WantedBy=multi-user.target
systemctl returns the status of it as active, but only if provided the pid:
[user#centos ~]# systemctl status 9177
● session-481.scope - Session 481 of user user
Loaded: loaded
Drop-In: /run/systemd/system/session-481.scope.d
└─50-After-systemd-logind\x2eservice.conf, 50-After-systemd-user-sessions\x2eservice.conf, 50-Description.conf, 50-SendSIGHUP.conf, 50-Slice.conf
Active: active (running) since Tue 2016-05-17 06:24:51 EDT; 1h 43min ago
CGroup: /user.slice/user-0.slice/session-481.scope
├─8815 sshd: root#pts/0
├─8817 -bash
├─9177 python /home/user/mydaemon_v01.py start
└─9357 systemctl status 9177
I have seen a similar question here on stack overflow, but it doesn't seem to have the solution to my problem.
I assume I am missing something very obvious due to the sheer lack of experience with systemd, and I'd be extremely grateful if somebody could point it out for me or show me the right direction to move. Thanks in advance and please forgive my mad English skillz.
Enabling the daemon with a full path name worked around the issue but there is a better solution.
The issue was the service was in a user directory but was started as a system service. However /usr/lib was not the right place to add new service files anyway. That directory is for files shipped as part of operating system packages. The correct directory to add a new system service is in /etc/systemd/system See related docs about systemd paths.
You still want to enable the service to make sure it gets loaded at boot time.
After some additional googling I found a solution: I actually forgot to add the daemon to systemctl:
[root#centos ~]# systemctl enable /usr/lib/systemd/user/mydaemon.service
Created symlink from /etc/systemd/system/multi-user.target.wants/mydaemon.service to /usr/lib/systemd/user/mydaemon.service.
Created symlink from /etc/systemd/system/mydaemon.service to /usr/lib/systemd/user/mydaemon.service.
It is also worth mentioning that the absolute path is required.
The only thing left is to refresh systemctl:
[root#centos ~]# systemctl daemon-reload
After that the service is added, and
[root#centos ~]# systemctl start mydaemon
[root#centos ~]# systemctl restart mydaemon
[root#centos ~]# systemctl stop mydaemon
all work perfectly.
I have a django app for which i am using celery tasks to perform some csv processing in background, and so i installed rabbitmq-server like sudo apt-get install rabbitmq-server, by this command the rabbitmq-server was installed and running successfully.
And i have some celery tasks code in tasks.py module inside an app and running the celery like below
celery -A app.tasks worker --loglevel=info
which was working fine and executing the csv files in background successfully, but now i just want to daemonize the above command, and i searched about any option to daemonize it but i din't found any arguments to pass like -D to daemonize the above command. So is there anyway that i can daemonize the above command and make celery run ?
I think you're looking for the --detach option. [1]
But is recommended that you use something like systemd.
The celery docs has a whole page on this topic. [2]
[1] http://celery.readthedocs.org/en/latest/reference/celery.bin.base.html#daemon-options
[2] http://celery.readthedocs.org/en/latest/tutorials/daemonizing.html
supervisorctl will be a better bet on this.
Installation: sudo apt-get install supervisor
The main configuration file of supervisor is here: /etc/supervisor/supervisord.conf
Run $vim /etc/supervisor/supervisord.conf to inspect. Looking into the file, at the bottom, youu'll notice:
[include]
files = /etc/supervisor/conf.d/*.conf
This basically means that config files of your projects can be stored here /etc/supervisor/conf.d/ and they will be automatically included.
Run: sudo vim /etc/supervisor/conf.d/myapp.conf. Your configuration may look like:
[program:myapp]
command={{ your celery commands without curly braces }}
directory=/directory/to/myapp
autostart=true
autorestart=true
stderr_logfile=/var/log/myapp.err.log
stdout_logfile=/var/log/myapp.out.log
To Restart service: $sudo service supervisor restart
To Re-read after making updates to any *.conf file: $sudo supervisorctl reread
To record updates: $sudo supervisorctl update
To check status of specific *.conf: sudo supervisorctl status myapp
Check your log files for more status data.
I'm using django-gunicorn-nginx setup by following this tutorial http://ijcdigital.com/blog/django-gunicorn-and-nginx-setup/ Upto nginx setup, it is working. Then I installed supervisor, configured it and then I reboot my server and checked, it shows 502 bad gateway. I'm using Ubuntu 12.04 LTS
/etc/supervisor/conf.d/qlimp.conf
[program: qlimp]
directory = /home/nirmal/project/qlimp/qlimp.sh
user = nirmal
command = /home/nirmal/project/qlimp/qlimp.sh
stdout_logfile = /path/to/supervisor/log/file/logfile.log
stderr_logfile = /path/to/supervisor/log/file/error-logfile.log
Then I restarted supervisor and I run this command $ supervisorctl start qlimp and I'm getting this error
unix:///var/run/supervisor.sock no such file
Is there any problem in my supervisor setup?
Thanks!
That there is no socket file probably means that supervisor isn't running. A reason that it isn't running might be that your qlimp.conf file has some sort of error in it. If you do a
sudo service supervisor start
you can see whether or not this is the case. If supervisor is already running, it will say. And if it is catching an error, it will usually give you a more helpful error message than supervisorctl.
I have met the same issue as you and after several times, here comes the solution:
First remove the apt-get supervisor version:
sudo apt-get remove supervisor
Kill the backend supervisor process:
sudo ps -ef | grep supervisor
Then get the newest version(apt-get version was 3.0a8):
sudo easy_install(pip install) supervisor==3.0b2
Echo the config file(root premission):
echo_supervisord_conf > /etc/supervisord.conf
5.Start supervisord:
sudo supervisord
6.Enter supervisorctl:
sudo supervisorctl
Anything has been done! Have fun!
Try this
cd /etc/supervisor
sudo supervisord
sudo supervisorctl restart all
Are you sure that supervisord is installed and running? Is there a socket file in present at /var/run/supervisor.sock?
The error indicates that supervisorctl, the control CLI, cannot reach the UNIX socket to communicate with supervisord, the daemon.
You could also check /etc/supervisor/supervisord.conf and see if the values for the unix_http_server and supervisorctl sections match.
Note that this is a Ubuntu-level problem, not a problem with Python, Django or nginx and as such this question probably belongs on ServerFault.
On Ubuntu 16+ it seems to been caused by the switch to systemd, this workaround may fix for new servers:
# Make sure Supervisor comes up after a reboot.
$ sudo systemctl enable supervisor
# Bring Supervisor up right now.
$ sudo systemctl start supervisor
and then do check your status of iconic.conf [My example] of supervisor
$ sudo supervisorctl status iconic
PS: Make sure gunicorn should not have any problem while running.
The error may be due to that you don't have the privilege.
Maybe you can fix the error by this way, open your terminal, and input vim /etc/supervisord.conf to edit the file, search the lines
[unix_http_server]
;file=/tmp/supervisor.sock ; (the path to the socket file)
;chmod=0700 ; socket file mode (default 0700)
and delete the Semicolon in the start of the string ;file=/tmp/supervisor.sock and ;chmod=0700, restart your supervisord. I suggest you do it.
Make sure that in /etc/supervisor.conf the following two sections exists
[unix_http_server]
file=/tmp/supervisor.sock ; path to your socket file
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
You can do something like this :-
sudo touch /var/run/supervisor.sock
sudo chmod 777 /var/run/supervisor.sock
sudo service supervisor restart
It's definitely work, try this.
In my case, Supervisor was not running. To spot the issue I run:
sudo systemctl status supervisor.service
The problem was that I had my logs pointing to a non-existing directory, so I just had to create it.
I hope it helps :)
touch /var/run/supervisor.sock
sudo supervisord -c /etc/supervisor/supervisord.conf
and after
supervisorctl restart all
if you want to listen the supervisor port
ps -ef | grep supervisord
if you want kill the process
kill -s SIGTERM 2503
Create a conf file and below add lines
Remember that in order to work with Nginx, you must have to disable autostart on system boot, that you activated while installing Nginx.
https://askubuntu.com/questions/177041/nginx-disable-autostart
Note: All the supervisor processes must be on "daemon off" mode, in order to work with supervisor
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
startretries=5
stopasgroup=true
stopsignal=QUIT
numprocs=1
startsecs=0
process_name=WebServer(Nginx)
stderr_logfile=/var/log/nginx/error.log
stderr_logfile_maxbytes=10MB
stdout_logfile=/var/log/nginx/access.log
stdout_logfile_maxbytes=10MB
sudo supervisorctl reread && sudo supervisorctl update
I have faced this error several times -
If server is newly created instance and facing this issue
Might be because of some wrong config or mistake happened during the process, or supervisor is not enabled.
Try restarting your supervisor and reconnecting ec2
or
Try reinstalling supervisor (#Scen)
or
Try approaches mentioned by #Yuvaraj Loganathan, #Dinesh Sunny. But mostly you might end up creating a new instance.
If server was running perfectly from long time but then it suddenly stopped
and threw
unix:///var/run/supervisor.sock no such file on sudo supervisorctl status.
It may be due to high memory usage, refer below image usage was 99% of 7.69GB earlier.
You can find the above config after connecting with ec2 via ssh or putty at the top.
You can upgrade your ec2 instance or you can then delete any extra files like logs (/var/logs), zip to free up the space. But careful do not delete any system files.
Restart supervisor
sudo service supervisor restart
Check sudo supervisorctl status