Deploying a Django application in Windows with Apache and mod_wsgi
Django is a powerful web framework widely used by many famous applications. Django includes a simplified development server for testing your code locally, but for anything even slightly production related, a more secure and powerful web server is required.
In this guide, we will demonstrate how to install and configure some components on a Windows server to support and serve Django applications. We will be setting up a MySQL database instead of using the default SQLite database. We will configure mod_wsgi to interface with our applications, and set up Apache to act as the gateway to the world.
Python
The first step is to download and install Python from the Python website. Select Windows as operating system and pick the 32 / 64 bit version based on your machine requirements.
Once you download the setup file, right click the setup file and select Run as Administrator
. You should see the below screen
Make sure both the checboxes at the bottom of the window are checked (Install for all users, and Add Python 3.7 to PATH checkboxes)
Click on Install Now. Once the installation is completed, you can close the window. To make sure the installation is successful, open Powershell and type python
. If the installation was successful, you should see an output similar to below
MySQL
The next step is the installation of MySQL. Before installation of MySQL, Visual Studio and the Visual C++ libraries have to be installed.
Download Visual Studio 2017 from here. When installing Visual Studio, make sure you select Desktop Environment with C++
on Workloads section, and the C++/CLI Support
option on the right side of the screen.
Download the latest Visual C++ from here and install it. Download the latest version of MySQL. Run the downloaded setup file. The first screen should look like this:
Click on I accept the license terms
and click Next
In the type of installation, choose Developer Default
In the requirements section, click Next. Then click on execute. Once all the items in the list are installed, you will then be taken to the configuration pages. In the Type and Networking
page, choose Config Type as Server Computer
In the next screen, setup the root user's password. And in the users section, add a user with the name as same as the logged in user. Click on Next till the end and click Exceute at last. In the next 2 configuration steps, nothing needs to be changed and so you can click on Next/Execute.
Once the installation is complete, create a new database called my_application
and provide all privileges of the same to the new user created.
mysql> create database my_application;
Query OK, 1 row affected (0.04 sec)
mysql> grant all on my_application.* to '<my-user>'@'localhost';
Query OK, 0 rows affected (0.08 sec)
virtualenv
A virtual environment is a tool that helps to keep dependencies required by different projects separate by creating isolated python virtual environments for them. To install virtualenv
, open powershell and run
pip install virtualenvwrapper-win
This will install the virtualenv package. In order to create a virtual environment and to start working on the virtual environment, run
mkvirtualenv my_application
workon my_application
Install Django
Install Django and mysql connector using pip
with the following command
pip install django
pip install pymysql
Create Django application
Next, let's create a sample Django project. Type the following command in the powershell window.
django-admin startproject my_application
Once that command is executed, you should see a folder called my_application
in the current folder and the my_application
will have the following structure
my_application
| manage.py
|
\---my_application
settings.py
urls.py
wsgi.py
__init__.py
Now let's run the server and check that it can be accessed from the browser
cd my_application
python manage.py runserver
Once the server starts running, you should see a similar output in your powershell terminal
PS C:\Users\myuser\my_application> python .\manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
April 29, 2019 - 06:15:40
Django version 2.1.5, using settings 'my_application.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Now let's access the server from the browser. Go to the URL - http://127.0.0.1:8000/
from your browser and you should see the following screen
Now you can stop the server by pressing Ctrl + C
in the powershell terminal.
Local setup
Next step is to provide the appropriate DB settings, e.t.c for the Django application. Open your my_application/settings.py file and replace the DATABASES variable to the following:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'my_application',
'USER': '<my-user>',
'PASSWORD': '<my-password>',
'HOST': 'localhost',
'PORT': 3306
}
}
In production environment, Django does not serve static files (css, js and images). Inorder for them to be server properly by Apache, let's configure the staticfile settings in the application. Add the following at the end of your my_application/settings.py
file
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Once the details are entered, create the database tables, and collect the staticfiles by running
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic
After collectstatic, you should see a static
folder created in your base folder. The current structure will be this
my_application
+---my_application
| \---__pycache__
\---static
\---admin
+---css
| \---vendor
| \---select2
+---fonts
+---img
| \---gis
\---js
+---admin
\---vendor
+---jquery
+---select2
| \---i18n
\---xregexp
Apache
Apache is the webserver that will be handling web requests, and communicating to the Django app using mod_wsgi. Download WAMP server from here. The default installation should have created a folder in C:, as C:\wamp64
Once you verify that the above folder is created, add an Environment variable in your machine with name MOD_WSGI_APACHE_ROOTDIR
whose value should be C:\wamp64\bin\apache\apache<version>\
.
You will need to restart the powershell window for this change to take effect.
wsgi.py
The default wsgi.py generated by Django works properly for LINUX based deployments, but for Windows we need to make a few changes to the file. Create a new file my_application/wsgi_windows.py
and paste the following contents in the file:
activate_this = 'C:/Users/myuser/Envs/my_application/Scripts/activate_this.py'
# execfile(activate_this, dict(__file__=activate_this))
exec(open(activate_this).read(),dict(__file__=activate_this))
import os
import sys
import site
# Add the site-packages of the chosen virtualenv to work with
site.addsitedir('C:/Users/myuser/Envs/my_application/Lib/site-packages')
# Add the app's directory to the PYTHONPATH
sys.path.append('C:/Users/myuser/my_application')
sys.path.append('C:/Users/myuser/my_application/my_application')
os.environ['DJANGO_SETTINGS_MODULE'] = 'my_application.settings'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_application.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
mod_wsgi
Once WAMP is installed, go to the my_application folder in powershell and install mod_wsgi by running
pip install mod_wsgi
To get the Apache configration to be set related to this project, run
mod_wsgi-express module-config
The output should be something similar to:
LoadFile "c:/users/myuser/appdata/local/programs/python/python37/python37.dll"
LoadModule wsgi_module "c:/users/myuser/appdata/local/programs/python/python37/lib/site-packages/mod_wsgi/serve
r/mod_wsgi.cp37-win_amd64.pyd"
WSGIPythonHome "c:/users/myuser/appdata/local/programs/python/python37"
Copy the output generated by the mod_wsgi-express
command and paste it at the end of C:\wamp64\bin\apache\apache<version>\conf\httpd.conf
.
Next step is to open the vhosts
file at C:\wamp64\bin\apache\apache<version>\conf\extra\httpd_vhosts.conf
and replace the contents over there with the content below:
# virtual SupervisionTool
<VirtualHost *:80>
ServerName localhost
WSGIPassAuthorization On
ErrorLog "logs/my_application.error.log"
CustomLog "logs/my_application.access.log" combined
WSGIScriptAlias / "C:\Users\myuser\my_application\my_application\wsgi_windows.py"
<Directory "C:\Users\myuser\my_application\my_application">
<Files wsgi_windows.py>
Require all granted
</Files>
</Directory>
Alias /static "C:/Users/myuser/my_application/static"
<Directory "C:/Users/myuser/my_application/static">
Require all granted
</Directory>
</VirtualHost>
# end virtual SupervisionTool
With this setup, you should now be able to go to the System Services panel, start the Apache service and you should be able to access the application at http://localhost
Can we use same process for linux?
it should mostly be the same but Linux and windows don’t share the same commands. I am a little experienced with Linux and Django but I don’t know the paths. It should theoretically be possible. I won’t be able to help apart from this.
I am getting an error when trying to start the service:
httpd.exe: Syntax error on line 581 of C:/wamp64/bin/apache/apache2.4.46/conf/httpd.conf: Cannot load c:/users/administrator/appdata/local/programs/python/python39/lib/site-packages/mod_wsgi/server/mod_wsgi.cp39-win_amd64.pyd into server: The specified mo .
i followed all the steps but finally when put http://localhost it is not reaching my app, its reaching same defualt html page. (html shows its works!)