- 投稿日:2020-09-17T22:40:53+09:00
Go入門 Part.1:パッケージ名のベストプラクティス
Goのパッケージ名のつけ方が理解できていなかったため、まとめてみました。
詳細は以下のドキュメントを参照ください。
Package names
Effective Go Package namesパッケージ名の仕組み
- パッケージ名はそのソースファイルのベースディレクトリ名となる
- 違う名前でインポートできる
- よって先験的に衝突を恐れる必要はない
- 違うパッケージに同じ名前の型があっても、パッケージで区別できる
import ( pg "~省略~/external/database/postgres" // ローカルパッケージ名:pg "gorm.io/driver/postgres" // パッケージ名: postgres ) jpeg.Reader // jpeg パッケージのReader関数 bufio.Reader // bufio パッケージのReader関数 csv.Reader // csv パッケージのReader関数シンプルで意味のある命名をする
- 慣習的に lowercase で一語の名前として与えられる
短くて簡潔で中身を想起させるようなシンプルな名詞であるべき
- アンダースコアや mixedCaps は必要なし
time (provides functionality for measuring and displaying time) list (implements a doubly linked list) http (provides HTTP client and server implementations)
一般的に馴染みがあったり、意味を断定できるなら省略してよい
- idiomatic(言葉として通じる単語)でなくていい
computeServiceClientは他の言語ではいい命名かもしれないが、Goではそうでないstrconv (string conversion) syscall (system call) fmt (formatted I/O)
- インポートしたパッケージのローカル名も、パッケージ名の命名規則に従う
アンチパターン
意味のないパッケージ名
![]()
util,common,miscなど一つのパッケージで全てのAPIを扱う
不必要な衝突を招く命名
一般的によく使われる単語や、他のパッケージでも使っていそうなパッケージ名
省略によって意味が分からなくなってしまっているもの
リファクタリング
- パッケージのいい名前が思いつかない場合、パッケージの抽象境界が間違っているかもしれない
- その場合はクライアントコードを書いてみて、必要に応じてパッケージを再構成する
おまけ:パッケージ内の型名・関数名
ベストプラクティス
パッケージの関数名は、しばしば型名を省略しても混乱しない
New関数は、パッケージの型を返す
list.New()はlist.Listを返す- パッケージの型ではない別の型を返す場合、その型名を関数名に含める
time.NewTicker()におけるTickerは、パッケージの型timeとは異なると分かる- 関数がパッケージの型を返す場合、その型名は省略する
start := time.Now()において、timeNow()とつけない
Now()がtime.Timeを返すと分かるためアンチパターン
パッケージの型を型名につける
![]()
httpパッケージの HTTP Server の型名をHTTPServerとする![]()
bufioパッケージの型ReaderをBufReaderなどとする
- 投稿日:2020-09-17T19:31:06+09:00
Cloud Run Go echoへの Cloud Schedulerからのリクエストで415エラー
掲題のとおりCloud Runで以下のエラーが発生
POST 415 324B 389ms Google-Cloud-SchedulerechoはGoのwebフレームワーク
path parameterを使いたくて利用echoのエラーログは以下
error: code=415, message=Unsupported Media Type
Unsupported Media TypeとのことなのでContent-Typeが原因っぽい結論
Cloud scheduler からくるリクエストヘッダはGUIから設定すると
Content-Typeが設定されず、
echo.Context.Bindを使ったリクエストのパースをすると上記エラーが発生する事象発生環境
- go 1.14
- echo 3.3.10
echo リクエストパース部分
Content-Type: application/jsonを想定していたのでリクエストボディのjsonを読み込んでstructにする部分を下記のように実装してCloud RunにデプロイMessage struct { RoomNames []string `json:"RoomNames"` } func Handler(c echo.Context) error { var m Message m := new(Message) if err := c.Bind(m); err != nil { return err } ... }下記のcurlでは成功
curl -H "Content-Type: application/json" -d '{"RoomNames":["living", "study"]}'Cloud Schedulerの設定
HTTPメソッドをPOSTで下記Bodyを設定
{"RoomNames":["living", "study"]}上記415エラーが発生
解決
gcloud scheduler jobs update httpのオプションで--update-headers=Content-Type=application/jsonをつけてリクエストヘッダを変更するもしくは以下
echo リクエストパース部分を下記の通り変更したところCloud Schedulerからリクエストしても成功するようになった
func Handler(c echo.Context) error { var m Message b, err := ioutil.ReadAll(c.Request().Body) defer c.Request().Body.Close() if err != nil { log.Printf("ioutil.ReadAll: %v", err) return echo.ErrBadRequest } if err := json.Unmarshal(b, &m); err != nil { log.Printf("json.Unmarshal: %v", err) return echo.ErrBadRequest } }おわり
Cloud Schedulerの設定GUIにはヘッダを設定する場所がなく、勝手に
Content-Typeが付いてるもんだと思ってた
単なる思い込み
- 投稿日:2020-09-17T14:14:27+09:00
A Tour of Go メモ 【6】 四日目 インターフェースについて
インターフェース
インターフェースの概念や用途が全然わからないので、インターフェースのチュートリアルを始める前に下調べしました。
なるべく消化できるようにわかりやすく、理解しやすく、咀嚼して説明を書いてみました。参考
上から順に読むと理解が進みました。
初心者に送りたいinterfaceの使い方
Goの実装例で理解するダックタイピング
【Golang】Golangのinterfaceで知っておくとお得なTips
Goのinterfaceがわからない人へ*補足
Goの実装例で理解するダックタイピング
サンプルコードが動かないので、以下に修正type Income interface { × calculate() string ◯ calculate() int / / 戻り値の型をstring型からint型へ } × (g google) calculate() int { ◯ func(g google) calculate() int { // "func"が抜けているので、追加 return g.baseSalary + (1000 * g.performance) }インターフェースとは何か
どんな型でも入れられる
package main import "fmt" func main() { var i interface{} i = 10 fmt.Println(i) // 10 i = "string" fmt.Println(i) // string // iは現在インターフェース型である // そのため、例えば変数 i にある文字列と他の文字列を結合したい時 // インターフェース型とstring型は結合できないというエラーになる fmt.Println("この中身は" + i) // invalid operation: (mismatched types interface {} and string) // だから、インターフェース型からstring型に戻してあげる必要がある // (型変更した物を受け取る変数) , ok := (型を変更したいインターフェース型の変数).(変更後の型名) // okは、型変更できたかどうかをtrue、falseで返す str_i , ok := i.(string) if ok { fmt.Println("この中身は" + str_i) // この中身はstring } }ダックタイピング
"If it walks like a duck and quacks like a duck, it must be a duck"
(もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルに違いない)上記の文をインターフェースのダックタイピングに言い換えると、
"もし、構造体がインターフェース型と同じ関数を持っているなら、その構造体はインターフェース型に違いない"
ダックタイピングの流れ
1.インターフェースを宣言
2.そのインターフェースが持つ関数を宣言
3.構造体を宣言する
4.構造体にインターフェースで宣言した関数名と同じ関数を宣言する
5.結果、明示的にその構造体はインターフェースであると宣言しなくても、自動的にその構造体はインターフェース型になる宇宙飛行士に例えると
1.宇宙飛行士というインターフェース型を宣言
2.宇宙飛行士ができることを宣言(例えば、宇宙にいく、ロケットの操縦をする)
3.とある青年を宣言する
4.その青年のできることを宣言(宇宙飛行士と同じで、宇宙にいく、ロケットの操縦をする)
5.わざわざその青年は宇宙飛行士であると宣言しなくても、宇宙に行ったり、ロケットを操縦するなら、彼は宇宙飛行士に違いないインターフェースの利用法
例えば、アームストロングさんと毛利さんという宇宙飛行士を作りたいとします。
同じ宇宙飛行士でも、アームストロングさんは月へ、毛利さんは火星へ行こうとしているとします。
そこで先ほどの宇宙飛行士のインターフェース型がすることに"宇宙にいく"というメソッドがあリます。
しかし、同じ宇宙でも、アームストロングさんは月、毛利さんは火星、と目的地が違います。
そこで、"宇宙にいく"のメソッドに
アームストロングさんの場合は、"月にいく"
毛利さんの場合は、"火星にいく"
というように同じ"宇宙にいく"というメソッドでも、それぞれの違いを設定することができる。宇宙飛行士の例を元にインターフェースを実装してみる
package main import "fmt" // 【ステップ1】 宇宙飛行士というインターフェースを宣言 type Astronaut interface { //【ステップ2】宇宙飛行士のできることを宣言 go_to_space() } // 【ステップ3】とある青年を宣言 type Armstrong struct { name string destination string experience int } // 【ステップ3】とある青年を宣言 type Mouri struct { name string destination string experience int } // 【ステップ4】とある青年がすること(メソッド)を宣言(宇宙飛行士(インターフェース型)で設定したメソッド名(go_to_space)と同じ) func (a Armstrong) go_to_space() { fmt.Printf("%sへは%d回行ったけど、もう一回行きます!\n", a.destination, a.experience) } //【ステップ4】とある青年がすること(メソッド)を宣言(宇宙飛行士(インターフェース型)で設定したメソッド名(go_to_space)と同じ) func (m Mouri) go_to_space() { fmt.Printf("%sに行ってきます!\n", m.destination) } func main() { // armstrong := Armstrong { name: "armstrong", destination: "月", experience: 1, } mouri := Mouri { name: "mouri", destination: "火星", experience: 0, } // 【結果】 armstrongとmouriを明示的にAstronaut型だと宣言しなくても、Astronaut型のスライスに入れることができている // つまり、自動的にarmstrong型とmouri型がAstronaut型になっている!! astronauts := []Astronaut{armstrong, mouri} greet(astronauts) } func greet(astronauts []Astronaut) { for _, astronaut := range astronauts { astronaut.go_to_space() } }
- 投稿日:2020-09-17T09:44:00+09:00
go.modの参照先をローカルのパスに向けてデバッグする
Goは依存ライブラリを
go.modで管理しますが、依存ライブラリの中にバグがあった場合に、一時的にライブラリコード内にデバッグ用のコードを差し込みたいことがあります。例えば、
github.com/hashicorp/hcl/v2=>/path/to/hclに参照先を変えるには、こんなかんじでgo.modにreplaceを書きます。手元の環境はGo 1.14です。go.modmodule tmp go 1.14 require ( github.com/davecgh/go-spew v1.1.1 github.com/hashicorp/hcl/v2 v2.6.1-0.20200915195656-bf0a7fe4fe09 github.com/zclconf/go-cty v1.2.0 ) replace github.com/hashicorp/hcl/v2 => /path/to/hclmain.gopackage main import ( "fmt" "github.com/davecgh/go-spew/spew" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclwrite" ) func main() { src := ` resource "foo_bar" "baz" { disabled = (true) } ` f, _ := hclwrite.ParseConfig([]byte(src), "", hcl.Pos{Line: 1, Column: 1}) got := f.BuildTokens(nil) fmt.Printf("got:\n%s\n", string(got.Bytes())) fmt.Printf("dump:\n%s\n", spew.Sdump(got)) }あとは
/path/to/hclのコードを適当にいじればよいだけ。参考: https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive
- 投稿日:2020-09-17T01:42:19+09:00
Goで予約された名前のCの構造体フィールドにアクセスする。
問題
typeという名前のフィールドを参照したいがGoに予約されているため下記のようなエラーがでる。
package main /* typedef struct { int type; } Struct; */ import "C" import "fmt" func main() { test := C.Struct{1} fmt.Println(test.type) }エラー./Main.go:14:20: expected selector or type assertion, found 'type'解決策
参照時にフィールド名にアンダーバーを付けることで参照できるようになる。
package main /* typedef struct { int type; } Struct; */ import "C" import "fmt" func main() { test := C.Struct{1} fmt.Println(test._type) // typeではなく_typeで参照。 }出力1参考
- 投稿日:2020-09-17T00:49:15+09:00
WSL2 + Docker Desktop + VSCode(Remote - Containers) でGoの開発環境構築
概要
バージョン
2004で正式導入されたWSL2ですが、先日バージョン1909と1903へのバックポートが発表されました!
https://devblogs.microsoft.com/commandline/wsl-2-support-is-coming-to-windows-10-versions-1903-and-1909/
筆者の開発PCは2004へのアップデートが許可されていないので、非常に助かります。
そこで今回は、Docker Desktop for WindowsのWSL2インテグレーション機能と、VSCodeのRemote - Containers拡張機能を使って、Dockerfileでコンテナ内にGoの「快適な」開発環境を作ってみるところまでやってみようと思います。
※既に以下のような素晴らしい記事があり書くのを迷いましたが、自身の理解を深めるのと備忘録も兼ねて書きました。
https://tech-lab.sios.jp/archives/21675筆者の環境
エディション バージョン OSビルド Windows 10 Pro 1909 18363.1049 システム要件
エディション バージョン OSビルド Windows 10(全エディション) 2004 - Windows 10 x64(全エディション) 1909 18363.1049 以上 Windows 10 x64(全エディション) 1903 18362.1049 以上 手順
WSLをインストールし、WSL2に更新する
Docker Desktop for Windows をインストールする
VSCoceの拡張機能 Remote Containers を使って、Goの開発環境を構築する
1. WSLをインストールし、WSL2に更新する
以下URLの公式手順通りにやれば問題ありませんが、一応この記事でも手順を書いておきます。
https://docs.microsoft.com/ja-jp/windows/wsl/install-win101‐1. CPU仮想化が有効になっているか確認
タスクマネージャを開き、CPUの仮想化が有効となっていることを確認してください。
もし有効になっていない場合は、BIOS(UEFI)で仮想化を有効にしてください。(メーカーによって設定方法が異なるので説明は割愛します)
1‐2. Windows Subsystem for Linuxをインストールする
GUI(マウス操作)でやる場合
コントロールパネル>プログラムと機能>Windowsの機能の有効化または無効化の順に選択して以下画面を開き、Linux用Windowsサブシステムにチェックを入れます。
CUI(コマンド操作)でやる場合
管理者権限でPowerShellを開き、以下コマンドを実行してください。
powershelldism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart成功すると以下のようなメッセージが表示されます。
powershell展開イメージのサービスと管理ツール バージョン: 10.0.18362.900 イメージのバージョン: 10.0.18363.1049 機能を有効にしています [==========================100.0%==========================] 操作は正常に完了しました。1‐3. 仮想化マシンプラットフォームのオプションコンポーネントを有効にする
GUI(マウス操作)でやる場合
先程と同様に、
コントロールパネル>プログラムと機能>Windowsの機能の有効化または無効化の順に選択して以下画面を開き、仮想マシンプラットフォームにチェックを入れます。
CUI(コマンド操作)でやる場合
管理者権限でPowerShellを開き、以下コマンドを実行してください。
powershelldism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart成功すると以下のようなメッセージが表示されます。
powershell展開イメージのサービスと管理ツール バージョン: 10.0.18362.900 イメージのバージョン: 10.0.18363.1049 機能を有効にしています [==========================100.0%==========================] 操作は正常に完了しました。1‐4. PCを再起動する
PCを再起動してWSLのインストールとWSL2の更新を完了させます。
1‐5. WSL2を既定のバージョンとして設定する
新しいLinuxディストリビューションをインストールする際の既定のバージョンをWSL2に変更します。
PowerShellを開き、以下コマンドを実行してください。powershellwsl --set-default-version 2以下のメッセージが表示された場合はLinuxカーネルを更新する必要があります。
powershellWSL 2 を実行するには、カーネル コンポーネントの更新が必要です。詳細については https://aka.ms/wsl2kernel を参照してください WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してくださいメッセージに表示されている以下URLにアクセスし、Linuxカーネル更新プログラムパッケージをダウンロードします。
https://aka.ms/wsl2kernelダウンロードしたインストーラーを起動し、Nextをクリックすればインストール完了です。
インストールが完了したら、再び以下コマンドを実行してみてください。今度は成功するはずです。
powershellwsl --set-default-version 21‐6. Linuxディストリビューションのインストール
Microsoft Storeを開き、Linuxディストリビューションをインストールします。
wslで検索すればいくつか候補が出てきます。
インストールが完了したら、
Ubuntuを起動します。
しばらく待つとユーザー名とパスワードの入力を促されるので、任意のものを入力します。
※今後Ubuntu内で何かするときはパスワード入力を求められるので、パスワードは忘れないでください。
これで、Windows上でLinux(Ubuntu)を起動できるようになりました!
念のためPowerShellを開き、以下コマンドを実行してWSLのバージョンが2になっていることを確認しましょう。
powershellwsl -l -v NAME STATE VERSION * Ubuntu Running 22. Docker Desktop for Windows をインストールする
次に、
Docker Desktop for Windowsをインストールし、Dockerを使えるようにします。ここで注意点ですが、以下のリリースノートに記載してある通り、バージョンが
19091903の場合はDocker Desktop Community 2.3.5.0以上をインストールする必要があります。
https://docs.docker.com/docker-for-windows/edge-release-notes/執筆時点(2020年9月4日)では、Stable版(安定板)の最新バージョンは
Docker Desktop Community 2.3.0.4です。
筆者の環境はバージョン1909なので、今回はEdge版をインストールします。
バージョン2004の方はStable版でも問題ないと思います。以下URLにアクセスし、
Docker Desktop for WindowsのEdge版のインストーラーをダウンロードします。
https://hub.docker.com/editions/community/docker-ce-desktop-windows/インストーラーを起動すると、最初にConfiguration画面が立ち上がります。
今回はDockerのバックエンドをWSL2にしたいので、Install required Windows components for WSL2にチェックが入っていることを確認します。
従来のHyper-V型は使わないので、Enabled Hyper-V Windows Featuresはオフにしておきます。
OKボタンをクリックするとインストールが始まります。以下画面が表示されたら成功です。
Close and log outボタンをクリックするとログアウトされるので、再度Windowsにログインします。
ログイン後、
Docker Desktop for Windowsが自動的に起動します。
しばらく待って起動に成功すると以下画面が表示されます。
Startボタンをクリックするとチュートリアルが始まりますが、今回はSKIPします。
画面上部の歯車アイコンをクリックして、Generalの設定で
Use the WSL2 backend engineがチェックされていることを確認します。
dockerコマンドが使用できるかどうか確認します。
PowerShellを起動してdocker versionコマンドを実行し、バージョンが表示されるかどうか確認します。
同じく
Ubuntuを起動してdocker versionコマンドを実行し、バージョンが表示されるかどうか確認します。
これで、WindowsでDockerが使用できるようになりました!3. VSCoceの拡張機能 Remote-Containers を使って、Goの開発環境を構築する
最後に、
Dockerコンテナ内でGoの開発を「快適に」行うための準備をしていきます。
Dockerコンテナで開発する際のメリットとしては以下のようなものがあります。
- 開発に必要な手順が記載されている
Dockerfileがあれば、コンテナを起動するだけですぐに開発できる環境が整います。- チーム内に
Dockerfileを配布すれば、チーム全員が同じ環境で開発することができます。- ランタイムやツールのインストールなどをする必要がないので、ホスト環境を汚しません。
Remote-Containersを使えば、上記のメリットに加えて、VSCodeで開発作業が行えるようになるので、コードの編集はもちろん、インテリセンス、構文チェック、定義ジャンプ、デバッグなどの豊富な支援機能も使えるようになり、コンテナ内での開発が非常にスムーズになります。それでは早速やっていきましょう。
3-1. VSCoceの拡張機能 Remote Developmentのインストール
まず、
VSCodeの拡張機能に、Remote Developmentをインストールします。
こちらはRemote-WSLとRemote-ContainersとRemote-SSHのセットになっています。
3-2. VSCodeをWSL(Ubunt)から起動する
次に、
Ubuntuを起動します。
mkdirでgo-sampleフォルダを作成し、cdで作成したフォルダに移動してから、code .コマンドでVSCodeを起動します。
すると、
VSCodeがWSL(Ubuntu)のgo-sampleフォルダを開いた状態になります。
3-3. Dockerfileの作成
次に、
go-sample直下に.devcontainerというフォルダを作成します。
.devcontainerフォルダ内に、Dockerfileという名前のファイルを作成します。
内容は以下の通りにします。goのバージョンは1.13.15にしてますが、1.14系やlatestでも問題ないです。
go getでインストールしているのはGo開発で必要なツール群です。
※コンテナをリビルドする度にインストールするのが面倒だったので、Dockerfile内に書きました。もっと良いやり方があったら教えてください!DockerfileFROM golang:1.13.15 RUN go get -v -u \ github.com/mdempsky/gocode \ github.com/uudashr/gopkgs/v2/cmd/gopkgs \ github.com/ramya-rao-a/go-outline \ github.com/acroca/go-symbols \ golang.org/x/tools/cmd/guru \ golang.org/x/tools/cmd/gorename \ github.com/cweill/gotests/... \ github.com/fatih/gomodifytags \ github.com/josharian/impl \ github.com/davidrjenni/reftools/cmd/fillstruct \ github.com/haya14busa/goplay/cmd/goplay \ github.com/godoctor/godoctor \ github.com/go-delve/delve/cmd/dlv \ github.com/stamblerre/gocode \ github.com/rogpeppe/godef \ golang.org/x/tools/cmd/goimports \ golang.org/x/lint/golint \ golang.org/x/tools/gopls3-4. devcontainer.jsonの作成
同じく
.devcontainerフォルダ内にdevcontainer.jsonという名前のファイルを作成します。
内容は以下の通りにします。settingsで設定、extentionsで拡張機能を指定できるので、お好みでどうぞ。
今回はGoの拡張機能をインストールして、設定をちょっと変えています。
エディタの環境まで共有できるのですごく便利ですね!devcontainer.json{ // VSCodeに表示されるワークスペース名 "name": "go-sample", // Docker buildを実行するディレクトリ。devcontainer.jsonファイルからの相対パスで設定します。 "context": "..", // コンテナの内容を定義するDockerfileのパス。devcontainer.jsonファイルからの相対パスで設定します。 "dockerFile": "Dockerfile", // コンテナ側のVSCodeの設定値(setting.json)を変更したい場合、設定します。 "settings": { "terminal.integrated.shell.linux": "/bin/bash", "go.formatTool": "goimports", "go.useLanguageServer": true, }, // コンテナ側のVSCodeに拡張機能をインストールする必要がある場合、拡張機能のIDを配列で設定します。 "extensions": [ "golang.Go" ] }3-5. Remote-Containersでコンテナにリモート接続する
次に、左下にある
>< WSL: Ubuntuをクリックし、Remote-Containers: Reopen in Containerを選択します。
VSCodeが再読込され、コンテナ内で起動します。
先程WSL(Ubuntu)側で作成したフォルダ/ファイルがマウントされているのがわかります。
※初回はコンテナの作成に時間がかかりますが、次回からはもう少し早く起動すると思います。
ターミナルで
Bashを起動し、go versionを実行します。
Goのバージョン1.13.15がインストールされていることを確認できます。
左下の歯車アイコンから設定を開き、
@modifiedと入力して変更した設定のみを表示します。
devcontainer.jsonのsettingsで記載した内容が、リモート側のVSCode設定に反映されていることを確認できます。
拡張機能はローカルにインストールするものとリモート側にインストールするものとで管理が分かれます。
devcontainer.jsonのextensionsで設定したGoの拡張機能がリモート側にインストールされていることを確認できます。
Dockerfileでインストールするよう設定したGoのツール群もインストールされています。
Docker Desktopでもイメージが作成されていることが確認できます。
3-6. コンテナ内でのGo開発(hello world)
環境が整ったので、コンテナ内で
Goのhello worldを作ってみます。
ワークスペース直下にmain.goという名前のファイルを作成します。
内容は以下の通りにします。コピペでなく自分で入力すると、インテリセンスやスニペットなどの支援機能が効いていることが実感できると思います。
main.gopackage main import "fmt" func main() { fmt.Println("hello world") }ターミナルでBashを開き、
go run main.goを実行します。hello worldと出力されれば成功です!
デバッグもやってみます。
main.goのソース上でfmt.Println("hellow world")にブレイクポイントを設定し、F5キーを押します。
しばらくするとデバッグが実行され、設定したブレイクポイントで止まります。
デバッグツールバーのステップオーバーをクリックするか、
F10キーを押すと次のステップへ進みます。
fmt.Plintlnが実行されて、デバッグコンソールにhello worldを出力されることが確認できます。
これで
Goのデバッグが出来るようになりました!
※デバッグを終了させる場合は再度F5キーを押してください。3-7. コンテナへのリモート接続を終了する
コンテナへのリモート接続を終了させる場合は、左下の
>< Dev Containerからリモート接続を終了するを選択するか、右上の×ボタンでVSCodeを閉じてください。
3-8. コンテナへのリモート接続を再開する
再度コンテナへのリモート接続をする場合は、
WSL(Ubunt)でgo-sampleフォルダを開き、左下の>< WSL: UbuntuからRemote-Containers: Reopen in Containerを選択してください。
初回起動では32.373秒かかりましたが、2回目は18.217秒で起動できました。
3-9. (おまけ)Windowsから直接Remote-Containersでコンテナにリモート接続する
今回は
WSL(Ubuntu)内にソースコードを配置して、WSL(Ubuntu)からVSCodeのRemote-Containersでコンテナを起動しましたが、Windows上にソースコードを配置して、Windowsからコンテナを起動することもできます。やり方は
WSL(Ubuntu)の時と同じで、3-3~3-5の手順をWindows上で行うだけです。
ソースコードはWindowsで管理したいよ!っていう方はその方法でも良いかもです。
初回起動では39.594秒かかりました。WSL(32.373秒)より若干遅い?です。
注意点としては、
Windowsからコンテナを起動すると、Docker Desktopが以下の警告を表示します。
Docker Desktopは、WindowsファイルをWSL2コンテナーに共有したことを検出しました。これはパフォーマンスが低下する可能性があります。
https://docs.docker.com/docker-for-windows/wsl/#best-practices
上記URLのDocker Desktop WSL2 Backendのベストプラクティスにもあるように、Linuxファイルシステムからマウントされるとパフォーマンスが大幅に向上するようです。Windowsファイルシステムからコンテナを起動するのは避けるように、ともあるので、気になる方はWSLでソースコードを管理したほうがよさそうです。まとめ
WSL2とDocker Desktop for WindowsとVSCodeの相性が良く、WindowsでもDocker開発がスムーズに行えるようになってきました。
Dockerfileで開発環境を共有できるのはもちろんですが、devcontainer.jsonでVSCodeの設定や拡張機能まで共有できるのもいいですね!
※Goはまだいいですが、ReactやVueなどのフロントエンドの開発だとESLintとPrettierの設定などでかなり労力を持っていかれるので、、、
これからは開発で積極的に取り入れていきたいと思います!


































