Dockerを思い出す②
今回の目的
DockerコンテナのIPアドレスをローカルPCのIPアドレスに変換する。
そうするとスマホ端末とDockerコンテナが同じネットワーク、ということになる。
参考サイト:ExpoをDocker上で動かしたい! | React Native+Expo+Docker – Zenn
127.0.0.1というのは「自分宛てのIPアドレス」という意味だそうです。今こうなっているのが問題です。
(「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典より)
ちなみに、本当にネットワークの問題なのか?ということを確かめるために一旦ローカルPCにEXPOをインストールしてQRコードを読み取ると問題なく初期画面が表示されました。IPアドレスも192.~~だったのでやはりネットワーク関連の問題なんだな〜と言うことを実感しました。
192.168.2.104って何?
192.168.2.104 は、ローカルやプライベートネットワークなどの特殊な用途のために予約されている IP アドレスです。一般的に公開インターネットには表示されません。
AIが見つけてくれた記事
10.X.X.X、172.X.X.X、192.168.X.XはプライベートIPアドレスといって、IPアドレス枯渇問題に対応したもので、「それぞれの会社や家のLAN内では同じIP使っても問題ないよね」というものだそうです。
(@ITネットワーク用語辞典より)
手段
- .envファイルに環境変数
REACT_NATIVE_PACKAGER_HOSTNAME
を使ってローカルPCのIPアドレスを設定する。 - docker-compose up時に読み込ませる
Docker Composeって何?
Compose とは、複数のコンテナを定義し実行する Docker アプリケーションのためのツールです。Compose は YAML ファイルを使い、アプリケーションのサービスを設定します。コマンドを1つ実行するだけで、設定内容に基づいた全てのサービスを生成・起動します。
Compose を使うには、基本的に3つのステップを踏みます。
Docker Compose 概要 – Docker公式
- アプリケーションの環境を
Dockerfile
に定義すると、アプリケーションはどこでも再構築できるようになります。- アプリケーションを構成するサービスを
docker-compose.yml
ファイル内に定義すると、各サービスは 独立した 環境で同時に実行できるようになります。docker compose up
を実行すると、この Docker compose コマンド によって、アプリ全体を起動・実行します。あるいは、 docker-compose バイナリを使えば、docker-compose up
でも実行できます。
Docker Composeとは複数のコンテナを実行するためのもので、下準備としてDockerfile
(Dockerイメージを設定するファイル)とdocker-compose.yml
(複数のDockerFileを束ねるファイル) が必要ということらしいです。
docker-compose.ymlにREACT_NATIVE_PACKAGER_HOSTNAMEを設定
environment:
- REACT_NATIVE_PACKAGER_HOSTNAME=${LOCAL_IP_ADDR}
.envにLOCAL_IP_ADDRを設定(直書きしたくない情報をここに書く)
LOCAL_IP_ADDR=192.168.2.104
get-local-ip-addr.sh(Macの仕様でコロコロ変わるIPアドレスを取得して.envに書き直すスクリプトだそうです)
#!/bin/bash
IP=`ifconfig | grep inet | cut -d " " -f2 | grep "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | awk 'NR==2'`
sed -i".bak" -e "/LOCAL_IP_ADDR=/d" .env
echo "LOCAL_IP_ADDR=$IP" >> .env
ここまで準備したものをMakefile(自作のコマンド)で使います。
expo_sample:
chmod +x ./get-local-ip-addr.sh
./get-local-ip-addr.sh
docker-compose up -d
docker-compose exec expo_sample bash --login
1行目:shファイルの実行権限を与えて、
2行目:shファイルを実行して(IPアドレスが.envに書き込まれる)、
3行目:docker-compose.ymlに書いてある通りにコンテナを起動して、
4行目:Dockerコンテナに接続します。
この一連の流れが自作した「make expo_sample」コマンドで実行されます。
「docker ps」でコンテナが起動しているか確認します。
設定通りに起動しました!
Expoをインストールします。
root@900d093c60e4:/# node --version
v20.18.0
root@900d093c60e4:/# npx create-expo-app@latest quiz
Need to install the following packages:
create-expo-app@3.0.0
Ok to proceed? (y) y
✔ Downloaded and extracted project files.
作られたプロジェクトフォルダに移動して、中身を確認します。色々作られています。
root@900d093c60e4:/# cd quiz
root@900d093c60e4:/quiz# ls -la
total 828
drwxr-xr-x 9 root root 4096 Oct 17 07:52 .
drwxr-xr-x 1 root root 4096 Oct 17 07:51 ..
-rw-r--r-- 1 root root 119 Oct 17 07:51 .gitignore
-rw-r--r-- 1 root root 1742 Oct 26 1985 README.md
drwxr-xr-x 3 root root 4096 Oct 17 07:51 app
-rw-r--r-- 1 root root 773 Oct 17 07:51 app.json
drwxr-xr-x 4 root root 4096 Oct 17 07:51 assets
-rw-r--r-- 1 root root 108 Oct 26 1985 babel.config.js
drwxr-xr-x 4 root root 4096 Oct 17 07:51 components
drwxr-xr-x 2 root root 4096 Oct 17 07:51 constants
drwxr-xr-x 2 root root 4096 Oct 17 07:51 hooks
drwxr-xr-x 743 root root 28672 Oct 17 07:52 node_modules
-rw-r--r-- 1 root root 754569 Oct 17 07:52 package-lock.json
-rw-r--r-- 1 root root 1353 Oct 17 07:51 package.json
drwxr-xr-x 2 root root 4096 Oct 17 07:51 scripts
-rw-r--r-- 1 root root 242 Oct 26 1985 tsconfig.json
「npx expo start」すると、、
IPアドレスがPCと同じになりました!
スマホとPCのIPアドレスが違う問題
早速QRコードを読み込んでみたのですが、同じ接続エラーが出てしまいました。
調べてみると、iPhone側もセキュリティ重視でランダムにIPアドレスを割り振るようです。
iPhone:192.168.1.2
PC:192.168.1.6
なのでiPhone側で手動で設定します。
IPアドレス揃えても接続出来ず
PCのIPアドレスと揃えたのにタイムアウトしてしまいました…。
アプリの設定を見てローカルネットワーク権限許可してる事も確認済みです。
なんでだ…
解決
Expoが使うポートが変わった
「8081 ポート 19000」で検索して出てきました。
「Expo CLI now defaults to port 8081 for all projects, rather than 19000.」
(Expo CLI は、すべてのプロジェクトでデフォルトのポート 19000 ではなく 8081 を使用するようになりました。)
Expoキャッチアップ会 〜Expo SDK 49まとめ〜 (2023/09/05) – Zenn
なので、docker-compose.ymlを変更しました。
ports:
- "8081:8081"
これでPCで初期画面を表示することはできましたが、スマホでは出来ず、、
トンネル接続タイプ…でプロキシ URL…を介して接続する
Expo Clientがうまくいかない場合 – @hitotchさん
「初回ビルドが遅すぎてClient側が待てなくてタイムアウトすることもあります。。。
いろいろ試してダメな場合は、ConnectionでTunnelを選んでやり直してみてください。」
ということだったのですが、その設定をする画面を見つけられなかったので、
expo app がつながらなくなった – @minahow3さん を参考にすることにしました。
「トンネリングという方法を用いて、プロキシ URL を介して開発サーバーに接続する。」というのを実行しました。
# @expo/ngrokのインストール
npm i -g @expo/ngrok
# トンネルURLから開発サーバを起動
npx expo start --tunnel
これでついにスマホで見れるようになりました!
まとめ
プライベートネットワークで使われるIPアドレスがわかった
10.X.X.X、172.X.X.X、192.168.X.X
これらを見たら「外部と繋がってない、ここだけのネットワークなんだな」ということが分かりました。
Dockerfileとdocker-compose.yml
Dockerfileは必須ではない。自分でDockerイメージを作りたい時に使う。
docker-compose.ymlは、前に使った「docker run」コマンドの内容をファイルにまとめた感じ。
docker run こんなの↓
[LOCAL]$ docker run \
-it \
-p 13000:3000 \
-v /Users/hoge/workspaces/docker:/app \
--name node20.18-docker \
-w /app \
node:20.18-bullseye-slim