DockerでReact＋Mysql＋Go環境構築



# はじめに
Dockerで、go+react+mysqlで環境構築した際の作り方です！
以下がフォルダの全体図になります。

![全体図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525798/dc854d81-a341-f05e-bd5a-e899de7c170a.png)


# 作成手順

### 手順１. フォルダ作成

- projectフォルダの作成
    - `mkdir project`
- `project/backend`フォルダ、`project/frontend`フォルダを作成
    - `cd project`
    - `mkdir backend`
    - `mkdir frontend`

### 手順2. reactプロジェクトの作成

- reactプロジェクトの作成
    - `cd frontend`
```
#typescriptの場合
npx create-react-app react-app --template typescript
```
```
#jsvascriptの場合
npx create-react-app react-app
```
- もし上記でエラー（nodeがインストールされてない場合）は以下(power shellです)

```
#typescriptの場合
docker run --rm -v "${PWD}:/usr/src/app" -w /usr/src/app node:20-alpine npx create-react-app react-app --template typescript
```
```
#jsvascriptの場合
docker run --rm -v "${PWD}:/usr/src/app" -w /usr/src/app node:20-alpine npx create-react-app react-app
```

### 手順3. goプロジェクトの作成

- goプロジェクトの作成
    - `cd backend`
    - `go mod init github.com/ユーザー名/project/backend`
- もしgoがインストールされてない場合は以下(power shellです)

```
docker run --rm -v "${PWD}:/usr/src/myapp" -w /usr/src/myapp golang:1.21.5 go mod init github.com/ユーザー名/project/backend
```

- goは、モジュール名に一意の名前を指定する必要がある
    - `github.com/ユーザー名/goがある場所`が一般的

### 手順4. 各種ファイルの作成

- 以下を参考に、backend、frontend用の`Dockerfile`、`docker-compose.yml`、`variables.env`を作成

`project/backend/Dockerfile`

```docker
FROM golang:1.21.5

WORKDIR /go/src

COPY go* ./
RUN go mod download

COPY . .
```

`project/frontend/Dockerfile`

```docker
FROM node:20-alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

CMD [ "npm", "start" ]
```

`project/docker-compose.yml`

```yaml
version: "3.8"
services:
  db:
    image: mysql:8.0.27
    env_file:
      - variables.env
    ports:
      - 3306:3306
    volumes:
      - mysql_data:/var/lib/mysql

  backend:
    build:
      context: ./backend/
      dockerfile: Dockerfile
    volumes:
      - ./backend/:/go/src/
    ports:
      - "8080:8080"
    depends_on:
      - db
    tty: true
    stdin_open: true

  frontend:
    build:
      context: ./frontend/
      dockerfile: Dockerfile
    volumes:
      - ./frontend:/usr/src/app
    ports:
      - "3000:3000"
    tty: true
    stdin_open: true
volumes:
  mysql_data:
```

`project/variables.env`

```docker
MYSQL_USER=user
MYSQL_ROOT_PASSWORD=root_pass
MYSQL_PASSWORD=pass
MYSQL_DATABASE=detabase
```

### 手順5. ホットリロードを有効化

- `Package.json`に、以下を追加

```jsx
"scripts": {
	"start": "WATCHPACK_POLLING=true react-scripts start",
```

- 変更が即反映されるようになる

### 手順6. 動作確認

#### frontendのテスト

- `localhost:3000`にアクセスする

#### dbのテスト

- データベースコンテナに入る
    - `docker exec -it データベースコンテナ bash`
- mysqlのバージョン確認
    - `mysql --version`
- mysqlにログイン
    - `mysql mysql -u root -p`
    - `project/variables.env`の`root_pass`を入力してログイン

#### backendのテスト
- `project/backend/`に`main.go`を作成
``` go
package main

import "fmt"

func main() {
	fmt.Println("Hello World")
}
```

- バックグラウンドコンテナに入る
    - `docker exec -it コンテナ名 bash`
- 関数の実行
    - `go run main.go`

# この環境構築使いまわしたい
- 使いまわす場合、プロジェクト名とポート番号を変える必要があります。
- 手順1で、projectフォルダの作成`mkdir project`としましたが、ここを違うフォルダ名に変える必要があります。
- それに伴って、手順3の`go mod init github.com/ユーザー名/新しいプロジェクト名/backend`の変更
- `docker-compose.yml`のポート番号の左側
- 例）ports: 3306:3306　→　ports: 3305:3306

# おわりに
- nodeとかgoとか、ローカルに入れなくても`docker run --rm -v "${PWD}:/usr/src/app" -w /usr/src/app node:20-alpine npx create-react-app react-app --template typescript`これでできるって知らなかったのでびっくりしました！
- chatGPTが教えてくれました。goをローカルに入れてなかったので助かりました。