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を使っているのか?
このサイトを見ると、例えば
- 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のなかでも公式のみで抽出した画面

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 /app/myapp . # 1つめ(builder)からビルド後の実行ファイルをコピー
CMD ["./myapp"] # アプリ実行