作成:2023年3月27日
前回までで、GoのAPIサーバー(GET,POST,PATCH,DELETE)とReactのAPIクライアント(GETのみ)を試作しました。今回はこれをDockerに載せてみたいと思います。
練習で新規ReactアプリをDockerへ載せてみる
Reactアプリをローカルで作成
% npx create-react-app docker-react20230325
App.jsをサンプルコードで更新します。
import React, { useState, useEffect } from "react";
const INITIAL_COUNT = 0;
const SampleComponent = () => {
const [count, setCount] = useState(INITIAL_COUNT);
const callbackFunction = () => {
document.title = `${count} 回クリックされました`;
}
useEffect(callbackFunction, [count]);
const countIncrement = () => {
setCount((prevCount) => prevCount + 1);
};
const countReset = () => {
setCount(INITIAL_COUNT);
};
return (
<div className="App">
<p>現在のカウント数:{count}</p>
<button onClick={countIncrement}>+1 ボタン</button>
<button onClick={countReset}>リセット</button>
</div>
);
};
export default function App() {
return <SampleComponent />;
}
試しにローカルで実行します。
% yarn install
% yarn start
Dockerfileを作成
docker-react20230325フォルダの直下に Dockerfile を作成します。
# ベースイメージの作成
FROM node:latest
# コンテナ内で作業するディレクトリを指定
WORKDIR /usr/src/app
# package.jsonとyarn.lockを/usr/src/appにコピー
COPY ["package.json", "yarn.lock", "./"]
# パッケージをインストール
RUN yarn install
# ファイルを全部作業用ディレクトリにコピー
COPY . .
# コンテナを起動する際に実行されるコマンド
ENTRYPOINT [ "yarn", "start" ]
イメージをビルド
% docker build -t test20230325:1.0 .
作成したイメージを確認します。
% docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
test20230325 1.0 4c6f98c9577a 35 seconds ago 1.46GB
コンテナを起動
% docker run -dit --name sample20230325 -p 3000:3000 test20230325:1.0
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
991a053dc232 test20230325:1.0 "yarn start" 8 seconds ago Up 6 seconds 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp sample20230325
AWS上 の Docker で起動してみます
イメージをファイル化します。
% docker save -o test20230325.tar test20230325:1.0
ファイル化したイメージを EC2 にファイル転送
% scp -i ~/.aws/docker20230223.pem ./test20230325.tar ubuntu@54.168.241.85:/home/ubuntu
EC2 で docker load する
$ docker load -i test20230325.tar
イメージが利用できることを確認して、実行します。ポートは8082を使ってみます。
% docker image ls
% docker run -dit --name sample20230325 -p 8082:3000 test20230325:1.0
EC2上の Docker で React を実行できました。
Go の APIサーバーを Docker で実行
ローカルの Docker で実行
コードの改修
Docker ではうまく動作しなかったので、103〜104行(Githubのコード)を更新しました。
Dockerfileを作成
go-api の直下に Dockerfile を作成します。
# https://hub.docker.com/_/golang
FROM golang:1.18.1-alpine
WORKDIR /app
# main.go と go.mod と go.sum を /app にコピー
COPY ["main.go", "go.mod", "go.sum", "./"]
# パッケージをインストール
RUN go build
# コンテナを起動する際に実行されるコマンド
CMD ["go", "run", "main.go"]
イメージをビルド
% docker build -t go_test20230326:1.0 .
作成したイメージを確認します。
% docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
go_test20230326 1.0 3d7a9e08b500 17 seconds ago 329MB
コンテナを起動
% docker run -it --name go_api -p 8080:8080 go_test20230326:1.0
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3eaec32c28f0 go_test20230326:1.0 "go run main.go" 5 seconds ago Up 3 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp go_api
Go の APIサーバーを EC2上の Docker で実行
イメージをファイル化します。
% docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
go_test20230326 1.0 f4b523363243 15 minutes ago 501MB
% docker save -o go_test20230326.tar go_test20230326:1.0
ファイル化したイメージを EC2 にファイル転送します。
% scp -i ~/.aws/docker20230223.pem ./go_test20230326.tar ubuntu@13.115.30.209:/home/ubuntu
EC2 で docker load します
$ docker load -i go_test20230326.tar
イメージが利用できることを確認して、実行します。ポートは8080を使ってみます。
$ docker image ls
$ docker run -it --name go-api -p 8080:8080 go_test20230326:1.0
Postman で、EC2 上の Docker の Go API からデータを取得できました。
Docker network の中で通信
ローカルの Docker で GoのAPIサーバー のコンテナ立てて、別のコンテナからリクエスト
ネットワーク apinet に GoのAPIサーバーのコンテナを立てる
% docker network create apinet
% docker run -it --name go-api --net apinet go-api20230326:1.0
APIリクエストするためのコンテナを立てます
% docker run -rm -it --net apinet ubuntu /bin/bash
コンテナの中で各種ソフトインストールと、APIリクエストして確認します
# apt update
# apt -y upgrade
# apt install -y iproute2 iputils-ping curl
# ping -c 4 go-api
# curl http://go-api:8080/health_data
[
{
"id": 1,
"month": 1,
"day": 1,
"weight": 55.5
},
{
"id": 2,
"month": 1,
"day": 2,
"weight": 66.6
},
{
"id": 3,
"month": 1,
"day": 3,
"weight": 77.7
}
ローカルのDocker上に、GoのAPIサーバーとReactのAPIクライアントのコンテナを立てます
Reactプログラムはローカルのブラウザに読み込まれて実行されて、「ローカルのブラウザ」から「ローカルのDocker上のGoのAPIサーバー」に
リクエストされます。
Githubのコード置き場のリンクです。
ネットワーク apinet を作ります。今回は直接使いませんが、将来のDB接続で使用予定です。
% docker network create apinet
GoのAPIサーバーのコンテナ立てます
% pwd
/***/go-api
% docker build -t go-api20230327:1.0 .
% docker run -it --name go-api --net apinet -p 8080:8080 go-api20230327:1.0
ReactのAPIクライアントのコンテナ立てます
% pwd
/***/react
% docker build -t react-api20230327:1.0 .
% docker run -it --name react-api --net apinet -p 3000:3000 react-api20230327:1.0
AWS EC2上のDockerに、GoのAPIサーバーとReactのAPIクライアントを立てます
ReactのコードにEC2のIPアドレスを反映
const response = await axios.get("http://54.199.172.102:8080/health_data");
GoのコードにEC2のIPアドレスを反映
config.AllowOrigins = []string{"http://54.199.172.102:3000"}
イメージをファイル化してEC2にコピー
% docker build -t react-api20230327a:1.0 .
% docker build -t go-api20230327a:1.0 .
% docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
react-api20230327a 1.0 873f12e8926c 2 hours ago 1.52GB
go-api20230327a 1.0 086fb0816a7c 17 hours ago 501MB
% docker save -o react-api20230327a.tar react-api20230327a:1.0
% docker save -o go-api20230327a.tar go-api20230327a:1.0
% scp -i ~/.aws/docker20230223.pem ./react-api20230327a.tar ubuntu@54.199.172.102:/home/ubuntu
% scp -i ~/.aws/docker20230223.pem ./go-api20230327a.tar ubuntu@54.199.172.102:/home/ubuntu
EC2 で docker load
$ docker load -i react-api20230327a.tar
$ docker load -i go-api20270327a.tar
EC2 でポート3000を開けておきます
EC2 でコンテナ立てます(GoのAPIサーバーとReactのAPIクライアント)
ReactのAPIクライアントにポートは3000を使用します。
$ docker network create apinet
$ docker run -it --name go-api --net apinet -p 8080:8080 go-api20230327:1.0
$ docker run -it --name react-api --net apinet -p 3000:3000 react-api20230327a:1.0
EC2 の Docker上のReactにアクセスして、EC2 の Docker上のGoのAPIサーバーからGETできました
参考
・DockerでReactの開発環境を作る
・SCP】AWSのEC2にファイル転送する
・UbuntuサーバーにNginxをインストールしよう
・EC2でReactをhttpsでnpm startして外部からアクセスする
・Docker 入門 | golang & gin の環境構築