⬆️ ⬇️

Deploying Django 1.9 on IIS 7+

Foreword



Hello!



Not so long ago I was asked to create a site. An interesting large project with a lot of " I want this ." Among the wishes were the two main ones that defined the web framework for writing, these are internationalization and the admin panel . As is already clear from the title of the article, Django has become such a framework.



At the start, and almost all the development time, we did not have one thing - the server . There was a domain name, a website was developed at a brisk pace, a designer joined the project, but we could not single out the server. All site shows were held on my laptop, not allowing the customer to sit down in the evening with a cup of coffee, relax and enjoy what we have already done for him. And also, the inability to show our work to people deprived us of receiving feedback.



And now, one can say the other day, a miracle happened - we got a server. And as a result of this - this article.





Problem



My joy was not long. The site is on Django , and the server is on Windows Server 2012 . First thought:



python manage.py runserver 80 


I open the site in a browser on the server - everything works Great I open the site on my home machine and see that the site is not available. Sadness



The next idea is to use IIS . But how? " Ok, Google " gave me a bunch of articles in different languages ​​with a lot of difficulties. I also did not ignore the article from Habr from Microsoft and from the official Django website , but all these decisions were rather cumbersome, and I wanted some simplicity and elegance.



What we have





Site structure (part of the tree):



 project/ manage.py project/ __init__.py settings.py urls.py wsgi.py 


Let's get down to solving the problem of deploying Django on IIS .



Solution to the problem



Python


Everything is simple, install wfastcgi and ready.



 pip install wfastcgi 


I would suggest installing in a global environment in order to configure IIS once for all Python framewoks.



IIS


Now configure IIS . In Windows Server, this component is already installed by default, but not in full. I mean an important component for our site - CGI .



Windows ComponentsInternet Information ServicesInternet ServicesApplication Development ComponentsCGI .



Install it. Now in the IIS Manager , our server has a FastCGI Settings item.



iis_manager_scrin



Next, we go into it. Perhaps if you have already installed CGI before you install wfastcgi, you will already have such a string.



fastcgi_settings



Otherwise, click on Add Application ... and fill in the fields:





Everything is OK . The main part is done. Next, create a new site . And at the site we select Mapping handlers .



handler_mappings



Handler MappingsAdd Module Mapping





Next OK . IIS is configured.



Django app


Copy the project to the site folder. Create a virtual environment in it. In the same folder we create the web.config file (or open it for editing if it has already been created).



web.config
 <?xml version="1.0" encoding="UTF-8"?> <configuration> <appSettings> <add key="WSGI_ALT_VIRTUALENV_HANDLER" value="django.core.wsgi.get_wsgi_application()" /> <add key="WSGI_ALT_VIRTUALENV_ACTIVATE_THIS" value="venv\Scripts\activate_this.py" /> <add key="WSGI_HANDLER" value="ptvs_virtualenv_proxy.get_virtualenv_handler()" /> <add key="PYTHONPATH" value="%APPL_PHYSICAL_PATH%" /> <add key="DJANGO_SETTINGS_MODULE" value="project.settings" /> </appSettings> <system.webServer> <handlers> <add name="Python FastCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="C:\Python\python.exe|C:\Python\Lib\site-packages\wfastcgi.py" resourceType="Unspecified" /> </handlers> </system.webServer> </configuration> 


We also create ptvs_virtualenv_proxy.py and paste the code below into it.



