Transfer a Django project using Conda environment to a Docker container

I am new to Django and am trying to follow the book Django for Professionals 3.1 by William S. Vincent. In this context, I am trying to move a simple Django project currently on my system (Mac OS) using conda environment on the PyCharm IDE to a Docker container.

The Problem

The book uses pipenv for the project and suggests to enter the following code in the Dockerfile: Dockerfile code given in the book

However, since I am using a Conda environment for the project, I cannot use the above code in Dockerfile.

What I Tried

Step 1

I started by entering the following code to create the environment.yml file containing all packages that the project uses.

(django_for_professionals_31) My-MacBook-Pro:django_for_professionals_31_ch1 me$ conda env export --no-builds > environment.yml

My environment.yml file looks like the following*:

name: django_for_professionals_31
channels:
  - defaults
dependencies:
  - asgiref=3.4.1
  - bzip2=1.0.8
  - ca-certificates=2022.4.26
  - certifi=2022.5.18.1
  - django=3.2.5
  - krb5=1.19.2
  - libedit=3.1.20210910
  - libffi=3.3
  - libpq=12.9
  - ncurses=6.3
  - openssl=1.1.1o
  - pip=21.2.4
  - psycopg2=2.8.6
  - python=3.10.4
  - pytz=2021.3
  - readline=8.1.2
  - setuptools=61.2.0
  - sqlite=3.38.3
  - sqlparse=0.4.1
  - tk=8.6.12
  - typing_extensions=4.1.1
  - tzdata=2022a
  - wheel=0.37.1
  - xz=5.2.5
  - zlib=1.2.12
prefix: /opt/anaconda3/envs/django_for_professionals_31

Step 2

Then, based on this tutorial, I tried to write my Dockerfile, as shown below:

# Pull base image
FROM continuumio/miniconda3

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /code

# Create the environment:
COPY environment.yml .
RUN conda env create -f environment.yml

# Make RUN commands use the new environment:
SHELL ["conda", "run", "-n", "django_for_professionals_31", "/bin/bash", "-c"]

# Demonstrate the environment is activated:
RUN echo "Make sure django is installed:"
RUN python -c "import django"

# The code to run when container is started:
COPY run.py .
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "django_for_professionals_31", "python", "run.py"]

# Copy project
COPY . /code/

Thereafter, I ran the command to build a docker image. The command and output I got are given below:

(django_for_professionals_31) My-MacBook-Pro:django_for_professionals_31_ch1 me$ docker build .
[+] Building 3.6s (12/13)                                                                                                                               
 => [internal] load build definition from Dockerfile                                                                                               0.0s
 => => transferring dockerfile: 737B                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                    0.0s
 => [internal] load metadata for docker.io/continuumio/miniconda3:latest                                                                           3.3s
 => [auth] continuumio/miniconda3:pull token for registry-1.docker.io                                                                              0.0s
 => [1/8] FROM docker.io/continuumio/miniconda3@sha256:24103733efebe6d610d868ab16a6f0e5f114c7aad0326a793d946b73af15391d                            0.0s
 => [internal] load build context                                                                                                                  0.0s
 => => transferring context: 5.29kB                                                                                                                0.0s
 => CACHED [2/8] WORKDIR /code                                                                                                                     0.0s
 => CACHED [3/8] COPY environment.yml .                                                                                                            0.0s
 => CACHED [4/8] RUN conda env create -f environment.yml                                                                                           0.0s
 => CACHED [5/8] RUN echo "Make sure django is installed:"                                                                                         0.0s
 => CACHED [6/8] RUN python -c "import django"                                                                                                     0.0s
 => ERROR [7/8] COPY run.py .                                                                                                                      0.0s
------
 > [7/8] COPY run.py .:
------
failed to compute cache key: "/run.py" not found: not found

Step 3

I was not sure what to do next when I got this error, and my first instinct was to comment out the code under the # The code to run when container is started: section in Dockerfile. So, I did that and my Dockerfile looked like the following:

# Pull base image
FROM continuumio/miniconda3

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /code

# Create the environment:
COPY environment.yml .
RUN conda env create -f environment.yml

# Make RUN commands use the new environment:
SHELL ["conda", "run", "-n", "django_for_professionals_31", "/bin/bash", "-c"]

# Demonstrate the environment is activated:
RUN echo "Make sure django is installed:"
RUN python -c "import django"

