I have multiple uWSGI vassals, all monitored by uwsgi emperor. I update the code for my app (Django) and I want the emperor to perform a clean reload of one of the vassals. To do that I
touch vassal-foo.ini
In the logs I see [emperor] reload the uwsgi instance vassal-foo.ini. This sounds promising, but the app is not reloaded. It continues to run the old version. Checking the process (PID) startup time, indeed, it has not been restarted.
Any hints what might cause this? Few things that might be uncommon:
Neither the emperor nor the vassal run in master mode
Emperor was installed with pip and runs under initctl
kill -9-ing the vassal triggers a correct reload (obviously)
I use symlinks
I have a secondary thread inside my python app (threading.Thread(target).start()) running with daemon=True
Things I tried and did not work:
Run the process without any additional threads (remove threading.Thread(target).start())
Touching with touch --no-dereference vassal-foo.ini
Starting emperor with --emperor-nofollow
vassal-foo.ini:
master = false
processes = 1
thunder-lock = true
enable-threads = true
socket = /tmp/%n.sock
chmod-socket = 666
vacuum = true
Emperor:
exec /tmp/uwsgi --emperor /tmp/configs/uwsgi/ --die-on-term --uid me --gid me --logto /tmp/logs/uwsgi-emperor.log
uWSGI version
$ uwsgi --version
2.0.17
The problem is that your vassal not run in master mode.
All the ways uwsgi reload a requires master process.
In emperor mode, when you touch the ini, the emperor send a sighup to the vassal and record in the log that the vassal is reload. But if the vassal doesn't has a master it just ignore the sighup. So that is why you see reload in log but nothing happened.
Related
I have a django project running a wsgi application using gunicorn. Ahhh too much for the python newbie like me.
I have a below gunicorn command which runs at the application startup.
exec ./env/bin/gunicorn $wsgi:application \
--config djanqloud/gunicorn-prometheus-config.py \
--name "djanqloud" \
--workers 3 \
--timeout 60 \
--user=defaultuser --group=nogroup \
--log-level=debug \
--bind=0.0.0.0:8002
Below is my wsgi.py file:
import os
from django.core.wsgi import get_wsgi_application
os.environ['DJANGO_SETTINGS_MODULE'] = 'djanqloud.settings'
application = get_wsgi_application()
gunicorn command shown from "ps- -eaf" command in a docker container:
/opt/gq-console/env/bin/python2 /opt/gq-console/env/bin/gunicorn wsgi:application --config /opt/gq-console//gunicorn-prometheus-config.py --name djanqloud --workers 3 --timeout 60 --user=gq-console --group=nogroup --log-level=debug --bind=0.0.0.0:8002
Their is one simple thread which I create inside django project which are killed when above worker threads are killed.
My question is:
Is there anyway where I can create my threads AGAIN when the above worker threads are auto restarted ?
I have tried to override the get_wsgi_application() function in wsgi.py file but got below error while worker threads are booted:
AppImportError: Failed to find application object: 'application'.
I am new to python django and wsgi applications so please try to elaborate your answers.
Basically I am looking for a location where I can keep my startup code which runs when the wsgi worker threads are killed and autostarted.
Thanks.
To automatically start your application after server boot or restart automatically your application if gunicorn worker get killed use a process control system such as supervisor. Which will take care of restarting your gunicorn process automatically.
Hi I have deployed Django using UWSGI and Nginx using following tutorial http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
Everything is running fine. I face a challenge while updating python code. I don't know the efficient way to deploy new changes.
after hit and trial, I used following commands to deploy
git pull; sudo service uwsgi stop; sudo service nginx restart; sudo service uwsgi restart; /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals
this command works fine. But I face following problems
Usagi runs in the foreground. Every time I make changes, a new UWSGI instance start running.
Due to multiple UWSGI instances, My AWS server get crashed, due to memory exhaustion.
I want to know what commands should I run to reflect changes in python code.
PS: in my previous APACHE Django setup, I only used to restart apache, is it possible to reflect changes by only restarting nginx.
Try this:
git pull
python manage.py migrate # to run any migrations
sudo service uwsgi restart
Press Ctrl + Z and then bg + enter
This should run the process in the background.
Please let me know if this works.
Please have a look at this for running uwsgi in background. create an .ini file /etc/uwsgi/sites/projectname.ini. The script would look like this(for ubuntu 16.04):
[uwsgi]
project = projectname
base = projectpath
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
socket = %(base)/%(project)/%(project).sock
chmod-socket = 666
vacuum = true
(For ubuntu 16.04):
then create the following systemd script at /etc/systemd/system/uwsgi.service:
[Unit]
Description=uWSGI Emperor service
After=syslog.target
[Service]
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
Refresh the state of the systemd init system with this new uWSGI service on board
sudo systemctl daemon-reload
In order to start the script you'll need to run the following:
sudo systemctl start uwsgi
In order to start uWSGI on reboot, you will also need:
sudo systemctl enable uwsgi
You can use the following to check its status:
systemctl status uwsgi
(For ubuntu 14.04):
Create an upstart script for uWSGI:
sudo nano /etc/init/uwsgi.conf
Then add following lines in the above created file:
description "uWSGI application server in Emperor mode"
start on runlevel [2345]
stop on runlevel [!2345]
setuid user
setgid www-data
exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
I'm using flask as a webserver for my UI (it's a simple web interface which controls the recording using gstreamer on ubuntu from a webcam and a framegrabber simultaneously / kinda simple player)
Every time I need to run the command "python main.py" to run the server from command prompt manually.
I've tried the init.d solution or even writing a simple shell script and launching it every time after rebooting the system on start up but it fails to keep the server up and running till the end (just invokes the server and terminates it I guess)
is there any solution that could help me to start the webserver every time after booting the system on startup and keep it on and running?
I'd like to configure my system to boot directly into the browser so don't wanna have any need for more actions by the user.
Any Kind of suggestion/help is appreciated.
I'd like to suggest using supervisor, the documentation is here
for a very simple demo purpose, after you installed it and finish the set up, touch a new a file like this:
[program:flask_app]
command = python main.py
directory = /dir/to/your/app
autostart = true
autorestart = true
then
$ sudo supervisorctl update
Now, you should be good to go. The flask app will start every time after you boot you machine.(note: distribution package has already integrated into the service management infrastructure, if you're using others, see here)
to check whether you app is running:
$ sudo supervisorctl status
For production, you can use nginx+uwsgi+supervisor. The flask deployment documentation is here
One well documented solution is to use Gunicorn and Nginx server:
Install Components and setup a Python virtualenv with dependencies
Create the wsgi.py file :
from myproject import application
if __name__ == "__main__":
application.run()
That will be handled by Gunicorn :
gunicorn --bind 0.0.0.0:8000 wsgi
Configure Gunicorn with setting up a systemd config file: /etc/systemd/system/myproject.service :
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn
--workers 3 --bind unix:myproject.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
Start the Gunicorn service at boot :
sudo systemctl start myproject
sudo systemctl enable myproject
I seem to be having some slight problems deploying a Pyramid web application. The problem seems to lie in my init script that I am using to start my web application on boot. For some reason, uWSGI will not work unless my socket is set to have a permission of "nobody.nobody" OR Nginx is started after my uwsgi init script. I'm changed my init script to reflect these changes, but it does not seem to be working. The init script (or the part that starts uwsgi) looks like so:
#!/sbin/runscript
args="--ini-paste /var/www/pyramid/app1/development.ini"
command="/var/www/pyramid/bin/uwsgi"
pidfile="/var/run/uwsgi.pid"
sock="/var/tmp/proxy/uwsgi.sock"
nobody="nobody.nobody"
start() {
ebegin "Starting app1"
chown $nobody $sock
start-stop-daemon --start --exec $command -- $args \
--pidfile $pidfile
chown $nobody $sock
einfo "app1 started"
eend $?
}
My Nginx configuration looks like so:
location / {
include uwsgi_params;
uwsgi_pass unix:///var/tmp/proxy/uwsgi.sock;
uwsgi_param SCRIPT_NAME "" ;
}
My ini file includes the following:
[uwsgi]
socket = /var/tmp/proxy/uwsgi.sock
pidfile = /var/run/uwsgi.pid
master = true
processes = 1
home = /var/www/pyramid
daemonize = /var/log/uwsgi.log
virtualenv = /var/www/pyramid/
pythonpath = /var/www/pyramid/bin
What happens is that Nginx will start, and then uwsgi will start. Performing a "ls -la" in /var/tmp/proxy reveals that the permissions of uwsgi.sock is set to "root root" instead of "nobody nobody". However, restarting Nginx will fix the problem, regardless of what the socket's permissions are (but Nginx has to be started first).
Thus, the ways I can get this to work is:
start uwsgi
start nginx
restart nginx
or
start nginx
start uwsgi
restart nginx
I'm at a complete loss as to why this isn't working. If anyone has any advice I'd greatly appreciate it!
You can use the following settings to change the permission of its socket in your ini file:
chmod-socket = 777 # socket permission
gid = www-data # socket group
uid = www-data # socket user
Another thing to consider is whether you actually want uWSGI to run as root. If you pass --uid and --gid arguments to uwsgi, uwsgi will masquerade as a different (preferably non-root) user.
For example, nginx usually runs as the www-data user and www-data group. So if you set up your wsgi app to run with "--gid www-data" and then add at least group-write permissions to your socket file with "--chmod-socket 020", then nginx will be able to write to the socket and you'll be in business.
See my blog post on the subject: http://blog.jackdesert.com/common-hurdles-to-deploying-uwsgi-apps-part-1
I'm using uwsgi-0.9.8.4 under Ubuntu 10.04 (32bit), here's the uwsgi section in my Pyramid application (which works fine with paster) .ini file --
[uwsgi]
socket = 127.0.0.1:6543
master = true
processes = 1
pythonpath = /home/jerry/virtualenv/lib/python2.6/site-packages/*.egg
pythonpath = /home/jerry/myapp
uwsgi runs and binds to port 6543 --
$ uwsgi --ini-paste development.ini -b 32768
...
2011-08-23 16:43:11,128 INFO sqlalchemy.engine.base.Engine {}
WSGI application 0 (SCRIPT_NAME=) ready on interpreter 0x9472fa8 pid: 14161 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 14161)
spawned uWSGI worker 1 (pid: 14170, cores: 1)
timeout waiting for header. skip request.
timeout waiting for header. skip request.
But http://localhost:6543/ requests in the browser just time out while uWSGI infrequently reports receiving nothing.
What could be wrong and is there any way to debug this situation?
Any pointer will be much appreciated.
uWSGI by default speaks the uwsgi (all lowercase) protocol, not the http one. So you cannot connect to it via browser. Add --protocol=http to let it speak http (slower obviously)