🌏

【デプロイ】(画像解説付)VercelとRender にそれぞれVueとDjangoアプリをデプロイ

に公開

達成イメージ


ローカルでの環境構築イメージ図

Vercelの画面(左)とRenderの画面(右)

デプロイのアーキテクチャ構成
[ユーザー][Vercel - フロントエンド(Vue.js)](https://app-name-woad-two.vercel.app)
    ↓ API呼び出し
[Render - バックエンド(Django)](https://app-name-v2px.onrender.com)[データベース](postgresql://health_buddy_db_6ipw_user:~)
今回デプロイするフロントエンド・バックエンドディレクトリ構成
バックエンド(Django)・フロントエンド(Vue)
myproject/
├── backend/
│   ├── django-project/ # Djangoのプロジェクト
│   ├── django-app/  # Djangoアプリケーション                  
│   ├── requirements.txt       
│   └── manage.py 
│
├── frontend/
│   ├── node_modules/
│   ├── public/
│   │   ├── favicon.ico
│   │   └── index.html
│   ├── src/
│   │   ├── assets/
│   │   │   └── main.css
│   │   ├── components/
│   │   │   ├── --.vue
│   │   │   └── --.vue
│   │   ├── views/
│   │   │   ├── --.vue
│   │   │   └── --.vue
│   │   ├── router/
│   │   │   └── index.js
│   │   ├── store/
│   │   │   └── index.js
│   │   ├── services/
│   │   │   └── api.js
│   │   ├── utils/
│   │   │   └── dateUtils.js
│   │   ├── config/
│   │   │   └── api.js
│   │   ├── App.vue
│   │   └── main.js
│   ├── index.html         
│   ├── package.json
│   ├── vite.config.js
│
├── docker/
│   ├── compose/
│   │   ├── docker-compose.dev.yml
│   │   └── docker-compose.prod.yml
│   └── env/
│       ├── .env.development
│       ├── .env.production
│       └── .env
│
├── .dockerignore
├── .gitignore
└── README.md

【Render準備】Backend側

準備1 requriment.txtへの記述
requriment.txtに以下を追加(★:必須)
Django>=4.0(★)
 # PythonのWebアプリケーションフレームワーク(構築そのものに必要)
gunicorn(★)
 # Pythonの本番用WSGI HTTPサーバー
whitenoise
 # Djangoの静的ファイル(CSS/JS/画像)を自動で配信するためのミドルウェア
psycopg2-binary(★)
 # PostgreSQLに接続するためのPythonドライバ(Render
dj-database-url
 # 環境変数のDATABASE_URLからDjangoのDATABASES設定を自動生成する便利ライブラリ
python-dotenv(★)
 # .env ファイルを読み込み、環境変数として使えるようにするライブラリ
django-cors-headers(★)
  # 他のドメイン(フロントエンド)から Django API にリクエストが来たとき、それを許可するための「CORS設定」
djangorestframework(★)
 # API通信を行うために必要
補足情報

whitenoise

whitenoiseは、Django 自身に静的ファイルを配信させる役割。
・RenderなどのPaaSでは、Nginx などの静的ファイルサーバーが使えないことが多いため、whitenoiseが便利。
・フロントエンド側のみで静的配信 → Vercelが担当(OK)
・Django 側の静的配信(管理画面など)→ whitenoise が必要(Render)

準備2 ALLOWED_HOSTSの設定
settings.pyのALLWED_HOSTSへ追加(.env.developmentで定義しているALLOWED_HOSTSが読み込まれる)
import os
from dotenv import load_dotenv
load_dotenv()
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "localhost").split(",")
.env.development
ALLOWED_HOSTS=localhost,127.0.0.1
.env.production
ALLOWED_HOSTS=<app_name>.onrender.com
準備2 CORS(ドメイン間の通信)の設定
設定1 settings.pyのINSTALLED_APPSの追加
settings.pyのINSTALLED_APPSの追加
INSTALLED_APPS = [
    'corsheaders', # INSTALLED_APPSの一番上に追加
]
設定2 settings.pyのMIDDLEWAREの追加
settings.pyのMIDDLEWAREに以下が追加されていることを確認
MIDDLEWARE = [
    # ...
    'corsheaders.middleware.CorsMiddleware',
    # ...
]
設定3 settings.pyにCROSの設定を追加
settings.py(後程、フロントエンドをVercelへデプロイした際に、URLが発行される。それを埋め込むための枠の記述を行う)
import os
from dotenv import load_dotenv # .envファイルを読み込むための記述

DEBUG = os.getenv('DEBUG', 'False') == 'True' # .env ファイルの DEBUG=TrueかFalseによって開発環境を判定

ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "localhost").split(",")

