🐳

go-tour-jpのローカル実行をDockerで仮想化してコマンド一発で実現できるようにした話

2021/12/22に公開

TL;DR

  • go-tour-jpをDockerから起動できるしくみを作りました
  • つかいかた
docker pull ryoku/gotour:1.0
docker run --rm -it -p 127.0.0.1:3999:3999 ryoku/gotour:1.0
# コマンド実行後にブラウザで `http://0.0.0.0:3999` にアクセス
  • 思いつきで作っただけなので,よければ改善点のご教示・レビューをお願いしたいです

go-tourおよびgo-tour-jpについて

go-tourはGoの基本的な文法を手を動かしながら学べるgo初学者向けのGoチュートリアルです.Githubレポジトリはこちら.
そしてgo-tour-jpは先駆者様(Ato Arakiさん)がgo-tourを日本語化したものです.Githubレポジトリはこちら.

モチベーション

gotourをローカルで動かしたい->うごかない

go-tour-jp公式によると

ローカルで Go Tour を実行するためには、はじめに、 Goのダウンロードとインストール し、コマンドラインで以下のように実行します:
go tool tour

ところがこの方法だと,自分の環境では動きませんでした.
今思うと,公式が指示した方法ではなく,goenvでバージョニングしてたのが良くなかったのかも...とは思うのですが原因不明です.

$ go tool tour
go tool: no such tool "tour"

先のコマンドで動かない場合の対処として,公式では以下のような記述があります.

上記のコマンドの実行に問題がある場合は手動でこのツアーをインストールして実行できます:
go get github.com/atotto/go-tour-jp/gotour
gotour

実行結果は以下の通り.

$ go get github.com/atotto/go-tour-jp/gotour
go get: github.com/atotto/go-tour-jp@v0.0.0-20201205034358-913c5eae8455 requires
        golang.org/x/tour@v0.0.0-00010101000000-000000000000: invalid version: unknown revision 000000000000

tour@v0.0.0-00010101000000-000000000000みたいなバージョンは本来ないハズなのですが,go modの名前空間が重ならないようにするための仕組みが暴走している?ため,バージョン欄がめちゃくちゃになっているようです.go-tourを使って勉強しているレベルの初学者なので本当によくわからない.
まとめると,

  • go tool tour方式→うごかない
  • go get github.com/atotto/go-tour-jp/gotour方式→うごかない

ということです.

まあオンラインでやればいいか 絶対ローカルでgo-tour-jpしたい

こうなると意地でもローカルでgo-tour-jpを動かしたくなってくるものです.
先程のgo get github.com/atotto/go-tour-jp/gotour方式で問題になっていたのはバージョン周りの話なので,ここを直せば上手く動きそうですね.

//go.mod
module github.com/atotto/go-tour-jp

go 1.11

require (
	golang.org/x/tools v0.0.0-20190312164927-7b79afddac43
-         golang.org/x/tour v0.0.0-00010101000000-000000000000
+         golang.org/x/tour v0.0.0
)

replace golang.org/x/tour => ./

修正後にgo run .してみると,正しく動作しました.

コマンド一発で実行できるようにしよう(ついでにDockerコンテナ化しよう)

go-tour-jpはgoroutineもよくわからない初学者がgoを学ぶために作られたのであって,それを動かすためにまずgo.modを触るみたいなのは全く本質的ではありません.

  • 初心者の人が数コマンドで実行できるようにしたい.
  • できればDockerで開発環境の差異も吸収したい

と思い,go-tour-jpをコマンド一発で実行できる仮想環境を作成・配布してみました.

つかいかた

事前準備

dockerのインストールをお願いします.
具体的な手順は公式(英語)先駆者様の記事を参考に.

実行

以下コピペでサーバーが立ち上がります.

docker pull ryoku/gotour:1.0
docker run --rm -it -p 127.0.0.1:3999:3999 ryoku/gotour:1.0

上記コマンド実行後,http://0.0.0.0:3999にアクセスしてください(http://localhost:3999ではないことに注意.[1]).

これだけでgotourローカル環境 on Docker環境が構築できるはずです.

docker pullだけオンラインで実行すれば,gotour起動はオフラインでできる(ハズ)です.

Dockerfile

FROM golang:1.17.5-alpine3.15
RUN apk update && apk add git
RUN git clone https://github.com/skonb/go-tour-jp.git
WORKDIR /go/go-tour-jp/
RUN go mod tidy
EXPOSE 3999

ENTRYPOINT go run . -http 0.0.0.0:3999 -openbrowser=false

「オヌシのGitリポジトリ(skonb)なんて信用ならん使いたくないんじゃ」と言う人は,元のgo-tour-jpをForkして,上部のversionの修正を行い,適宜そちらのリポジトリ名に置き換えて実行してください.

注意

  • M1Mac(ARM端末)で作ったので,Win・Ubuntuなど他OSや,Intelチップ特有の不具合があるかもしれません(「実行環境の差異を吸収する」とは...)
  • 自由にgoを実行できるDockerコンテナのポートを開放しており,それを利用した攻撃に遭うリスクがあります.自己責任でのご利用をお願いします
    • 一応dockerの起動時は127.0.0.1:3999:3999としてlocalhost以外からのアクセスを制限しているつもりです
  • その他,気になる点・修正点などあればコメントなりissueなりでご連絡ください

関連リンク

感想

これを作っている間にgo-tour-jpをオンラインで進めて無事完了できました.まさに本末転倒.
go modules関係とか,dockerのポートフォワード関連の勉強になったので良しとしたい.

脚注
  1. localhostの方にアクセスすると,ページ自体は取得できますが,websocketがつながっておらず,Webページ上でのgoの実行がいつまで経っても終わりません. ↩︎

Discussion