はじめに
こんにちは、Stackdriver担当者です。この記事はGo Advent Calendar 2019の24日目の記事です。昨日は@fist0さんでした。
私は職業柄「コードラボ」「ハンズオン」「ワークショップ」と呼ばれるような、参加者に実際に手を動かして課題を解いてもらうことで特定の技術や製品を理解してもらうイベントを開催したり講師をしたりすることがあります。その場合にこちらがコントロールしづらいものの一つが実行環境です。諸々のバージョンを固定したり、コンテナを用意したり、などいろいろな方法がありますが、今回はglitchを使ってGoでのハンズオン環境を用意する方法とその使い方を紹介します。
TL;DR
Glitchを使ってGo用のハンズオン環境を容易に提供できる。サンプルプロジェクトはこれ。
Glitchとは
ウェブアプリケーションを公開する無料の実行環境で、デフォルトではNode.jsの実行環境が用意されています。日本語でGlitchの丁寧な解説をしている記事もありますので詳細はそちらに譲ります。
- ブラウザだけで完結するウェブアプリ作成環境 Glitch | ラボラジアン
- [Node.js] 無料で簡単にウェブアプリを公開できるサービス「Glitch」を使ってみた! - Qiita
- Glitchで無料でNode.jsのWebアプリをオンライン運用してみた | Ariafloat Blog ‐ 一人旅好きITエンジニア
で、今回はこのGlitchをGoの実行環境として利用する方法について紹介して、さらにハンズオンなどで便利に使う方法についても解説します。
準備するもの
主催者・チューター
- Glitchアカウント
- Goのハンズオン用にセットアップされたGlitchプロジェクト
- (optional) 2.のコードをミラーするGitHubレポジトリ
参加者
- (optional) Glitchアカウント
手順
1. Glitchアカウント
フェデレーテッドログインができるので好きなIdPを選んでアカウントを作ってください。すぐにできます。参加者はアカウントが無くても一時アカウントが利用できるので大丈夫です。
2. GlitchプロジェクトをGo用にセットアップする
メインはここです。GlitchはデフォルトではNode.jsの実行環境なのですが、実はGoの実行環境も入っています。しかし、設定ファイルを書くことで、Goのダウンロードとインストールをして特定のバージョンのGoを使わせたり、コード変更時のGoプロジェクトの自動ビルドなどを設定して、さらにハンズオン環境として良い物にできます。
glitch.json
Goを含むNode.js以外のランタイムは glitch.json
と呼ばれる設定ファイルを用意する必要があります。JSONで設定できるフィールドはそれぞれ次のとおりです。
{ "install": string, "start": string, "watch": { ... } }
それぞれ次のような内容です。
- install: プロジェクトのコンテナ起動時に実行されるコマンド
- start: watchで定期的に実行されるコマンド
- watch:
watch.json
に関する設定(watch.json
を別途作成する場合は書かなくて良い)
watch.json
watch.json というファイルを設定すると、編集後に自動で実行したいコマンド等を記述できます。Linux等のwatchコマンドに似ていますね。ここではどのファイルを変更した場合にどういったトリガーを起動するかを設定します。対象ファイル名は正規表現で指定できます。
{ "install": { "include": [ "^glitch\\.json$", "^init\\.sh$", "^\\.env$" ] }, "restart": { "exclude": [ "^go/", "^pkg/" ], "include": [ "\\.go$" ] }, "throttle": 5000 }
設定項目はそれぞれ次のとおりです。
- install:
include
で記載されているファイルが変更されるとコンテナ自体の再インストールが行われる - restart:
exclude
で記載されているファイルが変更された場合は何もしない、include
で記載されているファイルが変更された場合はコンテナを再起動する - throttle: watchの確認自体の間隔を設定する(ミリ秒)
Go用プロジェクトセットアップのコツ
これは通常のコンテナイメージ構築の場合と勘所は同じです。つまり次のようにします。
- Goのバージョンを固定する
go.mod
でパッケージのバージョンを固定する
1のGoのバージョンの固定は、glitch.json
の install
に適当な初期化用のシェルスクリプトを指定して、その中でLinux用のtarballとsha256のチェックサムの確認をすることで固定できます。上のサンプルプロジェクトではこのような形で設定しています。
GO_ARCHIVE=go1.13.5.linux-amd64.tar.gz if [ ! -d /tmp/go ]; then cd /tmp if [ ! -f /tmp/${GO_ARCHIVE} ]; then wget -q https://dl.google.com/go/${GO_ARCHIVE} fi sha256sum -c ~/${GO_ARCHIVE}.SHA256SUMS || (echo "failed to verify go tarball" && rm /tmp/{$GO_ARCHIVE} && exit 1) tar -xzf ${GO_ARCHIVE} rm /tmp/${GO_ARCHIVE} fi mkdir -p /tmp/pkg if [ ! -L pkg ]; then ln -s /tmp/pkg $GOPATH/pkg fi
そしてこのSHA256SUMS
のファイルは自分で手元で作成してもいいですし、Go公式サイトの配布先に書いてあるSHA256 Checksumを自分でコピーして作成しても良いでしょう。
512103d7ad296467814a6e3f635631bd35574cab3369a97a323c9a585ccaa569 go1.13.5.linux-amd64.tar.gz
2.の go.mod
は固定です。ハンズオン参加者に編集させていはいけませんし、go mod tidy
を実行させてはいけません。アンタッチャブルです。編集させると即座にプロジェクトが予想しない形に壊れるので、もし触ってしまった人がいたら元のgo.mod
ファイルとgo.sum
ファイルを再度コピーしてもらうようにしましょう。またキャッシュも消す必要があります。
そしてプログラムのビルドと実行も glitch.json
の start
で指定したシェルスクリプト内で go fmt
や go run
等を実行するようにし、ハンズオン参加者が go
コマンドを自分で打つ必要がないように設定すると良いでしょう。
(optional) 3. 2.のコードをミラーするGitHubレポジトリ
万が一ブラウザではなくローカルで実行したい、もしくは何らかの事情でGlitchを使えない、という人がいた場合に備えて、GlitchのプロジェクトをGitHubにミラーリングしておくと安心感が高まります。
注意点としては、事前にExport先のレポジトリを作成し、かつ1つでもコミットがされた状態にしておく必要があります。その上で "Export to GitHub" ボタンを実行してExport先のレポジトリを指定すると、giltchブランチに変更がpushされます。
実際にミラーしたのがこちらです。
ハンズオンの進め方
ハンズオンの進め方はまずハンズオン開始時に上の 2. で作成したプロジェクトのURLを参加者に共有します。参加者に "View Source" を押してもらい、コードエディターが読み込み専用モードで開いてもらいます。ここで画面の右上の "Remix to Edit" のボタンを押してもらうと "Remix" が行われます。
参加者がRemixをすると元のコードをforkしたプロジェクトが任意のIDとともに作成され、参加者は自由に変更を加えられる環境を手に入れられます。そして課題を書き進めるわけです。わからないことがあったら、その部分のコードをハイライトします。すると手を上げたアイコンが出現するのでそれを押すと、質問が出来るようになります。
remixしたプロジェクトで質問がでると、remix元のプロジェクトオーナー(つまりチューター)のトップ画面に「質問が来ていますよ」というメッセージが出てきます。("Help Others, Get Thanks→" の部分。ここでは "Test question: bra bra bra" という質問メッセージが来ています。)
もちろん普通に手を上げてもらっても良いのですが、こういう形で質問をしてもらうことで、チューターがスクリーンなどにこのトップ画面を映していると質問内容がわかりつつ、これからその部分に取り組む人も事前に注意が出来るというわけです。
実際に試した
この方法は今年の11月5日に行われたVelocity Berlin 2019のワークショップで実際に試してみました。チューターや参加者のパソコンのOSがWindows、Linux、macOS、Chrome OSなど様々に分かれていたわけですが、OS特有のエラーなどにはまることがまったくありませんでした。
参加者が書いた結果のコードもプロジェクトの形で残るので、何か面白いことを取り組んだ参加者がいれば、そのプロジェクトURLを共有してもらうだけで手元でコードを見て、実行するところまでできるのも便利でした。
またハンズオンの内容もHTTPサーバーを立ててリクエストを受け取ったり投げたりするようなプログラムを書いたわけですが、ポート番号3000番で指定すればパブリックにサーバーを公開できるので、参加者同士で通信しあうような課題もできそうだったのが魅力的でした。
コンソールにアクセスしてコマンドを実行できるため、CLIを作るような課題もある程度可能です。
おわりに
コードラボやハンズオンは実際に手を動かすため短い時間で効率よく学習することが可能です。ぜひこの方法をいろいろな場所で試してもらって、Goのハンズオンとしてもっと便利な使い方を共有してもらえたらなと思います。
明日は最終日。担当は @tenntenn さんです。