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
9.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
94
Company Deck -English-
revcomm_inc
1
100
2024-02-07 ソフトウェアエンジニアリングの枠を超えて:テックブログ運営で見つけた自分の役割(DevRel/Tokyo #89 〜テックブログ運営〜)
revcomm_inc
0
72
エンジニア不足の中で どう技術的負債と向き合ったのか RevComm Research の場合 -
revcomm_inc
5
9.2k
Feature Flagについて本気出して考えて実践してみた
revcomm_inc
7
5.9k
快適なテスト体験を実現する、Djangoのテスト思想と工夫
revcomm_inc
0
1.8k
Djangoの特徴とRevCommにおける選定理由
revcomm_inc
1
960
会社紹介資料/Company Deck
revcomm_inc
3
61k
エンジニア向け_会社説明資料/Company Deck for Engineers
revcomm_inc
2
47k
Other Decks in Technology
See All in Technology
DB 醬,嗨!哪泥嘎斯基?
line_developers_tw
PRO
0
150
“プロダクトを好きになれるか“も QAエンジニア転職の大事な判断基準だと思ったの
tomodakengo
0
130
工具人的一生: 開發很多 AI 工具讓我 慵懶過一生
line_developers_tw
PRO
0
140
doda開発 生成AI元年宣言!自家製AIエージェントから始める生産性改革 / doda Development Declaration of the First Year of Generated AI! Productivity Reforms Starting with Home-grown AI Agents
techtekt
0
130
Digitization部 紹介資料
sansan33
PRO
1
4.2k
Autonomous Database サービス・アップデート (FY25)
oracle4engineer
PRO
2
760
What's new in OpenShift 4.19
redhatlivestreaming
1
220
型システムを知りたい人のための型検査器作成入門
mame
14
3.7k
白金鉱業Meetup_Vol.19_PoCはデモで語れ!顧客の本音とインサイトを引き出すソリューション構築
brainpadpr
2
300
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
2.1k
技術職じゃない私がVibe Codingで感じた、AGIが身近になる未来
blueb
0
120
「伝える」を加速させるCursor術
naomix
0
620
Featured
See All Featured
Scaling GitHub
holman
459
140k
Code Review Best Practice
trishagee
68
18k
Side Projects
sachag
454
42k
Building Applications with DynamoDB
mza
95
6.4k
What's in a price? How to price your products and services
michaelherold
245
12k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
The Cost Of JavaScript in 2023
addyosmani
50
8.3k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.2k
Building Adaptive Systems
keathley
43
2.6k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.6k
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