How to Run Django Application using Source Code from Host Folder in Docker

Posted on

Introduction

The content of this article has a specific connection with the previous article. In the previous article in ‘How to Run Django Application in Docker‘,  there is a specific content. That content is showing how to run a Django application using a Docker service. Unfortunately, there is no way to be able to change the source code when the Docker container which is already running. So, this article will aim to show how to run the Django application using Docker. In addition, it will also possible to update it all along. As also in the article in ‘How to Run Django Application in Docker‘, there are several steps which is necessary as for the preparation. Those preparation steps exist in the following one :

  1. In the first step, in the case of using device running using Microsoft Windows. Just install Docker Desktop. In order to do that, just install Docker Desktop in Microsoft Windows by referring to ‘How to Install Docker Desktop in Microsoft Windows‘.

  2. Another step, as soon after installing Docker Desktop for the device running using Microsoft Windows. In that case, just start the Docker service. In other words, just make sure to run the Docker service. Until it is finally start and running properly. In order to run the ‘Docker’ service in this context, just use Docker Desktop application.

How to Run Django Application using Source Code from Host Folder in Docker

In this part, after Docker service is running, just perform the task exist in ‘How to Run Django Application in Docker‘. So, there will be a Django application which is already running using Docker service with the following structure :

C:\django\app\myapp>dir
Volume in drive C is Windows-SSD
Volume Serial Number is CA30-19A4

Directory of C:\django\app\myapp

01/12/2023 12:42 PM <DIR>      .
12/11/2022 04:06 PM <DIR>      ..
11/18/2022 09:47 PM           0 db.sqlite3
01/12/2023 12:43 PM         134 docker-compose.yml
01/12/2023 01:01 PM         611 Dockerfile
10/21/2022 10:51 PM         687 manage.py
11/21/2022 03:50 PM       1,114 model_auth_user.py
12/24/2022 10:46 AM <DIR>       myapp
10/22/2022 09:20 AM <DIR>       myproject
01/12/2023 12:47 PM         451 requirements.txt
              6 File(s) 93,352 bytes
              4 Dir(s) 4,448,555,008 bytes free

C:\django\app\myapp>

