Reputation: 155
I want to deploy a Django website hosted in an Azure Web App.
The static files are served perfectly in DEBUG mode (DEBUG=False), but I can't find the right settings to have the server take care of it in production. All my static files are collected in a "static" directory at the app root wwwroot/static/.
Here is the web.config, at the root of the application.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="WSGI_ALT_VIRTUALENV_HANDLER" value="MyApp.wsgi.application" />
<add key="WSGI_ALT_VIRTUALENV_ACTIVATE_THIS" value="D:\home\site\wwwroot\env\Scripts\python.exe" />
<add key="WSGI_HANDLER" value="ptvs_virtualenv_proxy.get_venv_handler()" />
<add key="PYTHONPATH" value="D:\home\site\wwwroot" />
<add key="DJANGO_SETTINGS_MODULE" value="MyApp.settings" />
<add key="WSGI_LOG" value="D:\home\LogFiles\wfastcgit.log"/>
</appSettings>
<system.webServer>
<handlers>
<add name="PythonHandler" path="handler.fcgi" verb="*" modules="FastCgiModule" scriptProcessor="D:\Python34\python.exe|D:\Python34\Scripts\wfastcgi.py" resourceType="Unspecified" requireAccess="Script"/>
</handlers>
<rewrite>
<rules>
<rule name="Static Files" stopProcessing="true">
<conditions>
<add input="true" pattern="false" />
</conditions>
</rule>
<rule name="Configure Python" stopProcessing="true">
<match url="(.*)" ignoreCase="false" />
<action type="Rewrite" url="handler.fcgi/{R:1}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
I also added the following web.config in the static directory:
<?xml version="1.0"?>
<configuration>
<system.webServer>
<!-- this configuration overrides the FastCGI handler to let IIS serve the static files -->
<handlers>
<clear />
<add
name="StaticFile"
path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule"
resourceType="Either"
requireAccess="Read" />
</handlers>
</system.webServer>
I also defined the static directory as a "virtual directory" in the web app settings, with "\static" refering to "\site\wwwroot\static", and checking the "application" checkbox (i also tried to leave it unchecked but it does not change anything.
However, this is not working.
1) Is it possible to setup an Azure web app to serve the static files in production without using a CDN?
2) If yes, how to do it?
Upvotes: 1
Views: 6628
Reputation: 4164
If after trying all the other proposed solutions you still find yourself at trouble, you may have to understand that depending on the server that's running you application is the way static files are server. Django has it's own server, which is run by using the command:
python manage.py runserver
But PAAS providers do not use this server in most of the cases. gunicorn is in most times the chosen one. Azure sometimes uses IIS's FastCGI handler but at current date it is intelligent enough to detect a django application and try to use django's default server.
So, the first step you have to take is to find out what server is azure using to run your app, and you may know that by reading azure's log:
https:// YOUR APP NAME.scm.azurewebsites.net/api/logstream
If you confirm that azure is using django's default server, you must bear in mind that django does not server static files automatically when in a production environment. You must configure the static folder's url. So in your config/urls.py set the static url, like this:
from django.conf import settings
from django.conf.urls.i18n import i18n_patterns
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
urlpatterns = i18n_patterns(path('admin/', admin.site.urls), prefix_default_language=False) + \
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + \
static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
As you can see, I enable admin, static and media urls. This is enough to let django's default server know where to find and serve static files (and media files too, as well as admin routes)
Upvotes: 0
Reputation: 155
I was able to solve the problem after contacting Azure support. This is actually not a trivial problem, and other may have experienced it. The solution below also significantly improves the performances of the app.
According to Microsoft Azure support team:
Here is the procedure I followed to solve the problem(s):
Add a new web.config file in your static directory, as described in the same tutorial
Install Python packages, by using the debug console and your "requirements.txt" file, running:
D:\home\python353x86\python.exe -m pip install -r requirements.txt
Replace the python path with your actual path. The python packages are now installed along with your Python exe. Using a virtual environment will slow down the loading of your web page in case the application has to restart.
At this point, your web app should work properly
If you are using webjobs, you need to update the way you are running them. The solution is to create a "run.cmd" file in your webjob directory, containing :
D:\home\python353x86\python.exe start.py
Where start.py is your webjob script. Once again, replace the python path with your actual path.
Upvotes: 1
Reputation: 11
I've solved this problem by adding this 2 lines to the top of <handlers>
section in root web.config file:
<remove name="Python27_via_FastCGI" />
<remove name="Python34_via_FastCGI" />
Everything else is the same as your's web.config and I didn't need separate config file in static/
directory
Upvotes: 1
Reputation: 18387
It's a good idea to move your static content to Azure Blob Storage and use a CDN for a better performance.
1-) You can define your web.config just like the following: https://github.com/prashanthmadi/azure-django-customdeployment/blob/master/web.config
2-) to configure the static file handler, add the following: https://stackoverflow.com/a/2066040/1384539
Upvotes: 1