👺

Go言語+React Native+Python+Dockerの環境構築(ホットリロード対応)

2025/02/23に公開

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を使ったという微進歩です。

https://zenn.dev/shuji0425/articles/69e8bcd04be429

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