LoginSignup
10
13

More than 3 years have passed since last update.

Docker ComposeでDjangoとVue.jsの環境構築方法

Last updated at Posted at 2020-01-28

Docker ComposeでDjango(uwsgi)とMySQL,Nginxの環境構築方法をまとめます。
画面はバックエンドのViewで描画しますが、Vue.jsの環境を用意することで画面の一部をコンポーネントとして描画するようにしています。

今回はindex画面(ロケットが描画されている画面)と管理画面を立ち上げた後、アプリケーションディレクトリを作りアプリケーションのindexページの描画設定を行うところまでまとめています。

開発環境

Python:3.7
Django:2.2
Vue.js:2.6.0
MySQL:5.7
Nginx:1.17.0
uWSGI:2.0.18

参考

Docker-Composeで作るDjango開発環境(Django + MySQL + uWSGI + Nginx)

フォルダ構成

複雑になっていますが、下記のような構成になっています。

project/
    │
    ├──app/
    │   │
    │   ├──src/
    │   │   │
    │   │   ├──myapp/
    │   │   │   │
    │   │   │   ├──__pycache__/
    │   │   │   │
    │   │   │   ├──migrations
    │   │   │   │   │
    │   │   │   │   ├──__pycache__/
    │   │   │   │   ├──__init__.py
    │   │   │   │   └──0001_initial.py
    │   │   │   │
    │   │   │   ├──templates
    │   │   │   │   │
    │   │   │   │   ├──myapp/
    │   │   │   │   │   │
    │   │   │   │   │   └──index.html
    │   │   │   │   │
    │   │   │   │   └──layout.html
    │   │   │   │
    │   │   │   ├──__init__.py
    │   │   │   ├──admin.py
    │   │   │   ├──apps.py
    │   │   │   ├──models.py
    │   │   │   ├──tests.py
    │   │   │   ├──urls.py
    │   │   │   └──views.py
    │   │   │
    │   │   ├──project/
    │   │   │   │
    │   │   │   ├──__init__.py
    │   │   │   ├──settings.py
    │   │   │   ├──urls.py
    │   │   │   └──wsgi.py
    │   │   │
    │   │   ├──static/
    │   │   │   │
    │   │   │   ├──css/
    │   │   │   │   │
    │   │   │   │   └──app.css
    │   │   │   │
    │   │   │   ├──img/
    │   │   │   │
    │   │   │   └──js/
    │   │   │       │
    │   │   │       ├──components/
    │   │   │       └──app.js
    │   │   │
    │   │   ├──manage.py
    │   │   ├──package-lock.json
    │   │   ├──package.json
    │   │   └──webpack.config.js
    │   │
    │   ├──static/
    │   │   │
    │   │   ├──admin/   *管理対象外
    │   │   └──bundles/ *管理対象外
    │   │
    │   ├──Dockerfile
    │   └──requirements.txt
    │
    ├──mysql/
    │   │
    │   ├──mysql_data/   *管理対象外
    │   │
    │   ├──sql/
    │   │   │
    │   │   └──initialize.sql
    │   │
    │   ├──Dockerfile
    │   └──my.cnf
    │
    ├──nginx/
    │   │
    │   ├──Dockerfile
    │   ├──nginx.cnf
    │   └──iwsgi_params
    │
    ├──.editorconfig
    ├──.env_example
    ├──.gitignore
    ├──docker-compose.yml
    └──Readme.md

環境構築

docker-comopose.ymlの内容

.envでポート番号等の設定を行なっています。
DockerファイルやDB作成用のSQLは参考のものを流用しています。
* uwsgiコンテナにはnpmをインストールする様に編集しています。


version: "3.5"

