現在、勉強がてら個人開発をしていて、せっかくの個人開発なので、今までさわったことがないReact, Go, MongoDBでwebアプリを作ります。 その最初の段階として、Docker Composeを使って環境構築を進めます。
Reactの環境構築
今回の開発では、プロジェクト配下をこんな感じにしています。
プロジェクト
├── backend
├── frontend
Reactはfrontend
配下に構築します。
Dockerfile
の作成
Dockerfile
にDocker上で起動させるコンテナの構成情報を書きます。
frontend
配下に以下内容で作成します。
FROM node:13.12.0-alpine3.10
WORKDIR /usr/src/app
1行目にはコンテナのDockerイメージ、2行目にはコンテナ内の作業ディレクトリを記載しています。 alpineはAlpine Linuxのことで、必要最低限の構成がされているおかげで、Dockerイメージの軽量化を図ることができます。
docker-compose.yml
の作成
docker-compose.yml
で複数のコンテナをまとめて起動することができます。拡張子は「.yml」「.yaml」どちらでも動きます。
どっちかに統一してくれればいいのに。
プロジェクト配下に以下内容で作成します。
version: '3'
services:
node:
build:
context: ./frontend
dockerfile: Dockerfile
volumes:
- ./frontend:/usr/src/app
command: sh -c "yarn start"
ports:
- "3000:3000"
volumes
ではコンテナ内のusr/src/app
をfrontend
に永続化させます。
ports
では外部の3000ポートとコンテナ内の3000ポートをつなげています。ローカル環境ではlocalhost:3000
でアクセスができるようになります。
Dockerイメージのビルド
docker-compose.yml
のある階層で以下コマンドを叩きます。
docker-compose build
Building node
Step 1/2 : FROM node:13.12.0-alpine3.10
---> b529a862f234
Step 2/2 : WORKDIR /usr/src/app
---> Using cache
---> b753b92fbf97
Successfully built b753b92fbf97
Successfully tagged プロジェクト名_node:latest
上記のような表示がされ、ビルドすることができます。
コンテナの起動
僕はすでにローカル環境でReactのひな形を作成していたので、Reactの導入は省きます。 niftyさんのReactの開発環境をDockerで構築してみたを参考にして作業を進めてください。 コンテナの起動をするには以下コマンドを叩きます。
docker-compose up
このコマンドにより、docker-compose.yml
の sh -c "yarn start"
が実行されて、Reactが起動します。
Starting プロジェクト名_node_1 ... done
Attaching to プロジェクト名_node_1
node_1 | yarn run v1.22.4
node_1 | $ react-scripts start
node_1 | ℹ 「wds」: Project is running at http://172.20.0.2/
node_1 | ℹ 「wds」: webpack output is served from
node_1 | ℹ 「wds」: Content not from webpack is served from /usr/src/app/public
node_1 | ℹ 「wds」: 404s will fallback to /
node_1 | Starting the development server...
node_1 |
node_1 | Files successfully emitted, waiting for typecheck results...
node_1 | Compiled successfully!
node_1 |
node_1 | You can now view frontend in the browser.
node_1 |
node_1 | Local: http://localhost:3000
node_1 | On Your Network: http://172.20.0.2:3000
node_1 |
node_1 | Note that the development build is not optimized.
node_1 | To create a production build, use npm run build.
node_1 |
http://localhost:3000
にアクセスすると次のような画面が表示されます。
Go, MongoDBの環境構築
次にGo, MongoDBの環境構築を進めます。 今のところ以下のようなディレクトリ構成になっています。
プロジェクト
├── backend
├── frontend
├── node_modules
├── public
├── src
├── Dockerfile
├── package.json
├── README.md
└── yarn.lock
僕のReactのひな形の作り方が参考記事とは違っているので、間違っているかもしれないです。backend
配下にGo
ディレクトリを作成して、そこにGoを構築します。
今回はGoのサーバを起動するコンテナとMongoDBのコンテナを連携させていきます。
Dockerfile
の作成
Go
配下に以下内容で作成します。
FROM golang:1.14
WORKDIR /go/
COPY . .
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["go", "run", "src/serversample/main.go"]
go run src/serversample/main.go
でWebサーバを立ち上げています。go run
でコンパイルをして実行してくれます。
GoのWebサーバ作成
go
配下にsrc/serversample/main.go
を以下内容で作成します。
package main
import (
"fmt"
"log"
"net/http"
"strings"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //オプションを解析します。デフォルトでは解析しません。
fmt.Println(r.Form) //このデータはサーバのプリント情報に出力されます。
fmt.Println("path", r.URL.Path)
fmt.Println("scheme", r.URL.Scheme)
fmt.Println(r.Form["url_long"])
for k, v := range r.Form {
fmt.Println("key:", k)
fmt.Println("val:", strings.Join(v, ""))
}
fmt.Fprintf(w, "Hello astaxie!") //ここでwに入るものがクライアントに出力されます。
}
func main() {
http.HandleFunc("/", sayhelloName) //アクセスのルーティングを設定します。
err := http.ListenAndServe(":9090", nil) //監視するポートを設定します。
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
9090ポートからGoのWebサーバにアクセスすることができるようになります。
docker-compose.yml
に追記
ここら辺からはこの記事を参考に作成しました。
docker-compose.yml
を以下内容に更新します。
version: '3'
services:
node:
build:
context: ./frontend
dockerfile: Dockerfile
volumes:
- ./frontend:/usr/src/app
command: sh -c "yarn start"
ports:
- "3000:3000"
dbapi:
build:
context: ./backend/go
dockerfile: Dockerfile
links:
- mongodb
depends_on:
- mongodb
ports:
- "9090:9090"
mongodb:
image: mongo
container_name: mongodb
volumes:
- mongodata
volumes:
mongodata:
driver: local
MongoDBはimage: mongo
でdockerイメージを作成していて、mongodb
という名前のコンテナになっています。
dbapi
はGoのDockerfile
のビルド、links
でmongodb
との連携、depends_on
でmongodb
を先に実行する設定にしています。
volumes:
mongodata:
driver: local
でMongoDBのデータを永続化するようにしています。
Dockerイメージのビルド
準備は整ったので、Dockerイメージをビルドします。
docker-compose build
mongodb uses an image, skipping
Building node
Step 1/2 : FROM node:13.12.0-alpine3.10
---> b529a862f234
Step 2/2 : WORKDIR /usr/src/app
---> Using cache
---> b753b92fbf97
Successfully built b753b92fbf97
Successfully tagged プロジェクト名_node:latest
Building dbapi
Step 1/6 : FROM golang:1.14
---> b022a9b82d88
Step 2/6 : WORKDIR /go/
---> Using cache
---> b44021327ebc
Step 3/6 : COPY . .
---> Using cache
---> f2f46b278392
Step 4/6 : RUN go get -d -v ./...
---> Using cache
---> bdf5c8a92f17
Step 5/6 : RUN go install -v ./...
---> Using cache
---> 8700edd290d2
Step 6/6 : CMD ["go", "run", "src/serversample/main.go"]
---> Using cache
---> 5f9bd6f4def1
Successfully built 5f9bd6f4def1
Successfully tagged プロジェクト名_dbapi:latest
ビルドに成功しています。
コンテナの起動
いよいよ全コンテナを起動します。
docker-compose up
今回はターミナルに表示される量がかなり多いので、省きます。http://localhost:3000
にアクセスして、Reactの画面が表示され、
http://localhost:9090
にアクセスして、このような画面になれば成功です!
終わりに
今回はReact + Go + MongoDBの環境をDocker Composeで作成することができました!
docker-compose.yml
に全てまとめて記載をしましたが、クラウドにデプロイするときは同じサーバにはおかないですし、コンテナ起動も時間がかかってしまうので、フロントとサーバサイドで分けた方がいいですね。
また、今回はGoとMongoDBの接続をすることはできていなくて、Goに関してはWebサーバを立ち上げただけなので、そこらへんに次回は取り組みたいです。