Windows+DjangoでDocker入門【入門者向け】

スポンサードリンク



こんにちは。sinyです。

最近Docker入門したばかりですが、知識定着のためDocker関連の記事をアウトプットしていきます。

本記事では、Windows環境+DockerでDjangoアプリを構築する手順のまとめ記事です。

前提環境

本記事では、以下の環境を前提にしています。

項目 バージョン等
OS Windows10(Home)
DB  Postgress
Django 2.x
Docker DockerToolbox
 Windows(Home)ではDocker環境構築のハードルがかなり高いため、現状古いバージョンになっているため推奨はされていませんが、簡単にDocker環境を構築できるためDockerToolboxを利用しています。

DockerToolboxのインストール

まず最初にDockerToolboxをインストールします。

上記リンク先から「DockerToolbox-19.03.1.exe」をダウンロードしたらexeファイルをダブルクリックしてインストールします。

インストール自体は画面の指示に従うだけで簡単にできます。

インストールが完了すると、デスクトップに「Docker Quickstart Terminal」というアイコンが生成されるので、クリックするとDocker環境のターミナル画面が起動します。

 DockerTerminal画面で以下のようなエラーが発生する場合はWindowsのBIOS画面でVT-X/AMD-vの項目をenableに変更しましょう。
Error creating machine: Error in driver during machine creation: This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory

Djangoコンテナ作成に必要なファイルの準備

Djangoのコンテナ環境構築に必要な3つのファイルを設定指定します。

Dockerfileの作成

任意のフォルダで以下を記述したDockerfileを作成します。
今回はC:\Users\django_dockerとします。

FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt 

 

設定ファイルの意味は以下の通りです。

  • FROM python:3.6 → Dockerイメージのベースとなるイメージを指定(Docker hubで公開されているイメージ名を指定します)
  • ENV PYTHONUNBUFFERED 1→バッファが溜まってから出力するのを避けるための記述。
  • RUN mkdir /code → /codeフォルダを作成
  • WORKDIR /code → ワークディレクトリを設定
  • ADD requirements.txt /code/  → requirements.txtをワークディレクトリ(/codeにコピーする)
  • RUN pip install -r requirements.txt → pip install で必要なモジュールをインストール

docker-compose.ymlの作成

つづいて、Dockerfileと同じディレクトリにdocker-compose.ymlという名称でファイルを作り以下の設定を記述します。

version: '3' 
services:
 db:
   image: postgres
 web: 
   build: . 
   command: python3 manage.py runserver 0.0.0.0:8000
   volumes:
     - .:/code
   ports:
     - "8000:8000"
   depends_on:
     - db 
  • version: '3'   →docker-compose.ymlのファイルフォーマットバージョンを宣言(バージョン3は最新版)
  • services:  →サービスの要素を定義
  • db: →コンテナの名前の定義(データベース)
  • image: postgres →利用するDockerイメージ名を指定(今回はpostgres)
  • web:  →コンテナの名前の定義(ウェブサーバ)
  • build: .  → カレントディレクトリを指定してDockerイメージのビルドを実行
  • command: python3 manage.py runserver 0.0.0.0:8000 → コマンドの実行(Django開発サーバの実行)
  • volumes: 
    - .:/code →カレントディレクトリをコンテナ内のワークディレクトリにマウント
  • ports:
    - "8000:8000" →ポートフォワーディング設定(外から80ポートにアクセスしてコンテナ内の80ポートに連携)depends_on: → コンテナの依存関係を定義する(webサーバはdbコンテナに依存する関係を定義)
    - db

 

requirements.txtの作成

続いて、インストールpythonモジュールの定義をrequirements.txtに記載します。
今回は、djangoとpostgresの連携に必要なpsycopg2をインストールします。

Django>=2.1,<2.2
psycopg2

 

Dockerコンテナの作成と起動

dockerのターミナル画面でC:\Users\django_dockerに移動してから以下のコマンドを実行します。

cd /c/Users/django_docker
docker-compose run --rm web django-admin.py startproject example . 

docker-compose runコマンドを使ってコンテナを作成&実行します。
これでDjangoのプロジェクトが生成されます。(プロジェクト名がexample)

コマンドが正常終了すると、以下の通りdjango-dockerフォルダ直下にexampleフォルダ(Djangoプロジェクト)が生成されます。
また、manage.pyも同じフォルダ内に生成されます。

 

Django初期設定

example\settings.pyを開いて以下の点を変更します。
1点目は、ALLOWED_HOSTS = ["*"]です。
2点目はpostgres用のdb接続設定を以下の通り設定します。

ALLOWED_HOSTS = ["*"]


