django deploy - ubuntu 14.04 and apache2 - python

https://www.sitepoint.com/deploying-a-django-app-with-mod_wsgi-on-ubuntu-14-04/
and
https://www.youtube.com/watch?v=hBMVVruB9Vs
This was the first time I deploy a website.And these are the tutorials I followed.
Now I can access to the server(by typing 10.231.XX.XX) from other machine and see the Apache2 Ubuntu Default Page.
Then I tried to access my django project. I run:
python manage.py runserver 8000
Validating models...
0 errors found August 03, 2016 - 09:44:20 Django version 1.6.1, using
settings 'settings' Starting development server at
http://127.0.0.1:8000/ Quit the server with CONTROL-C.
Then I type 10.231.XX.XX:8000 to try to acess the django page. But I failed.
It said:
This site can’t be reached
10.231.XX.XX refused to connect. Search Google for 231 8000 ERR_CONNECTION_REFUSED
I have tried every thing I can but still can't figure why.
(as followed the website https://www.sitepoint.com/deploying-a-django-app-with-mod_wsgi-on-ubuntu-14-04/)
I have apache folder in mysite folder, and in override.py:
from mysite.settings import *
DEBUG = True
ALLOWED_HOSTS = ['10.231.XX.XX']
in wsgi.py:
import os, sys
# Calculate the path based on the location of the WSGI script.
apache_configuration= os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)
sys.path.append(workspace)
sys.path.append(project)
# Add the path to 3rd party django application and to django itself.
sys.path.append('/home/zhaojf1')
os.environ['DJANGO_SETTINGS_MODULE'] = '10.231.52.XX.apache.override'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
and __init__py is empty.
in /etc/apache2/sites-enabled/000-default.conf :
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
WSGIScriptAlias /msa.html /home/zhaojf1/Web-Interaction/apache/wsgi.py
<Directory "/home/zhaojf1/Web-Interaction-APP">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
I have also restart apache after I do everything.
Thanks for help

The connection refused error is likely going to come down to Apache being incorrectly configured for the VirtualHost or you accessing wrong port. You also have other basic mistakes in your wsgi.py file as well.
Starting with the wsgi.py file, the DJANGO_SETTINGS_MODULE value is wrong:
os.environ['DJANGO_SETTINGS_MODULE'] = '10.231.52.XX.apache.override'
The value is meant to be a Python module path. Having the IP address in there looks very wrong and is unlikely to yield what you need.
Next is changes to sys.path. The location of your project and activation of any Python virtual environment is better done through options for mod_wsgi in the Apache configuration file.
That you are adding a home directory into the path is also a flag to potential other issues you may encounter. Specifically, the user that Apache runs as often cannot read into home directories as the home directories are not readable/accessible to others. You may need to move the project out of your home directory.
As to the Apache configuration, your VirtualHost lacks a ServerName directive. If this was an additional VirtualHost you added and not the default (first one appearing in Apache configuration when parsed), it will be ignored, with all requests going to the first VirtualHost. You do show this as in the default site file, so may be you are okay.
Even so, that VirtualHost is set up to listed on port 80. You are trying to connect to port 8000, so there wouldn't be anything listening.
Next issue is the WSGIScriptAlias line.
WSGIScriptAlias /msa.html /home/zhaojf1/Web-Interaction/apache/wsgi.py
It is strange to have msg.html as the mount point as that makes it appear as if you are accessing a single HTML page, but you have it mapped to a whole Django project. If you were accessing the root of the host, it also wouldn't map through to the Django application as you have it mounted at a sub URL. Thus perhaps need to use:
WSGIScriptAlias / /home/zhaojf1/Web-Interaction/apache/wsgi.py
Next problem is that the directory specified in Directory directive doesn't match where you said the wsgi.py file existed in the WSGIScriptAlias. They should match. So maybe you meant:
<Directory /home/zhaojf1/Web-Interaction/apache>
Even then that doesn't look right as where is the apache directory coming from. That last directory in the path should normally be the name of the Django project.
One final thing, you may need to change ALLOWED_HOSTS as well. If you find you start getting bad request errors it probably doesn't match properly. Change it to ['*'] to see if that helps.
So lots of little things wrong.
Suggestions are:
Make sure you read the official Django documentation for setting up mod_wsgi. See https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/modwsgi/
If you are only wanting to do development at this point, use mod_wsgi-express instead. See http://blog.dscpl.com.au/2015/04/using-modwsgi-express-with-django.html and http://blog.dscpl.com.au/2015/04/integrating-modwsgi-express-as-django.html

