Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PythonにとってのよりよいDockerfileを考える
Search
RevComm_inc
February 07, 2023
Technology
7
8.3k
PythonにとってのよりよいDockerfileを考える
2022年8月に社内のTechTalkで発表したスライドです。
「良いコンテナイメージ」に関する考察とPythonを例にしたDockerfileのサンプルを示します。
RevComm_inc
February 07, 2023
Tweet
Share
More Decks by RevComm_inc
See All by RevComm_inc
“駆け出しPlatformチーム"の立ち上がりとこれから
revcomm_inc
0
58
Company Deck -English-
revcomm_inc
1
78
2024-02-07 ソフトウェアエンジニアリングの枠を超えて:テックブログ運営で見つけた自分の役割(DevRel/Tokyo #89 〜テックブログ運営〜)
revcomm_inc
0
50
エンジニア不足の中で どう技術的負債と向き合ったのか RevComm Research の場合 -
revcomm_inc
5
8.8k
Feature Flagについて本気出して考えて実践してみた
revcomm_inc
6
4.7k
快適なテスト体験を実現する、Djangoのテスト思想と工夫
revcomm_inc
0
1.6k
Djangoの特徴とRevCommにおける選定理由
revcomm_inc
1
830
会社紹介資料/Company Deck
revcomm_inc
3
44k
エンジニア向け_会社説明資料/Company Deck for Engineers
revcomm_inc
2
33k
Other Decks in Technology
See All in Technology
GoogleのAIエージェント論 Authors: Julia Wiesinger, Patrick Marlow and Vladimir Vuskovic
customercloud
PRO
0
130
AWSマルチアカウント統制環境のすゝめ / 20250115 Mitsutoshi Matsuo
shift_evolve
0
110
Oracle Base Database Service:サービス概要のご紹介
oracle4engineer
PRO
1
16k
AWS re:Invent 2024 re:Cap Taipei (for Developer): New Launches that facilitate Developer Workflow and Continuous Innovation
dwchiang
0
160
re:Invent 2024のふりかえり
beli68
0
110
今年一年で頑張ること / What I will do my best this year
pauli
1
220
JuliaTokaiとJuliaLangJaの紹介 for NGK2025S
antimon2
1
110
Amazon Route 53, 待ちに待った TLSAレコードのサポート開始
kenichinakamura
0
160
2024年活動報告会(人材育成推進WG・ビジネスサブWG) / 20250114-OIDF-J-EduWG-BizSWG
oidfj
0
210
Bring Your Own Container: When Containers Turn the Key to EDR Bypass/byoc-avtokyo2024
tkmru
0
850
dbtを中心にして組織のアジリティとガバナンスのトレードオンを考えてみた
gappy50
0
210
月間60万ユーザーを抱える 個人開発サービス「Walica」の 技術スタック変遷
miyachin
1
140
Featured
See All Featured
YesSQL, Process and Tooling at Scale
rocio
170
14k
What's in a price? How to price your products and services
michaelherold
244
12k
4 Signs Your Business is Dying
shpigford
182
22k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
240
Docker and Python
trallard
43
3.2k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.8k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
Code Review Best Practice
trishagee
65
17k
Optimising Largest Contentful Paint
csswizardry
33
3k
Transcript
Copyright © 2022 RevComm Inc. よりよいDockerfileを考える ~Pythonの実例とともに~ RevComm Shota Kokado
Copyright © 2022 RevComm Inc. contents 1. はじめに 2. “よい
Dockerfile” とは 3. Let’s practice! 4. 実践事例の紹介
Copyright © 2022 RevComm Inc. はじめに 3 この資料の想定読者 • コンテナ技術に入門済みの人
• Dockerfile を書いたことがある人 • Web アプリケーション開発者(インタプリタ言語)
Copyright © 2022 RevComm Inc. はじめに 4 この資料の想定読者 • コンテナ技術に入門済みの人
• Dockerfile を書いたことがある人 • Web アプリケーション開発者(インタプリタ言語) この資料で話さないこと • コンテナとは何か?コンテナ技術の仕組み • ML/DL、バッチ処理用途のワークロード • コンパイル言語向けのこと(Java, Go, Rust) ◦ …Dockerfile の戦略が異なってくる (alpine とか distroless とか)
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 5
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 6 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 • 開発利便性 • 可搬性 / セキュリティ
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 7 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン (VM) と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 • 可搬性 / セキュリティ
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 8 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 9 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない ⇒Python アプリケーションを想定した実例とともに深堀り
Copyright © 2022 RevComm Inc. Let’s practice! 10
Copyright © 2022 RevComm Inc. 前提 11 • Django を動かすだけの簡単なアプリケーションを想定
• uWSGI でサーバー起動するまでを目標 JSON で応答を返す
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 12
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する 開発利便性 - ビルド時キャッシュを活用する(1/2) 13
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する 開発利便性 - ビルド時キャッシュを活用する(1/2) 14 ソースコード変更の度に「pip install …」が実行される
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する 開発利便性 - ビルド時キャッシュを活用する(1/2) 15 ソースコード変更後は 7行目から開始
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する ◦ パッケージマネージャを使用する場合 開発利便性 - ビルド時キャッシュを活用する(1/2) 16 • Pipenv ※以降、Pipenv を使用する前提のサンプルとする • Poetry
Copyright © 2022 RevComm Inc. • 必要な定型処理を先に実行する ◦ パッケージのインストールを先に行う 開発利便性
- ビルド時キャッシュを活用する(2/2) 17
Copyright © 2022 RevComm Inc. • 必要な定型処理を先に実行する ◦ パッケージのインストールを先に行う 開発利便性
- ビルド時キャッシュを活用する(2/2) 18 Pipfile / Pipfile.lock を変更した場合、 直後のビルドは7行目から開始する
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 19 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. “可搬性” (Portability) … コンテナイメージを軽量に保つことで複数のホスト・基盤上で共有しやすくする。 軽量化には不要なパッケージ・ライブラリを含めないことが重要。結果、セキュリティ向上につながる。
可搬性 / セキュリティ 20
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 21
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • 同じ命令は可能な限りまとめる レイヤの数を最小にする > RUN
、 COPY 、 ADD 命令のみレイヤを作成します。他の命令では、一時的な中間イメージ(temporary intermediate images)を作成し、構築時の容 量は増えません。 1. RUN 可搬性 / セキュリティ (1/2) - レイヤの数は最小に 22 2. COPY 3. ADD ※COPY が推奨される
Copyright © 2022 RevComm Inc. • 同じ命令は可能な限りまとめる レイヤの数を最小にする > RUN
、 COPY 、 ADD 命令のみレイヤを作成します。他の命令では、一時的な中間イメージ(temporary intermediate images)を作成し、構築時の容 量は増えません。 1. RUN 可搬性 / セキュリティ (1/2) - レイヤの数は最小に 23 2. COPY 3. ADD ※COPY が推奨される 1行目の中間レイヤーを保持するため 3-4行目はイメージサイズ削減に効果が無い
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 24
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • ベースイメージ ◦ “buster” イメージを使っていませんか?(python:3.x-buster、python:3.x-slim-buster)
◦ No!最新は “bullseye” です(= Debian 11.0) ※2022年11月時点 ◦ ベースイメージには debian バージョンを指定しなくても良いかも(alias があるので) ▪ python:3.10.8 = python:3.10.8-bullseye ▪ python:3.10.8-slim = python:3.10.8-slim-bullseye ベースイメージとパッケージを最新化する 25
Copyright © 2022 RevComm Inc. • ベースイメージ ◦ “buster” イメージを使っていませんか?(python:3.x-buster、python:3.x-slim-buster)
◦ No!最新は “bullseye” です(= Debian 11.0) ※2022年11月時点 ◦ ベースイメージには debian バージョンを指定しなくても良いかも(alias があるので) ▪ python:3.10.8 = python:3.10.8-bullseye ▪ python:3.10.8-slim = python:3.10.8-slim-bullseye • パッケージ ◦ Docker 公式ドキュメントで「Dockerfile の中で apt-get upgrade しないように」と書かれていたのは昔の話 ◦ OWASP が提唱して、Docker コミュニティも修正済み ◦ Not installing security updates is bad advice by itamarst · Pull Request #614 · OWASP/CheatSheetSeries ◦ Stop telling people not to install security updates by itamarst · Pull Request #12571 · docker/docs ◦ パッケージは必ず最新化しましょう! ◦ 定期的にイメージを更新しましょう! ベースイメージとパッケージを最新化する 26
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 27
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • デフォルトのベースイメージには無駄なパッケージが(非常に)多い ⇒slim イメージを使いましょう •
slim イメージには gcc などビルドツール群が含まれないため、Python ライブラリをビルドできない場合がある ⇒マルチステージビルドを使う ◦ slim イメージに gcc をインストールするのは 可搬性 / セキュリティ (2/2) - 不要なパッケージをインストールしない 28
Copyright © 2022 RevComm Inc. ここまでの整理 • slim イメージを使用する ◦
Python ライブラリの準備を “not slim イメージ” で行う (マルチステージビルド) 可搬性 / セキュリティ (2/2) - 不要なパッケージをインストールしない 29
Copyright © 2022 RevComm Inc. ここまでの整理 • slim イメージを使用する ◦
Python ライブラリの準備を “not slim イメージ” で行う (マルチステージビルド) • 課題 ◦ パッケージマネージャー (Pipenv / Poetry) をアプリケーションに含めたくない ◦ dev-packages (テスト用ツールなど)を本番用イメージから分離した ▪ CI では dev-packages を使いたい 可搬性 / セキュリティ (2/2) - 不要なパッケージをインストールしない 30 アプリケーション自体に Pipenv は要らない (普通は)
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 31 こちらでも見れます
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 32 FROM [base image] AS [stage name] という形式 1つの FROM 命令のブロックが1ステージと対応
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 33 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv が不要となる
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 34 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv 不要となる 2. ステージ: builder / dev-builder ◦ requirements.txt を元にライブラリを準備する ◦ COPY --from=[stage name] … でステージ間でファイルを受け取る ◦ prod 用、dev 用の2通りを用意
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 35 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv 不要となる 2. ステージ: builder / dev-builder ◦ requirements.txt を元にライブラリを準備する ◦ COPY --from=[stage name] … でステージ間でファイルを受け取る ◦ prod 用、dev 用の2通りを用意 3. ステージ: base ◦ 最終的なアプリケーション用の環境をセットアップ ◦ 必要なパッケージをインストール ◦ ※一般ユーザーを作成、スイッチなど(割愛) libpq5: PostgreSQL 接続に必要 libxml2: uWSGI 実行に必要
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 36 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv 不要となる 2. ステージ: builder / dev-builder ◦ requirements.txt を元にライブラリを準備する ◦ COPY --from=[stage name] … でステージ間でファイルを受け取る ◦ prod 用、dev 用の2通りを用意 3. ステージ: base ◦ 最終的なアプリケーション用の環境をセットアップ ◦ 必要なパッケージをインストール ◦ ※一般ユーザーを作成、スイッチなど(割愛) 4. ステージ: dev / prod ◦ Python ライブラリをインストール ◦ ソースコードを配置 ◦ ※dev / prod で CMD を分ける、など適宜 ◦ docker build --target [stage-name] .... でビルド対象ステージを 指定する
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 37
Copyright © 2022 RevComm Inc. 実践事例の紹介 38
Copyright © 2022 RevComm Inc. • とあるマイクロサービスに対して実践したところ、大幅に効果があった Before 実践事例の紹介 39
Copyright © 2022 RevComm Inc. • とあるマイクロサービスに対して実践したところ、大幅に効果があった Before 実践事例の紹介 40
①slim イメージを使っていない ②アプリケーション起動が root ユーザー
Copyright © 2022 RevComm Inc. After 実践事例の紹介 41 ①slim イメージを使用するように変更。
builder ステージでライブラリをでインストール・ビルドし、 runner ステージで利用。 ①一般ユーザーでアプリケーションを起動するように変更。 ※80番ポートを起動できないためポート番号も変更。
Copyright © 2022 RevComm Inc. • 開発利便性と軽量性/セキュリティ は両立できる(相反する性質ではない) • なるべく
slim イメージを使用しましょう • マルチステージビルドを活用することで「アプリケーションに必要十分な環境」が作りやすくなる ◦ 開発 / 本番用イメージを同一 Dockerfile で管理できる(DRY 原則を保てる) ※必要に応じて Dockerfile を分離して可読性を維持する(要はバランス) リンク • サンプルコード: GitHub revcomm/public-slide-docker-multistage-build-for-python ◦ dev コンテナ: ユニットテスト実行 ◦ prod コンテナ:アプリケーション起動、動作確認 • 仕事でPythonコンテナをデプロイする人向けのDockerfile (1): オールマイティ編 | フューチャー技術ブログ • 軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog まとめ 42
Copyright © 2022 RevComm Inc. Have a good container life!
43