Open4

Docker なんもわからん

あざらしあざらし

Dockerfile / docker-compose.yml

Dockerfile

1コンテナを立てるときに使う定義ファイル
軽量のイメージを作りたいときとか
単品レシピ、みたいな

docker-compose.yml

複数コンテナを立てるときに使う
Dockerfileで定義したコンテナを docker-compose で組み合わせて使うことが多い
Webサーバー、DBサーバー、管理ツール・・・みたいなのを複数使いたいときとか
オーケストレーションのつーる ということもいわれる

定食レシピ帳、みたいな

あざらしあざらし

Dockerfile のなかみ:FROM

まず書かれているはずなのが FROM hogehoge
これが、ベースとなるイメージを設定している部分

書き方としては FROM イメージ名:バージョン
例:FROM ubuntu:22.04 FROM python:3.12

このベースの上にアプリを構築していく みたいなかんじ

OSではないのか?

イメージってOSなのでは?と思っていたが、どうやら 言語・アプリ向けの公式イメージ という感じのものもあるみたい

たとえば

FROM ubuntu:22.04
と書くと、純粋なOSだけ入っているようなイメージ
NodeとかPythonとかは別途インストールするように書く必要がある

FROM python:3.12
と書くと、OSに加えて、Pythonが入った状態のイメージになる
つまり、「Pythonが実行できるような最小環境」をこの一文で設定することができる

ではどのOSを使っているのか?

https://hub.docker.com/_/python

このサイトを見ると、例えば

  • python:3.12 → Debian GNU/Linux ベース(通常は bookworm または bullseye)
  • python:3.12-slim → Debian の軽量バージョン
  • python:3.12-alpine → Alpine Linux(超軽量 Linux)

みたいな感じで、OSを指定することもできるし、デフォルトを使うこともできる

Docker Hub

Dockerイメージの共有サービス
ローカルにイメージファイル落として・・・みたいな作業はすべて吹っ飛ばして
ここにあるイメージを使うことですぐにコンテナ化することができる
(自分が作ったイメージをアップロードすることもできる)

↓DockerHubのなかでも公式のみで抽出した画面
https://hub.docker.com/search?badges=official

あざらしあざらし

Dockerfile のなかみ:WORKDIR

カレントディレクトリを指定する部分。以降はこのディレクトリ直下で実行するよ〜〜ということ
つまりcd hogehoge みたいなことをやっている

Dockerfile のなかみ:RUN

コンテナ内で実行したいコマンドをこれで書く
例えば RUN npm install とか RUN chmod +x hogehoge.sh とか
つまり、コンテナでCUIコマンドを打ちたいときに使う

Dockerfile のなかみ:CMD

コンテナを起動したときに実行されるデフォルトコマンド
例えば CMD [ "node", "app.js" ]
これは、 node app.js を実行してアプリを起動する、という意味

CMDはDockerfile内で一度しか使えないので注意
最後に書かれたものだけが有効 というかんじ
更に、docker run の時にコマンドを指定すると指定したコマンドのみが有効になる

例:

FROM ubuntu
CMD ["echo", "hello"]

こうあったとき

docker run myimage      # → echo hello が実行される(出力:hello)
docker run myimage date # → date が実行される(出力:現在日時)

Dockerfile のなかみ:ENTRYPOINT

コンテナが起動されるときに実行されるコマンド
確実に実行したいものはENTRYPOINTで書く
あとから何か渡されたら引数として扱う(CMDのように上書きはしない)

例:

FROM ubuntu
ENTRYPOINT ["echo"]

こうあったとき

docker run myimage hello    # → echo hello が実行される(出力:hello)
docker run myimage date    # → echo date が実行される(出力:date)

CMD と ENTRYPOINT を一緒に使うと

例:

FROM ubuntu
ENTRYPOINT ["echo"]
CMD ["hello"]

こうあったとき

docker run myimage            # → echo hello が実行される(出力:hello)
docker run myimage date    # → echo date が実行される(出力:date)

つまり、 CMD が ENTRYPOINT の引数になるかんじ

あざらしあざらし

FROM が2回以上出てくるんだけど

「マルチステージビルド」という
ビルド用と実行用のステージを分けて、最終的に不要なものを削ぎ落とした軽量なイメージを作ることができる

通常のビルド(FROMが1個)の場合・・・

アプリのビルドに必要なツール、アプリを実行するツール、などなどが同じイメージになる
→つまりイメージが重くなったりする

マルチステージビルド(FROMが複数)の場合・・・

例えば1つ目のステージでビルド用、2つ目のステージでコピーするだけ とすれば
最終的なイメージはビルド用のものが入っていないので軽量化できる!


たとえば以下なかんじ
最終的に動くのは「実行ステージ」以降であり、Goの環境は不要だし入らなくなる

# ===== ビルドステージ =====
FROM golang:1.20 AS builder # 1つめのイメージでGo環境を構築。builderと名付ける

WORKDIR /app
COPY . .
RUN go build -o myapp # Goをビルドする

# ===== 実行ステージ =====
FROM debian:bookworm-slim # 2つめのイメージで軽量なイメージを指定

WORKDIR /app
COPY --from=builder /app/myapp . # 1つめ(builder)からビルド後の実行ファイルをコピー

CMD ["./myapp"] # アプリ実行