お題
DockerfileのRUN命令はコンテナ内で実行されるコマンドを書くんだよというだけの話。
※便宜上、Golangアプリのコンテナ化を事例とする。
開発環境
# OS - Linux(Ubuntu)
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
# Dockerコンテナ
Docker
$ sudo docker -v
Docker version 19.03.5, build 633a0ea838
RUN
どこに対して実行されるのか?
Dockerfileは自分の作業PC上で書いている。
Dockerfileは「こういうコンテナを作ってね」という指示書のようなもの。
RUNコマンドは、FROMで記載したベースイメージに対して追加で行っていく処理を表す。
※自分の作業PC上に対する処理ではない。
自分の作業PCが↓のようにあって
$ pwd
/home/sky0621/work/dockerfiles/try01/sub01
$
$ tree
.
├── Dockerfile
└── main.go
Dockerfileが以下であるとき
FROM golang:1.13.6-alpine3.11
RUN go build -o try01sub01
CMD ["./try01sub01"]
自分の作業PC上にmain.go
があるからgo build
できるだろうと勘違いして、docker build
すると以下のように失敗する。
$ sudo docker build . -t try01sub01
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM golang:1.13.6-alpine3.11
---> caaf68df625f
Step 2/3 : RUN go build -o try01sub01
---> Running in baab70c5fc22
can't load package: package .: no Go files in /go
/go
というパスにGolangのファイルがない?
確認してみる。以下のようにDockerfileに追記。
FROM golang:1.13.6-alpine3.11
RUN pwd
RUN ls -l
RUN go build -o try01sub01
CMD ["./try01sub01"]
結果は、
$ sudo docker build . -t try01sub01
Sending build context to Docker daemon 3.072kB
Step 1/5 : FROM golang:1.13.6-alpine3.11
---> caaf68df625f
Step 2/5 : RUN pwd
---> Running in 7e2456a2a237
/go
Removing intermediate container 7e2456a2a237
---> adcba019e471
Step 3/5 : RUN ls -l
---> Running in d7489f93d1f5
total 8
drwxrwxrwx 2 root root 4096 Jan 10 00:25 bin
drwxrwxrwx 2 root root 4096 Jan 10 00:25 src
Removing intermediate container d7489f93d1f5
---> a156c11921aa
Step 4/5 : RUN go build -o try01sub01
---> Running in 952b36a0a88b
can't load package: package .: no Go files in /go
RUN pwd
の結果が/go
になってる。作業PCの場所ではない。
RUN ls -l
の結果はsrc
とbin
ディレクトリが並んでる。やはり作業PCのカレントディレクトリの内容と違う。
これは、FROM
命令に記載したベースイメージ(今回指定したベースイメージのDockerfileの内容はここ参照)の中のパスを表してる。
つまり、RUN
はコンテナ内で実行されるコマンドを書くので、go build
したければ作業PC上のファイルをコンテナ内にコピーする必要がある。
以下のように。
FROM golang:1.13.6-alpine3.11
COPY . .
RUN go build -o try01sub01
CMD ["./try01sub01"]
こうすると、以下のようにビルド成功となる。
$ sudo docker build . -t try01sub01
Sending build context to Docker daemon 3.072kB
Step 1/4 : FROM golang:1.13.6-alpine3.11
---> caaf68df625f
Step 2/4 : COPY . .
---> 1ca460311aed
Step 3/4 : RUN go build -o try01sub01
---> Running in 405644fb8481
Removing intermediate container 405644fb8481
---> 56cea12c7d73
Step 4/4 : CMD ["./try01sub01"]
---> Running in 1aae16780989
Removing intermediate container 1aae16780989
---> 87d3a86afc4e
Successfully built 87d3a86afc4e
Successfully tagged try01sub01:latest
実際にイメージが作られているか確認。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
try01sub01 latest 87d3a86afc4e 56 seconds ago 361MB
<none> <none> a156c11921aa 16 minutes ago 359MB
golang 1.13.6-alpine3.11 caaf68df625f 27 hours ago 359MB
動かしてみる。
$ sudo docker run try01sub01
Hello, Dockerfile
ちなみに、main.go
の中身は下記。
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello, Dockerfile")
}