I have in my server two Python versions: the Python default, already present in Ubuntu Server 16.04 and Anaconda Python.
When I run the Flask application with Apache, because this is running in user www-data, the application runs in Python default, but I have to run in Anaconda installation.
How to configure to use the Anaconda Python version and how to install new modules in this version?
The path of Anaconda installed is /home/wandre/anaconda2
This is one way that worked for me to let Apache run the python module in Anaconda environment so that Flask app can run.
First is installation. Install Apache with the command sudo apt-get install apache2 apache2-bin apache2-dev. Then, install Anaconda under the directory /opt as sudo. After having Anaconda installed on /opt/anaconda2, install conda packages as below:
sudo su # Login as superuser
export PATH=/opt/anaconda2/bin:$PATH # Add conda to your path
conda install -c anaconda flask
pip install mod_wsgi
mod_wsgi-express install-module # the outputs to this is used for Apache configuration in the next step
Now you need to update the Apache configurations. This involves updating three files:
wsgi.load
Open the file /etc/apache2/mods-available/wsgi.load and add the following (this is the output from mod_wsgi-express install-module so yours could be different)
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi-py27.so
If the LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so was originally included in this file, comment it out. Otherwise (at least from what I checked), the apache server will run the default python instead of the one in Anaconda. Next, enable the wsgi mod:
sudo a2enmod wsgi
wsgi.conf
Open the file /etc/apache2/mods-available/wsgi.conf and add the following
<IfModule mod_wsgi.c>
WSGIPythonHome /opt/anaconda2
</IfModule>
000-default.conf (your filename may be different)
Open the file /etc/apache2/sites-available/000-default.conf and add the following
WSGIDaemonProcess flaskapp python-home=/opt/anaconda2 python-path=/var/www/flask
WSGIScriptAlias / /var/www/flask/flaskapp.wsgi
<Directory /var/www/flask>
WSGIProcessGroup flaskapp
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
You are all set.
Please note that I was not able to find tutorial for setting 'Anaconda + Flask + Apache' so I referred to a post on 'Anaconda + Django + Apache'.
Related
I'm trying to deploy my first django app in windows 10 (x64), so installed apache 2.4(x86), installed and build mod_wsgi (4.9.1) with python 3.8(x86) (I have microsoft visual studio 2019 installed) and configured Apache httpd.conf and httpd-vhosts.conf files.
My app runs fine, but the annoying error 500 keeps showing every now and then, and goes away by refreshing the browser every time.
There seems to be a bug with python 3.8, so decided to upgrade to python 3.10 (X86),
Reinstalled mod-wsgi and other packages using pip in new virtual environment in the same directory, and reconfigured httpd.conf accordingly. now apache service fails to start with error: "windows could not start the Apache2.4 on local computer....".
If I change httpd.conf configuration to load and use the python3.8 , Apache starts with no error (but again Error 500 keeps showing).
by the way I tried the same with python3.9 (x64) and Apache 2.4 (X64), and apache fails to start again.
Any help would be greatly appreciated.
In httpd.conf:
This configuration fails:
LoadFile "C:/Program Files (x86)/Python310-32/python310.dll"
LoadModule wsgi_module "d:/django project/unemployment project/.venv/lib/site-packages/mod_wsgi/server/mod_wsgi.cp310-win32.pyd"
WSGIPythonHome "d:/django project/unemployment project/.venv"
This configuration works:
LoadFile "C:/Program Files (x86)/Python38-32/python38.dll"
LoadModule wsgi_module "d:/django project/unemployment project/venv/lib/site-packages/mod_wsgi/server/mod_wsgi.cp38-win32.pyd"
WSGIPythonHome "d:/django project/unemployment project/venv"
I am trying to host a django application on a server using apache2 and mod_wsgi.
The project itself is located at the path /usr/share/django-projects/mysite
The virtual environment is located at the path /home/zakhar/django_test/env
It's part of apache2 (2.4 version) conf file. In venv python version is 3.8.13
WSGIDaemonProcess mysite user=www-data group=www-data python-path=/usr/share/django-projects/mysite:/home/zakhar/django_test/env/lib/python3.8/site-packages python-home=/home/zakhar/django_test/env
It's last error from apache arror.log
File "/home/zakhar/django_test/env/lib/python3.8/site-packages/django/db/models/aggregates.py", in line 84
if (default := c.default) is None:
^
SyntaxError: invalid syntax
I think apache use python 3.6.9 in global env, but not in venv
I would be very grateful if someone could help me
I installed mod_wsgi in my venv and edited /etc/apache2/mods-avaible/wsgi.load
LoadModule wsgi_module "/home/zakhar/django_test/env/lib/python3.8/site-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so"
WSGIPythonHome "/home/zakhar/django_test/env"
I am hosting my django app on Linode with Ubuntu OS and i have configured apache webserver.
When I try to access the site i get 500 Internal Server error
Apache logs show the following error
Traceback (most recent call last):
File "/home/mosajan/artistry/artistry/wsgi.py", line 12, in <module>
from django.core.wsgi import get_wsgi_application<br>
ImportError: No module named 'django'
Target WSGI script '/home/mosajan/artistry/artistry/wsgi.py' cannot be loaded as Python module.
Exception occurred processing WSGI script '/home/mosajan/artistry/artistry/wsgi.py'.
wsgi.py
import os
import sys
from django.core.wsgi import get_wsgi_application
sys.path.append('home/mosajan/artistry/')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'artistry.settings')
application = get_wsgi_application()
apache2 conf file
artistry.conf
Alias /static /home/mosajan/artistry/static
<Directory /home/mosajan/artistry/static>
Require all granted
</Directory>
<Directory /home/mosajan/artistry/artistry>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/mosajan/artistry/artistry/wsgi.py
WSGIDaemonProcess artistry python-path=/home/mosajan/artistry python-home=/home/mosajan/artistry/venv
WSGIProcessGroup artistry
WSGIPythonHome /home/mosajan/artistry/venv
WSGIPythonPath /hom/mosajan/artistry
File structure
This answer assumes that you manually activated the venv and that when you do something like python manage.py runserver 0.0.0.0:8000 in your project folder, are you able to see the project and run it without any errors. If that's the case, this means you have installed django as well as other needed project requirements / packages, so you can deactivate the venv for now.
Let's start by making sure that the server's IP address was added to ALLOWED_HOSTS in your settings.py file.
Now, with the venv deactivated, make sure to install Apache 2.4 with the service httpd with the module wsgi which is gonna help the Django app behave as a web app totally compatible with Apache 2.4. If you're using yum as a package manager, then you'd run something like this
yum install -y httpd python36u-mod_wsgi
Let's now add a group www
groupadd www
and edit the group
vim /etc/group
and add in the end of the file
www:x:10000:root,apache
Go to the root directory and run the following commands to make the www group owner of this directory
chown root.www -R /home/mosajan
chmod 775 -R /home/mosajan
Now in your Apache virtual host configuration file artistry.conf, the version you're presenting has an error in the last line (WSGIPythonPath /hom/mosajan/artistry). Fix it by using WSGIPythonPath /home/mosajan/artistry instead, save the file and check if the Apache config file if fine by running
httpd -t
You should get Syntax OK if all is well. I'm assuming you have that code inside a <VirtualHost *:8000></VirtualHost> block and would add as well an ErrorLog to it as well and probably would structure the file differently. Check if it works, if it doesn't then I would put some more thought into it. You can use this documentation page as reference (How to use Django with Apache and mod_wsgi).
Then, in your wsgi.py file I would change the sys.path.append line to have '/home/mosajan/artistry', so you would have something like this
import os, sys
from django.core.wsgi import get_wsgi_application
sys.path.append('/home/mosajan/artistry')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'artistry.settings')
application = get_wsgi_application()
Then, open port 80, enable and start httpd and check the result in the browser
enable httpd
systemctl start httpd
systemctl status httpd
You should see that it's starting fine and now when you go to the browser you should be able to see the project working just fine.
I'm really struggling here. I have a simple Python Flask REST API that I've developed. The API runs fine in my local development environment (Mac OS X) and when directly executed via the console on my EC2 instance.
I want to move this service into production and as such would like to host it behind Apache running on the EC2 instance. This is where I keep hitting a wall and I can't seem to get past the configurations and errors. I've research several articles online and questions here, none seem to be able to help me.
I'm hoping someone here can please provide me with step-by-step directions on how to deploy my service to production behind Apache running on an Amazon Linux EC2 instance.
Here are the steps I've taken:
Launched a basic Amazon Linux EC2 instance.
Apply updates to the instance, sudo yum update
Install Apache and WSIG, sudo yum install httpd24 mod24_wsgi
Start Apache, sudo service httpd start
Configure Apache to start automatically, sudo chkconfig httpd on
Test by hitting the DNS of my EC2 box. I successfully get the Amazon Linux AMI test page.
Adjust permissions on /var/www as follows
sudo groupadd www
sudo usermod -a -G www ec2-user
Logon/off and confirm membership, groups
sudo chown -R root:www /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
Test by hitting DNS of my EC2 box - still good so far.
Now that I know my instance is running, I would like to create two folders where I can test and run my Python Flask code. I do so as follows:
I create two folders, one for development and one for production.
/var/www/rest-dev/
/var/www/rest-prod/
I setup a virtual environment within each of the folders and install Flask.
virtualenv env
env/bin/pip install Flask
I then place a copy of my service in each folder.
Then I set permissions on app.py, chmod a+x app.py
I can successfully execute ./app.py and test the service by hitting the DNS name + port 5000. It works.
Now this is where I get tripped up. My goal is to be able to hit api.example.com and have my service's root load up. In the example code below, "Hello, World!" should simply display.
I've followed the tutorials found here with no luck.
http://peatiscoding.me/geek-stuff/mod_wsgi-apache-virtualenv/
http://webpy.org/cookbook/mod_wsgi-apache
http://www.jakowicz.com/flask-apache-wsgi/
After executing any of the steps in any of the articles above, I get an HTTP error page and nothing loads anymore, including the default Amazon Linux AMI test page. Below are the pieces of code and configurations that I've changed. I haven't changed my httpd.conf ... should I? There are probably several other things I'm missing.
Can someone please help me by providing me the necessary steps in detail to correct my mistakes?
Many thanks in advance!
When I view the error_log for HTTPD, it lists errors like this:
mod_wsgi (pid=8270): Target WSGI script '/var/www/rest-dev/deploy.wsgi' cannot be loaded as Python module.
mod_wsgi (pid=8270): Exception occurred processing WSGI script '/var/www/rest-dev/deploy.wsgi'.
Traceback (most recent call last):
File "/var/www/rest-dev/deploy.wsgi", line 16, in <module>
from app import app as application
File "/var/www/rest-dev/app.py", line 2, in <module>
from flask import Flask
ImportError: No module named flask
Here is my deploy.wsgi file, located in the rest-dev folder:
import os
import sys
import site
# Add virtualenv site packages
site.addsitedir(os.path.join(os.path.dirname(__file__), 'env/local/lib64/python2.7/site-packages'))
# Path of execution
sys.path.append('/var/www/rest-dev')
# Fired up virtualenv before include application
activate_env = os.path.expanduser(os.path.join(os.path.dirname(__file__), 'env/bin/activate_this.py'))
execfile(activate_env, dict(__file__=activate_env))
# import my_flask_app as application
from app import app as application
Here is my vhost.conf file located in /etc/httpd/conf.d/
<VirtualHost *:80>
ServerName api.example.com
WSGIDaemonProcess webtool user=ec2-user group=www threads=5 home=/var/www/rest-dev/
WSGIScriptAlias / /var/www/rest-dev/deploy.wsgi
<directory /var/www/rest-dev>
WSGIProcessGroup webtool
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Order deny,allow
Allow from all
</directory>
</VirtualHost>
Here is my app.py example service code for reference:
#!env/bin/python
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return "Hello, World!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Turns out, in my deploy.wsgi file I'm referencing lib64 instead of just lib. All the site packages exist in lib.
After changing it and restarting Apache, I'm able to successfully hit my service from the URL.
The team I currently work with has outgrown the django development server for running django applications within our local development environments. The environment itself (server 2008 vm) is a mix of .net applications backed off of IIS7 coupled with several django applications.
We have a need for being able to have our local development environments run all applications concurrently for ease of development and testing. We have decided to move towards a full instance of apache running alongside IIS to more closely resemble our production and testing environments (the difference of course being linux / windows for the host of apache).
We have configured mod_wsgi and apache to run locally however it seems that we do not quite have either the python or the django path configured correctly as at runtime our applications are complaining that views do not exist with error's like:
Could not import reporting.views.
Error was: DLL load failed: The
specified module could not be found.
The django exception location is showing:
Exception Location: C:\Python27\lib\site-packages\django\core\urlresolvers.py in _get_callback, line 132
Therefore we assume it is some sort of path problem but as of yet we have not been able to figure out what is going wrong.
Thanks all.
LoadModule wsgi_module modules/mod_wsgi.so
WSGIPythonHome X:\PathToApplication\venv\Scripts
<VirtualHost *:8000>
ServerName applicationdomain
ServerAlias applicationapidomain
SetEnv DJANGO_ENV local
WSGIScriptAlias / X:/PathToApplication/apache/django.wsgi
<Directory X:/PathToApplication/ >
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:8001>
ServerName applicationdomain
SetEnv DJANGO_ENV local
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\conf\wildcard.crt"
SSLCertificateKeyFile "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\conf\wildcard.key"
WSGIScriptAlias / X:/PathToApplication/apache/django.wsgi
<Directory X:/PathToApplication/ >
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Your problem has to do with compiled modules and mod_wsgi.
Python from Python.org has an embedded manifest that allows it to load DLL files. When compiling C modules python used to embed the manifest in the compiled modules, however since has started stripping them out by default. The issue here is that mod_wsgi includes it's own python interpreter which does not have that manifest file included.
I think in order to get this to work you need to either compile with MingW, embed a manifest into Apache, or change python to embed a manifest into the modules you are compiling.
http://www.mail-archive.com/modwsgi#googlegroups.com/msg06255.html has a response from someone who was embedding the manifest into apache2.
If my memory serves somewhere around line 680ish of Python27/Lib/distutils/msvc9compiler.py there should be a bit of code that looks like
try:
# Remove references to the Visual C runtime, so they will
# fall through to the Visual C dependency of Python.exe.
# This way, when installed for a restricted user (e.g.
# runtimes are not in WinSxS folder, but in Python's own
# folder), the runtimes do not need to be in every folder
# with .pyd's.
manifest_f = open(manifest_file)
try:
manifest_buf = manifest_f.read()
finally:
manifest_f.close()
pattern = re.compile(
r"""<assemblyIdentity.*?name=("|')Microsoft\.""" \
r"""VC\d{2}\.CRT("|').*?(/>|</assemblyIdentity>)""",
re.DOTALL)
manifest_buf = re.sub(pattern, "", manifest_buf)
pattern = "<dependentAssembly>\s*</dependentAssembly>"
manifest_buf = re.sub(pattern, "", manifest_buf)
manifest_f = open(manifest_file, 'w')
try:
manifest_f.write(manifest_buf)
finally:
manifest_f.close()
except IOError:
pass
removing or commenting this out should stop python from stripping out the manifest file.