# The code to run when container is started:
#COPY run.py .
#ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "django_for_professionals_31", "python", "run.py"]

# Copy project
COPY . /code/

Upon re-running the $ docker build . on the terminal, I was able to create the Docker image, as the last line of the output I got was => => writing image sha256:....

Step 4

Then, the book required to create the docker-compose.yml file. I am using the exact same code in the book, given below:

version: '3.8'

services:
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - 8000:8000

After that, I ran the command to build a Docker container based on the created image. The command and output are shown below.

(django_for_professionals_31) My-MacBook-Pro:django_for_professionals_31_ch1 me$ docker-compose up
[+] Building 3.8s (13/13) FINISHED                                                                                                                      
 => [internal] load build definition from Dockerfile                                                                                               0.0s
 => => transferring dockerfile: 734B                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                    0.0s
 => [internal] load metadata for docker.io/continuumio/miniconda3:latest                                                                           3.4s
 => [auth] continuumio/miniconda3:pull token for registry-1.docker.io                                                                              0.0s
 => [1/7] FROM docker.io/continuumio/miniconda3@sha256:24103733efebe6d610d868ab16a6f0e5f114c7aad0326a793d946b73af15391d                            0.0s
 => [internal] load build context                                                                                                                  0.1s
 => => transferring context: 5.11kB                                                                                                                0.0s
 => CACHED [2/7] WORKDIR /code                                                                                                                     0.0s
 => CACHED [3/7] COPY environment.yml .                                                                                                            0.0s
 => CACHED [4/7] RUN conda env create -f environment.yml                                                                                           0.0s
 => CACHED [5/7] RUN echo "Make sure django is installed:"                                                                                         0.0s
 => CACHED [6/7] RUN python -c "import django"                                                                                                     0.0s
 => [7/7] COPY . /code/                                                                                                                            0.1s
 => exporting to image                                                                                                                             0.1s
 => => exporting layers                                                                                                                            0.1s
 => => writing image sha256:d0166e8db7d10a43f18975955b398d9227ae7c2a217a69a2fe76a9cc869c0917                                                       0.0s
 => => naming to docker.io/library/django_for_professionals_31_ch1_web                                                                             0.0s
[+] Running 2/2
 ⠿ Network django_for_professionals_31_ch1_default  Created                                                                                        0.1s
 ⠿ Container django_for_professionals_31_ch1-web-1  Created                                                                                        0.2s
Attaching to django_for_professionals_31_ch1-web-1
django_for_professionals_31_ch1-web-1  | Traceback (most recent call last):
django_for_professionals_31_ch1-web-1  |   File "/code/manage.py", line 11, in main
django_for_professionals_31_ch1-web-1  |     from django.core.management import execute_from_command_line
django_for_professionals_31_ch1-web-1  | ModuleNotFoundError: No module named 'django'
django_for_professionals_31_ch1-web-1  | 
django_for_professionals_31_ch1-web-1  | The above exception was the direct cause of the following exception:
django_for_professionals_31_ch1-web-1  | 
django_for_professionals_31_ch1-web-1  | Traceback (most recent call last):
django_for_professionals_31_ch1-web-1  |   File "/code/manage.py", line 22, in <module>
django_for_professionals_31_ch1-web-1  |     main()
django_for_professionals_31_ch1-web-1  |   File "/code/manage.py", line 13, in main
django_for_professionals_31_ch1-web-1  |     raise ImportError(
django_for_professionals_31_ch1-web-1  | ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?
django_for_professionals_31_ch1-web-1 exited with code 1

From the above, it seems to me that (I could be wrong though) after commenting out the two lines of code in Dockerfile, the conda environment does not get activated in the Docker container but including those two lines of code leads to the failed to compute cache key: "/run.py" not found: not found error because of which the image cannot be created.

How can I resolve the above issue and create a docker image and use that to build a container for my project? Any help would be much appreciated. Thanks.


*Note: I removed the libcxx=12.0.0 package from the environment.yml file because with it, I got the following error upon running $ docker build . on the terminal. I took the advice to remove this package after reading this

> [4/7] RUN conda env create -f environment.yml:                                                                                                       
#9 1.036 Collecting package metadata (repodata.json): ...working... done                                                                                
#9 8.859 Solving environment: ...working... failed                                                                                                      
#9 8.874 
#9 8.874 ResolvePackageNotFound: 
#9 8.874   - libcxx=12.0.0
#9 8.874