ptvs_virtualenv_proxy.py
 # ############################################################################ # # Copyright (c) Microsoft Corporation. # # This source code is subject to terms and conditions of the Apache License, Version 2.0. A # copy of the license can be found in the License.html file at the root of this distribution. If # you cannot locate the Apache License, Version 2.0, please send an email to # vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound # by the terms of the Apache License, Version 2.0. # # You must not remove this notice, or any other, from this software. # # ########################################################################### import datetime import os import sys if sys.version_info[0] == 3: def to_str(value): return value.decode(sys.getfilesystemencoding()) def execfile(path, global_dict): """Execute a file""" with open(path, 'r') as f: code = f.read() code = code.replace('\r\n', '\n') + '\n' exec(code, global_dict) else: def to_str(value): return value.encode(sys.getfilesystemencoding()) def log(txt): """Logs fatal errors to a log file if WSGI_LOG env var is defined""" log_file = os.environ.get('WSGI_LOG') if log_file: f = open(log_file, 'a+') try: f.write('%s: %s' % (datetime.datetime.now(), txt)) finally: f.close() ptvsd_secret = os.getenv('WSGI_PTVSD_SECRET') if ptvsd_secret: log('Enabling ptvsd ...\n') try: import ptvsd try: ptvsd.enable_attach(ptvsd_secret) log('ptvsd enabled.\n') except: log('ptvsd.enable_attach failed\n') except ImportError: log('error importing ptvsd.\n') def get_wsgi_handler(handler_name): if not handler_name: raise Exception('WSGI_HANDLER env var must be set') if not isinstance(handler_name, str): handler_name = to_str(handler_name) module_name, _, callable_name = handler_name.rpartition('.') should_call = callable_name.endswith('()') callable_name = callable_name[:-2] if should_call else callable_name name_list = [(callable_name, should_call)] handler = None while module_name: try: handler = __import__(module_name, fromlist=[name_list[0][0]]) for name, should_call in name_list: handler = getattr(handler, name) if should_call: handler = handler() break except ImportError: module_name, _, callable_name = module_name.rpartition('.') should_call = callable_name.endswith('()') callable_name = callable_name[:-2] if should_call else callable_name name_list.insert(0, (callable_name, should_call)) handler = None if handler is None: raise ValueError('"%s" could not be imported' % handler_name) return handler activate_this = os.getenv('WSGI_ALT_VIRTUALENV_ACTIVATE_THIS') if not activate_this: raise Exception('WSGI_ALT_VIRTUALENV_ACTIVATE_THIS is not set') def get_virtualenv_handler(): log('Activating virtualenv with %s\n' % activate_this) execfile(activate_this, dict(__file__=activate_this)) log('Getting handler %s\n' % os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) handler = get_wsgi_handler(os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) log('Got handler: %r\n' % handler) return handler def get_venv_handler(): log('Activating venv with executable at %s\n' % activate_this) import site sys.executable = activate_this old_sys_path, sys.path = sys.path, [] site.main() sys.path.insert(0, '') for item in old_sys_path: if item not in sys.path: sys.path.append(item) log('Getting handler %s\n' % os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) handler = get_wsgi_handler(os.getenv('WSGI_ALT_VIRTUALENV_HANDLER')) log('Got handler: %r\n' % handler) return handler 


Now open the browser, enter the address of our site and it works.



A bit more



If you do not plan to use a virtual environment in your project, then you should not add ptvs_virtualenv_proxy.py , and the web.config will look like this:



web.config
 <?xml version="1.0" encoding="UTF-8"?> <configuration> <appSettings> <add key="WSGI_HANDLER" value="django.core.wsgi.get_wsgi_application()" /> <add key="PYTHONPATH" value="%APPL_PHYSICAL_PATH%" /> <add key="DJANGO_SETTINGS_MODULE" value="project.settings" /> </appSettings> <system.webServer> <handlers> <add name="Python FastCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="C:\Python\python.exe|C:\Python\Lib\site-packages\wfastcgi.py" resourceType="Unspecified" /> </handlers> </system.webServer> </configuration> 


Also, now on your IIS you can deploy projects not only on Django, but also on other Python frameworks . The main thing to remember is to edit the web.config .



Afterword



Now we have a working site, a small group of people that helps us with development and improvement, for which many thanks to them. And I had some experience on friendship of Python projects and IIS which I shared with you. Hope that comes in handy.



')

Source: https://habr.com/ru/post/305566/



All Articles