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
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:
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"))
- 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()
- 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"))
- 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,
}
}
- Configure .env for database
DATABASE_NAME = "mysql_new_db"
DATABASE_USER = "myProject"
DATABASE_PASSWORD = "myProject"
DATABASE_ROOT_PASSWORD = "myProject"
DATABASE_HOST = "db"
- 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
-
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:
- 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
Final myProject directory 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
- 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
- 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
- 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
Top comments (0)