Dockerはもう怖くないよ!
こんにちは!ビクトルと申します!今回Dockerに大して便利なコマンドとパターンを紹介したいと思っています。
たまに Dockerfile
を書くとき大変になってしまいます。今回は Dockerfile
にたいして役に立つコマンドやベストプラクティスについて話したいと思います。
まず基本的なDockerfile
を書きましょう
FROM golang:1.21 as builder
WORKDIR /tmp/app
COPY . .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -o /server -gcflags="-l -N" .
EXPOSE 8080
CMD ["/server"]
さきのDockerfileがフォルダーで作成して必要なファイルも作成しましょう
$ ls
Dockerfile go.mod main.go README.md
main.go
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello\n")
}
func main() {
http.HandleFunc("/hello", hello)
http.ListenAndServe(":8080", nil)
}
go.mod
go mod init github.com/example/docker
README.md
This is an example
さささ!やっていきましょう!
Build args
docker build
を実行するとき --build-args
を使ってパラメターを渡すことができます。
Multilayer
この機能について別のイメージにカプセル化やサイズなど小さくなって改善に行って行きます。
docker history example:latest
を実行して
c5ad8c7d9737 2 seconds ago /bin/sh -c #(nop) CMD ["/server"] 0B FROM a0fb5814dba9
<missing> 2 seconds ago /bin/sh -c #(nop) EXPOSE 8080 0B FROM c5ad8c7d9737
<missing> 2 seconds ago /bin/sh -c go build -o /server -gcflags="-... 6.82MB FROM 77fd079a98b7
77fd079a98b7 6 seconds ago /bin/sh -c go install github.com/go-delve/... 213MB FROM 62190e738985
62190e738985 39 seconds ago /bin/sh -c #(nop) COPY dir:f5c2e292f81ed65... 20.5kB FROM 6fd7b9fc33ed
4c88d2e04e7d 40 seconds ago /bin/sh -c #(nop) WORKDIR /tmp/app 0B FROM docker.io/library/golang:1.21
<missing> 6 days ago /bin/sh -c #(nop) WORKDIR /go 0B
<missing> 6 days ago /bin/sh -c mkdir -p "$GOPATH/src" "$GOPATH... 3.07kB
<missing> 6 days ago /bin/sh -c #(nop) ENV PATH=/go/bin:/usr/l... 0B
<missing> 6 days ago /bin/sh -c #(nop) ENV GOPATH=/go 0B
<missing> 6 days ago /bin/sh -c #(nop) ENV GOTOOLCHAIN=local 0B
<missing> 6 days ago /bin/sh -c set -eux; arch="$(dpkg --print... 224MB
<missing> 6 days ago /bin/sh -c #(nop) ENV GOLANG_VERSION=1.21.4 0B
<missing> 12 days ago /bin/sh -c #(nop) ENV PATH=/usr/local/go/... 0B
<missing> 12 days ago /bin/sh -c set -eux; apt-get update; apt... 262MB
<missing> 13 days ago /bin/sh -c apt-get update && apt-get insta... 181MB
<missing> 13 days ago /bin/sh -c set -eux; apt-get update; apt... 49.6MB
<missing> 13 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 13 days ago /bin/sh -c #(nop) ADD file:3e9b6405f11dd24... 0B
結構ありますね、サイズはどんな感じかな
localhost/example latest f48d3fcb9285 2 minutes ago 1.06 GB
ファー!!!さって魔法かけましょう
Dockerfileに少し変更して
FROM golang:1.21 as builder
WORKDIR /tmp/app
COPY . .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -o /server -gcflags="-l -N" .
FROM debian:trixie-slim as final
COPY /server /server
EXPOSE 8080
CMD ["/server"]
サイズは変わりましたか?
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/example latest 25aa1fbb8efb About a minute ago 84.4 MB
historyはどんな感じでしょうか?
ID CREATED CREATED BY SIZE COMMENT
c36612233573 4 seconds ago /bin/sh -c #(nop) CMD ["/server"] 0B FROM adec807294e4
<missing> 4 seconds ago /bin/sh -c #(nop) EXPOSE 8080 0B FROM c36612233573
<missing> 4 seconds ago /bin/sh -c #(nop) COPY file:abc6a385865f2d... 6.78MB FROM docker.io/library/debian:trixie-slim
50db52f24025 13 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 13 days ago /bin/sh -c #(nop) ADD file:0938f74e88fc9a5... 0B
non-root user
non-rootユーザ使ってセキュリティーのために権限を減らします。
docker run -ti example:latest /bin/sh
を実行してデフォルトはrootユーザ使っています。
それで Dockerfile
を変更タイム!
FROM golang:1.21 as builder
WORKDIR /tmp/app
COPY . .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -o /server -gcflags="-l -N" .
FROM debian:trixie-slim as final
RUN groupadd -r nonroot && \
useradd -r -g nonroot nonroot
WORKDIR /home/nonroot
COPY /server /home/nonroot/server
RUN chmod -R 755 /home/nonroot/server
USER nonroot
EXPOSE 8080
CMD ["/home/nonroot/server"]
と同じコマンドを実行したらシェルが$
を出してきます。
Volumes
キャッシュとかパソコンのフォルダーをコンテナの中に使用したい場合。
ENTRYPOINTとCMD
- CMD: コマンドを実行、オーバロードができます。先の
-ti
パラメターを使ってCMD
を使用しませんでした。 - ENTRYPOINT: コマンドを実行だがオーバロードできません
大ヒント! docker run -ti —entrypoint /bin/sh <image>
つかって別のentrypointを設定できます。
Distroless images
さきのイメージはdebian
とgolang
のベースイメージ使ってきましたがもっと小さいイメージも作成できます:
FROM golang:1.21 as builder
WORKDIR /tmp/app
COPY . .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN CGO_ENABLED=0 go build -o /server -gcflags="-l -N" .
FROM gcr.io/distroless/static-debian12 as final
COPY /server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
今回注意ことを確認しましょう
- CGO_ENABLED=0
- ENTRYPOINTやCMD使って大丈夫です
- 僕
podman
使ってますのでgcloud
をインストールしないといけない
それでどんなイメージを作成されましたか
REPOSITORY TAG IMAGE ID CREATED SIZE
example latest 43bb5066f693 5 minutes ago 8.7MB
8MiB。。。
ADDとCOPY
COPYはホストからコンテナにファイルをコピーします。ADDはコピーもできますがhttpリクエストもできます。
Compress RUNS
Dockerfile
には RUNやCOPYや追加したらイメージにcommitが追加されてます。
IMAGE CREATED CREATED BY SIZE COMMENT
43bb5066f693 16 minutes ago ENTRYPOINT ["/server"] 0B buildkit.dockerfile.v0
<missing> 16 minutes ago EXPOSE map[8080/tcp:{}] 0B buildkit.dockerfile.v0
<missing> 16 minutes ago COPY /server /server # buildkit 6.71MB buildkit.dockerfile.v0
<missing> N/A 233kB
<missing> N/A 346B
<missing> N/A 497B
<missing> N/A 0B
<missing> N/A 64B
<missing> N/A 149B
<missing> N/A 1.46MB
<missing> N/A 22.9kB
<missing> N/A 271kB
もしあのRUNがまとめたらどうになりましょうか
FROM golang:1.21 as builder
WORKDIR /tmp/app
COPY . .
RUN go install github.com/go-delve/delve/cmd/dlv@latest && \
go build -o /server -gcflags="-l -N" .
FROM debian:trixie-slim as final
COPY /server /server
EXPOSE 8080
CMD ["/server"]
RUNには失敗してdocker build
もう一度実行してキャッシュを使わなくて最初からビルドされてます。
ビルドtargets
docker build --target
を実行してターゲットまでにビルドされてます。
Metadata for doc Docker
コメントアウトのように開発者の資料です。
Drop capabilities
セキュリティーに対してrootに権限を下がれます。
docker build --drop-cap
Expose ports
ドキュメントのためです。
Multi architecture
docker run --platform linux/amd64
とかできます
Ignore files
.gitignore
と同じのようにしています、コンテナにコピーしたくないファイルを .dockerignore
に追加してください
Workdir
$HOME
みたいなpathです
参考
Discussion