Related

OSError: [Errno 98] Address already in use Running Flask Application on Apache2

I have my flask code in app.py
/some code//
if __name__ == '__main__':
app.run()
and i have set up my wsgi file as in the path /var/www/AutomateTests
#!/usr/bin/python3.6
import sys
import logging
sys.path.insert(0,"/var/www/AutomateTests/")
from app import app as application
application.root_path = '/var/www/AutomateTests/'
and I have /etc/apache2/sites-available/automate_tests.conf
VirtualHost *:80>
ServerName htstool.arubanetworks.com
ServerAdmin admin#htstool.arubanetworks.com
ServerAlias htstool.arubanetworks.com
ErrorLog /var/log/apache2/hts-error.log
CustomLog /var/log/apache2/htstool-access.log combined
WSGIDaemonProcess AutomateTests user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/AutomateTests/automate_tests.wsgi
<Directory /var/www/AutomateTests>
WSGIProcessGroup AutomateTests
WSGIApplicationGroup %{GLOBAL}
Order allow,deny
Allow from all
</Directory>
LogLevel info
</VirtualHost>
I have set up everything rightly and i have been stuck on this problem for weeks now. Can someplease help me on how to bring it up on the server. Is there a step i am missing.
im setting the same error of my port is in use although ITS NOT!
See the picture of my error
enter image description here
But as you can see my ports are empty and not being used. I check that using the command netstat -ntlp
see my ports are listening and not established
Can someone please please help me. I am stuck and don't mark it as already answered before checking it completely. I have tried all the answers and they don't work! Please be patient and let others help me because I can't do it myself.
My server is running fine and I'm seeing the default ubuntu page which means that my apache2 server is working fine so there is something wrong with either the configuration or my ports
Two things come to mind when I see this.
Do you have Apache installed and running on the server? Apache may be listening on port 80 and preventing your Python script from binding to that port, but the way you ran netcat won't show this. You can check this at [sever_ip]:80.
But as you can see my ports are empty and not being used. I check that using the command netstat -ntlp
Note the first line of output from that command: (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Apache runs with elevated privileges, so you'll need to run as root (append sudo to the beginning of your command) to see its port binding. I'd bet that this is the issue. Once this is fixed, you may run in to the following issue:
Are you running the script as root? On Linux, you need to use sudo to bind to ports 0 through 1024 (as explained here).
One more thing, not related to the script specifically, but it looks like you're using AWS EC2 in the screenshots (correct me if I'm wrong). If you want to be able to reach the instance on port 80 from the public internet, you'll need to make sure you allow it in the Security Group. I know this can cause some confusion for people using AWS EC2 for the first time, sure did for me.
Hope this helps!

Apache httpd not able to access local MongoDB (permission denied)

