TLS対応にしているGo言語のサーバを、Dockerコンテナの中から使えるようにしたい

2023年5月12日

https://teratail.com/questions/8xzab7sat8gujj#reply-3jfh5txotuqxqb

の質問サイトに投げたものですが、ローカルでも作っておきます。

実現したいこと

TLS対応にしているGo言語のサーバを、Dockerコンテナの中から使えるようにしたい

前提

GO言語を使ってサーバを作っています。これらのサーバをDockerコンテナに格納して、運用しやすくしたいと考えております。

発生している問題・エラーメッセージ

Dockerコンテナに格納すると、https(×http)通信が使えません。

cert.pem、key.pemを使わない場合、http://127.0.0.1:18888で、ブラウザに"hello"メッセージがされますが、cert.pem、key.pemを使ってhttps://127.0.0.1:18888とした場合、「このサイトにアクセスできません」と表示されます。

該当のソースコード

GO言語

package main

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

var url_host string

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")
}

var addr = flag.String("addr", "127.0.0.1:18888", "http service address") // テスト

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("url_host:", url_host)

	log.Println("start http listening :18888")

	var httpErr error
	if _, err := os.Stat("./cert.pem"); err == nil {
		if httpErr = http.ListenAndServeTLS(*addr, "./cert.pem", "./key.pem", nil); httpErr != nil {
			log.Fatal("No pem file with https error: ", httpErr.Error())
		}
	}
}

ちなみに、cert.pemと、key.pemは、"127.0.0.1","localhost"で通るように作ってあります。

ローカルネットワークにおける「オレオレ証明書」の作り方 "http: TLS handshake error from 192.168.0.22:59914: remote error: tls: unknown certificate"のエラーを、ようやく消せました

Dockerfile
#FROM golang:apline
FROM golang:1.16.3-alpine
WORKDIR /go
ADD . /go
CMD ["go", "run", "main.go"]

docker-compose.yml

version: '3'
services:
  app:
    build: .
    ports:
      - "18888:18888" # "ホストのポート:コンテナのポート"

試したこと

上記のmain.go のfunc main()を以下のようにしている場合は,http(×https)で通信できます。

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

補足情報(FW/ツールのバージョンなど)

■Windows10上のDocker for Windowsを使用しています。
■Dockerコンテナを使わないで、 windowsのコマンドプロンプトから起動する場合は、"https://127.0.0.1:18888"は問題なく起動します。

で、頂いたご回答が以下の通り。

Dockerfile

#FROM golang:apline
FROM golang:1.16.3-alpine
WORKDIR /app
ADD . /app
CMD ["go", "run", "main.go", "-addr", ":18888"]

と最後の一行を、CMD ["go", "run", "main.go", "-addr", ":18888"]

とするだけでした。

で、以外な盲点が、

ブラウザのキャッシュを消去しないと、変更がブラウザに反映されない

だったりします。(何度も経験しているのに、これをよく忘れるんだよなぁ)

感想

散々、色々試したあげく、最初に頂いた、Dockerfileの内容に変更することで、無事問題を解決することができました。現在、Dockerの中で立ち上げたgoのサーバに対して、https://localhost:18888で表示されることを確認しました。

今後のサーバ立ち上げに関して、かなり有益な知見となりました(実サーバ運用では、ご指摘の内容を反映してリスクを回避したいと思います)。 この度は、誠にありがとうございました。

以上

2023年5月12日2023,江端さんの技術メモ

Posted by ebata