#  DEBUG が True(開発環境)なら、CORS_ALLOW_ALL_ORIGINS を True にする。
if DEBUG:
    CORS_ALLOW_ALL_ORIGINS = True # CORS_ALLOW_ALL_ORIGINSはDjango の django-cors-headersライブラリによって定義されている公式の設定項目(キーワード)である。キーワードをTureにすることで全てのオリジンからの通信を許可する
# そうでなければ、else 以下で CORS_ALLOW_ALL_ORIGINS = False にする。
else:
    CORS_ALLOW_ALL_ORIGINS = False
    CORS_ALLOWED_ORIGINS = [ 
        "https://<app-name>.vercel.app", # どのURLからのアクセスを許可するのか
     ]

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = [ # クロスオリジンリクエストでブラウザが送信して良いと許可されているHTTPヘッダーの一覧
    'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt','origin', 'user-agent', 'x-csrftoken', 'x-requested-with', 'cache-control', 'pragma',
]
CORS_ALLOW_METHODS = ['DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT'] # クロスオリジンリクエストで許可されるHTTPメソッド(操作)の一覧。

CORS_PREFLIGHT_MAX_AGE = 86400 # ブラウザのプリフライトリクエスト(事前確認リクエスト)の結果を、キャッシュしてよい秒数

# CSRFトークンの設定
CSRF_TRUSTED_ORIGINS = [
    "https://<app-name>.vercel.app", # CSRF保護で「信頼できるオリジン(ドメイン)」として認めるリスト。ここにないオリジンからのPOSTリクエストなどは拒否される。
]
準備4 Backendディレクトリ内にDockerfileを作成
backend/Dockerfile
FROM python:3.11-slim

WORKDIR /app

