# Installing and configuring Django on Linux shared hosting

> Set up a Django site on Linux shared hosting with cPanel's Python app tool, including the admin interface and SQLite.

Source: https://helpcenter.ruachost.com/developers/programming-languages/installing-and-configuring-flask-on-a-linux-shared-hosting-account/

## Installing and configuring Django on Linux shared hosting

This guide explains how to install and configure Django on a Linux shared hosting account using cPanel. After following these steps, you will have a Django site that:

- Loads a static homepage.
- Loads the Django administration interface.
- Uses a SQLite database.

> **Caution:**
This configuration is tested but not officially supported on shared hosting. It can be used as a starting point for your own Django projects.

## Step 1: Create a Python application in cPanel

1. Log in to **cPanel**.
2. In the **Software** section, click **Setup Python App**.
3. Click **CREATE APPLICATION**.
4. In the application form:

   - Select **Python 3.8.1** in the Python version list.
   - Set **Application root** to `myapp`.
   - Select your domain in **Application URL**. Leave the rest blank.
   - Leave **Application startup file** and **Application Entry point** blank. cPanel will automatically create `passenger_wsgi.py`.
   - Optionally specify a **Passenger log file**.
5. Click **CREATE**. cPanel will create the application and set up the Python environment.
6. Note the command next to **Enter to the virtual environment**. You will need it in the next step.

## Step 2: Configure the Django project

1. Log in via **SSH**.
2. Activate the virtual environment (replace with your environment path):

```
source /home/username/virtualenv/myapp/3.8/bin/activate && cd /home/username/myapp
```

**Important:** Your prompt should show `(myapp:3.8)` indicating the active virtual environment. Reactivate the environment if you log out or deactivate it.

3. Install Django:

```
cd ~
pip install django==2.1.8
```

4. Verify Django installation:

```
django-admin --version
```

5. Create the Django project:

```
django-admin startproject myapp ~/myapp
```

6. Create directories for static files:

```
mkdir -p ~/myapp/templates/static_pages
mkdir ~/myapp/static_files
mkdir ~/myapp/static_media
```

7. Edit `~/myapp/myapp/settings.py`:

- Set allowed hosts (replace with your domain):

```
ALLOWED_HOSTS = ['example.com']
```

- Update the TEMPLATES block:

```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```

- Add static and media settings:

```
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_files')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "static_media")
```

8. Edit `~/myapp/myapp/urls.py` to include:

```
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from django.conf.urls import url
from django.views.generic.base import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^$', TemplateView.as_view(template_name='static_pages/index.html'), name='home'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
```

9. Edit `~/myapp/passenger_wsgi.py`:

```

from django.core.wsgi import get_wsgi_application

sys.path.append(os.getcwd())
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'

SCRIPT_NAME = os.getcwd()

class PassengerPathInfoFix(object):
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        from urllib.parse import unquote
        environ['SCRIPT_NAME'] = SCRIPT_NAME
        request_uri = unquote(environ['REQUEST_URI'])
        script_name = unquote(environ.get('SCRIPT_NAME', ''))
        offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
        environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
        return self.app(environ, start_response)

application = get_wsgi_application()
application = PassengerPathInfoFix(application)
```

10. Create a basic `index.html` in `~/myapp/templates/static_pages` containing simple text, e.g., "Hello world".
11. Run migrations and create a superuser:

```
python ~/myapp/manage.py migrate
python ~/myapp/manage.py createsuperuser
```

Follow prompts to set admin username, email, and password.

12. Collect static files:

```
python ~/myapp/manage.py collectstatic
```

Type `yes` if prompted to overwrite files.

## Step 3: Restart the Python application

1. Log in to **cPanel**.
2. In **Software → Setup Python App**, locate your `myapp` application and click **Restart**.

## Step 4: Test the Django site

- Visit `http://www.example.com` to see your `index.html` page.
- Visit `http://www.example.com/admin` to access the Django admin interface using your superuser credentials.

**Tip:** If the site does not appear, run:

```
python ~/myapp/passenger_wsgi.py
```

There should be no output. Check for syntax errors if there are any.

## More information

- Django documentation: [http://docs.djangoproject.com](http://docs.djangoproject.com/)
- Django extensions: <https://github.com/django-extensions/django-extensions>
- South for database migrations: <https://pypi.python.org/pypi/South>
- Fabric for deployment automation: [http://docs.fabfile.org](http://docs.fabfile.org/)