I am using to apache httpd to serve my python application. The application is running perfectly in standalone mode using the binary executable command inginious-webapp. MongoDB also works fine.
But the problem arises when serving it though Apache HTTPD
When I browse the website I get a 500 error. This is the error_log
[Wed Jun 14 06:00:20.113043 2017] [wsgi:error] [pid 1194] [client 125.99.159.82:29947] pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [Errno 13] Permission denied, referer: http://<my_domain>.eastus.cloudapp.azure.com/
Config Info
Added apache to mongodb -> usermod -aG mongodb apache
Changed owner to apache -> chown -R apache:apache /var/www/INGInious
httpd.conf
# Default config till here. Changes follows
Include conf.modules.d/*.conf
#
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User apache
Group apache
LoadModule wsgi_module /usr/lib64/python3.5/site-packages/mod_wsgi/server/mod_wsgi-py35.cpython-35m-x86_64-linux-gnu.so
WSGIScriptAlias / "/usr/bin/inginious-webapp"
WSGIScriptReloading On
Alias /static/common /usr/lib/python3.5/site-packages/inginious/frontend/common/static/
Alias /static/webapp /usr/lib/python3.5/site-packages/inginious/frontend/webapp/static/
Alias /static/lti /usr/lib/python3.5/site-packages/inginious/frontend/lti/static/
# 'Main' server configuration
#
# The directives in this section set up the values used by the 'main'
# server, which responds to any requests that aren't handled by a
# <VirtualHost> definition. These values also provide defaults for
# any <VirtualHost> containers you may define later in the file.
#
# All of these directives may appear inside <VirtualHost> containers,
# in which case these default settings will be overridden for the
# virtual host being defined.
#
#
# ServerAdmin: Your address, where problems with the server should be
# e-mailed. This address appears on some server-generated pages, such
# as error documents. e.g. admin#your-domain.com
#
ServerAdmin root#localhost
#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName http://<my_domain>.eastus.cloudapp.azure.com:80
#
# Deny access to the entirety of your server's filesystem. You must
# explicitly permit access to web content directories in other
# <Directory> blocks below.
#
<Directory />
AllowOverride none
Require all denied
</Directory>
#
# Note that from this point forward you must specifically allow
# particular features to be enabled - so if something's not working as
# you might expect, make sure that you have specifically enabled it
# below.
#
<Directory "/usr/bin">
<Files "inginious-webapp">
Require all granted
</Files>
</Directory>
<DirectoryMatch "/usr/lib/python3.5/site-packages/inginious/frontend/(.+)/static/">
Require all granted
</DirectoryMatch>
# Rest Unchanged
I was having the same issue, and after a fair bit of hair pulling I found out that selinux was enabled on the virtual machine I was using.
If it so happens you also have selinux enabled (http://www.microhowto.info/howto/determine_whether_selinux_is_enabled.html), to get around this issue you need to allow the httpd process make network requests. You can do that by executing the following:
sudo /usr/sbin/setsebool -P httpd_can_network_connect 1
and then restart the apache service.
Unfortunately, you will most likely run into another road block afterwards when INGInious attempts to connect to the docker daemon. To get around this you will need to create a local policy module. The local policy module will then permit INGInious to connect to the docker daemon. I recommend installing sealert. This can be done by running:
sudo yum install setroubleshoot setools
if you are using CentOS (and likely RedHat). Once you have sealert installed run:
sealert -a /var/log/audit/audit.log
This will give you some info about operations being blocked by selinux. If you dig through the log you will see that the httpd is being denied access to the socket for the docker daemon. Chances are it will give you some instructions on how to generate the local policy module for httpd. Using CentOS, I had to run:
ausearch -c 'httpd' --raw | audit2allow -M my-httpd
semodule -i my-httpd.pp
If ausearch returns an error indicating that /etc/selinux/targeted/contexts/files/file_contexts.local is not present, simply run:
sudo touch /etc/selinux/targeted/contexts/files/file_contexts.local

How do I prevent the raw WSGI python file from being read?

I am using mod_wsgi with apache to serve the python application. I have a directive in the VirtualHost entry as follows WSGIScriptAlias /app /home/ubuntu/www/app.wsgi. I also have DocumentRoot /home/ubuntu/www/. Therefore, if the user attempts to read /app.wsgi it gets the raw file. If I try to block access to it via .htaccess, the application becomes unusable. How do I fix this? Is there a way to do so without moving the file out of the DocumentRoot?
This is far from the best option, but it does seem to work: I added WSGIScriptAlias /app.wsgi /home/ubuntu/www/app.wsgi to the VirtualHost as well so that it will run the app on that uri instead of returning the raw file.
You should not stick the WSGI file in the DocumentRoot directory in the first place. You have created the situation yourself. It doesn't need to be in that directory for WSGIScriptAlias to work.

Making Django work with Apache

I have a test django project that I have been using the django development server for. I want to start using an actual apache server to properly simulate a production environment. I am using Mac OS X.
I have been using this tutorial here, but in the first set of instructions I am getting a 403 from localhost. The browser says I do not have permission to access / on the server.
When I comment out the apache config line from the tutorial, WSGIScriptAlias / /Users/username/Projects/django_books/django_books/django.wsgi I can access localhost.
This is the contents of my django.wsgi file:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_books.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
path = '/Users/username/Projects/django_books/django_books'
if path not in sys.path:
sys.path.append(path)
What is causing the 403 and why can't I see my django application?
EDIT
Directory structure:
django_books
apache (empty directory right now)
random_book
__init__.py
models.py
views.py
django_books
__init__.py
django.wsgi
settings.py
urls.py
views.py
wsgi.py
media
static
css
style.css
manage.py
2ND EDIT
Permissions on all the directories:
/Users/username/Projects/django_books/django_books/django.wsgi
-rw-r--r--
/Users/username/Projects/django_books/django_books
drwxr-xr-x
/Users/username/Projects/django_books/
drwxr-xr-x
/Users/username/Projects/
drwxr-xr-x
/Users/username/
drwxr-xr-x+
/Users/
drwxr-xr-x
According to my small experience I think you must add the following lines "just below the import sys line to place your project on the path" (so juste under "import sys") like it's said in the tutorial you quote. Also, erase the second "django_books" in your path because you want to link to your site not the app in your site ;-) ("mysite" in the tutorial, not mysite/mysite)
import os
import sys
path = '/Users/username/Projects/django_books'
if path not in sys.path:
sys.path.append(path)
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_books.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Bye
It's likely an issue related either to your Apache installation, python library, or the filesystem's permissions.
Testing Apache
You don't say it in your question, but I assume from your link you are working with Apache2 and mod_wsgi.
You can test if Apache and mod_wsgi (or your wsgi module) are working properly by placing a dummy wsgi script in the place of django.wsgi . This script (stolen from mod_wsgi's docs) doesn't rely on Django and helps make sure that Apache can read and execute the wsgi script:
# test version of django.wsgi
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
And restart apache
sudo service apache2 restart
Go ahead and test the page. Did it work? Great. Undo the changes to the django.wsgi script, restart Apache and test again. If the Django site still doesn't work, we need to keep looking. If the test script didn't work, there may be a problem with your Apache installation. Check apache's error log for more information about what happened. On linux it's commonly at /var/log/apache2/error.log . mod_wsgi could be improperly installed, the script's daemon may not have appropriate permission to the wsgi file.
Correcting permission errors
Apache may not be able to read and execute the wsgi file. Running ls -l in the wsgi file's directory as indicated in other answers will tell you the user and group a file belongs to (and if that user and group can read, write, or execute a given file). It's common for a default installation to have the wsgi permissions like so:
-rw------- 1 www-data www-data 1470 Aug 29 16:00 django.wsgi
If you want to use a different user for the daemon process, you need to make sure that the apache conf file defines WSGIDaemonProccess
WSGIScriptAlias / /Users/username/Projects/django_books/django_books/django.wsgi
WSGIDaemonProcess wsgi_user processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup wsgi_group
Testing changes to these files and restarting Apache can help narrow down what's up. Keep checking the Apache log files.
Apache Configuration
Django's tutorial on setting up mod_wsgi is good, but read through mod_wsgi's wiki as well. There are a lot of helpful things to consider in your apache conf file besides WSGIScriptAlias. Make sure there is a tag pointing to the folder with your wsgi file. If there are non-public files (like django project files) in that directory, either use the apache directory (update your apache conf file) or add a tag under the node to keep those other files private. While you're in there, you may notice other things that look wrong, like an improperly configured servername, multiple virtual hosts, or other errors.
Testing Python
If you're using virtualenv (do it), make sure that
1. The WSGIDaemonProcess variable defines the appropriate site-packages and the wsgi script's location in the variable's python-path attribute
2. The daemon has rights to read the site packages in your virtualenv.
3. Your wsgi script properly imports django and your site's settings.
Logging Apache
You can increase the level of logging reported by Apache by adding a few lines to your Apache conf file. This setup gives you very verbose logging that you may want during deployment (make sure to make a log folder):
LogLevel info
ErrorLog /Users/username/Projects/django_books/logs/apache_error.log
CustomLog /Users/username/Projects/django_books/logs/apache_access.log combined
I would suspect that the www-data (or whatever user apache is running as) doesn't have access to /Users/username/Projects/django_books/django_books.
su to that user and try and access that directory and the wsgi file within it.
To print all the relevant permissions:
ls -ld /Users /Users/username /Users/username/Projects /Users/username/Projects/django_books /Users/username/Projects/django_books/django_books /Users/username/Projects/django_books/django_books/django.wsgi
You should also check the apache error logs, they might tell you what is going wrong.

How to configue apache and mode_wsgi for local django development on windows

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.

Categories