さて、年末年始休暇でなんかやってみよう その1

なにかやってみよう

前回、こんなことを思いついてみたので、色々と調べてみたので早速、実務にも役立つ感じで、まとめていければと思った。

Flaskを使ったDocker環境を作ってGoogle Cloudに構築

完全なる元ネタはここにあります。

ただ、私なりの解釈とアップデートをいくつか入れました。
始めます。

フォルダ構成

docker-gcpapp
│├ templates
││└ index.html
│└ app.pyDockerfileRequirements.txt

最終的にはこんな構成にします(現在はdocker-gcpフォルダにいる前提で以降の話は進みます)

Flaskを使ったPythonアプリ

= app/app.py =
from flask import Flask, Response, jsonify, render_template, logging, request
app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)
= app/templates/index.html =
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>hello world!</h1>
</body>
</html>

こんな感じのファイルを用意します。

次にrequirements.txtを作成するために、下記のコマンドを実行

pip freeze > requirements.txt

Pythonのプログラムを書いたことがある人はなんども目にしますね

Docker用のファイル作成

= Dockerfile =
FROM python:3.8

ENV PORT 80
ENV HOST 0.0.0.0

EXPOSE 80

RUN apt-get update -y && \
    apt-get install -y python3-pip

COPY ./requirements.txt /app/requirements.txt

WORKDIR /app

RUN pip install -r requirements.txt

COPY ./app /app

ENTRYPOINT ["python", "app.py"]

簡単に言うと、pythonが入っているDockerをベースにapt-getですべてのパッケージを最新化し、python3-pipをインストール。その後、requirements.txtを使って必要なパッケージをインストールし、Docker上にappフォルダを作成し、そこにFlaskをコピーする。Pythonで実行されるプログラムはapp.pyを指定
ここまで分かれば、自分で変更したい場合に、何を直せばいいかわかりますね。

次はDockerを動かしてみる

最初に、DockerをInstallしておいてください。

> docker build .
[+] Building 6.5s (11/11) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.5s
 => => transferring dockerfile: 32B                                                                                0.1s
 => [internal] load .dockerignore                                                                                  0.3s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/python:3.8                                                      3.5s
 => [internal] load build context                                                                                  0.3s
 => => transferring context: 473B                                                                                  0.0s
 => [1/6] FROM docker.io/library/python:3.8@sha256:3a519327ab069a4e356a8aa279e80b7ef6270e17c5df1493dd0a5b281755e9  0.0s
 => CACHED [2/6] RUN apt-get update -y &&     apt-get install -y python3-pip                                       0.0s
 => CACHED [3/6] COPY ./requirements.txt /app/requirements.txt                                                     0.0s
 => CACHED [4/6] WORKDIR /app                                                                                      0.0s
 => CACHED [5/6] RUN pip install -r requirements.txt                                                               0.0s
 => [6/6] COPY ./app /app                                                                                          0.6s
 => exporting to image                                                                                             1.2s
 => => exporting layers                                                                                            0.6s
 => => writing image sha256:fb7d91a2daf74669e5d22bf3560b02b6ab843fcd63f9bc71fe2555d119385f96                       0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

最後の「.」は重要です。カレントフォルダ内のDockerfileを使ってDocker Imageを作成します
作成できたら、次のコマンドを実行します

> docker images
REPOSITORY              TAG       IMAGE ID       CREATED        SIZE
<none>                  <none>    5db4d5bb9e12   9 hours ago    980MB

こんな風に出ていればOK
で、こんな感じで起動します

> docker run -p 5000:80 5db4d5bb9e12
 * Serving Flask app 'app' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:80
 * Running on http://172.17.0.2:80
Press CTRL+C to quit

意味は、80番ポートを、5000番ポートとして、IMAGE ID: 5db4d5bb9e12を起動します。
http://localhost:5000
で「hello world!」が表示されればDocker Imageの確認は完了です

Google Cloud Runで動かしてみる

Cloud Runの説明は省略します。自身で調べてください。
早速、コマンドですが下記の通りに実行していきます
※そうそう、先程のDockerの止め方は、Ctrl+Cで止まると書いてありますが、止まるときと、止まらないときがあります。止まらないときは、Docker Desktopからプロセスを止めてください

Google Cloudにアクセスして、適当にプロジェクトを作成します。そのときにプロジェクトIDが発行されるので、それを控えておきます

> docker tag 5db4d5bb9e12 gcr.io/[PROJECT ID]/docker-gcp
> docker images
REPOSITORY                                                TAG       IMAGE ID       CREATED         SIZE
gcr.io/********/docker-gcp   latest    5db4d5bb9e12   9 hours ago     980MB

こんな感じで、REPOSITORYが変わっていればOKです
ここからはGoogle Cloudのコマンド操作です

> gcloud init
> gcloud auth configure-docker
> docker push gcr.io/********/docker-gcp

終わったら、Google CloudでCloud Runを選択し、サービスの作成をします
サービス名を選択するところで、先程Pushしたイメージを選択します
リージョンはus-central1(アイオワ)を選択します
インスタンスの最大数は1に変更します(費用を抑えるために)
認証は未認証の呼び出しを許可を選択します
そして、「作成」ボタンを押す
その後、すぐに「新しいリビジョンの編集とデプロイ」を選択して、コンテナポートを8080→80に変更し、「デプロイ」ボタンを押します
※これを忘れると起動しません
画面上部に、URLが表示されるので、それをクリックすると、Dockerで試した「hello world!」が再度表示されます

さて、GithubのPushに連動して、自動でデプロイできる手段は、後日。

この記事が気に入ったらサポートをしてみませんか?