開発環境と本番環境でDockerを分ける

# はじめに
DjangoとVueとNginxを使って開発をしています。
開発環境から本番環境へのデプロイ時に手間取ったのでスムーズに移行できるような仕組みを作ろうと思いました。
まだまだ至らない点があると思います。もっとこうした方がいいなどのアドバイスがありましたらコメントで教えていただけると幸いです。

# 開発環境
- macOs Monterey ver12.1(M1)
- docker Engine 20.10.12
- docker-compose version 1.29.2

# 全体構成
![env-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679892/0e2c9bd6-c0c9-dd49-ae70-624bcbb31776.png)

- Dockerを使って環境を作成していきます
- 開発環境ではDBサーバーはDjangoのSQLiteを使用して、本番環境だけNginxのコンテナを使います。

# 手順
## 開発環境作成
### docker-compose.dev.yml作成
まずは、開発環境用のdocker-composeファイルを作成していきます。
```terminal:
touch docker-compose.dev.yml
touch .env.dev
```
.env.devファイルは後で使います。

```docker:docker-compose.dev.yml
version: '3.7'

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.dev
    command: sh -c " python manage.py migrate && python manage.py runserver 0.0.0.0:8000 "
    ports:
      - 8000:8000
    env_file:
      - ./.env.dev

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    command: npm run serve
    ports:
      - 8080:8080
    env_file:
      - ./.env.dev
```

それに合わせてフォルダ作成を行います。
### backendフォルダ作成
django用のフォルダとしてbackendフォルダを作成して、プロジェクトを作成します。
```terminal:terminal
mkdir backend
touch .backend/requirements.dev.txt
django-admin startproject config ./backend/
```

開発環境で立ち上げた時にアクセスするために設定ファイルを書き換えます。
```diff_python:./backend/config/settings.py
- ALLOWED_HOSTS = []
+ ALLOWED_HOSTS = ["*"]

```

```terminal:requirements.dev.txt
django==4.0.5
django-webpack-loader==0.7.0
pytz==2022.1
```
backend用のDockerfileを作成します。
```Dockerfile:Dockerfile.dev
FROM python:3.10-alpine

ENV APP_HOME=/home/app/web
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN pip install --upgrade pip
COPY ./requirements.dev.txt .
RUN pip install -r requirements.dev.txt

COPY . .
```

### frontendフォルダ作成
Vueプロジェクトを作成します。
インストール方法はマニュアルでお好みです。
vue2.XとVueRouter、Vuexを入れました。
```terminal:terminal
vue create frontend .
```

その後作成したフォルダに移動して、webpack-bundle-trackerをインストールします。
バージョン0系と1系がありますが、1系だとうまくいかなかったので0系でインストールします。
```terminal:terminal
cd frontend
npm install webpack-bundle-tracker@0.4.3
```

frontend用のDockerfileを作成します。
```Dockerfile:Dockerfile.dev
FROM node:14-alpine

# カレントワーキングディレクトリとして 'app' フォルダを指定する
WORKDIR /app

# `package.json` と `package-lock.json` （あれば）を両方コピーする
COPY package*.json ./

# プロジェクトの依存ライブラリをインストールする
RUN npm install

# カレントワーキングディレクトリ(つまり 'app' フォルダ)にプロジェクトのファイルやフォルダをコピーする
COPY . .
```

ここまででディレクトリ構成は以下になります。
```terminal:project_dir
.
├── .env.dev
├── backend
│   ├── Dockerfile.dev
│   ├── config
│   ├── manage.py
│   └── requirements.dev.txt
├── docker-compose.dev.yml
└── frontend
    ├── .gitignore
    ├── Dockerfile.dev
    ├── README.md
    ├── babel.config.js
    ├── jsconfig.json
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── public
    ├── src
    └── vue.config.js
```

開発用の環境を立ち上げて動作確認
```terminal
docker-compose -f docker-compose.dev.yml build
docker-compose -f docker-compose.dev.yml up -d
```