services:

  uwsgi:
    build: ./app
    container_name: project_uwsgi
    volumes:
      - ./app:/var/www/
    expose:
      - "${UWSGI_PORT}"
    depends_on:
      - db
    ports:
      - "${UWSGI_PORT}:${UWSGI_PORT}"
    tty: true
    environment:
      TZ: "Asia/Tokyo"
      APP_URL: ${APP_URL}
      APP_ENV: ${APP_ENV}
      DB_USER: ${DB_USER}
      DB_PASSWORD: ${DB_PASSWORD}
      DB_HOST: ${DB_HOST}
      DB_DATABASE: ${DB_DATABASE}

  nginx:
    build: ./nginx
    container_name: project_nginx
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
      - ./app/static:/static
    depends_on:
      - uwsgi
    ports:
      - "${NGINX_HOST_HTTP_PORT}:${NGINX_HOST_HTTP_PORT}"
      - "${NGINX_HOST_HTTPS_PORT}:${NGINX_HOST_HTTPS_PORT}"
    environment:
      TZ: "Asia/Tokyo"

  db:
    build: ./mysql
    container_name: project_db
    volumes:
      - ./mysql/mysql_data:/var/lib/mysql # データの永続化
      - ./mysql/sql:/docker-entrypoint-initdb.d
    ports:
      - "${MYSQL_PORT}:${MYSQL_PORT}"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      TZ: "Asia/Tokyo"

requirements.txtの内容

Django==2.1.1
uwsgi==2.0.18
mysqlclient==1.4.6
django-webpack-loader==0.6.0
Pillow==6.2.1

実際の環境構築手順

docker-composeコマンドでstartprojectの実行

$ docker-compose run uwsgi django-admin.py startproject project .

settings.pyに下記の事項をそれぞれ所定の箇所に記載する

DB設定

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db_name',
        'USER': 'user_name',
        'PASSWORD': 'user_pass',
        'HOST': 'db_port',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4'
        },
    }
}

文字コード、タイムゾーン

LANGUAGE_CODE = 'ja_JP.UTF-8'

TIME_ZONE = 'Asia/Tokyo'

collectstaticコマンド実行時に静的ファイルを集める場所を指定

STATIC_ROOT = '/var/www/static'

トップページに表示する画像などを格納するパスの設定「/static」
webpackでビルドしたファイルの格納場所の指定

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'bundles/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
    }
}

マイグレーションの実行

$ docker-compose run uwsgi ./manage.py makemigrations
$ docker-compose run uwsgi ./manage.py migrate

管理画面作成

管理者名、メールアドレス、パスワードを作成する

$ docker-compose run uwsgi ./manage.py createsuperuser

任意の値を設定する。

管理者画面のCSS設定

settings.pyに「STATIC_ROOT」の記述をした状態で下記を実行する

$ docker-compose run uwsgi ./manage.py collectstatic

npm環境の構築

(uwsgiコンテナにて)Dockerファイルで特にnpmの設定をしていない場合、下記の手順でnpmをインストールします。

apt install -y nodejs npm
npm install -g n
n stable
apt purge -y nodejs npm

Vue.jsのインストール

webpackなどもこのタイミングでインストールしておきます。

npm install --save-dev webpack webpack-cli webpack-bundle-tracker
npm install --save-dev vue-loader
npm install --save-dev style-loader css-loader sass-loader
npm install --save vue
npm install --save-dev @babel/core @babel/preset-env
npm install --save-dev babel-loader

npm installの実行

下記のようなpackage.jsonを予め用意しておけばnpm installコマンドだけでインストール出来ます。

$ docker-compose run uwsgi npm install

package.jsonの内容

場所:app/src/package.json

{
  "name": "app",
  "version": "1.0.0",
  "description": "### myapp application.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "node_modules/.bin/webpack --mode development",
    "build": "node_modules/.bin/webpack --mode production",
    "watch": "node_modules/.bin/webpack --watch -d"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.7.4",
    "@babel/preset-env": "^7.7.4",
    "babel-loader": "^8.0.6",
    "css-loader": "^3.2.1",
    "sass-loader": "^8.0.0",
    "style-loader": "^1.0.1",
    "vue-loader": "^15.7.2",
    "vue-template-compiler": "^2.6.10",
    "webpack": "^4.41.2",
    "webpack-bundle-tracker": "^0.4.3",
    "webpack-cli": "^3.3.10"
  },
  "dependencies": {
    "vue": "^2.6.10"
  }
}

