🗿
Dockerfileのテンプレートを作るCLIを作った話
初めに
個人開発でDockerを使っているのですが、毎回Dockerfileを作るのが
めんどくさくなったのでテンプレを用意しました。
とりあえずソースコードです
使い方
init
コマンドを叩くと空のDockerfileが作成でき、
create
コマンド+言語を指定するとテンプレートの言語が作成されます。
$ kuzira init
$ ls Dockerfile
Dockerfile
---
$ kuzira create go
create Dockerfile for Golang
仕組み
CLIは以下のライブラリを使っていますが、テンプレートはembedを使ってみました。
go:embed
Go1.16から追加された機能です。
go:embed はその意味の通り埋め込みができます。1.16以前もos
やio/ioutil
で読み込みなどできましたが、embedを使うとgo build
時にバイナリに埋め込むことができます。
工夫点
上記でも記載しましたが、go:embedを使っています。
そのため、今回はこのような形でテンプレートファイルをおいて参照するようにしました。
.
├── README.md
├── action
│ ├── cli.go
│ └── cookbook
│ ├── go-dockerfile
│ └── python-dockerfile
---
cookbook内にテンプレートファイルを置くようにしました。
そしてcli.goにこのような形で書きました。
package action
import (
"embed"
"fmt"
"github.com/urfave/cli"
"log"
"os"
)
//go:embed cookbook/*
var cookbook embed.FS
func Create(c *cli.Context) {
switch os.Args[2] {
case "go":
rd, err := cookbook.ReadFile("cookbook/go-dockerfile")
if err != nil {
log.Fatal(err)
}
err = os.WriteFile("Dockerfile", rd, 0644)
if err != nil {
log.Fatal(err)
}
fmt.Println("create Dockerfile for Golang")
...
}
embedの特徴はここです
//go:embed cookbook/*
var cookbook embed.FS
//go:embed cookbook/*
を指定することでその参照したいファイルを選択できます。
例えば//go:embed index.html
とすることで実行ファイルのindex.htmlを参照することができます。参照ができたら、以下のように書くことでファイルの中身を読み込むことができます。
rd, err := cookbook.ReadFile("cookbook/go-dockerfile")
改善点
今後はこのあたりを改善していこうと思います。
- テンプレートが少ない(Go,pythonのみ)
- 言語が増えるとswitchが増えてしまう
- 自分でカスタマイズできない。
まとめ
久しぶりにCLIを作成したのですが、embedができてからテンプレートの埋め込みがだいぶ楽になりました。
まだまだ改善点が多いですが、今後もCLIを作っていこうと思います。
Discussion