Help us understand the problem. What is going on with this article?

Docker+golang+Nginxでリバースプロキシ・ホットリロードな開発環境を構築する

More than 1 year has passed since last update.

はじめに

こんにちは、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ファイルは以下のようになります。

docker-compose.yml
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用)

Dockerfile
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用)

Dockerfile
FROM nginx:latest
COPY ./nginx.conf /etc/nginx/nginx.conf

設定はホスト側のnginx.confを適用させたいので、コンテナ側の/etc/nginx/nginx.confにコピーします。

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:3000golangはservicesに記述したサービス名と同じにしてください。そうしないとちゃんと動いてくれません。

main.go

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

.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」∠)_

yoship1639
ゲームエンジニア。C#er。バックエンドも触る。ゲーム、ゲームエンジン、仮想通貨等を自作していました。フロントエンドから物理ベースシェーダまで幅広く対応可能。理解しやすく正しい記事を記述することを心がけます。
https://twitter.com/yoship1639
unity-game-dev-guild
趣味・仕事問わずUnityでゲームを作っている開発者のみで構成されるオンラインコミュニティです。Unityでゲームを開発・運用するにあたって必要なあらゆる知見を共有することを目的とします。
https://unity-game-dev-guild.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away