Vue+DjangoのDocker環境を作成した時のメモ

# 背景

2019年1月に構築してみた時のメモです。

# 目標

* vueとdjangoを単一のGitリポジトリに入れたい

# 環境

* vue-cli: 3.2.2
* node.js: v10.15.0  (nodebrewでインストール)
* python: 3.6.6 (pyenvでインストール)

## vue側準備

```shell
npm upgrade -g npm
npm install -g @vue/cli
```

vue-routerはhistoryモードではなくhashモードで(サーバーの設定が面倒)、eslintはstandard、unitテストはJestを選択

## Django側準備

```shell
python -m venv myvenv
source myvenv/bin/activate
pip install --upgrade pip
pip install django==2.1.4
django-admin startproject server .
python manage.py migrate

# 動作確認
python manage.py runserver
```

pipパッケージを追加するときは、 `source myvenv/bin/activate` でvenvの環境に入ることを忘れないこと。

Elastic Beanstalkにデプロイできるように( https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create-deploy-python-django.html ) を参考にしながら設定を追加。

```shell
pip freeze > requirements.txt
mkdir .ebextensions
vim .ebextensions/django.config
```

configの中はwsgi.pyの場所を指定

```yaml:django.config
option_settings:
  aws:elasticbeanstalk:container:python:
      WSGIPath: server/config/wsgi.py
```

## Dockerイメージを作成

```yaml:docker-compose.yml
version: "3"

services:
  db:
    image: postgres:10.5-alpine
    restart: always
    ports:
      - "15432:5432"
    environment:
      DEBUG: 1
      POSTGRES_DB: "postgres"
      POSTGRES_USER: "hoge"
      POSTGRES_PASSWORD: "hogehoge"
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=ja_JP.UTF-8"
      TZ: Asia/Tokyo
    volumes:
      - ./dbdata/pgdata:/var/lib/postgresql/data
      - ./db:/docker-entrypoint-initdb.d
  vue:
    build: ./client
    ports:
      - 8080:8080
    volumes:
      - ./client:/app
    command: yarn serve --mode localdev
  django:
    build: ./server
    command: sh -c "./wait-for-it.sh db:5432 -t 120 && python3 manage.py runserver 0.0.0.0:8000 --settings=config.settings_docker"
    stdin_open: true
    tty: true
    volumes:
      - ./server:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
```

alpineのpythonだと `psycopg2` のインストールが大変っぽいので挫折した。

[wait-for-it.sh](https://github.com/vishnubob/wait-for-it)を使うことでDjango側はdbの起動を待ってくれている。

```dockerfile:server/Dockerfile
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install --upgrade pip setuptools &&  pip install -r requirements.txt
ADD . /code/
```

```dockerfile:client/Dockerfile
FROM node:10.15-alpine as build-stage
WORKDIR /app
COPY . /app/
RUN yarn install
```

ひとまずdockerからvueとDjangoは立ち上がるようになった。

## 第三者が使うときにvue環境がうまく動いてない

ホストのnode_modulesが空のときにvolumeとしてコンテナにつないでしまい、 `RUN yarn install` の中身を台無しにしてしまうのが原因。なので一旦 yarn installのみを行う docker-compose を作ってあげる。(すごいバットノウハウっぽい……)

```yaml:docker-compose_first.yml
version: "3"

services:
  vue:
    build: ./client
    ports:
      - 8080:8080
    volumes:
      - ./client:/app
    command: yarn install

```

起動するときはこう

```
docker-compose -f docker-compose_first.yml up
```

## vue.config.js

```js:vue.config.js
// 参考:
// https://qiita.com/Niemuuu/items/5dde43b4e7e6f3dc5cf4
// https://cli.vuejs.org/config/#vue-config-js
module.exports = {
  configureWebpack: {
    plugins: [
      //
    ]
  },
  pages: {
    pc_index: {
      entry: 'src/pc/main.js', // エントリーポイントとなるjs
      template: 'public/index.html',
      filename: 'pc/pc_entry.html' // build時に出力されるファイル名
    }
  },
  devServer: {
    proxy: {
      '^/static': {
        target: 'http://django:8000', // コンテナ間通信になるのでlocalhostではなくdockerのコンテナ名を指定する ( localhost:8080/static/HOGE のアクセスは django:8000/static/HOGE )
        changeOrigin: true,
        secure: false
      }
    },
    watchOptions: {
      ignored: /node_modules/,
      aggregateTimeout: 300, // 最初の変更から300ms待ち、他の変更も含めてリビルドする
      poll: 3000
    }
  },
  css: { // devTOOLsでcss等の行番号表示
    loaderOptions: {
      css: {
        sourceMap: true
      },
      postcss: {
        sourceMap: true
      }
    }
  }
```

# 参考

* [「Vue.js + Go言語 + Docker」で作る！画像アップロード機能実装ハンズオン](https://qiita.com/po3rin/items/c70105f684e6816621d2)
* [Quickstart: Compose and Django](https://docs.docker.com/compose/django/)
* [vue-django](https://github.com/NdagiStanley/vue-django)