I have deployed a flask application with uwsgi and nginx
The following is the .ini file for uwsgi
[uwsgi]
;module = name of file which contains the application object in this case wsgi.py
LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib
chdir=/home/ansible/apps/payment_handler
module = wsgi:application
;tell uWSGI (the service) to start in master mode and spawn 5 worker *processes* to serve requests
master = true
processes = 5
;a socket is much faster than a port, and since we will be using nginx to exppose the application this is better
socket = 0.0.0.0:8001
vaccum = true
die-on-term = true
When I run this from the command line like so
uwsgi --ini payment_app.ini
It works !
However I would like to run the application using a service, the following is the service file
[Unit]
Description=uWSGI instance to serve service app
After=network.target
[Service]
User=root
WorkingDirectory=/home/ansible/apps/payment_handler
Environment="PATH=/home/ansible/apps/payment_handler/env/bin"
ExecStart=/home/ansible/apps/payment_handler/env/bin/uwsgi --ini payment_app.ini
[Install]
WantedBy=multi-user.target
However it does not work because it cannot find the libs for cx_oracle
I have it set in my bashrc file
export LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib
However since the service file does not use this to load it's env variables it seems to not find it
Error log
Jun 17 09:58:06 mau-app-036 uwsgi: cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://oracle.github.io/odpi/doc/installation.html#linux for help
I have tried setting it in the .ini file (as seen above)
LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib
I have also tried setting it in my init.py file using the os module
os.environ['LD_LIBRARY_PATH'] = '/usr/lib/oracle/18.3/client64/lib'
Both to no avail, any help would be great thanks Centos 7 btw
Problems like this are why the Instant Client installation instructions recommend running:
sudo sh -c "echo /usr/lib/oracle/18.3/client64/lib > \
/etc/ld.so.conf.d/oracle-instantclient.conf"
sudo ldconfig
This saves you having to work out how & where to set LD_LIBRARY_PATH.
Note that the 19.3 Instant Client RPM packages automatically runs this for you. Some background is in the Instant Client 19c Linux x64 release announcement blog.
Related
I'm trying to configure a basic a Django application served by uwsgi so that it can be started from systemd on a CentoS 7.X server.
So far my SystemD service is started (active and in running state) but application is not reachable on the configured port. Note that application is running inside a Python virtual environment.
Systemd service is active and running
uwsgi worker processes are
active
socket bind to TCP 8003 is in LISTEN state
SystemD unit file
# /etc/systemd/system/django_03.service
[Unit]
Description=My Django app
Requires=network.target
After=network.target
After=syslog.target
[Service]
TimeoutStartSec=0
RestartSec=10
Restart=always
User=myuser
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog
RuntimeDirectory=uwsgi
ExecStart=/bin/bash -c 'cd /opt/scripts/django/django_03; source django_03_env/bin/activate; uwsgi --ini /opt/scripts/django/django_03/django_03.ini'
[Install]
WantedBy=multi-user.target
uwsgi configuration file
# /opt/scripts/django/django_03/django_03.ini
[uwsgi]
module = wsgi:application
master = true
processes = 5
socket = 127.0.0.1:8003
chmod-socket = 664
vacuum = true
die-on-term = true
Django application
# wsgi.py
def application(environ, response):
response('200 OK', [('Content-Type', 'text/html')])
return [b"Test OK (Django 03) !!"]
Thanks for your help
In this example, systemd service is called "django_03", Python virtual env name is "django_03_env", Python application is "wsgi" with a callable named "application".
1 ] Prerequisites
Create a root directory for Python code, configuration files and virtual env:
mkdir /opt/scripts/django/django_03
Create a virtualenv
cd /opt/scripts/django/django_03
python3 -m venv django_03_env
Start virtualenv
source django_03_env/bin/activate
Install Django and uwsgi
pip install django
pip install uwsgi
2 ] Files
There are three files to create
uwsgi configuration file (INI format): django_03.ini
SystemD service unit: django_03.service
Python application: wsgi.py
2.1 SystemD unit file
# /etc/systemd/system/django_03.service
[Unit]
Description=My Django app
Requires=network.target
After=network.target
After=syslog.target
[Service]
TimeoutStartSec=0
RestartSec=10
Restart=always
User=myuser
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog
RuntimeDirectory=uwsgi
# Main call: Virtual env is activated and uwsgi is started with INI file as argument
ExecStart=/bin/bash -c 'cd /opt/scripts/django/django_03; source django_03_env/bin/activate; uwsgi --ini /opt/scripts/django/django_03/django_03.ini'
[Install]
WantedBy=multi-user.target
2.2 uwsgi configuration file
# /opt/scripts/django/django_03/django_03.ini
[uwsgi]
# "callable": Application entry point, <Python filename without extension: application method name>
module = wsgi:application
# Master process for uwsgi
master = true
# Worker processes for uwsgi
processes = 5
# uwsgi protocol modification
protocol = http
# Socket format X.X.X.X:<port number>
socket = 127.0.0.1:8003
chmod-socket = 664
vacuum = true
die-on-term = true
2.3 Django application file
# /opt/scripts/django/django_03/wsgi.py
# Application callable (main entry point)
def application(environ, response):
response('200 OK', [('Content-Type', 'text/html')])
return [b"Test OK (Django 03) !!"]
III ] Managing application
Django application can now be started by a regular systemd command:
sudo systemctl start django_03
Verify systemd service status
sudo systemctl -l status django_03
journalctl -u django_03
Verify that HTTP socket is listening
netstat -ntap | grep 8003
Verify HTTP response:
curl http://127.0.0.1:8003
Note that by default uwsgi operates with its default transfert protocol which is NOT HTTP. It is not recommended to use uwsgi HTTP socket, the best setup being the use of uswgi default protocol and a reverse proxy in front of it (NGINX, Apache HTTPd). Of course code presented here is far from perfect and might be optimized and tailored to your needs.
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 found a MediaCrush open source from here
https://github.com/MediaCrush/MediaCrush
But stuck in last steps.
I started the Redis server, use command
$redis-cli
that received the "PONG" response.
Then used the command
$celery worker -A mediacrush -Q celery,priority
and after
python app.py
But it seem that nothing works. I just installed nginx, run it on my IP ok, but after edit the nginx.conf like a Mediacrush script, then accessing my IP, nothing happens.
So what am I missing here? and how to config nginx server and start redis server to run this script on CentOS (i can change it to Arch like them if required)
Thanks!
I just wanted to run it for fun.. so this may be wrong but what I did after running the celery daemon was edit the app.py script and manually set the host, port, and set debug to false. Then I just executed it like any other python script.
EDIT: This may work
PORT=8000 gunicorn -w 4 app:app
it switches your port to 8000 and runs the gunicron daemon with 4 workers. both approaches worked for me.
Edit File: ./app.py
from mediacrush.app import app
from mediacrush.config import _cfg, _cfgi
import os
app.static_folder = os.path.join(os.getcwd(), "static")
if __name__ == '__main__':
# CHANGE THIS LINE TO REFLECT YOUR DATA
app.run(host=_cfg("debug-host"), port=_cfgi('debug-port'), debug=True)
# FOR EXAMPLE I CHANGED IT TO THIS
# app.run(host="92.222.25.245", port=8000, debug=0)
Also to start redis i believe you should do redis-server& I use the cli to manually tinker with it.
Btw I did this on linux mint / ubuntu 14.04 / debian
Ubuntu 12.04, nginx 1.2.0, uwsgi 1.0.3.
I start uwsgi with the following command:
uwsgi -s 127.0.0.1:9010 -M -t 30 -A 4 -p 4 -d /var/log/uwsgi.log
On each request nginx replies with 502 and uwsgi writes to log the following line:
-- unavailable modifier requested: 0 --
Original answer
For Python 2 on Ubuntu 11.10, using upstart, install the python plugin for uWSGI with apt-get install uwsgi-plugin-python and if you're using an ini file to configure your uWSGI app, then add plugins = python to the [uwsgi] section and it should solve this problem.
Edit: Updated for Python 3 and Ubuntu 17.10
For Python 3 on Ubuntu 17.10, using systemd, install the python plugin for uWSGI with apt-get install uwsgi-plugin-python3 and if you're using an ini file to configure your uWSGI app, then add plugins = python to the [uwsgi] section and it should solve this problem.
For more information on getting started with python/uWSGI apps, including how to configure them using an ini file then please take a look at this handy guide
Solved by installing uwsgi-plugin-python3 plugin and adding --plugin python3 option to uwsgi start command
Im starting uwsgi from upstart on Ubuntu. I solved the problem by running apt-get install uwsgi-plugin-python, and then adding plugins=python to my application.ini in /etc/uwsgi/applications-available.
from http://uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html, "To route requests to a specific plugin, the webserver needs to pass a magic number known as a modifier to the uWSGI instances. By default this number is set to 0, which is mapped to Python."
I'm using 9 for a bash script and it's working. the numbers and their meanings are on this page: http://uwsgi-docs.readthedocs.org/en/latest/Protocol.html
in my nginx configuration:
location ~ .cgi$ {
include uwsgi_params;
uwsgi_modifier1 9;
uwsgi_pass 127.0.0.1:3031;
}
Modify your ini file by added plugins line.
[uwsgi]
plugins = python3
I'm using Ubuntu 18.04 with Python 3. Below is the exact config I used to get it working.
You must have the Python 3 uWSGI plugin installed:
apt install uwsgi-plugin-python3
Your Nginx site configuration should point to your uWSGI socket. Make sure the port matches the configuration in the later steps.
location / {
uwsgi_pass 127.0.0.1:9090;
include uwsgi_params;
}
Reload the Nginx config to reflect the changes you just made:
systemctl reload nginx
You can use command-line arguments or an ini file for configuration. I created uwsgi.ini. Make sure the socket address matches your nginx config.
[uwsgi]
socket = 127.0.0.1:9090
chdir = /var/www
processes = 4
threads = 2
plugins = python3
wsgi-file = /var/www/app.py
My app.py just has a basic example:
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/plain')])
return [b"Hello World!"]
Now start the uWSGI server from the command line:
uwsgi uwsgi.ini