HTTP Real Worldの ハンズオンの準備をWindows10+Vagrant+Docker+VsCodeで行ったメモ

## 概要
[Real World HTTP 第2版――歴史とコードに学ぶインターネットとウェブ技術](https://www.oreilly.co.jp/books/9784873119038/)を買った。
ハンズオンが準備されていたので、その環境設定を行ったメモ。

- ソース
  - [1章読了時点](https://github.com/hibohiboo/develop/tree/de2484d91a6443d2a3619c1309b1e23db422e6fb/tutorial/lesson/realworld/)
  - [Vagranfile](https://github.com/hibohiboo/develop/blob/de2484d91a6443d2a3619c1309b1e23db422e6fb/Vagrantfile)
  - [3章読了時点](https://github.com/hibohiboo/develop/tree/e6945b8ea2aa3464cd43b973ebee3fbb381e7477/tutorial/lesson/realworld/)

※ [正誤表](https://github.com/oreilly-japan/real-world-http/wiki/1st-print-eratta)が出ているので要確認。goライブラリのパスが違っていたりする。(正：github.com/k0kubun/pp. 誤: github.com/k0kibun/pp  など）


## 環境

- Windows 10 Home
  - Vagrant 2.2.7
  - virtualbox 6.1.6
      - ubuntu 18.04 LTS
         - docker-ce Docker version 19.03.5, build 633a0ea838
         - docker-compose version 1.25.3, build d4d1b42b

## 環境構築
### chocolateyの準備
* 使用するパッケージを簡単にインストールできるように、Windows用のパッケージマネージャを導入

```
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command " [System.Net.ServicePointManager]::SecurityProtocol = 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
```

### curl の準備
* gitbashのものを使用する

```
choco install git -y
```

### golangの準備

#### エディタ

* vscodeのおススメを利用。(.vscode/extensions.json)に記述
* 上記を利用するために、golangのパスの場所が必要になったのでchocolateyでインストール

```
choco install golang -y
```

* TabNineの初期設定を確認するときは、ctrl+shift+pでコマンドパレットを開いて、`TabNine:config`を入力。パスを確認する。
  *  (参考：
[VSCode + golang での快適な補完について自分なりにまとめてみた](https://qiita.com/akinobufujii/items/50d605ecf22daa3309cb))
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/e42bca68-541e-ba52-6a40-7eaf89c57c99.png)


#### 実行環境
* vagrant上でdockerを動かす。

```yml:docker/docker-compose.yml
version: "3"
services:
  realworld:
    build: ./golang
    volumes:
      - ../src:/app/src
    working_dir: /app
    ports:
      - 18888:18888
```
```Docker:docker/golang/Dockerfile
FROM golang:latest
```
```bash:bin/go.sh
#!/bin/bash

bin_dir=$(cd $(dirname $0) && pwd)
parent_dir=$bin_dir/..
docker_dir=$parent_dir/docker
composeFile=${1:-"docker-compose.yml"}
container_name=${1:-realworld}

docker ps | grep $container_name

if [ $? -eq 0 ]; then
  cd $docker_dir && docker-compose exec $container_name go run /app/src/server.go
else
  cd $docker_dir && docker-compose run --service-ports $container_name go run /app/src/server.go
fi
```
```go:src/server.go
package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
)

func handler(w http.ResponseWriter, r *http.Request) {
	dump, err := httputil.DumpRequest(r, true)
	if err != nil {
		http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
		return
	}
	fmt.Println(string(dump))
	fmt.Fprintf(w, "<html><body>Hello</body></html>\n")
}

func main() {
	var httpServer http.Server
	http.HandleFunc("/", handler)
	log.Println("start http listening :18888")
	httpServer.Addr = ":18888"
	log.Println(httpServer.ListenAndServe())
}
```

#### 動作確認
* 上記を準備した後、vagrant上で`go.sh`を動かせば検証用のサーバが起動する。
  * curlでアクセスして確認
```
curl --http1.0 http://192.168.50.10:18888/greeting
```


## 参考
[Chocolatey Software | Installation](https://chocolatey.org/docs/installation)
[Chocolateyを使った環境構築の時のメモ](https://qiita.com/konta220/items/95b40b4647a737cb51aa)
[Docker で Go の開発環境を構築する](https://qiita.com/uji_/items/8c9eda89526abe0ba900)
[VSCode + golang での快適な補完について自分なりにまとめてみた](https://qiita.com/akinobufujii/items/50d605ecf22daa3309cb)
[docker-compose run は port を mapping しない](https://blog.ikedaosushi.com/entry/2018/07/23/191952)