はじめに
こんにちは、3Dとかゲームがメインのyoship1639です。
Web知識皆無な人間だったのですが、最近Web系を触るようになり(強制)、その中でDocker+golang+NginxでWebサービスを作るという状況になったので、備忘録含めどうやったらDocker上でNginx+golangな環境を構築できるのかをご紹介したいと思います。
なるべく最小限の環境を構築したいので、Nginxは設定としてリバースプロキシ部分のみ、golangはrealizeによるホットリロード機能のみを記述します。
一応、私の環境はこんな感じです
・Win10 64bit Home
・VSCode 1.34.0
・Virtualbox 5.2.8 r121009
・Docker 18.03.0-ce
構築
今回作成するプロジェクト名はわかりやすく「docker_go_nginx」とします。
配置場所はgo/src/github.com/docker_go_nginx
です。
フォルダ構成は以下の通りです。
docker_go_nginx
├─ app
│ ├─ main.go
│ └─ .realize.yml
├─ nginx
│ ├─ Dockerfile
│ └─ nginx.conf
├─ docker-compose.yml
└─ Dockerfile
それぞれについて見ていきます
docker-compose.yml
docker-composeファイルは以下のようになります。
version: "3"
services:
golang:
tty: true
build: "."
volumes:
- ./app:/go/src/github.com/docker_go_nginx/app
ports:
- "3000"
command: bash -c "cd app && realize start --server"
nginx:
build: ./nginx
ports:
- "80:80"
depends_on:
- "golang"
golangコンテナのポートはNginxのプロキシを通すので80ではなく3000を指定しています。逆にNginxのコンテナに80を指定します。また、golangコンテナ起動時にホットリロードを開始させます(realize start --server)。これによってついでにmain.goが自動で走ります。
nginxはgolangのリバースプロキシになるのでdepends_on: - "golang"
を指定します。
Dockerfile (golang用)
FROM golang:latest
RUN go get -u github.com/oxequa/realize && \
go get -u github.com/gorilla/mux
WORKDIR /go/src/github.com/docker_go_nginx/
golangは最新のイメージを取得し、realizeパッケージをgo getします。
WORKDIR /go/src/github.com/docker_go_nginx/
は後でコンテナのシェルに入ったときに一々cdするのが面倒なので予めワークディレクトリとして指定しておきます。
Dockerfile (nginx用)
FROM nginx:latest
COPY ./nginx.conf /etc/nginx/nginx.conf
設定はホスト側のnginx.confを適用させたいので、コンテナ側の/etc/nginx/nginx.conf
にコピーします。
nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http {
server {
listen 80;
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://golang:3000;
}
}
}
非常に最小限なnginx.confです。80ポートをlistenしたらリバースプロキシとしてhttp://golang:3000
にパスします。これで、Nginx経由でwebアプリ(golang)にアクセスします。
また、http://golang:3000
のgolang
はservicesに記述したサービス名と同じにしてください。そうしないとちゃんと動いてくれません。
main.go
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func rootHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("Hello world!")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", rootHandler)
http.Handle("/", r)
http.ListenAndServe(":3000", nil)
}
main.goに関しては特に何も言うことないですね。
3000ポートをlistenして、ルートにアクセスがあったらHello world!するだけです。
.realize.yaml
settings:
legacy:
force: true
interval: 0s
server:
status: true
open: false
port: 5002
host: localhost
schema:
- name: app
path: .
commands:
run:
status: true
watcher:
extensions:
- go
paths:
- /
ignored_paths:
- .git
- .realize
- vendor
realizeは自動生成されたものを少し修正して、コンテナの立ち上がりと同時に自動で実行させるようにしています。
実行
ファイル一式そろえたらdocker-compose up
します
$ cd docker_go_nginx
$ docker-compose up
Starting dockergonginx_golang_1 ... done
Starting dockergonginx_nginx_1 ... done
Attaching to dockergonginx_golang_1, dockergonginx_nginx_1
golang_1 | [04:08:01][APP] : Watching 1 file/s 0 folder/s
golang_1 | [04:08:01][APP] : Install started
golang_1 | [04:08:01][REALIZE] : Started on localhost:5002
golang_1 | ⇨ http server started on 127.0.0.1:5002
golang_1 | [04:08:02][APP] : Install completed in 1.330 s
golang_1 | [04:08:02][APP] : Running..
golang_1 | [04:08:44][APP] : Hello world!
realizeのおかげで自動でmain.goが走るので、あとは192.168.99.100
にブラウザでアクセスして真っ白い画面がでたら成功です。ついでにHello worldが出力されます。
これで、リバースプロキシ+ホットリロードな開発環境ができたので、あとは煮るなり焼くなりするだけです。
まとめ
Docker上でNginx+golangによるリバースプロキシ、ホットリロードな最小限の開発環境を構築しました。
ホットリロードを機能させておくと編集するたびにコンパイルしなおさなくてもいいのでgolangの開発がとてもスムーズになりおススメです。
Web初心者なので間違ってたらコメントください_(:3」∠)_