Django development using Docker as host - Part 5: Django development
Tags: django, docker, devops, devjournal
Published: 2021-01-17 07:27:53

Till now we covered application setup and docker services running via `docker-compose`. In this step, we will use the docker container to develop the Django application.

## TOC
1. [Start `docker-compose` services](#p5-start-docker-compose)
2. [Django settings](#p5-django-settings)
3. [Run Django application](#p5-run-django)
4. [Live reload Django changes](#p5-live-reload-django)
5. [Sync python dependencies](#p5-sync-python-dependencies)
6. [Create Django app](#p5-create-django-app)

## Let's dive-in

### 1. Start `docker-compose` services <a name="p5-start-docker-compose"></a>
Before we start with the Django development, we need to run the docker containers with the required services.
Execute the following command to run the services defined in the `docker-compose.yml` file

```
docker-compose up --build
```

After the service has been started, execute the below command in a new terminal to see the running containers
```
docker ps
```
You will see the list of running containers.

### 2. Django settings <a name="p5-django-settings"></a>
When the docker-compose runs for the first time, you will see a Django exception
```
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
```
This is because we have not yet configured the `STATIC_ROOT` settings where the static files are copied on running `collectstatic` management command.
Add the following settings to the `src/my_app/settings.py` file.

#### Static file settings
```
STATICFILES_DIRS = [
    os.path.join(os.path.dirname(BASE_DIR), 'static_my_project')
]

STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static_cdn', 'static_root')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static_cdn', 'media_root')
```
* The `STATICFILES_DIRS` setting defines where the static files will be kept. While development, we will keep the static files inside the `static_my_project` directory.
* `STATIC_ROOT` is the path where the static files are copied on `collectstatic` management command

#### Database settings
```
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'database',
        'PORT': '3306',
        'NAME': 'app_db',
        'USER': 'app_db',
        'PASSWORD': 'app_db'
    }
}
```
Where `database` is the service inside the `docker-compose`.

#### Template directory
In order to allow the creation of the template files inside the application directory, add the following to the **`TEMPLATES.DIRS`** settings
```
[
   os.path.join(BASE_DIR, 'templates')
]
```
This allows us to add the template files inside the `src/templates` directory and also in the app's `templates/` directory.

### 3. Run Django application <a name="p5-run-django"></a>
After adding the settings, run the following to start the docker services
```
docker-compose up --build
```

After the services have been started, let's verify the following:
* Django database has been migrated to the MySQL database.
  Visit `http://localhost:8080` and use the database credentials to log in to the database management.
* Open `http://localhost:8000` to see the Django application running.

### 4. Live reload Django changes <a name="p5-live-reload-django"></a>
As we have the `.src/` directory mapped to the `/app` directory, the host `.src/` directory will work as the container's `/app` directory. Any changes in the `.src/` directory files will reload the Django application.
Check the `docker-compose` logs for the logs.

### 4. Sync python dependencies <a name="p5-sync-python-dependencies"></a>
We do not have python installed in our system instead we are using python using `Dockerfile` container. So the python dependencies should be installed in the container.

* Open a bash shell in the running container
```
docker exec -it app_image bash
```
* Install the dependency using `pip`
```
pip install requests
```
This dependency can be used until the container is running. Once stopped, re-running the container, it will be removed.
It is required to sync the `requirements.txt` file in the host with the latest dependencies in the container to keep both in sync.

This can be achieved in two ways:
1. Add the `requests` dependency with the version number in the host's `requirements.txt` file
```
requests==<version>
```
2. Freeze the pip dependencies from container to the host:
```
pip freeze > /requirements.txt
```
Note, since the `requirements.txt` in the host is mapped to the same file in the root of the container, the path should start with `/`. Without `/` it will create a `requirements.txt` file inside the `src/` directory.

---

You can create the Django applications by running the `manage.py` management commands inside the container and edit the source code in the `./src` directory.

### 6. Create Django app <a name="p5-create-django-app"></a>
#### Let's create a Django app
Run the following in the container bash
```
python manage.py startapp home
```
It will create a `home` directory in the `./src` directory.

#### Add view
Add the following content to the `./src/home/views.py` file
```
from django.views.generic import TemplateView


class IndexView(TemplateView):
    template_name = "home/index.html"
```

#### Add template
Create a template file `index.html` inside the `templates/home` directory with the following content
```
<html>
<head>
    <title>Index page</title>
</head>

<body>
    <h2>Welcome to the Index page</h2>
</body>
</html>
```

#### Add routing
Add the following to the `home/urls.py` file
```
from django.urls import path
from home.views import IndexView

app_name = 'home'
urlpatterns = [
    path('', IndexView.as_view()),
]
```
Include the URLs to the application `urls.py` file
```
path('home/', include('home.urls', namespace='home'))
```

#### Include the app to the `settings.py` file
```
INSTALLED_APPS = [
   'home'
]
```

#### Open in browser
In the browser, open the following URL
```
http://localhost:8000/home/
```
You will see the index page content.

---

Congratulations, we have completed the setup of Django project using the docker as host.
Now you can develop the Django application without depending on the host system.

:blush: :heart_eyes: :computer:

---

Check complete source code on Github
{% github anuj9196/django-docker-host no-readme %}