After that, using the base of the Django application exist above, the following are the modification steps so that the Django application can be modified while running the Docker container :

  1. So, continuing on from the previous process, first of all, modify the Dockerfile exist by changing it to the following content  :

    FROM python:3.9
    WORKDIR /usr/src/app
    COPY./usr/src/app
    RUN pip install --upgrade pip
    RUN pip install -r requirements.txt
    CMD python3 ./manage.py runserver 0.0.0.0:8000
    EXPOSE 8000
    
  2. Since there will be a modification where the main purpose is to be able to still run the docker container while changing the source code of the Django application and in turn it will update the running Django application in the docker container, it need a docker-compose file. In this context, docker-compose will be able to accommodate the volume for further binding the host folder where the Django application exist. Just create the ‘docker-compose.yml’ file and then fill it with the following content :

    version: '3.1'
    services:
      mycontainer:
        image: django_myproject_image
        build: .
        volumes:
          - "./:/usr/src/app"
    
  3. Continue on the step, build the Docker image by executing the following command  :

    (env) C:\django\app\myapp>docker-compose build
    [+] Building 87.3s (10/10) FINISHED
    => [internal] load build definition from Dockerfile 0.0s
    => => transferring dockerfile: 648B 0.0s
    => [internal] load .dockerignore 0.0s
    => => transferring context: 2B 0.0s
    => [internal] load metadata for docker.io/library/python:3.9 3.6s
    => [internal] load build context 0.0s
    => => transferring context: 6.61kB 0.0s
    => [1/5] FROM docker.io/library/python:3.9@sha256:5d0b605039499444251643500686a6e52f2549f4bb1b16cbbb67a4ea04f4c306 0.0s
    => CACHED [2/5] WORKDIR /usr/src/app 0.0s
    => [3/5] COPY . /usr/src/app 0.1s
    => [4/5] RUN pip install --upgrade pip 52.4s
    => [5/5] RUN pip install -r requirements.txt 29.9s
    => exporting to image 1.2s
    => => exporting layers 1.2s
    => => writing image sha256:89946a4bb4f24064e18484c88f373702e0b71d0d871e9441ba7a87e6f4a0334c 0.0s
    => => naming to docker.io/library/django_myproject_image 0.0s
    
    Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
    
    (env) C:\django\app\myapp>
    

    After successfully creating the Docker image, check it first whether it is available or not by typing the following command :

    (env) C:\django\app\myapp>docker image ls
    REPOSITORY             TAG    IMAGE ID     CREATED        SIZE
    django_myproject_image latest b57a07bb4ce0 53 minutes ago 957MB
    
    (env) C:\django\app\myapp>
    
    
  4. Then, run the docker container by executing the following command : Access the Django application in the web browser as follows :

    (env) C:\django\app\myapp>docker run -v "C:\django\app\myapp/:/usr/src/app" -p 8000:8000 django_myproject_image
    Watching for file changes with StatReloader
    Exception in thread django-main-thread:
    Traceback (most recent call last):
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 282, in ensure_connection
    self.connect()
    File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 263, in connect
    self.connection = self.get_new_connection(conn_params)
    File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 215, in get_new_connection
    connection = Database.connect(**conn_params)
    File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
    psycopg2.OperationalError: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
    could not connect to server: Cannot assign requested address
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
    File "/usr/local/lib/python3.9/threading.py", line 980, in _bootstrap_inner
    self.run()
    File "/usr/local/lib/python3.9/threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 137, in inner_run
    self.check_migrations()
    File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 564, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
    File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
    File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 58, in __init__
    self.build_graph()
    File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 235, in build_graph
    self.applied_migrations = recorder.applied_migrations()
    File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
    if self.has_table():
    File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 57, in has_table
    with self.connection.cursor() as cursor:
    File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 323, in cursor
    return self._cursor()
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 299, in _cursor
    self.ensure_connection()
    File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 282, in ensure_connection
    self.connect()
    File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 282, in ensure_connection
    self.connect()
    File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 263, in connect
    self.connection = self.get_new_connection(conn_params)
    File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
    File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 215, in get_new_connection
    connection = Database.connect(**conn_params)
    File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
    django.db.utils.OperationalError: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
    could not connect to server: Cannot assign requested address
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?
    
  5. So, there is an error where the execution of the Docker container ends in a failure. The Django application itself is facing a failure for connecting to the database as in the above error message appearing :

    File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 215, in get_new_connection connection = Database.connect(**conn_params) File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 122, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) django.db.utils.OperationalError: could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432? could not connect to server: Cannot assign requested address Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432?
    

    So, in order to prove that the editing of the source will directly affecting to the running Django application in the Docker container, below is the process for editing ‘settings.py’ file as follows :

    # Database
    # https://docs.djangoproject.com/en/4.1/ref/settings/#databases
    DATABASES = {
        # 'default': {
        #    'ENGINE': 'django.db.backends.sqlite3',
        #    'NAME': BASE_DIR / 'db.sqlite3',
        # }
        'default': {
           'ENGINE': 'django.db.backends.postgresql',
           'NAME': 'db_myapp',
           'USER': 'postgres',
           'PASSWORD': 'password',
           'HOST': 'localhost',
           'PORT':'5432',
        }
    }

    Just change from the PostgreSQL database connection configuration into the default database connection using SQLite3. The reason is because there is no PostgreSQL database running at this time in the docker container. In that case, just use the default database exist in the Django application which is the SQLite3 as follows :

    # Database
    # https://docs.djangoproject.com/en/4.1/ref/settings/#databases
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': BASE_DIR / 'db.sqlite3',
        }
        #    'default': {
        #        'ENGINE': 'django.db.backends.postgresql',
        #        'NAME': 'db_myapp',
        #        'USER': 'postgres',
        #        'PASSWORD': 'password',
        #        'HOST': 'localhost',
        #        'PORT':'5432',
        #    }
    }
  6. At that time the configuration changed, the command line where the Docker container is running will suddenly changed as follows :

    /usr/src/app/myproject/settings.py changed, reloading.
    Performing system checks...
    
    System check identified no issues (0 silenced).
    Watching for file changes with StatReloader
    Not Found: /
    [12/Jan/2023 06:03:27] "GET / HTTP/1.1" 404 2168
    [12/Jan/2023 06:03:32] "GET /myapp HTTP/1.1" 301 0
    [12/Jan/2023 06:03:32] "GET /myapp/ HTTP/1.1" 200 20
    

    Moreover, the Django application will return back to its default display as follows :

    How to Run Django in Docker
    How to Run Django in Docker

Leave a Reply