まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:go

元ネタはこの記事です:
Cloudflare の ngrok的なサービスがあるらしい ⇒ $ cloudflared tunnel --url localhost:8080 といった使い方

(特に開発中のサービスなど)ローカルホスト内で動いている状態のウェブサービスを試験的・一時的にインターネットに公開して外部から利用できるようにするものです。この手のツールとしては ngrok が有名ですが、CDN で有名な Cloudflare 社も同様のツールを公開していたんですね。。

上記ページはその導入手順を含めて紹介しています。また公式のインストールページもリンクされています:
https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation


が、残念ながらラズベリーパイ向けのインストール方法はここで書かれている方法だけではわかりにくい内容でした(要はラズパイの場合、ソースコードからビルドする必要があるのですが、ビルドの前提となる Go 言語のインストールがまた面倒で・・・)。というわけで、ラズベリーパイ環境向けの cloudflared のインストール手順を以下に紹介します。


【ラズベリーパイ向け cloudflared のインストール手順】
(1) Go 言語のインストール

この後の手順で Go 言語を使って cloudflared をビルドします。そのため Go 言語をインストールしておく必要があります。

以前に紹介した以下のサイトを参照して、ラズベリーパイに Go 言語をインストールしてください:
ラズベリーパイに Go 言語をインストールする


(2) cloudflared のビルド

Go 言語用のソースコードをダウンロードして、Go 言語でビルドしてツールを作成します。

まず GitHub からソースコードをダウンロードします:
$ git clone https://github.com/cloudflare/cloudflared.git

ダウンロードしたソースコードを Go 言語でビルド&インストールします:
$ cd cloudflared

$ make cloudflared

$ go install github.com/cloudflare/cloudflared/cmd/cloudflared

ここまでの手順で ~/go/bin/cloudflared に実行バイナリが作られています。このままだと利用が不便なので、パスの通ったフォルダ(例えば /usr/local/bin/ 以下)にこのファイルをコピーします:
$ sudo cp ~/go/bin/cloudclared /usr/local/bin/

これでインストール完了です。


【ラズベリーパイで cloudflared を使ってみる】

ではインストールした cloudflared を実際に使ってみます。そのためには何でもいいのですが、何らかのウェブアプリケーションをラズベリーパイ上で動かす必要があります。docker で nginx を動かすとか、適当なウェブアプリを動かすとかでも構いません。こちらの方法を参照いただいて Node-RED をインストールして動かす、とかでも構いません(以下は最後の方法を実行し、 $ node-red コマンドまでを実行して、Node-RED が 1880 番ポートで稼働しているという前提で説明を続けます):
2021040801
(↑プライベートアドレスの 1880 番ポートで待受け準備完了した様子)


ラズベリーパイ上で何かウェブアプリが動いていたら、ラズベリーパイの端末(既に利用中の場合は別のターミナルの画面)から cloudflared コマンドを実行します:
$ cloudflared tunnel --url localhost:1880

※上述コマンドの 1880 部分は実際にリクエストの待受けをしているポート番号を指定します

すると実行結果の画面に以下のようなメッセージが表示されます:
  :
  :
2021-04-08T05:01:22Z INF +-------------------------------------------------------+
2021-04-08T05:01:22Z INF |  Your free tunnel has started! Visit it:              |
2021-04-08T05:01:22Z INF |    https://xxxxxx-xx-xxxxxx-xxxxxx.trycloudflare.com  |
2021-04-08T05:01:22Z INF +-------------------------------------------------------+
  :
  :

この青字で表示された URL が cloudflared のトンネリングによってインターネットに公開されたアドレスです。自分の PC はもちろん、全く別のネットワークに接続された別の PC からでもウェブブラウザでこのアドレスにアクセスすると、ラズベリーパイの localhost:1880 で稼働しているアプリケーションをパブリックなインターネットから見ることができるようになります:
2021040802
(↑パブリックアドレスで https で待受け準備完了した様子)



ラズベリーパイへの Go 言語インストール、普通にリポジトリから $ sudo apt-get install go でインストールできるかと思っていたら出来なかったので手順を調べました:
go


2021/04/07 現在ではラズベリーパイに Go 言語をインストールするには最新版バイナリ(のアーカイブ)をダウンロードして展開するのがてっとり早そうでした。

まずはこのページで Go 言語の最新バージョンを確認します:
https://golang.org/dl/

2021040701


2021/04/07 時点での最新版安定(stable)バージョンは 1.16.3 のようでした。以下、このバージョンをインストールする前提で説明を続けます。

ラズベリーパイのターミナルから、ラズパイアーキテクチャ(armv6l)向け最新バイナリをダウンロードして、/usr/local 以下に展開します:
$ wget https://golang.org/dl/go1.16.3.linux-armv6l.tar.gz

$ sudo tar -C /usr/local -xzf go1.16.3.linux-armv6l.tar.gz

これで /usr/local/go フォルダ以下に Go 言語がコピーされました。実際の go コマンドは /usr/local/go/bin/go に存在している状態です。

このままだとパスが通っていなくて不便なので、パスを通します。~/.bashrc ファイルをテキストエディタで開いて、最終行に以下を追加して保存します:
export PATH=$PATH:/usr/local/go/bin

