【React&Golang&MySql】Dockerで開発環境構築


dockerでReact&Golang&MySqlを使ったアプリケーション開発環境構築してみました。
<h2>リポジトリ</h2>
githubリポジトリは[こちら](https://github.com/atsugitakuya/react-go)です。

<h2>環境</h2>
とりあえず、以下の環境で動かしてます。
docker：19.03.8
docker-compose：1.25.4

<h2>Reactサーバー構築</h2>
まずはReact用意から。
とりあえず、Dockerfileとdocker-compose.yml作成する。
今回は、[こちらの記事](https://qiita.com/kerochelo/items/1063da8893026de5ebbf)を参考にしました。

```ruby:/docker/react/Dockerfile
FROM node:8.16.0-alpine  
WORKDIR /app/react
RUN npm install --save prop-types
RUN npm install -g create-react-app
```
```ruby:/docker-compose.yml
version: '3'
services:
  react:
    build:
      context: .
      dockerfile: ./docker/react/Dockerfile
    container_name: react_container
    tty: true
    volumes:
    - ./react-app:/app/react
    command: sh -c "cd /app/react  && yarn start"
    ports:
      - 3000:3000
```
Reactを動かす環境の準備はできたので、次にreactのアプリケーションを作成する。
ルートパス（docker-compose.ymlと同じ階層）で実行する。

```ruby:zsh
$docker-compose run --rm react sh -c 'create-react-app react-app'
....
Happy hacking!
```

アプリが作成されたら、docker-compose.ymlをビルド、実行する

```ruby:zsh
$docker-compose build
Successfully built 810a299d8ee1
Successfully tagged react-go_react:latest

$docker-compose up -d
Starting react-go_react... done
```
無事起動できたら、Reactの環境構築はこれでOK
念のため、[localhost:3000](http://...)にアクセスするして、画面が表示されることを確認
<img width="1364" alt="スクリーンショット 2020-05-10 15.17.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631619/9c9f6ed1-7075-b0c5-c1b8-5f4ec389ba47.png">

<h2>Golangサーバー構築</h2>

次にGolangを動かす。
Golang実行用のDockerfileし、先ほど作ったdocker-compose.ymlに設定を追記する

```ruby:/docker-compose.yml
version: '3'
services:
  react:
    build:
      context: .
      dockerfile: ./docker/react/Dockerfile
    container_name: react_container
    tty: true
    volumes:
    - ./react-app:/app/react
    command: sh -c "cd /app/react  && yarn start"
    ports:
      - 3000:3000
  # 以下、追記部分
  go:
    build:
      context: .
      dockerfile: ./docker/golang/Dockerfile
    container_name: go_container
    ports:
      - 8000:8000
    tty: true
```


```ruby:/docker/golang/Dockerfile
FROM golang:alpine
COPY ./go-app /app/go
WORKDIR /app/go
RUN go build -o main . 
CMD ["/app/go/main"]
```
main.goを作成
今回のものは、localhost:8000/にアクセスした時に「Hello World」を表示するだけのシンプルな物。

```ruby:/go-app/main.go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	// controller
	http.HandleFunc("/", echoHello)
	// port
	http.ListenAndServe(":8000", nil)
}

func echoHello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<h1>Hello World</h1>")
}

```

Golangの準備ができたので、docker-compose.ymlをbuildし、再起動する。

```ruby:zsh
$docker-compose build
Successfully built 810a299d8ee1
Successfully tagged react-go_react:latest
....
Successfully built 92ffa33f7dc5
Successfully tagged react-go_go:latest

$docker-compose restart
Restarting react_container ... done
Restarting go_container    ... done
```
localhost:8000にアクセスすると「Hello World」が表示されることを確認する。
<img width="1357" alt="スクリーンショット 2020-05-11 9.11.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631619/2a563066-8382-bd4f-54de-122045cadfd0.png">

<h2>NginxでWebサーバー構築し、React、Golangにパスする</h2>
いちいちポート指定して接続するわけにはいかないので、webサーバーとしてnginxを利用して
reactとgolangのアプリケーションそれぞれ以下のようなポートにパスする設定を行う。
【react】localhost→localhost:3000
【golang】localhost/api→localhost:8000

これを表現するnginxの設定ファイルを作成する

```ruby:/nginx/nginx.conf
worker_processes auto;

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;

    location /api/ {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_pass http://go:8000/;
    }

    location / {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_pass http://react:3000/;
    }
  }
}
```
docker-compose.ymlにnginxの設定を追記する。

```ruby:/docker-compose.yml
version: '3'
services:
  react:
    build:
      context: .
      dockerfile: ./docker/react/Dockerfile
    container_name: react_container
    tty: true
    volumes:
    - ./react-app:/app/react
    command: sh -c "cd /app/react  && yarn start"
    ports:
      - 3000:3000
  go:
    build:
      context: .
      dockerfile: ./docker/golang/Dockerfile
    container_name: go_container
    ports:
      - 8000:8000
    tty: true
  # 以下、追記部分
  nginx:
    image: nginx
    container_name: nginx_container
    ports:
      - 80:80
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
```
またまたビルドして再起動し、localhostとlocalhost/apiに接続して確認する
<img width="1363" alt="スクリーンショット 2020-05-11 9.56.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631619/7db6e8a3-d557-953c-a685-3234fc8f9e75.png">
<img width="1365" alt="スクリーンショット 2020-05-11 9.56.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631619/73533019-cf2b-e9a3-4afe-efb0e4a27955.png">

<h2>MySqlサーバー構築</h2>
MySqlサーバーと、確認用にphpmyadminサーバーも立ててみる。

Golangアプリからmysqlに繋げられるようにする.
MySqlのDockerfileと、configファイルを作成する

```ruby:/docker/mysql/Dockerfile
FROM mysql:8.0.16
```
```ruby:/docker/mysql/conf.d/my.cnf
[mysqld]
default_authentication_plugin= mysql_native_password
explicit-defaults-for-timestamp=1
general-log-file=/var/log/mysql/mysqld.log
```

次にdocker-compose.ymlにmysqlとphpmyadminの設定を追記する。

```ruby:/docker-compose.yml
version: '3'
services:
  react:
    build:
      context: .
      dockerfile: ./docker/react/Dockerfile
    container_name: react_container
    tty: true
    volumes:
    - ./react-app:/app/react
    command: sh -c "cd /app/react  && yarn start"
    ports:
      - 3000:3000
  go:
    build:
      context: .
      dockerfile: ./docker/golang/Dockerfile
    container_name: go_container
    ports:
      - 8000:8000
    tty: true
  nginx:
    image: nginx
    container_name: nginx_container
    ports:
      - 80:80
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
  #以下、追記
  mysql:
    build:
      context: .
      dockerfile: ./docker/mysql/Dockerfile
    container_name: mysql_container
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: react-go-app
      TZ: 'Asia/Tokyo'
    volumes:
      - ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d
      - ./docker/mysql/conf.d:/etc/mysql/conf.d
      - ./docker/mysql/mysql_data:/var/lib/mysql
    ports:
    - 3306:3306
    links:
      - go
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=root
      - PMA_PASSWORD=root
    links:
      - mysql
    ports:
      - 1234:80
    volumes:
      - /sessions
```

またまたまた、ビルド＆再起動するしてlocalhost:1234にアクセスすると...
<img width="1362" alt="スクリーンショット 2020-05-11 15.31.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631619/3abc9d77-2c95-ef7a-ed20-a9f56b67f4d0.png">

phpmyadminからMySqlに接続確認できました。（react-gp-appが作成されていることを確認）

これでReact&Golang&MySqlでアプリ開発用の環境構築が完了しました！！