webpack.config.jsの作成

var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var VueLoaderPlugin = require('vue-loader/lib/plugin');

var env = process.env.NODE_ENV;


module.exports = {
    context: __dirname,
    entry: './static/js/app.js',

    output: {
        filename: "[name]-[hash].js",
        path: path.resolve('../static/bundles/'),
        // publicPath: '/'
    },

    plugins: [
        new BundleTracker({filename: './webpack-stats.json'}),
        // .vueファイルを読み込めるようにする
        new VueLoaderPlugin()
    ],

    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            },
            {
                test: /\.css$/,
                use: [
                    "vue-style-loader",
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            url: false,
                            sourceMap: true
                        }
                    }
                ]
            },
        ]
    },

    resolve: {
        extensions: ['.js', '.vue'],
        modules: [
            "node_modules"
        ],
        alias: {
            'vue': path.resolve('./node_modules/vue/dist/vue.js'),
        }
    },
}

アセットコンパイル

$ docker-compose run uwsgi npm run dev

コンテナの起動

$ docker-compose up -d

ブラウザでチェック

http://localhost

これでindexの画面(ロケットが表示されている画面)と管理画面が見れるようになります!

アプリケーションの新規作成

$ docker-compose run uwsgi ./manage.py startapp myapp

project/settings.pyの「INSTALLED_APPS」に作成したアプリケーション名を追記すること。

INSTALLED_APPS = {
...
    'myapp',
...
}

sttings.pyの「INSTALLED_APPS」に下記を追記

INSTALLED_APPS = {
...
    'webpack_loader',
    'myapp',
...
}

アセットコンパイル

$ docker-compose run uwsgi npm run dev

myappアプリケーションのページをブラウザで表示する為の設定は下記の通りです。

myapp/urls.pyの作成

touch app/src/myapp/urls.py

下記の通り編集

from django.urls import path
from . import views

app_name = 'myapp'
urlpatterns = [
    path('', views.index, name='index'),
]

myapp/views.pyの編集

from django.http import HttpResponse
from django.template import loader

def index(request):
    template = loader.get_template('myapp/index.html')
    context = {}
    return HttpResponse(template.render(context, request))

project/urls.pyの編集

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

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

あとは「/app/src/myapp/templates/myapp」ディレクトリにindex.htmlを作成することでmyappのindexページ(URL:localhost)をブラウザから開くことが出来るようになります。
jsファイルやcssファイルを追加して編集した際は随時npm runでビルドをします。

補足:不要ファイルの削除

環境を再構築したい時は下記のコマンドで既存のものを削除します。

$ docker-compose down --rmi all
$ unlink app/src/myapp
$ rm -rf app/src/node_modules
$ rm -rf app/src/project
$ rm -rf app/src/manage.py
$ rm -rf app/static/*
$ rm -rf mysql/mysql_data

まとめ

Laravelだと比較的直ぐにアセットのビルド環境を構築出来ていたのですが、Djangoの場合だとWebpackの設定ファイルを作るところから始めたのが新鮮で楽しかったです!
上記の内容でならアプリケーションコンテナでnpm run buildを実行することでVue.jsの画面を作成することが出来ますが、やはりフロントの環境をPythonのアプリケーションに混ぜると煩雑になり管理しにくくなります。
今回まとめた方法はあくまでViewをサーバーサイドで持ちたいと言う場合に使えそうな手段ですが、今後環境を構築するのならフロントエンドとバックエンドに分けて構築しようと思いました。

10
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13