保存後、 $ source ~/.bashrc を実行するか、ターミナルを一度終了して開き直すと設定が有効になります。go version コマンドを実行して、以下のような結果が表示されればインストール成功です:
$ go version
go version go1.16.3 linux/arm

 

ラズベリーパイに go 言語をインストールします。
go_lang1


といっても普通に
$ sudo apt-get install golang

でもインストールは可能です。ただこの方法で go をインストールすると、少し古いバージョン 1.3 が導入されます。このバージョンでも問題なければこの方法でもいいのですが、以下はバージョン 1.8 の導入方法を紹介します。

具体的には Google のサイトから、ラズパイ用にビルドされたバイナリをダウンロードし、展開します:
$ cd /tmp
$ wget https://storage.googleapis.com/golang/go1.8.linux-armv6l.tar.gz
$ sudo tar -C /usr/local -xzf go1.8.linux-armv6l.tar.gz

続いて環境変数を設定します。~/.bashrc に以下の行を追加します:
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

この例では GOPATH を ~/go に設定しています。go 言語のソースコードを書く場合のフォルダを指定しています。

この状態で再ログインするか、source ~/.bashrc を実行すると設定内容が有効になって、go 1.8 が使えるようになります:
$ go version
go version go1.8 linux/arm


IBM LinuxONE(メインフレーム上の Linux)ネタシリーズ、今回は Go 言語を動かしてみます。
http://golang-jp.org/


前提として、IBM LinuxONE の環境が必要になります。今回は 120 日間無料で使える IBM LinuxONE コミュニティクラウド上の RHEL 6.x 環境を使うことにします。この IBM LinuxONE コミュニティクラウドの導入方法についてはこちらを参照してください:

さて、s390x 向けの Go 言語をどうやってインストールするかというと・・・ なんとグーグルから同環境を含めた各種プラットフォーム向けのバイナリが主要バージョン毎に提供されているのでした:
https://storage.googleapis.com/golang/

Windows や Linux, OS X 向けはもちろん、ARM デバイス向けのバイナリも提供されています。そしてメインフレーム Linux である s390x アーキテクチャのバイナリも提供されていることが分かります:
2017012001


2017/Jan/20 現在、正式リリースされている中では 1.7.4 が Go 言語の最新バージョンだったので、これをダウンロードして利用することにします:
# cd /tmp
# wget https://storage.googleapis.com/golang/go1.7.4.linux-s390x.tar.gz
# tar -C /usr/local -xzf go1.7.4.linux-s390x.tar.gz

上記のコマンドで /usr/local/go 以下に Go を展開しました。環境変数 GOPATH と合わせて PATH を設定しておきます:
# vi /etc/bashrc

    :
(最後に以下の2行を追加して保存) : export GOPATH=/usr/local/go/ export PATH=$PATH:/usr/local/go/bin

改めてログインし直し(或いは source /etc/bashrc を実行し)、Go 言語のバージョンを確認してみます(青字が出力結果):
# go version
go version go1.7.4 linux/s390x

正しくインストールできたと同時に、s390x 環境で Go 言語を導入できたことが確認できました。

前回の続きです:
CentOS に Go をインストールする


Go の実行環境が導入できたので、テンプレートエンジンを使ってみます。まずは HTML テンプレートを作成しておきます。base.html というファイル名で以下の内容を作成/保存します:
{{define "base"}}<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>{{.Title}}</title>
</head>
<body>
<div class="content">
<h1>{{.Title}}</h1>
<hr/>
<div>
{{.Body|safehtml}}
</div>
</div>
</body>
</html>{{end}}

↑ほぼ HTML ですが、赤字で書いた部分が変数になります。変数名としては Title と Body の2つがあり、その中身はこの後の Go アプリの中で定義して渡します。また全体を "base" という名前で定義しています(青字部分)。


次にこのテンプレートを使って画面を表示する Go のウェブアプリを作成します(http2.go というファイル名で、base.html と同じディレクトリに作成します):
package main

import(
  "net/http"
  "html/template"
)

func viewHandler( w http.ResponseWriter, req *http.Request ){
  funcMap := template.FuncMap{
    "safehtml": func(text string) template.HTML { return template.HTML(text) },
  }
  templates := template.Must(template.New("").Funcs(funcMap).ParseFiles("base.html"))
  dat := struct {
    Title string
    Body string
  }{
    Title: req.FormValue( "title" ),
    Body: req.FormValue( "body" ),
  }
  err := templates.ExecuteTemplate(w, "base", dat)
  if err != nil {
    http.Error( w, err.Error(), http.StatusInternalServerError )
  }
}

func main(){
  http.HandleFunc( "/", viewHandler )
  http.ListenAndServe( ":8080", nil )
}

基本形は前回の Go ウェブアプリとほぼ同じですが、まず html/template を使う宣言をして、テンプレートに上記で作成した(同じディレクトリ上にある) base.html を使う宣言をしています。

またテンプレート内の変数 Title, Body を、それぞれ title, body という URL パラメータを受け取って定義するようにしています。

この状態で http2.go を実行します:
# go run http2.go


そしてウェブブラウザでこのサーバーの 8080 番ポートのルートパスに、パラメータ title と body を指定してアクセスすると、指定した内容がウェブページの一部になって表示されるはずです:
2016042602


これで Go でもテンプレートエンジンっぽいこともできました。

このページのトップヘ