DATABASES = {
     'default': { 'ENGINE': 'django.db.backends.postgresql',   
     'NAME': 
     'postgres',
     'USER':
     'postgres', 
     'HOST':
     'db',
     'PORT': 5432, 
     }
    } 

 

以下のコマンドを実行して変更内容をコンテナに反映させます。

docker-compose up -d

以下の表なメッセージが表示されればOKです。

http://192.168.99.100:8000/にアクセスして以下のようなDjango画面が表示されればOKです。

 

Djangoアプリの作成

続いて以下のコマンドを実行してDjangoのアプリケーションを作成します。
今回は家計簿アプリを作るのでアプリケーション名をkakeiboにしています。

docker-compose run --rm web python manage.py startapp kakeibo

コマンドが正常終了すると、以下の通りdjangoのアプリケーションフォルダ(kakeibo)が生成されます。

kakeiboフォルダの中身は以下の通り通常のDjangoで作ったときのアプリケーションのモジュールが生成されます。

 

Djangoモデルの作成

続いてkakeibo\models.pyに家計簿テーブルを定義します。
設定は以下の通りCategoryとKakeiboテーブルを定義します。

from django.db import models
from datetime import datetime

class Category(models.Model):

    class Meta:
        #カテゴリ
        verbose_name ="カテゴリ"
        verbose_name_plural ="カテゴリ"
      
#カラム名の定義
    category_name = models.CharField(max_length=255,unique=True)

    def __str__(self):
        return self.category_name


class Kakeibo(models.Model):

    class Meta:
      
        verbose_name ="家計簿"
        verbose_name_plural ="家計簿"

    #カラムの定義
    date = models.DateField("日付",default=datetime.now)
    category = models.ForeignKey(Category, on_delete = models.PROTECT, verbose_name="カテゴリ")
    money = models.IntegerField("金額", help_text="単位は日本円")
    quantity = models.IntegerField(verbose_name="数量",default=0)
    memo = models.CharField(verbose_name="メモ", max_length=500)

    def __str__(self):
        return self.memo


 

次に、settings.pyに先ほど作成したアプリケーションを追加しておきます。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'kakeibo',#add
]

 

マイグレーションの実行

続いて、定義したモデルの内容をデータベースへ反映させるためにマイグレーションを実行します。

docker-compose run --rm web python manage.py makemigrations kakeibo

以下のようにエラーが表示されなければOKです。

続いて以下のコマンドでmigrateを実行してdbに反映させます。

docker-compose run --rm web python manage.py migrate

以下のようにエラーなしで正常終了すればOKです。

管理ユーザの作成

続いて、Djangoの管理サイトのアクセスするために管理者ユーザを作成しておきます。
コマンドは以下の通りです。

docker-compose run --rm web python manage.py createsuperuser

admin.pyの設定

管理画面上にCategoryとKakeiboテーブルが表示されるようにkakeibo\admin.pyの設定を以下の通り変更します。

from django.contrib import admin

from .models import Category, Kakeibo

class KakeiboAdmin(admin.ModelAdmin):
    list_display=('pk','date','category','money','quantity','memo')

class CategoryAdmin(admin.ModelAdmin):
    list_display=('pk','category_name')



admin.site.register(Category, CategoryAdmin)
admin.site.register(Kakeibo,KakeiboAdmin)

 

以下のコマンドを実行して変更を反映させます。

docker-compose up -d

http://192.168.99.100:8000/adminにアクセスして先ほど作成した管理者ユーザでログオンします。

以下のとおりKakeiboとCategoryテーブルが表示されればOKです。

以下のような感じでいくつかカテゴリと家計簿テーブルにデータを登録しておきましょう。

追加モジュールのインストール手順

ここで、以下の追加モジュールをインストールします。

django-bootstrap-form
django-extensions

後からコンテナに対してモジュールをインストールしたい場合はdocker container exec コマンドを使います。

docker container exec -it django_docker_web_1 pip install django-bootstrap-form
docker container exec -it django_docker_web_1 pip install django-extensions

以下の通りインストールが正常終了すればOKです。

なお、-itの次に指定している「django_docker_web_1」はdocker psコマンドで以下の通り確認できます。

新しく追加した2つのモジュールをsettings.pyに追加しておきましょう。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'kakeibo',
    'bootstrapform', #add
    'django_extensions', #add
]

 

構文エラーチェックの方法

ちなみに、djangoプロジェクトのエラーは以下のコマンドで確認できます。

docker container exec -it <コンテナID> python manage.py check

エラーがなければ以下のように表示されます。

家計簿一覧画面設定

最後に、家計簿一覧画面を定義するためにviews.py、urls.py,templatesを作成していきます。

まずはkakeibo\views.pyに以下の定義を設定します。

from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import ListView
from .models import Category, Kakeibo


