Cannot resolve path in Flask application running on WSGI/Apache [duplicate] - flask

This question already has an answer here:
Refering to a directory in a Flask app doesn't work unless the path is absolute
(1 answer)
Closed 5 years ago.
I am trying to deploy a FLASK application in Ubuntu VPS using wsgi but I get an Internal server error. Checking the apache.log gives me following error:
No such file or directory: 'files/filesystem/filesystem.pickle'.
My directory tree looks like this under /var/www/:
dmft_seacrh_engine
files
filesystem
filesystem.pickle
dmft_search.wsgi
dmft_search
controllers
search.py
I am trying to open the filesystem.pickle inside search.py as following:
with open('/files/filesystem/filesystem.pickle', 'rb') as handle:
filesystem = pickle.load(handle)
Contents of the dmft.wsgi file are:
activate_this = '/opt/dmft/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/dmft_search_engine")
from dmft_search import app as application
This is how my conf file looks:
<VirtualHost *:80>
ServerName dmft_search_engine.com
WSGIScriptAlias / /var/www/dmft_search_engine/dmft_search.wsgi
<Directory /var/www/dmft_search_engine/dmft_search/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/dmft_search_engine/dmft_search/static
<Directory /var/www/dmft_search_engine/dmft_search/static/>
Order allow,deny
Allow from all
</Directory>
Alias /files /var/www/dmft_search_engine/files/$
<Directory /var/www/dmft_search_engine/files/>$
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Kindly help me out. I have also added an alias for /files in .conf file.
How can I resolve this?

The problem is that the app run in the context of root directory
so the correct path should be:
with open('var/www/html/dmft_search_engine/files/filesystem/filesystem.pickle', 'rb') as handle:
filesystem = pickle.load(handle)

Related

Django: how to configure Apache to serve Django apps with mod_wsgi

I tried to set up a Django app with Apache and mod_wsgi, but ran into a problem that I have no ideas where is the cause. The app works fine with the command "python manage.py runserver", but when I tried to run it with Apache, I got the following errors in the Apache error log file.
Current thread 0x00007fb4880ad940 (most recent call first):
<no Python frame>
Python path configuration:
PYTHONHOME = '/data/anaconda3/envs/partsdb'
PYTHONPATH = (not set)
program name = 'python3'
isolated = 0
environment = 1
user site = 1
import site = 1
sys._base_executable = '/usr/bin/python3'
sys.base_prefix = '/data/anaconda3/envs/partsdb'
sys.base_exec_prefix = '/data/anaconda3/envs/partsdb'
sys.platlibdir = 'lib64'
sys.executable = '/usr/bin/python3'
sys.prefix = '/data/anaconda3/envs/partsdb'
sys.exec_prefix = '/data/anaconda3/envs/partsdb'
sys.path = [
'/data/anaconda3/envs/partsdb/lib64/python38.zip',
'/data/anaconda3/envs/partsdb/lib64/python3.8',
'/data/anaconda3/envs/partsdb/lib64/python3.8/lib-dynload',
]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'
I have the following lines in an Apache conf file.
WSGIPythonHome /data/anaconda3/envs/partsdb
WSGIPythonPath /data/partsdb/partsdb
WSGIScriptAlias / /data/partsdb/partsdb/wsgi.py
<Directory "/data/partsdb/partsdb">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
I also replaced the following two lines in the Apache conf file
WSGIPythonHome /data/anaconda3/envs/partsdb
WSGIPythonPath /data/partsdb/partsdb
with the following two lines, but got the same errors.
WSGIDaemonProcess partsdb python-path=/data/partsdb/partsdb python-home=/data/anaconda3/envs/hla3db_venv
WSGIProcessGroup partsdb
The file /data/partsdb/partsdb/wsgi.py just contains the following lines of codes.
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'partsdb.settings')
application = get_wsgi_application()
Upon a brief debugging, I found out that the errors were from this line in wsgi.py.
from django.core.wsgi import get_wsgi_application
My machine's OS is redhat 8, and the Apache version is 2.4.37. Thanks for any info/hints.
Try the following code:
WSGIDaemonProcess partsdb python-path=/data/partsdb/partsdb python-home=/data/anaconda3/envs/hla3db_venv
WSGIProcessGroup partsdb
WSGIApplicationGroup %{GLOBAL}
WSGIPythonHome /data/anaconda3/envs/partsdb
WSGIPythonPath /data/partsdb/partsdb
WSGIScriptAlias / /data/partsdb/partsdb/wsgi.py
<Directory "/data/partsdb/partsdb">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
Alias /static /path/to/directory/defined/as/STATIC_ROOT/
# The first part is defined by STATIC_URL in settings.py
<Directory /path/to/directory/defined/as/STATIC_ROOT>
Require all granted
</Directory>
<VirtualHost *:80>
ServerName mysite.app
ServerAdmin webmaster#localhost
# You do not need to specify DocumentRoot
# I have seen advice not to do so
ErrorLog ${APACHE_LOG_DIR}error.log
CustomLog ${APACE_LOG_DIR}access.log combined
</VirtualHost>
Please note I used this for a single app running in daemon mode as suggested in the documentation, on a Ubuntu server. Check the permissions on the folders, in my case I had to change permissions to allow apache to read and write to the folders the site was in.
You can also look at the answer Graham Dumpleton gave a few years back here:
Apache with virtualenv and mod_wsgi : ImportError : No module named 'django'

