Go言語+React Native+Python+Dockerの環境構築(ホットリロード対応)
Go言語とReactの環境構築がスムーズにできるようになりました。
調子に乗っているので、AIとかも入れちゃおうとしてPythonを導入しました。
そして、以前は断念したReact Native+Dockerに再挑戦します。
ディレクトリ構成
ディレクトリ構成はこちらです。
Laravelをやっている都合上、フロントエンドはバックエンドの次に来て欲しいという思いでフォルダを作ってます。
.
├── ai/
│ ├── ## Python
│ ├── Dockerfile
│ ├── main.py
│ └── requirements.txt
├── backend/
│ ├── ## Go言語
│ ├── Dockerfile
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── mobile/
│ ├── ## React Native
│ ├── .dockerignore
│ └── Dockerfile
├── .env
└── docker-compose.yml
Go言語のDocker環境構築
Go言語に関しては前回と変わらずなのでリンク貼ります。
今回はdocker-compose.ymlに.envを使ったという微進歩です。
PythonのDocker環境構築
Pythonは最近の環境構築で最もスムーズに行きました。
フレームワークはfastapiを使用しました。
requirements.txtを使って必要なものをインストールするみたいです。
fastapi
uvicorn
numpy
pandas
Dockerfileの記述はとてもシンプルになりました。
FROM python:3.9
WORKDIR /app/ai
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
詳しいことはこれから勉強しますが、main.pyはちゃんと動いていたので成功と判断してます。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello from FastAPI!"}
React NativeのDocker環境構築
ここが難所でした。
以前もモバイルアプリを作ろうとして挫折し、結局Docker使わずにやってました。
しかし、今回はwebもios版もexpo Goを使って環境構築できたの紹介します。
Dockerfileはとてもシンプルです。
最後のCMDはnpx expo startにしておくとQRもポートも表示されたので良きでした。
# Node.js の公式イメージを使用
FROM node:20
# 作業ディレクトリ
WORKDIR /app/mobile
# 依存関係をインストール
COPY package.json package-lock.json ./
RUN npm install
# ソースコードをコピー
COPY . .
# 開発サーバーを起動
CMD ["npx", "expo", "start"]
docker-compose.ymlの中身
version: '3.8'
services:
backend:
build: ./backend
container_name: backend-go
image: backend-go
ports:
- "8080:8080"
depends_on:
db:
condition: service_healthy
environment:
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
volumes:
- ./backend:/app/backend
command: air
frontend:
build: ./mobile
container_name: frontend-react
image: frontend-react
ports:
- "8081:8081"
- "19000:19000" # Expo Go 用
- "19001:19001" # Metro Bundler
- "19002:19002" # Metro Debugger
volumes:
- ./mobile:/app/mobile
- /app/mobile/node_modules # ホットリロードするために必要でした
environment:
- EXPO_DEVTOOLS_LISTEN_ADDRESS=${EXPO_DEVTOOLS_LISTEN_ADDRESS}
- REACT_NATIVE_PACKAGER_HOSTNAME=${LOCAL_IP_ADDRESS}
command: npx expo start
stdin_open: true
tty: true
ai:
build: ./ai
container_name: ai-python
image: ai-python
ports:
- "${AI_PORT}:${AI_PORT}"
volumes:
- ./ai:/app/ai
command: uvicorn main:app --host ${EXPO_DEVTOOLS_LISTEN_ADDRESS} --port ${AI_PORT} --reload
db:
image: postgres:15
container_name: db-posgres
ports:
- "${DB_PORT}:${DB_PORT}"
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 5s
timeout: 3s
retries: 5
volumes:
db_data:
backendに関しては、Go言語の環境構築を参考にしてください。
何をしているかをざっくり箇条書きします。
・ポート:8080
・ホットリロード:command air
・DBの接続テスト用にenvironmentとconditionを設定
frontendはreact nativeの設定です。
ports:
- "8081:8081"
- "19000:19000" # Expo Go 用
- "19001:19001" # Metro Bundler
- "19002:19002" # Metro Debugger
ここは初期値に設定してます。
明示的にすることで他と競合しないようにします。
これはexpo goとDockerを使うために必要な設定です。
environment:
- EXPO_DEVTOOLS_LISTEN_ADDRESS=${EXPO_DEVTOOLS_LISTEN_ADDRESS}
- REACT_NATIVE_PACKAGER_HOSTNAME=${LOCAL_IP_ADDRESS}
command: npx expo start
${LOCAL_IP_ADDRESS}この中に自分のIPアドレスを入れるのがポイントでした。
REACT_NATIVE_PACKAGER_HOSTNAME=${LOCAL_IP_ADDRESS}
IPはipconfig(Windows)または ipconfig getifaddr en0(Mac)で調べてください。
こちらはDockerコンテナ内でnpx expo startをするときにはいるような記述があったので入れました。
stdin_open: true
tty: true
ちなみに、web版もexpo goも立ち上げるのに時間がかかるので少し待つようにしてください。
補足
ファイルを追記しました。
ビルド速度が遅すぎたので.dockerignoreファイルを作りました。
# .dockerignoreファイルを作成
node_modules
余談 react-nativeのapp配下のディクトリ構成
気にする必要はないと思いますが念のため載せておきます。
frontend
app
(tabs)
_layout.tsx
+not-found.tsx
## Reactを追加予定
docker-compose.yml
初期設定です。
Discussion