はじめに
今回は、VSCodeの拡張機能でGitHub Copilotを使って、シンプルなWebアプリケーション実行環境をDockerで構築した体験談をお届けします。
背景としまして最近、会社でGithub Copilotの積極利用が推奨されていまして、かつ自分自身が新たにGo言語のサービスの運用を任されたこともあり「Go言語の勉強をしながらCopilotも触ってみよう!」という試みになります。
早速命令してみる
以下の画像のように結構雑に命令してみました。
「まずはdocker-compose.ymlから」って言ったら「なめんなよ」ってことで一式全部提案してくれました。
「ワークスペースの作成...」を押すと親ディレクトリを指定して、本当に一式作成することができました。ここが一番気持ちいいですね。
作られたファイルたちの紹介
実際に作られたファイルの中身をご紹介。
まずはdocker-compose.ymlです。
今回の想定はDBは必要としないシンプルなアプリケーションだったので、
Goが動作するwebサーバーのコンテナだけあれば良くて、希望通りといったところ。
version: '3.8'
services:
go-qiita-app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
- PORT=8080
volumes:
- ./src:/app/src
networks:
- go-qiita-network
networks:
go-qiita-network:
driver: bridge
続いてDockerfile
FROM golang:1.20 AS builder
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY src/ ./src/
RUN go build -o go-qiita-app ./src/main.go
FROM gcr.io/distroless/base
COPY --from=builder /app/go-qiita-app /go-qiita-app
CMD ["/go-qiita-app"]
そしてアプリケーションのコードまで書いてくれちゃう。
そこはGoの勉強のために自分で書きたいところではあるが、気が利きすぎたCopilot。
go.modファイルの中身は載せてませんが、gorilla/muxというウェブアプリ用のルーターのパッケージまで用意してくれました。
アプリケーションのコードは一度読み解いて、自分で色々カスタマイズします。
package main
import (
"log"
"net/http"
"github.com/gorilla/mux"
"go-qiita-app/src/handlers"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/articles", handlers.GetArticles).Methods("GET")
http.Handle("/", r)
log.Println("Starting server on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
package handlers
import (
"encoding/json"
"net/http"
"log"
"io/ioutil"
)
const qiitaAPIURL = "https://qiita.com/api/v2/items"
// Article represents a Qiita article
type Article struct {
Title string `json:"title"`
URL string `json:"url"`
}
// GetArticles fetches articles from the Qiita API
func GetArticles(w http.ResponseWriter, r *http.Request) {
resp, err := http.Get(qiitaAPIURL)
if err != nil {
http.Error(w, "Failed to fetch articles", http.StatusInternalServerError)
log.Println(err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
http.Error(w, "Failed to fetch articles", resp.StatusCode)
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
http.Error(w, "Failed to read response body", http.StatusInternalServerError)
log.Println(err)
return
}
var articles []Article
if err := json.Unmarshal(body, &articles); err != nil {
http.Error(w, "Failed to parse articles", http.StatusInternalServerError)
log.Println(err)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(articles)
}
Dockerを立ち上げてみる
諸々準備してもらったので、早速Dockerを立ち上げてみる。
$ docker compose build
~~~諸々省略~~~
"/go.sum": not found
しかしさすがに一発ではうまくいかず。
Dockerfileにプロジェクトルートのgo.sumファイルをコピーする工程がありますが、
go.sumファイルが存在していませんでした。
Copilotにとことん任せると決めたので、エラーの解決もCopilotに任せる。
チャットで、うまく立ち上がらなくてこんな事を怒られたよと伝えたら、
以下のように返信がきました。
ということで言われた通りに実行。
$ go mod tidy
go: go-qiita-app/src imports
github.com/gorilla/mux: github.com/tidwall/gjson@v1.12.3: reading github.com/tidwall/gjson/go.mod at revision v1.12.3: unknown revision v1.12.3
するとまたもや失敗。
tidwall/gjsonのバージョンがよろしくなさそう。
Copilotに聞いてみる。
解決策を示してくれました。
ただ、「2024年8月時点の最新」が気になったので、
github.com/tidwall/gjsonのリポジトリのタグを見に行き、
最新のv1.18.0を使うことにしました。
go.modのgithub.com/tidwall/gjsonがv1.12.3だったので
修正してもう一度go mod tidyで無事にgo.sumが出来上がりました。
さあ立ち上げ再チャレンジ
$ docker compose build
~~~中略~~~
[+] Building 1/1
✔ qiitaapp-go-qiita-app Built
イェ〜〜〜イ✌️
ビルドは無事成功したのでコンテナ立ち上げへ。
$ docker compose up -d
~~~中略~~~
[+] Running 3/3
✔ qiitaapp-go-qiita-app Built 0.0s
✔ Network qiitaapp_go-qiita-network Created 0.0s
✔ Container qiitaapp-go-qiita-app-1 Started 0.2s
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4b0657090d60 qiitaapp-go-qiita-app "/go-qiita-app" 8 seconds ago Up 7 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp qiitaapp-go-qiita-app-1
イェ〜〜〜イ✌️
ではでは、ブラウザで確認してみましょう。

QiitaのAPIを利用して記事を取得・表示しようとしているのですが、
どうやらQiitaのAPIに疎通がうまくいかなかったみたいです。
ここからは本来の目的の一つであるGoの勉強ということで自分でコードを色々いじってみようと思います。
ここも完璧に作られてしまったら学習の余地がないということで、その意図まで汲んでくれた優秀なCopilotでした。
ということで記事はここまで。Docker環境をさくっと作ってくれたGithub Copilotに感謝🙏
まとめ
Copilotのチャット機能を活用することで、エラーに直面しながらも、かな〜りスムーズにDocker環境構築を進めることができました。
バイブコーディングの魅力に少し触れることができたので、もっと本格的なものにもこれからチャレンジしていきたいと思っています。