Django apache internal server error

I got "500 Internal Server Error", when I try to connect to my django project.
I try lots of way to setting the configuration file, include some method on stackoverflow. But I still can't solve the problem.Can someone help? Thank you very much.
This is my vhost wsgi config
<Directory "/home/antus/bazoo/Antus_Bazoo_Web">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess antus_bazoo python-
path=/home/antus/bazoo:/home/antus/bazoo/bazoo_env/lib/python3.7/site-
packages display-name=antus_bazoo python-home=/home/antus/bazoo/bazoo_env
WSGIProcessGroup antus_bazoo
WSGIScriptAlias / /home/antus/bazoo/Antus_Bazoo_Web/wsgi.py process-
group=antus_bazoo
This is the wsgi file
import os
import sys
import site
# Add the site-packages of the chosen virtualenv to work with
site.addsitedir('/home/antus/bazoo/bazoo_env/lib/python3.7/site-packages')
# Add the app's directory to the PYTHONPATH
sys.path.append('/home/antus/bazoo')
sys.path.append('/home/antus/bazoo/Antus_Bazoo_Web')
sys.path.append('/home/antus/bazoo/antus_bazoo')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Antus_Bazoo_Web.settings")
fh = open('/home/antus/bazoo/wsgi_hello.txt', 'w')
fh.write('wsgi execution')
fh.close()
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
I do also save the errors in error log but it does not have anything to consider and even the file is not created.
UPDATE
This is the Vhost configuration.
<VirtualHost *:80>
ServerName mywebsite
ServerAlias www.mywebsite
ServerAdmin webmaster#mywebsite
DocumentRoot /home/antus/public_html
UseCanonicalName Off
ScriptAlias /cgi-bin/ /home/antus/public_html/cgi-bin/
# Custom settings are loaded below this line (if any exist)
Include /usr/local/apache/conf/userdata/antus/bazoo/*.conf
ErrorLog /usr/local/apache/logs/userdata/antus/bazoo/error_log
CustomLog /usr/local/apache/logs/userdata/antus/bazoo/custom_log combined
<IfModule mod_userdir.c>
UserDir disabled
UserDir enabled antus
</IfModule>
<IfModule mod_suexec.c>
SuexecUserGroup antus antus
</IfModule>
<IfModule mod_suphp.c>
suPHP_UserGroup antus antus
suPHP_ConfigPath /home/antus
</IfModule>
<Directory "/home/antus/public_html">
AllowOverride All
</Directory>
</VirtualHost>
The "500 Internal Server Error" would indicate something has gone wrong on the server and seeing that the wsgi.py has a file open operation, I'd looking for errors start there seeing as well that you mentioned something about "the file is not created".
fh = open('/home/antus/bazoo/wsgi_hello.txt', 'w')
The above line will not create a file. To create a file with open() use:
fh = open('/home/antus/bazoo/wsgi_hello.txt', 'w+')
Also a bit of the logs would go a great way in debugging this

Setting up Apache to serve the django admin files

In my apache.conf file (see code below°), VirtualHost port 80 configuration works fine. However, in the port 443, the Alias /admin/media/ /usr/local/lib/python2.7/site-packages/django/contrib/admin/media/ shows two issues:
my settings.py has : STATIC_URL = '/m/' and ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
my admin directory is : /home/user/project/virtual-environment/lib/python2.7/site-packages/django/contrib/admin/static/admin/
When I put Alias /m/admin/ /home/user/project/virtual-environment/lib/python2.7/site-packages/django/contrib/admin/static/admin/ it shows error 403 access forbidden.
When I add:
<Directory "/home/user/project/virtual-environment/lib/python2.7/site-packages/django/contrib/admin/static/admin/">
Require all granted
</Directory>
<Directory "/home/user/project/">
<Files django.wsgi>
Require all granted
</Files>
</Directory>
It shows error 404 not found with error_log saying :[wsgi:error] Target WSGI script '/home/user/project/django.wsgi' does not contain WSGI application 'application'
Could you please help me configure my apache virtualhost port 443 to server django admin app?
°My apache.conf file is as below:
#The following two directories must be both readable and writable by apache
WSGISocketPrefix /var/run/apache2/wsgi
#WSGIPythonEggs /var/python/eggs
# the following directory must be readable by apache
WSGIPythonHome /home/user/project/virtual-environment/local/
# NOTE: all urs below will need to be adjusted if
# settings.FORUM_SCRIPT_ALIAS is anything other than empty string (e.g. = 'forum/')
# this allows "rooting" forum at http://domain-name/forum, if you like
#replace default ip with real IP address
<VirtualHost *:80>
ServerAdmin you#domain-name
DocumentRoot /home/user/project/
ServerName domain-name
# aliases to serve static media directly
Alias /m/ /home/user/project/static/
Alias /upfiles/ /home/user/project/askbot/upfiles/
<DirectoryMatch "/home/user/project/askbot/skins/([^/]+)/media">
Require all granted
</DirectoryMatch>
<Directory "/home/user/project/askbot/upfiles">
Require all granted
</Directory>
<Directory "/home/user/project/ask-skins">
Require all granted
</Directory>
<Directory "/home/user/project//static">
Require all granted
</Directory>
#must be a distinct name within your apache configuration
WSGIDaemonProcess askbot2 python-path=/home/user/project:/home/user/project/virtua-environment/lib/python2.7/site-packages
WSGIProcessGroup askbot2
WSGIScriptAlias / /home/user/project//django.wsgi
<Directory "/home/user/project/">
<Files django.wsgi>
Require all granted
</Files>
</Directory>
# make all admin stuff except media go through secure connection
<LocationMatch "/admin(?!/media)">
RewriteEngine on
RewriteRule /admin(.*)$ https://domain-name/admin$1 [L,R=301]
</LocationMatch>
CustomLog /var/log/apache2/domain-name/access_log common
ErrorLog /var/log/apache2/domain-name/error_log
LogLevel debug
</VirtualHost>
#again, replace the IP address
<VirtualHost *:443>
ServerAdmin you#domain-name
DocumentRoot /home/user/project/
ServerName domain-name
<LocationMatch "^(?!/admin)">
RewriteEngine on
RewriteRule django.wsgi(.*)$ http://domain-name$1 [L,R=301]
</LocationMatch>
SSLEngine on
#your SSL keys
SSLCertificateFile /etc/httpd/ssl.crt/server.crt
SSLCertificateKeyFile /etc/httpd/ssl.key/server.key
Alias /admin/media/ /usr/local/lib/python2.7/site-packages/django/contrib/admin/media/
WSGIScriptAlias / /home/user/project/django.wsgi
CustomLog /var/log/httpd/askbot/access_log common
ErrorLog /var/log/httpd/askbot/error_log
</VirtualHost>
My django.wsgi file is as below :
import os
import sys
import time
import traceback
import signal
current_directory = os.path.dirname(__file__)
parent_directory = os.path.dirname(current_directory)
module_name = os.path.basename(current_directory)
sys.path.append(parent_directory)
sys.path.append(current_directory)
os.environ['DJANGO_SETTINGS_MODULE'] = '%s.settings' % module_name
from django.core.wsgi import get_wsgi_application
try:
application = get_wsgi_application()
print 'WSGI without exception'
except Exception:
print 'handling WSGI exception'
# Error loading applications
if 'mod_wsgi' in sys.modules:
traceback.print_exc()
os.kill(os.getpid(), signal.SIGINT)
time.sleep(2.5)
You have a number of things wrong or sub optimal with your configuration.
The first is that when using mod_wsgi daemon mode and have only the one application, it is recommended you force use of the main Python interpreter context. This avoids problems with some third party Python modules that do not work with Python sub interpreters. To do this, add:
WSGIApplicationGroup %{GLOBAL}
to both VirtualHost definitions.
The second is that your SSL VirtualHost is not delegating the WSGI application to run in the same mod_wsgi daemon process group as non SSL VirtualHost defines. You need to add to the SSL VirtualHost:
WSGIProcessGroup askbot2
There is no need to add a WSGIDaemonProcess directive to the SSL VirtualHost as it is piggy backing off that setup in non SSL VirtualHost to avoid multiple copies of application. Right now you have an even bigger problem in that the SSL variant is running in embedded mode, with is even less desirable scenario.
The third is that when setting up a Python virtual environment, you should use the python-home option to refer to the root of the Python virtual environment and not use python-path to refer to site-packages. For details on that see:
http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
The fourth problem is how you are dealing with Django initialisation failing. There is no need to to use the try/except around creating the WSGI application object. What you should do if using mod_wsgi daemon mode is use a modern mod_wsgi version (not likely the ancient version your OS packages provide), and set the startup-timeout option on the WSGIDaemonProcess directive. That option will automatically force a restart of process if WSGI script file fails to load within a certain time. For details on that option see:
http://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIDaemonProcess.html
If you are not going to do that, you at least need to add a raise to the except part so that the exception is propagated back to mod_wsgi so it knows the WSGI script file couldn't be loaded. if you don't, mod_wsgi thinks the WSGI script file was loaded fine, but then when it looks for application can't find it and so generates a 404 response and the error your see.

django deployment using wsgi, on local machine

I'm trying to learn how to deploy with mod_wsgi. I'm using django 1.4 with a small app running in virtualenv
Here are my apache2.conf code changes (ubuntu):
# https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/modwsgi/
# jcg 9/18/2012
WSGIScriptAlias / /home/jgoldstick/code/learn/myapp/wsgi.py
#WSGIPythonPath /home/jgoldstick/code/learn/myapp
WSGIPythonPath /home/jgoldstick/code/learn/myapp/lib/python2.7/site-packages
<Directory /home/jgoldstick/code/learn/myapp>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
I am getting 404 pages when I access the site. I am using the standard wsgi.py script that django produces.
what am I missing
Update to be more complete:
Here is my wsgi.py file in myapp/myapp
I added the appends as per first answer.
I am assuming in that answer that wsdl.py really meant wsgi.py.
import os, sys
sys.path.append('/home/jgoldstick/code/learn')
sys.path.append('/home/jgoldstick/code/learn/myapp')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)
I changed apache2.conf (which I believe is same as httpd.conf for ubuntu configuration) to:
https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/modwsgi/
# jcg 9/18/2012
Alias /media/ /home/jgoldstick/code/learn/media/
<Directory /home/jgoldstick/code/learn/media>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /home/jgoldstick/code/learn/myapp/wsgi.py
WSGIPythonPath /home/jgoldstick/code/learn/myapp/lib/python2.7/site-packages
<Directory /home/jgoldstick/code/learn/myapp>
Order deny,allow
Allow from all
</Directory>
I restarted apache
But I still get 404 when I go to my app
wsdl.py:
import os, sys
sys.path.append('/home/jgoldstick/code/learn')
sys.path.append('/home/jgoldstick/code/learn/myapp')
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
And httpd.conf should look like:
Alias /media/ /home/jgoldstick/code/learn/media/
<Directory /home/jgoldstick/code/learn/media>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /home/jgoldstick/code/learn/myapp/django.wsgi
WSGIPythonPath /home/jgoldstick/code/learn/myapp/lib/python2.7/site-packages
<Directory /home/jgoldstick/code/learn/myapp>
Order deny,allow
Allow from all
</Directory>
If django.wsgi is located in /home/jgoldstick/code/learn/myapp/myapp/django.wsgi please add /myapp everywhere.
The same configuration as /media/ directory shoud have static and remember to execute ./manage.py collectstatic
Please refer to Documentation Django-modWSGI

Can't get mod_wsgi to work with Apache and Django on Mac OS X

I've been trying to get mod_wsgi working on a Mac OS X server, and I'm having absolutely no luck. I've added the LoadModule statement to the httpd.conf, and I've got the following file included:
apache_django_wsgi.conf:
WSGIDaemonProcess django
WSGIProcessGroup django
Alias /plagtest/ "/Users/plagtest/myproject/"
<Directory "/Users/plagtest/myproject/">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
WSGIScriptAlias /plagtest "/Users/plagtest/myproject/apache/myproject.wsgi"
<Directory "/Users/plagtest/myproject/apache">
Allow from all
</Directory>
And here's my WSGI file:
myproject.wsgi:
import os
import sys
paths = [ '/Users/plagtest/myproject',
'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages',
'/Users/plagtest',
]
for path in paths:
if path not in sys.path:
sys.path.append(path)
sys.executable = '/usr/local/bin/python2.7'
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
I can restart Apache just fine, but when I browse to localhost/plagtest/ it comes up file not found, and this is what I get in the error log:
File does not exist: /Library/WebServer/Documents/plagtest/
I'm not entirely familiar with Apache, and I'm sure that it's probably something very simple, but I can't for the life of me find a solution online. Any help in this matter would be greatly appreciated.
It looks like you have two Aliases for the same path. So hence you have a duplication. Remove:
Alias /plagtest/ "/Users/plagtest/myproject/"
<Directory "/Users/plagtest/myproject/">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
Without the media alias's the django manuals recommended HTTP conf is:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Order allow,deny
Allow from all
</Files>
</Directory>