---
title: Cloud Native Buildpacks Tutorial - 5.5. ┗ heroku/buildpacks:18 BuilderでPythonアプリのOCIイメージを作成
tags: ["Cloud Native Buildpacks Tutorial", "Cloud Native Buildpacks", "Heroku", "Series"]
categories: ["Dev", "Infrastructure", "CloudNativeBuildpacks", "Heroku"]
date: 2020-04-28T10:30:13Z
updated: 2020-05-11T03:35:07Z
---

`heroku/buildpacks:18`でPythonのアプリケーションのOCIイメージを作成します。

BuilderとStackを予めpullしておいてください。

```
docker pull heroku/buildpacks:18
docker pull heroku/pack:18
```

次のコマンドで"Hello World"アプリケーションを作成します。

```
mkdir hello-flask
cd hello-flask
cat <<'EOF' > web.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
  return 'Hello World!'
EOF

cat <<'EOF' > requirements.txt
Flask==1.1.1
EOF

cat <<'EOF' > Procfile
web: FLASK_APP=web.py python3 -m flask run --host=0.0.0.0 --port=$PORT
EOF
```

`pack build`コマンドでイメージを作成します。

```
pack build making/pack-flask --no-pull --builder heroku/buildpacks:18
```

> BuilderとStackを事前にpullしていない場合は`--no-pull`を外せば、ビルド時にBuilderとStackもpullしますが、ビルドが遅くなります。

次のようなログが出力されます。

```
===> DETECTING
[detector] heroku/python   0.1.2
[detector] heroku/procfile 0.5
===> ANALYZING
[analyzer] Warning: Image "index.docker.io/making/pack-flask:latest" not found
===> RESTORING
===> BUILDING
[builder] cp: cannot create regular file '/layers/heroku_python/shim/.heroku/requirements.txt': No such file or directory
[builder] -----> Installing python-3.6.10
[builder] -----> Installing pip
[builder] -----> Installing SQLite3
[builder] Sqlite3 successfully installed.
[builder] -----> Installing requirements with pip
[builder]        Collecting Flask==1.1.1
[builder]          Downloading Flask-1.1.1-py2.py3-none-any.whl (94 kB)
[builder]        Collecting click>=5.1
[builder]          Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
[builder]        Collecting Jinja2>=2.10.1
[builder]          Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
[builder]        Collecting Werkzeug>=0.15
[builder]          Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
[builder]        Collecting itsdangerous>=0.24
[builder]          Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
[builder]        Collecting MarkupSafe>=0.23
[builder]          Downloading MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl (27 kB)
[builder]        Installing collected packages: click, MarkupSafe, Jinja2, Werkzeug, itsdangerous, Flask
[builder]        Successfully installed Flask-1.1.1 Jinja2-2.11.2 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 itsdangerous-1.1.0
[builder] -----> Discovering process types
[builder]        Procfile declares types     -> web
===> EXPORTING
[exporter] Adding layer 'launcher'
[exporter] Adding layer 'heroku/python:profile'
[exporter] Adding 1/1 app layer(s)
[exporter] Adding layer 'config'
[exporter] *** Images (66da02aac1f1):
[exporter]       index.docker.io/making/pack-flask:latest
[exporter] Adding cache layer 'heroku/python:shim'
Successfully built image making/pack-flask
```

> `pack build`時に`--publish`オプションをつけると、Docker Registryでのpushを行います。事前に`docker login`が必要です。

作成したイメージを`docker run`で起動します。

```
docker run --rm -e PORT=8080 -p 8080:8080 making/pack-flask
```

アプリケーションにアクセスします。

```
$ curl localhost:8080 -w '\n'
Hello World!
```

Docker Imageのサイズを確認します。

```
$ docker images | grep making/pack-flask
making/pack-flask                    latest              66da02aac1f1        40 years ago        648MB
```

`pack inspect-image`でイメージを解析します。

```
$ pack inspect-image making/pack-flask
Inspecting image: making/pack-flask

REMOTE:
(not present)

LOCAL:

Stack: heroku-18

Base Image:
  Reference: 60f9e03398de7d6a5268be95224246f05eed9f1eecb1fe7605753261f2bd871a
  Top Layer: sha256:ceefbd5b67bc32a9d87867c8c8d375675246e9db9b470cb95133b4e93429b113

Run Images:
  heroku/pack:18

Buildpacks:
  ID                     VERSION
  heroku/python          0.1.2
  heroku/procfile        0.5

Processes:
  TYPE                 SHELL        COMMAND                                                                  ARGS
  web (default)        bash         FLASK_APP=web.py python3 -m flask run --host=0.0.0.0 --port=$PORT  
```

おわったらDocker Imageを削除します。

```
docker rmi making/pack-flask
```
