DEV Community

Cover image for Dockerizing Django and MySql
ishanshre
ishanshre

Posted on

Dockerizing Django and MySql

Dockerizing Django and MySql(Linux)

In this guide, I will show you how to dockerize your django project in one container and MySql Server in another container in Linux Operating System. We will create, manage and run these container using docker-compose. For this I assume you have installed python, docker and docker-compose in your machine. If not, refer to "install python" and "install docker".

First we setup our django project using terminal:

$ mkdir myProject
$ cd myProject
$ python -m venv venv
$ source venv/bin/activate
(venv) $ pip install Django==4.1.4 python-dotenv
(venv) $ django-admin startproject core .
(venv) $ pip freeze > requirements.txt
Enter fullscreen mode Exit fullscreen mode

Lets go line by line:

  • mkdir myProject create a new directory in your current working directory
  • cd myProject change directory to myProject
  • python -m venv venv create a python virtual environment
  • source venv/bin/activate activate the virtual environment.
  • pip install Django==4.1.4 python-dotenv install django and python-dotenv package. Python-dotenv package is used for securing our secret keys
  • django-admin startproject core . create django project in current directory. The dot after core represents the current directory
  • pip freeze > requirements.txt create a requirements.txt file in current directory with all the package installed in this virtual environment

This is my basic project directory tree:

Basic Project Folder Tree

Configuring Our Project:

  • Create a .env file in our project directory with touch .env
  • Setup our python-dotenv in settings.py of myProject/core/settings.py
import os
from dotenv import load_dotenv
load_dotenv(os.path.join(BASE_DIR, ".env"))
Enter fullscreen mode Exit fullscreen mode

settings

  • Create a new secret key for our project
(venv) $ python manage.py shell
>>> from django.core.management.utils import get_random_secret_key
>>> print(get_random_secret_key())
>>> exit()
Enter fullscreen mode Exit fullscreen mode
  • Copy the secret key and paste it to .env file
  • Replace the secret key in settings.pyby pointing it to the .env file
SECRET_KEY = str(os.getenv("DJANGO_SECRET_KEY"))
Enter fullscreen mode Exit fullscreen mode
  • Configure Django Database in settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': str(os.getenv("DATABASE_NAME")),
        'USER': str(os.getenv("DATABASE_USER")),
        'PASSWORD': str(os.getenv("DATABASE_PASSWORD")),
        'HOST': str(os.getenv("DATABASE_HOST")),
        'PORT': 3306,
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Configure .env for database
DATABASE_NAME = "mysql_new_db"
DATABASE_USER = "myProject"
DATABASE_PASSWORD = "myProject"
DATABASE_ROOT_PASSWORD = "myProject"
DATABASE_HOST = "db"
Enter fullscreen mode Exit fullscreen mode
  • Setup files for dockerizing our project and MySql: We need to create three files to dockerizing our project and MySql. They are .dockerignore, Dockerfile and docker-compose.yml. A Dockerfile contains all the commands a user could call on the command line to assemble an image. .dockerignore is similar to .gitignore. It allows to specify the list of files and folders to ignore when building a image. And docker-compose.yml a YAML file to define the services and we can also spin everything up or tear it all down.

Setup Dockerfile

Create a Dockerfile in project directory (venv) $ touch Dockerfile

FROM python:3
LABEL maintainer="ishanshrestha"
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED 1 
WORKDIR /app
COPY requirements.txt /app/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY . /app/
EXPOSE 8000
Enter fullscreen mode Exit fullscreen mode
  • FROM python:3 is the python docker image. It will be your base image your Docker image will be built upon.
  • LABEL maintainer="ishanshrestha" specifies the maintainer of your docker image. A maintainer can be your name or the website you own. It is a best practice to define a maintainer.
  • ENV PYTHONDONTWRITEBYTECODE=1 prevents Python from writing out files with extension .pyc .
  • ENV PYTHONUNBUFFERED 1 tells Python that you don't want to buffer the stdin/stdout. Prints output directly to the console, which prevents any delay of message on the screen.
  • WORKDIR /app is a default directory in your docker image where the all docker commands runs from.
  • COPY requirements.txt /app/ copies earlier created requirements.txt to the docker image working directory.
  • RUN pip3 install  -- upgrade pip upgrade the pip in the docker image.
  • RUN pip install -r requirements.txt installs all the packages defined in the requirements.txt file.
  • COPY . /app/ copies our project to working directory of your docker image.
  • EXPOSE 8000 exposes the container to your local machine

Setup docker-compose.yml

Create a docker-compose file in project directory (venv) $ touch docker-compose.yml

version: "3.9"

services:
  db:
    container_name: mysql_new_db
    image: mysql:latest
    restart: always
    ports:
      - 3306:3306
    environment:
      - MYSQL_DATABASE=${DATABASE_NAME}
      - MYSQL_USER=${DATABASE_USER}
      - MYSQL_PASSWORD=${DATABASE_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DATABASE_ROOT_PASSWORD}
      - MYSQL_HOST=${DATABASE_HOST}
    volumes:
      - .:/app
      - mysql_new_data:/var/lib/mysql

  app:
    container_name: app
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - 8000:8000
    depends_on:
      - db
    restart: always

volumes:
  mysql_new_data:
Enter fullscreen mode Exit fullscreen mode
  • We define two services int the docker-compose file. These services db and app are the two containers we are going to create. "db" refers to our MySql container and "app" refers to our project container. ### Lets break our "db" section:
  • container_name: mysql_new_db is the name of the container
  • image: mysql:latest is the MySql docker image that we pull from docker hub
  • restart: always sets the restart policy of Docker container to
  • port: 3306:3306 defines the port for our MySql Server
  • environment: defines the environment variables for MySql Server
  • volumes: defines volume mapping of database storage

Now, lets break our "app" section:

  • build: . points to project directory when building the image
  • command: runs our django projects
  • ports: exposes our project image to the local machine
  • depends_on: sets the order of image for start/stop. In our case, MySql container/image must start before our app image/container.

Setup dokcerignore

.

git
.gitignore

.docker
code/__pycache__/
code/*/__pycache__/
code/*/*/__pycache__/
code/*/*/*/__pycache__/
.env/
.venv/
venv
Enter fullscreen mode Exit fullscreen mode

Final myProject directory tree:

Final Project Tree

Final project directory treeAppend mysqlclient==2.1.1 to requirements.txt

Build and run the docker container

  • To build and run the docker continer:
(venv) $ docker-compose up -d --build
Enter fullscreen mode Exit fullscreen mode
  • It will take some time to build the image for first time. It uses caching system to speed up the image building for second time.
  • In command -d tag tells docker to run in the background. To stop the conatiner, run the command
docker-compose down
Enter fullscreen mode Exit fullscreen mode
  • View the container running
$ docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
2303bef6e116   myproject-app   "python manage.py ru…"   5 minutes ago   Up 5 minutes   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp              app
b2ea4a7ba174   mysql:latest    "docker-entrypoint.s…"   5 minutes ago   Up 5 minutes   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql_new_db
Enter fullscreen mode Exit fullscreen mode
  • Running manage.py commands
$ docker ps
(venv) $ docker-compose run exec app manage.py makemigrations
(venv) $ docker-compose run exec app manage.py migrate
(venv) $ docker-compose run exec app manage.py startapp
Enter fullscreen mode Exit fullscreen mode

Project Link

Top comments (0)