Run Django (Django REST Framework) & MySQL Application using Docker (Bonus: PHPMyAdmin) ======================================================================================= ### Prerequisite * Ensure that you already installed Docker in your machine. To learn more about installation: [follow this gist](https://gist.github.com/arsho/6249e3f0fc1d966d115c34718e1a8a0a#file-docker_installation_ubuntu_16-04-md) * Ensure that you already installed Docker Compose in your machine. To learn more about installation: [follow this gist](https://gist.github.com/arsho/6249e3f0fc1d966d115c34718e1a8a0a#file-docker_compose_ubuntu_16-04-md) ### Environment * Operating System : Ubuntu 16.04 LTS (64-bit) ### Running Django app with MySQL database inside Docker The following steps showed the step by step guideline. #### Create Project Directory For separating the application from other projects let's first create a directory and move to that: ``` mkdir django_mysql cd django_mysql ``` #### Create Dockerfile Create a `Dockerfile` inside the project directory and insert the following: ``` FROM python:3 ENV PYTHONBUFFERED 1 RUN mkdir /code WORKDIR /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/ ``` #### Create requirements.txt Create a `requirements.txt` file inside the project directory and insert the following: ``` certifi==2017.11.5 chardet==3.0.4 click==6.7 coverage==4.4.2 decorator==4.1.2 Django==2.0 django-ckeditor==5.4.0 django-constance==2.0.0 django-cors-headers==2.1.0 django-countries==5.0 django-js-asset==0.1.1 django-nose==1.4.5 django-picklefield==1.0.0 djangorestframework==3.7.6 geocoder==1.30.1 idna==2.6 mysqlclient==1.3.12 nose==1.3.7 olefile==0.44 Pillow==4.3.0 pytz==2017.3 ratelim==0.1.6 requests==2.18.4 six==1.11.0 urllib3==1.22 Markdown==2.6.11 pytz==2017.3 ``` #### Create Docker Compose Configuration File Create a `docker-compose.yml` inside the project directory and insert the following: ``` version: '3' services: db: image: mysql ports: - "3307:3306" environment: MYSQL_ROOT_PASSWORD: mypassword MYSQL_USER: root MYSQL_DATABASE: django_mysql web: build: . command: python3 manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - "8000:8000" depends_on: - db phpmyadmin: image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 restart: always ports: - 8082:80 volumes: - /sessions ``` #### Build Docker Compose In this step we are going to build docker compose: ``` sudo docker-compose build ``` The execution of the command will take some time based on internet connection speed. If you failed to build everything succesfully retry several times as network connection sometimes cause the error. Check if the instances are running: ``` sudo docker-compose up ``` Press `CTRL-C` to stop the instances for now. #### Create Django Project To create django project inside the instance: ``` sudo docker-compose run web django-admin.py startproject composeexample . ``` In this stage we have the following directory tree: ``` django_mysql ├── composeexample │   ├── __init__.py │   ├── __pycache__ │   ├── settings.py │   ├── urls.py │   └── wsgi.py ├── db.sqlite3 ├── docker-compose.yml ├── Dockerfile ├── manage.py ├── requirements.txt ``` The files which are created by `django-admin` are owned by `root`. Change the ownership of the new files: ``` sudo chown -R $USER:$USER . ``` To use `Django REST Framwork` to create APIs and `MySQL` as database, we need to change `composeexample\settings.py` to include: ``` ALLOWED_HOSTS = ['*'] DJANGO_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] NATIVE_APPS = [ 'ridecoupon', ] THIRD_PARTY_APPS = [ 'rest_framework', ] INSTALLED_APPS = DJANGO_APPS + NATIVE_APPS + THIRD_PARTY_APPS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_mysql', 'USER': 'root', 'PASSWORD': 'mypassword', 'HOST': 'db', 'PORT': '3306', }, } STATIC_URL = '/static/' STATIC_ROOT = './static' MEDIA_URL = '/media/' MEDIA_ROOT = './media' ``` The `ridecoupon` is the django app we are going to create. We also need to update `composeexample\urls.py` file to add our `ridecoupon` app: ``` from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('ridecoupons/', include('ridecoupon.urls')) ] if settings.DEBUG: urlpatterns = urlpatterns + \ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + \ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ``` #### Run the Instance in Daemon Mode Run the instance in background using: ``` sudo docker-compose up -d ``` Check running processes using: ``` sudo docker ps ``` #### Create New App inside the django project To run `manage.py` we need to get logged into the container containing the django app. For this we need to know the container ID of that container. To get the container ID, check the running docker processes using: ``` sudo docker ps ``` This will show the container ID of all the containers. We need the container ID that has the django app. Then, use the container ID to open a bash in that directory of `manage.py`: ``` sudo docker exec -t -i 8f88e0935895 bash ``` Here `8f88e0935895` is container ID of my container. It will be different for your case. 1. Create an app: ``` python manage.py startapp ridecoupon ``` 2. Create `models.py`, `urls.py` and other necessary files in `ridecoupon`. Then makemigrations of newly created model and migrate it: ``` python manage.py makemigrations ridecoupon python manage.py migrate ``` 3. Create super user: ``` python manage.py createsuperuser Username: Email address: Password: ``` 4. Run the project: ``` python manage.py runserver ``` sudo docker-compose build sudo docker-compose up -d sudo docker ps CONTAINER ID IMAGE 8f88e0935895 djangomysql_web sudo docker exec -t -i 8f88e0935895 bash python manage.py makemigrations ridecoupon python manage.py migrate python manage.py createsuperuser #### Access the web app Open [http://0.0.0.0:8000/](http://0.0.0.0:8000/) and see the running web application #### (Bonus) Access the phpmyadmin Open [http://0.0.0.0:8082/](http://0.0.0.0:8082/) and see the running `PHPMyAdmin`. Use ``` User: root Password: mypassword ``` and keep the host empty. #### Referencese * [Start Django project with Docker](http://mmorejon.github.io/en/blog/start-django-project-with-docker/)