#一覧表示用のDjango標準ビュー(ListView)を承継して一覧表示用のクラスを定義
class KakeiboListView(ListView):
   #利用するモデルを指定
   model = Kakeibo
   #データを渡すテンプレートファイルを指定
   template_name = 'kakeibo/kakeibo_list.html'

   #家計簿テーブルの全データを取得するメソッドを定義
   def queryset(self):
       return Kakeibo.objects.all()

 

続いてプロジェクト直下のexample\urls.pyを以下の設定にします。

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('kakeibo/',include('kakeibo.urls')),
]

 

次はアプリケーション配下のkakeibo\urls.pyを新規に作成し以下の通り設定します。

from django.urls import path
from . import views

urlpatterns = [
    path('kakeibo_list/', views.KakeiboListView.as_view(), name='kakeibo_list'),
]

 

最後にテンプレートファイルを作成します。
テンプレートはkakeibo\templates\kakeiboフォルダを作成し、base.htmlとkakeibo_list.htmlを以下の通り作成します。

base.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  {# Bootstrap4を使う #}
  <!-- linkタグでbootstrapのcssファイルを読み込む -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
  <!-- linkタグでDataTableのcssファイルを読み込む -->
  <link rel="stylesheet" href="https://cdn.datatables.net/t/bs-3.3.6/jqc-1.12.0,dt-1.10.11/datatables.min.css"/> 

  <!-- タイトルの設定-->
  <title>Tutorial</title>

<body>

  {% block content %}

   <!-- block content ~ endblockの間に子テンプレートの内容が差し込まれる -->

  {% endblock %}

  <!-- bootstrapのjavascrit読み込み-->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
  <!-- DataTablesのjavascrit読み込み-->
  <script src="https://cdn.datatables.net/t/bs-3.3.6/jqc-1.12.0,dt-1.10.11/datatables.min.js"></script>
  <!-- chart.jsの読み込み -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>

  <script type="text/javascript" charset="utf8" src="//cdn.datatables.net/plug-ins/1.10.6/sorting/currency.js"></script>
  
  <!-- Databableの定義-->
  <script>
  jQuery(function($){
    // デフォルトの設定を変更
    $.extend( $.fn.dataTable.defaults, {
        language: {
            url: "http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Japanese.json"
            }
            });

    $("#kakeibo_list").DataTable({
        "searching": true,     //検索機能
        "paging":   true,      //ページング機能
        "ordering": true,      //ソート機能
        "lengthChange": true,  //件数切り替え機能

        }).columns.adjust().draw();

        });

  </script>
  
</body>
</html>

 

kakeibo_list.html

<!-- 親テンプレートを読み込む-->
{% extends './base.html' %}

{% block content %}

  <div class="content-wrapper">
    <div class="container-fluid">
      <!-- パンくずリストの設定-->
      <ol class="breadcrumb">
        <li class="breadcrumb-item">
          <a href="{% url 'kakeibo_list' %}">TOP</a>
        </li>
        <li class="breadcrumb-item active">一覧表示</li>


      </ol>
      <!--ページタイトル-->
      <div class="card mb-3">
        <div class="card-header">
           <h3><b>家計簿アプリ</b></h3></div>
        <div class="card-body">

          <!-- テーブル表の定義 -->
          <table id=kakeibo_list width="100%" class="table table-striped table-bordered table-hover">
             <!-- 表の列の定義-->
              <thead>
                <tr>
                  <th class="text-center">日付</th>
                  <th class="text-center">カテゴリ</th>
                  <th class="text-center">金額</th>
                  <th class="text-center">数量</th>
 
                  <th class="text-center">メモ</th>
  
                </tr>
              </thead>
             <!-- ここまでが表の列の定義-->

             <!-- 表のデータ部分の表示-->
              <tbody>
                {% for item in object_list %}
                
                  <tr class="odd gradeX text-center">
                    <td class="text-center" width="100">{{ item.date}}</td>
                    <td class="text-center" width="100">{{ item.category }}</td>
                    <td class="text-center" width="140">{{ item.money}}円</td>
                    <td class="text-center" width="140">{{ item.quantity}}</td>
                    <td class="text-center" width="140">{{ item.memo }}</td>

                  </td>
                  </tr>
         
              {% endfor %}
            
              </tbody>
             <!-- ここまでが表のデータ部分の表示-->

            </table>
            <!-- ここまでがテーブル表の定義 -->
       </div>
       </div>
    </div>
   </div>
{% endblock content %}

 

http://192.168.99.100:8000/kakeibo/kakeibo_list/にアクセスして以下の通り家計簿一覧画面が表示されればOKです。

以上、Windows+DjangoでDocker入門【入門者向け】でした。

おすすめの記事