django
[http://0.0.0.0:8000/](http://0.0.0.0:8000/)

vue
[http://0.0.0.0:8080/](http://0.0.0.0:8080/)

動作確認が終わったらコンテナを立ち下げます。
```terminal
docker-compose -f docker-compose.dev.yml down -v
```

## 本番環境作成
次に本番環境用のファイルを作成していきます。
手順としては、先ほどの開発環境と同じです。
1. docker-composeファイル作成
2. Dockerfile作成
3. 設定ファイル変更

### docker-compose.prod.yml作成

```terminal:terminal
touch docker-compose.prod.yml
touch .env.prod
```

さきほどの.env.devファイルを編集していきます。
```terminal:.env.dev
DEBUG=True
SECRET_KEY=$x=-wc4hbdkfbd$who$tova=js7b19nb&tf=n)eq6txjz#du2m
#*の後にスペースを忘れない
ALLOWED_HOSTS=* 
```
本番用の環境変数ファイルを編集します。
```terminal:.env.prod

SQL_DATABASE=db_name
SQL_USER=user_name
SQL_PASSWORD=password
SQL_HOST=db
SQL_PORT=5432
 
POSTGRES_USER=user_name
POSTGRES_PASSWORD=password
POSTGRES_DB=db_name

DATABASE=postgres
```

本番用のdocker-composeファイルです。
```docker:docker-compose.prod.yml
version: '3.7'

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.prod
    command: sh -c "python manage.py collectstatic --no-input --clear && python manage.py makemigrations && python manage.py migrate && gunicorn config.wsgi:application --bind 0.0.0.0:8000 "
    volumes:
      - static_volume:/home/app/web/static
      - media_volume:/home/app/web/media
      - frontend_volume:/app
    expose:
      - 8000
    env_file:
      - ./.env.prod
    depends_on:
      db:
        condition: service_started
      frontend:
        condition: service_completed_successfully

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.prod
    command: npm run build
    ports:
      - 8080:8080
    env_file:
      - ./.env.prod
    volumes:
      - frontend_volume:/app

  db:
    image: postgres:12.0-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    env_file:
      - ./.env.prod

  web:
    build:
      context: ./nginx
      dockerfile: Dockerfile.prod
    volumes:
      - static_volume:/home/app/web/static
      - media_volume:/home/app/web/media
    ports:
      - 1317:80
    depends_on:
      - backend

volumes:
  postgres_data:
  static_volume:
  media_volume:
  frontend_volume:

```
Dockerfileを作成して編集していきます。
```terminal
touch ./backend/Dockerfile.prod
touch ./frontend/Dockerfile.prod
```

### backendフォルダ作成
本番環境用のDockerfile（backend）
```Dockerfile:./backend/Dockerfile.prod
FROM python:3.10-alpine

ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir -p $APP_HOME
RUN mkdir -p $APP_HOME/static
RUN mkdir -p $APP_HOME/media 
WORKDIR $APP_HOME

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install psycopg2 dependencies
RUN apk update \
    && apk add postgresql-dev gcc python3-dev musl-dev

RUN pip install --upgrade pip
COPY ./requirements.prod.txt .
RUN pip install -r requirements.prod.txt

COPY ./entrypoint.sh .

COPY . .

ENTRYPOINT ["/home/app/web/entrypoint.sh"]
```

Djangoは本番環境でDBサーバーと連携するため、DBサーバーの立ち上がりを待つ必要があります。
postgreSQL→backendの順番で動作するよう待機用のシェルを読み込みます。
```sh:.backend/entrypoint.sh
#!/bin/sh
 
if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."
 
    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 0.1
    done
 
    echo "PostgreSQL started"
fi
 
exec "$@"
```

新しくアプリを追加します。
```terminal:terminal
python manage.py startapp vue
```

このアプリからVueのページを見に行くようにするための設定とDjango側で環境変数を読み込むための設定を行います。
```diff_python:./backend/config/settings.py
INSTALLED_APPS = [
    # 省略
    # 3rd party
+     'rest_framework',
+     'webpack_loader',
    # my-app
+     'vue',
]
+ STATIC_ROOT = os.path.join(BASE_DIR, "static")
+ STATICFILES_DIRS = [
+     os.path.join('/app/dist')
+ ]

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


- DATABASES = {
-     'default': {
-         'ENGINE': 'django.db.backends.sqlite3',
-         'NAME': BASE_DIR / 'db.sqlite3',
-     }
- }
+ DATABASES = {
+     'default': {
+         'ENGINE': 'django.db.backends.postgresql_psycopg2',
+         'NAME': os.environ.get("SQL_DATABASE"),
+         'USER': os.environ.get("SQL_USER"),
+         'PASSWORD': os.environ.get("SQL_PASSWORD"),
+         'HOST': os.environ.get("SQL_HOST"),
+         'PORT': os.environ.get("SQL_PORT"),
+     }
+ }
```

djangoでvueのページを表示するようにルーティングを追加します。
まずは、configのurls.py
```python:./backend/config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('vue.urls')), #追加
]
```

vue用のurls.pyを作成
```terminal
touch ./backend/vue/urls.py
```

vue用のurls.pyを編集する。
```python:./backend/vue/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
]
```

次にviews.pyを編集する
```python:./backend/vue/views.py
from django.views.generic import TemplateView


class IndexView(TemplateView):
    template_name = 'vue/index.html'
```

テンプレートフォルダとindex.htmlの作成
```terminal
mkdir -p templates/vue
touch templates/vue/index.html
```

index.htmlの中身を記述する。
```django:.backend/vue/templates/vue.index.html
{% load render_bundle from webpack_loader %}


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue Board</title>
  </head>
  <body>
    <h1>Vue JS</h1>
    <div id="app"></div>
    {% render_bundle 'app' %}
  </body>
</html>
```

本番環境でnginxと連携するためにDjangoをgunicornで起動する必要があるため、ライブラリを追加していきます。
```terminal
touch ./backend/requirements.prod.txt
```
作成したファイルを編集していきます。
```python:./backend/requirements.prod.txt
django==4.0.5
psycopg2-binary==2.9.3
gunicorn==20.1.0
django-webpack-loader==0.7.0
djangorestframework==3.11.0
pytz==2022.1
```
### frontendフォルダ作成
本番環境用のDockerfile（frontend）
```Dockerfile:./frontend/Dockerfile.prod
FROM node:14-alpine

# カレントワーキングディレクトリとして 'app' フォルダを指定する
WORKDIR /app

# `package.json` と `package-lock.json` （あれば）を両方コピーする
COPY package*.json ./

# プロジェクトの依存ライブラリをインストールする
RUN npm install

# カレントワーキングディレクトリ(つまり 'app' フォルダ)にプロジェクトのファイルやフォルダをコピーする
COPY . .
```

ここでvuetifyを追加します。
マニュアルを選択しました。
lintのエラーが出ますが、無視して大丈夫です。
```terminal:terminal
vue add vuetify
```

本番ではwebpackを使ってバンドルしたファイルをNginxから配信するためwebpackの設定を変更していきます。
```javascript:./frontend/vue.config.js
const BundleTracker = require("webpack-bundle-tracker");

module.exports = {
  publicPath: "/static/dist/",

  outputDir: "./dist/dist/",
  transpileDependencies: ["vuetify"],

  chainWebpack: (config) => {
    config
      .plugin("BundleTracker")
      .use(BundleTracker, [{ filename: "./webpack-stats.json" }]);
    config.output.filename("bundle.js");
    config.optimization.splitChunks(false);
    config.resolve.alias.set("__STATIC__", "static");
    config.devServer
      .https(false)
      .headers({ "Access-Control-Allow-Origin": ["*"] });
  },

  lintOnSave: false,
};
```


### nginxフォルダ作成
本番環境ではwebサーバーとしてnginxを使用します。
そのためのDockerfileを作成します。
またnginx.confファイルの作成も行います。
```terminal
mkdir nginx
touch ./nginx/nginx.conf
touch ./Dockerfile.prod
```

```Dockerfile:./nginx/Dockerfile.prod
FROM nginx:latest

RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
```

nginx.confファイルにwebサーバの設定を書いていきます。
```terminal:nginx.conf
upstream project {
   server backend:8000;
}

server {

   listen 80;
   
   location / {
       proxy_pass http://project;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Host $host;
       proxy_redirect off;
    }
   
   location /static/ {
       alias /home/app/web/static/;
    }
   location /media/ {
       alias /home/app/web/media/;
    }
}
```

ここまででフォルダ構成は以下になります。
```terminal:project_dir
.
├── .env.dev
├── .env.prod
├── backend
│   ├── Dockerfile.dev
│   ├── Dockerfile.prod
│   ├── config
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── entrypoint.sh
│   ├── manage.py
│   ├── requirements.dev.txt
│   ├── requirements.prod.txt
│   └── vue
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── migrations
│       ├── models.py
│       ├── templates
│       ├── tests.py
│       ├── urls.py
│       └── views.py
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── frontend
│   ├── .gitignore
│   ├── Dockerfile.dev
│   ├── Dockerfile.prod
│   ├── README.md
│   ├── babel.config.js
│   ├── jsconfig.json
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   │   ├── favicon.ico
│   │   └── index.html
│   ├── src
│   │   ├── App.vue
│   │   ├── assets
│   │   ├── components
│   │   ├── main.js
│   │   ├── plugins
│   │   ├── router
│   │   ├── store
│   │   └── views
│   └── vue.config.js
├── nginx
    ├── Dockerfile.prod
    └── nginx.conf
```

本番環境の準備が整ったので、起動して動作確認していきます。
```terminal
docker-compose -f docker-compose.prod.yml build
docker-compose -f docker-compose.prod.yml up -d
```

以下のURLにアクセスして表示されるか確認します。
vuetifyが表示されると成功です。
[localhost:1317/](localhost:1317/)

動作確認できたら、立ち下げます。
```terminal
docker-compose -f docker-compose.dev.yml down -v
```

## 開発環境と本番環境を切り替えて使用する
最後に開発環境と本番環境で環境変数を切り替えられるようにします。
手順としては、以下の通りです。
1. docker-compose用の.env編集
2. docker-compose.dev.yml編集
3. Djangoのsettingsを分ける
4. Vueの.env作成

### docker-compose用の.envファイルを編集していきます。
すでにプロジェクトディレクトリ直下に.env.devと.env.prodファイルがあるのでその2つを編集していきます。
```terminal:.env.dev
DEBUG=True
SECRET_KEY=$x=-wc4hbdkfbd$who$tova=js7b19nb&tf=n)eq6txjz#du2m
ALLOWED_HOSTS=* 

DJANGO_SETTINGS_MODULE=config.settings.dev

NODE_ENV=development
```

```terminal:.env.prod
DEBUG=False
SECRET_KEY=$x=-wc4hbdkfbd$who$tova=js7b19nb&tf=n)eq6txjz#du2m
ALLOWED_HOSTS=localhost 127.0.0.1 [::1]

SQL_DATABASE=db_name
SQL_USER=user_name
SQL_PASSWORD=password
SQL_HOST=db
SQL_PORT=5432
 
POSTGRES_USER=user_name
POSTGRES_PASSWORD=password
POSTGRES_DB=db_name

DATABASE=postgres

DJANGO_SETTINGS_MODULE=config.settings.prod

NODE_ENV=production
```

### docker-compose.dev.yml編集
webpack-loaderでファイルが見れるようにvolumesを追加します。

```docker:docker-compose.dev.yml
version: '3.7'

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.dev
    command: sh -c " python manage.py migrate && python manage.py runserver 0.0.0.0:8000 "
    volumes:
      - frontend_volume:/app
    ports:
      - 8000:8000
    env_file:
      - ./.env.dev

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    command: npm run serve
    volumes:
      - frontend_volume:/app
    ports:
      - 8080:8080
    env_file:
      - ./.env.dev
volumes:
  frontend_volume:
```

### Djangoのsettingsを分ける
手順
1. configフォルダ直下にsettingsフォルダを新規作成
2. settings.pyファイルをbase.pyに名前変更してsettingsフォルダに移動
3. 新規にdev.pyとprod.pyと__init__.pyファイルの3つをsettingsフォルダ直下に作成

configのフォルダ構成は以下を参考にしてください。
__pycache__以下はなくても問題ありません。

```terminal:変更前
./config
├── __init__.py
├── __pycache__
│   ├── __init__.cpython-310.pyc
│   └── settings.cpython-310.pyc
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
```

```terminal:変更後
./config
├── __init__.py
├── __pycache__
│   ├── __init__.cpython-310.pyc
│   ├── settings.cpython-310.pyc
│   ├── urls.cpython-310.pyc
│   └── wsgi.cpython-310.pyc
├── settings
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-310.pyc
│   │   ├── base.cpython-310.pyc
│   │   └── dev.cpython-310.pyc
│   ├── base.py
│   ├── dev.py
│   └── prod.py
├── urls.py
└── wsgi.py
```

base.pyを変更します。
```python:base.py
from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # 3rd party
    'rest_framework',
    'webpack_loader',

    # my-app
    'vue',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'config.wsgi.application'


# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [
    os.path.join('/app/dist')
]


# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

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

```

dev.pyを編集します。
```python:dev.py
from .base import *
import os


# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ.get("DEBUG") == "True" #DEBUGはbool型なので文字列の判定結果を格納する

ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS").split(" ")


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
```

prod.pyを編集します。
```python:prod.py
from .base import *
import os


# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ.get("DEBUG") == "True" #DEBUGはbool型なので文字列の判定結果を格納する

ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS").split(" ")


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.environ.get("SQL_DATABASE"),
        'USER': os.environ.get("SQL_USER"),
        'PASSWORD': os.environ.get("SQL_PASSWORD"),
        'HOST': os.environ.get("SQL_HOST"),
        'PORT': os.environ.get("SQL_PORT"),
    }
}
```

settingsファイルのディレクトリが変わったので、少し修正します。
```diff_python:manage.py
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev')
```

```diff_python:wsgi.py
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev')
```

```diff_python:asgi.py
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev')
```

### Vueの.env作成
frontendフォルダ直下に.env.development.localと.env.production.localを作成します。
.env.localと.env.*.localは.gitignoreにデフォルトで含まれているのでgithubに共有されることはありません。

```terminal:.env.development.local
BASE_URL=http://0.0.0.0:8080/
```

```terminal:.env.production.local
BASE_URL=/static/dist/
```
設定したBASE_URLを読み込めるようにvue.config.jsファイルを修正します。

```diff_javascript:vue.config.js
- publicPath: "/static/dist/",
+ publicPath: process.env.BASE_URL,
```

最終的にディレクトリ構成は以下になります。
./frontend/node_modulesは非表示にしています。
```terminal:project_dir
.
├── .env.dev
├── .env.prod
├── backend
│   ├── Dockerfile.dev
│   ├── Dockerfile.prod
│   ├── config
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   ├── asgi.py
│   │   ├── settings
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── entrypoint.sh
│   ├── manage.py
│   ├── requirements.dev.txt
│   ├── requirements.prod.txt
│   └── vue
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── migrations
│       ├── models.py
│       ├── templates
│       ├── tests.py
│       ├── urls.py
│       └── views.py
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── frontend
│   ├── .env.development.local
│   ├── .env.production.local
│   ├── .gitignore
│   ├── Dockerfile.dev
│   ├── Dockerfile.prod
│   ├── README.md
│   ├── babel.config.js
│   ├── jsconfig.json
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   │   ├── favicon.ico
│   │   └── index.html
│   ├── src
│   │   ├── App.vue
│   │   ├── assets
│   │   ├── components
│   │   ├── main.js
│   │   ├── plugins
│   │   ├── router
│   │   ├── store
│   │   └── views
│   └── vue.config.js
└── nginx
    ├── Dockerfile.prod
    └── nginx.conf
```
開発環境と本番環境の動作確認を行います。
```terminal:開発環境
docker-compose -f docker-compose.dev.yml build
docker-compose -f docker-compose.dev.yml up -d
```

django
[http://0.0.0.0:8000/](http://0.0.0.0:8000/)
[http://0.0.0.0:8000/admin](http://0.0.0.0:8000/admin)

vue
[http://0.0.0.0:8080/](http://0.0.0.0:8080/)

vuetifyの画面が表示されれば正常です。
確認できたら、立ち下げます。
```terminal:開発環境
docker-compose -f docker-compose.dev.yml down -v
```

そして、本番環境で起動します。
```terminal:開発環境
docker-compose -f docker-compose.prod.yml build
docker-compose -f docker-compose.prod.yml up -d
```

django
[http://localhost/1317](http://localhost/1317)

確認できたら、立ち下げます。
```terminal:本番環境
docker-compose -f docker-compose.prod.yml down -v
```

# 参考サイト
開発環境と本番環境を分けるために以下のサイトを参考にさせていただきました。
ありがとうございました。

https://note.com/hathle/n/na6f02aeb8384#FHMMl

https://tomato-develop.com/docker-dockercompose-python-django-postgresql-gunicorn-nginx-how-to-build-development-and-production-environment/