本番デプロイ用設定ファイルを追加
- backend/Dockerfile.prod: gunicorn で起動する本番用 Dockerfile - frontend/Dockerfile.prod: マルチステージビルドの本番用 Dockerfile - docker-compose.prod.yml: Traefik 連携・本番用 compose 設定 - main.keinafarm.net でフロントエンド・バックエンドを公開 - /api/ はバックエンド(priority=10)、それ以外はフロントエンド(priority=5) - .env.production.example: 本番環境変数のサンプル - settings.py: ALLOWED_HOSTS・CORS_ALLOWED_ORIGINS を環境変数から設定可能に Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
7
.env.production.example
Normal file
7
.env.production.example
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# 本番環境用の環境変数サンプル
|
||||||
|
# サーバー上で .env.production としてコピーして値を設定してください
|
||||||
|
# このファイル自体は git にコミットして OK(値は入れない)
|
||||||
|
|
||||||
|
DB_PASSWORD=ここにDBパスワードを設定
|
||||||
|
SECRET_KEY=ここにDjangoのSECRET_KEYを設定(50文字以上のランダム文字列)
|
||||||
|
MAIL_API_KEY=ここにWindmillとの連携用APIキーを設定
|
||||||
31
backend/Dockerfile.prod
Normal file
31
backend/Dockerfile.prod
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
gcc \
|
||||||
|
g++ \
|
||||||
|
postgresql-client \
|
||||||
|
libpq-dev \
|
||||||
|
libgdal-dev \
|
||||||
|
libgeos-dev \
|
||||||
|
libproj-dev \
|
||||||
|
fonts-noto-cjk \
|
||||||
|
libgirepository1.0-dev \
|
||||||
|
libcairo2 \
|
||||||
|
libpango-1.0-0 \
|
||||||
|
libpangocairo-1.0-0 \
|
||||||
|
gir1.2-pango-1.0 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
ENV CPLUS_INCLUDE_PATH=/usr/include/gdal
|
||||||
|
ENV C_INCLUDE_PATH=/usr/include/gdal
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["gunicorn", "keinasystem.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "2", "--timeout", "120"]
|
||||||
@@ -20,7 +20,8 @@ SECRET_KEY = os.environ.get('SECRET_KEY', 'django-insecure-default-key')
|
|||||||
|
|
||||||
DEBUG = os.environ.get('DEBUG', 'True') == 'True'
|
DEBUG = os.environ.get('DEBUG', 'True') == 'True'
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['*']
|
_allowed_hosts = os.environ.get('ALLOWED_HOSTS', '*')
|
||||||
|
ALLOWED_HOSTS = [h.strip() for h in _allowed_hosts.split(',')]
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
@@ -145,12 +146,16 @@ SIMPLE_JWT = {
|
|||||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
||||||
}
|
}
|
||||||
|
|
||||||
CORS_ALLOWED_ORIGINS = [
|
_cors_origins = os.environ.get('CORS_ALLOWED_ORIGINS', '')
|
||||||
"http://localhost:3000",
|
if _cors_origins:
|
||||||
"http://127.0.0.1:3000",
|
CORS_ALLOWED_ORIGINS = [o.strip() for o in _cors_origins.split(',')]
|
||||||
"http://localhost:3001",
|
else:
|
||||||
"http://127.0.0.1:3001",
|
CORS_ALLOWED_ORIGINS = [
|
||||||
]
|
"http://localhost:3000",
|
||||||
|
"http://127.0.0.1:3000",
|
||||||
|
"http://localhost:3001",
|
||||||
|
"http://127.0.0.1:3001",
|
||||||
|
]
|
||||||
|
|
||||||
# メールフィルタリング機能
|
# メールフィルタリング機能
|
||||||
MAIL_API_KEY = os.environ.get('MAIL_API_KEY', '')
|
MAIL_API_KEY = os.environ.get('MAIL_API_KEY', '')
|
||||||
|
|||||||
83
docker-compose.prod.yml
Normal file
83
docker-compose.prod.yml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik-net:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgis/postgis:16-3.4
|
||||||
|
container_name: keinasystem_db
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: keinasystem
|
||||||
|
POSTGRES_USER: keinasystem
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U keinasystem -d keinasystem"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile.prod
|
||||||
|
container_name: keinasystem_backend
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
DB_NAME: keinasystem
|
||||||
|
DB_USER: keinasystem
|
||||||
|
DB_PASSWORD: ${DB_PASSWORD}
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 5432
|
||||||
|
SECRET_KEY: ${SECRET_KEY}
|
||||||
|
DEBUG: "False"
|
||||||
|
ALLOWED_HOSTS: main.keinafarm.net
|
||||||
|
CORS_ALLOWED_ORIGINS: https://main.keinafarm.net
|
||||||
|
MAIL_API_KEY: ${MAIL_API_KEY}
|
||||||
|
FRONTEND_URL: https://main.keinafarm.net
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- traefik-net
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.keinasystem-api.rule=Host(`main.keinafarm.net`) && PathPrefix(`/api/`)"
|
||||||
|
- "traefik.http.routers.keinasystem-api.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.keinasystem-api.tls=true"
|
||||||
|
- "traefik.http.routers.keinasystem-api.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.routers.keinasystem-api.priority=10"
|
||||||
|
- "traefik.http.services.keinasystem-api.loadbalancer.server.port=8000"
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ./frontend
|
||||||
|
dockerfile: Dockerfile.prod
|
||||||
|
args:
|
||||||
|
NEXT_PUBLIC_API_URL: https://main.keinafarm.net
|
||||||
|
container_name: keinasystem_frontend
|
||||||
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
networks:
|
||||||
|
- traefik-net
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.keinasystem.rule=Host(`main.keinafarm.net`)"
|
||||||
|
- "traefik.http.routers.keinasystem.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.keinasystem.tls=true"
|
||||||
|
- "traefik.http.routers.keinasystem.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.routers.keinasystem.priority=5"
|
||||||
|
- "traefik.http.services.keinasystem.loadbalancer.server.port=3000"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
28
frontend/Dockerfile.prod
Normal file
28
frontend/Dockerfile.prod
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
FROM node:20-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# NEXT_PUBLIC_API_URL はビルド時に埋め込まれる
|
||||||
|
ARG NEXT_PUBLIC_API_URL=https://main.keinafarm.net
|
||||||
|
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# --- 実行ステージ ---
|
||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=builder /app/package*.json ./
|
||||||
|
COPY --from=builder /app/.next ./.next
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD ["npm", "start"]
|
||||||
Reference in New Issue
Block a user