# システムパッケージをインストール
RUN apt-get update && apt-get install -y \
  gcc \
  postgresql-client \
  && rm -rf /var/lib/apt/lists/*

# 依存関係をインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションファイルをコピー
COPY . .

# 環境変数
ENV PYTHONUNBUFFERED=1
ENV PORT=10000

# 起動時にmigrationとサーバー起動を実行
CMD python manage.py makemigrations --noinput; \
  python manage.py migrate --noinput; \
  python manage.py collectstatic --noinput; \
  exec gunicorn --bind 0.0.0.0:$PORT --workers 2 --timeout 120 health_buddy.wsgi:application

準備5 静的ファイル設定(任意)
settings.py(Djangoで画像などを用いている場合)
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')  # ここに collectstatic で集める
settings.py(whitenoiseを使用する場合)
MIDDLEWARE = [
    'whitenoise.middleware.WhiteNoiseMiddleware',  # ←この行を追加
    ...
]
準備6 GitHubへPush(mainブランチへ)
RenderとGitHubの連携を行う際に連携するブランチへプッシュしておく
$ git add .
$ git commit -m "Renderデプロイ準備"
$ git push

【Render】ログイン

ログイン

https://render.com/


Get Standerd for Free>をクリックして持っているアカウントでログインする

【Render】サービス作成

サービス作成


Create a New Service画面で「New Web Service」をクリックする

【Render】GitHub連携

GitHubを連携(図)


Configure画面にてGitHubと連携する設定画面を開き連携するリポジトリを選択する

【Render】設定

設定


Renderの設定画面(どのブランチに接続するかや連携後にどのディレクトリでコマンドを実行するかを指定する

設定について
  • Language:
     Python 3(Djangoであるため)
  • Branch:
     main (GitHubのmainブランチを連携する)
  • Region:
     Singapore (Southeast Asia) (日本から近い)
  • Root Directory:
     backend (requirements.txtやmanage.pyがあるディレクトリ)
  • Instance Type:
     Free プラン

【Render】データベース作成

データベース作成


RenderのNewからPostgresを選択しデータベースを作成していく

入力項目について
    1. Name
      読みやすくプロジェクトと連携しやすい名前にする
    1. Project
      ✅「Create a new project」にチェックを入れて、プロジェクト名を入力
      後でバックエンドもこのプロジェクトに紐付けると管理がしやすくなります。
    1. Database
      未入力可。(自動でDB名が生成されます)
    1. User
      任意のユーザー名(未入力でもOK、自動生成される)
    1. Region
      Singapore (Southeast Asia)
    1. PostgreSQL Version
      16
    1. Datadog API Key(Optional)
      Datadog にメトリクス(CPU使用率、接続数、クエリ時間など)を送信するための。
      Datadog アカウントを持っていて、監視を有効にしたい場合だけ入力します。
    1. Datadog Region(Optional)
      Datadog にデータを送信する際のリージョン。デフォルトはUS1(アメリカ)。
    1. Plan Options
      必要に応じたものを選択。まずは無料で作成し、いずれ上位に切り替え可能。
データベースの作成を確認


Statusがavailableになっていることを確認する

【Render】データベースの環境変数の設定

データベースの環境変数を確認


Connectionsの内容を確認しておく

.envファイルに環境変数を反映する
.env.productionにRenderで作成したDBのConnectionsの内容を記述する
ENVIRONMENT=production
DEBUG=False
SECRET_KEY=<your_secret_key>
# DATABASE
DATABASE_NAME=<your_db_name>
DATABASE_USER=<your_db_user_name>
DATABASE_PASSWORD=<your_db_password>
DATABASE_HOST=<your_db_host>
DATABASE_PORT=5432
DATABASE_URL=<your_db_url>
ALLOWED_HOSTS=<Renderで作成されたURL>
settings.pyのDATABASE周りの設定
settings.pyの設定
import os
from pathlib import Path
from datetime import timedelta
from dotenv import load_dotenv
from django.core.management.utils import get_random_secret_key

BASE_DIR = Path(__file__).resolve().parent.parent

# .envファイルを最初に読み込み
load_dotenv()

# 環境変数ENVIRONMENTで環境判定(production or development)
ENVIRONMENT = os.getenv('ENVIRONMENT', 'development').lower()

# SECRET_KEYの設定
SECRET_KEY = os.getenv('SECRET_KEY')
if not SECRET_KEY:
    if ENVIRONMENT == 'production':
        raise ValueError("SECRET_KEY must be set in production environment.")
    else:
        SECRET_KEY = get_random_secret_key()
        print("Warning: Using auto-generated SECRET_KEY for development")

# DEBUG設定
if ENVIRONMENT == 'production':
    DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
else:
    DEBUG = os.getenv('DEBUG', 'True').lower() == 'true'

# ALLOWED_HOSTS設定
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "localhost").split(",")

# データベース設定
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DATABASE_NAME', 'health_buddy_dev'),
        'USER': os.getenv('DATABASE_USER', 'default_user'),
        'PASSWORD': os.getenv('DATABASE_PASSWORD', ''),
        'HOST': os.getenv('DATABASE_HOST', 'db'),
        'PORT': os.getenv('DATABASE_PORT', '5432'),
    }
}

【Render】DBの環境変数をRenderの環境変数にも設定

Renderの環境変数にも設定する


DBを作成した際の環境変数をそれぞれ登録していく

【Render】デプロイ

デプロイ



Create Deployをクリックしてデプロイを開始する

【Vercel準備】Frontend側

準備1 Frontend/vercel.jsonの作成
プロジェクトルート(Frontendのルートディレクトリへ配置)
{
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/index.html"
    }
  ]
}
準備2 npm run buildの実行
frontendディレクトリにて以下を実行してdistディレクトリを作成
npm run build
準備3 URLの設定


RenderのEnviromentにVercelで作成したURLをALLOW_HOSTSとして登録する


.envファイルをFrontend内にも作成しURLを記載する

準備4 GitHubへPush(mainブランチへ)
GitHubの連携を行う際に連携するブランチへプッシュしておく
$ git add .
$ git commit -m "Vercelデプロイ準備"
$ git push

【Vercel】ログイン

Vercelにログインする

https://vercel.com/

Start Deployingをクリックする

【Vercel】GitHub連携

GitHub連携


GitHubのアイコンを押してそこから連携を行う

【Vercel】設定

設定


上記のようにリポジトリとデプロイ時の設定を行う

【Vercel】RenderのURLをVercelに登録する

URLの登録


Render(Backend)作成時のURLをVercel(Frontend)のEnviroment Variableに登録する

【確認】VercelのダッシュボードからURLにアクセス

DmainsのURLの一番上をクリックすることでアクセスが可能

Discussion