Pythonで書かれたWebアプリケーションをDockerでデプロイする実践

Pythonで書かれたWebアプリケーションをDockerでデプロイする実践

1. Dockerをインストールする

WSL2 に docker をインストールする https://www.jb51.net/article/223179.htm

エラーを報告します:

# docker インストール スクリプトを実行しています。コミット: 93d2499759296ac1f9c510605fef85052a2c32be

WSL が検出されました: Docker Desktop for Windows の使用をお勧めします。
https://www.docker.com/products/docker-desktop から Docker Desktop を入手してください。


このスクリプトを中止するには、Ctrl+C を押してください。
+ 睡眠 20

WindowsでDockerをダウンロードしてインストールする

ここに画像の説明を挿入

ここに画像の説明を挿入

2. コードを書く

Flask フレームワークを使用して Web サーバーを起動します。その唯一の機能は、現在の環境に環境変数「NAME」がある場合は「Hello」の後にそれを出力し、ない場合は「Hello world」を出力し、最後に現在の環境のホスト名を出力することです。

インポートOS
FlaskからFlaskをインポート 
インポートソケット 
gevent から pywsgi をインポートします
アプリ = Flask(__name__) 

@app.route('/') 
デフハロー(): 
    html = "<h3>こんにちは {name}!</h3>" \
    「<b>ホスト名:</b> {hostname}」 
    html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname()) を返します。 

__name__ == "__main__" の場合: 
    サーバー = pywsgi.WSGIServer(('0.0.0.0', 12345), アプリ)
    server.serve_forever()

依存パッケージをエクスポートする

pip フリーズ >requirements.txt
フラスコ==2.0.1
gevent==21.8.0
グリーンレット==1.1.1
危険です==2.0.1
ジンジャ2==3.0.1
マークアップセーフ==2.0.1
ツール==2.0.1
zope.event==4.5.0
zope.インターフェース==5.4.0

3. Dockerfileを書く

# 公式のPython開発イメージをベースイメージとして使用します FROM python:3.8-slim 

# 作業ディレクトリを/appに変更します 
ワークディレクトリ /app 

#現在のディレクトリ内のすべての内容を /app ADD にコピーします。 /app

# pip を使用して、このアプリケーションに必要な依存関係をインストールします # RUN pip install --trusted-host pypi.python.org -r requirements.txt 
pip install --trusted-host https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt を実行します。 
# 国内ソースの方が高速です# コンテナのポート 12345 への外部アクセスを許可 EXPOSE 12345 

# 環境変数 ENV NAME World を設定する 

# コンテナプロセスを python app.py に設定します。つまり、この Python アプリケーションの起動コマンドです。CMD ["python", "app.py"]
# CMD は暗黙的に ENTRYPOINT を含みます、/bin/sh -c

ここに画像の説明を挿入

WSL の場合:

Dockerにイメージを作成させ、-tタグを追加し、Dockerfileを自動的にロードし、その中のステートメントを実行させます。

helloworld を実行します。
[+] 建物 17.4秒 (10/10) 完了
 => [内部] Dockerfile 0.1sからビルド定義をロード
 => => dockerfile を転送中: 757B 0.0 秒
 => [内部] .dockerignore を 0.1 秒ロード
 => =>コンテキストを転送中: 2B 0.0s
 => [内部] docker.io/library/python:3.8-slim のメタデータを 2.9 秒読み込みます
 => [auth] library/python:registry-1.docker.io 0.0s のトークンをプル
 => [1/4] docker.io/library/python:3.8-slim@sha256:4dd66d1ccaddaa0587851cb92b365bf3090dccb41393c6f8b から 0.0 秒
 => [内部] ビルドコンテキストを 0.1 秒ロード
 => => コンテキストを転送中: 813B 0.0s
 => キャッシュ済み [2/4] WORKDIR /app 0.0s
 => [3/4] ./app 0.1sを追加
 => [4/4] pip install --trusted-host https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt を実行 13.6 秒
 => 画像へのエクスポート 0.6秒
 => => レイヤーのエクスポート 0.6秒
 => => 画像を書き込んでいます sha256:390d32b9f7a20ccd347361bd31450807d3e63d052e334865cf8460968ffceff4 0.0s
 => => docker.io/library/helloworld 0.0s に名前を付けます

「docker scan」を使用してイメージに対してSnykテストを実行し、脆弱性を見つけて修正方法を学びます

ミラーを見る

(k8s)PC:/mnt/d/gitcode/k8s$ dockerイメージls
リポジトリ タグ イメージ ID 作成 サイズ
helloworld 最新 390d32b9f7a2 約1分前 169MB

コンテナを起動する

docker run -p 4000:12345 helloworld

Dockerfile に CMD が指定されているためです。それ以外の場合は、 python app.py最後にプロセス起動コマンドを追加する必要があります。

コンテナの起動を表示

(ベース) $ docker ps
コンテナID イメージ コマンド 作成ステータス ポート名
f6e051d1af6b helloworld "python app.py" 2 分前 2 分前にアップ 0.0.0.0:4000->12345/tcp, :::4000->12345/tcp upbeat_elion

-p 4000:12345 は、コンテナ内のポート 12345 をホスト マシンのポート 4000 にマップするように Docker に指示します。

この目的は、ホスト マシンのポート 4000 にアクセスして、コンテナー内のアプリケーションによって返された結果を確認することです。

カール http://localhost:4000
# <h3>Hello World!</h3><b>ホスト名:</b> dc1c1343e366<br/>

コンテナを使用したアプリケーションの開発とテストを完了しました

4. 画像をアップロードする

docker hubを登録し、docker loginコマンドでログインする

docker タグ helloworld kobe24o/helloworld:v0

kobe24oはアカウント名(イメージリポジトリ)、helloworldはイメージ名、v0は自身で割り当てたバージョン番号です。

docker push kobe24o/helloworld:v0
(k8s) $ docker push kobe24o/helloworld:v0
プッシュはリポジトリ[docker.io/kobe24o/helloworld]を参照します。
931022d457d6: プッシュ中 [==================> ] 16.07MB/47.27MB
c76dc68917fc: プッシュ
047ca6dfe9ab: 押された
d82f4c466b47: library/python からマウント
5aa75f4e55e7: library/python からマウント
74d6903a940b: library/python からマウント
2f9c2b8e82bd: library/python からマウント
ba5a5fe43301: library/python からマウント

5. 画像を修正する

(ベース) $ docker ps
コンテナID イメージ コマンド 作成ステータス ポート
           名前
dd3bf057cb09 helloworld "python app.py" 7 秒前 5 秒前にアップ 0.0.0.0:4000->12345/tcp, :::4000->12345/tcp compassionate_carver

(ベース) $ docker exec -it dd3bf057cb09 /bin/sh
#パスワード
/アプリ
# 新しいファイル.txt をタッチする
# ls
Dockerファイル app.py newfile.txt requirements.txt
# 出口

(ベース) $ docker commit dd3bf057cb09 kobe24o/helloworld:v1
sha256:ca8880f84040f9bdd7ef13763b9c64f8bd4a513a74bc2b095be06aae5b60268a

上記の操作により、イメージに新しいファイルが追加され、保存がコミットされます。

docker 検査 --format '{{ .State.Pid}}' dd3bf057cb09
1763
# 実行中のコンテナのプロセスID PIDを表示します 

ホスト マシンの proc ファイルを表示すると、このプロセスのすべての名前空間に対応するファイルを確認できます。

ルート:/# ls -l /proc/{PID}/ns/
合計 0
lrwxrwxrwx 1 ルート ルート 0 9月14日 11:15 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 ルート ルート 0 9月14日 11:15 ipc -> 'ipc:[4026532220]'
lrwxrwxrwx 1 ルート ルート 0 9月14日 09:49 mnt -> 'mnt:[4026532218]'
lrwxrwxrwx 1 ルート ルート 0 9月14日 11:15 ネット -> 'net:[4026531992]'
lrwxrwxrwx 1 ルート ルート 0 9月14日 11:15 pid -> 'pid:[4026532221]'
lrwxrwxrwx 1 ルート ルート 0 9月14日 11:15 pid_for_children -> 'pid:[4026532221]'
lrwxrwxrwx 1 ルート ルート 0 9月14日 11:15 ユーザー -> 'ユーザー:[4026531837]'
lrwxrwxrwx 1 ルート ルート 0 9月14日 11:15 uts -> 'uts:[4026532219]'

プロセスは、特定のプロセスの名前空間に参加して、そのプロセスが配置されているコンテナに「入る」ことを選択できます。これはまさにdocker execの実装原理です。

ハブにプッシュ

(ベース) $ docker push kobe24o/helloworld:v1
プッシュはリポジトリ [docker.io/kobe24o/helloworld] を参照します。
dfee38b42dbb: プッシュ
931022d457d6: レイヤーが既に存在します
c76dc68917fc: レイヤーが既に存在します
047ca6dfe9ab: レイヤーが既に存在します
d82f4c466b47: レイヤーが既に存在します
5aa75f4e55e7: レイヤーが既に存在します
74d6903a940b: レイヤーが既に存在します
2f9c2b8e82bd: レイヤーが既に存在します
ba5a5fe43301: レイヤーは既に存在します
v1: ダイジェスト: sha256:7af7ff571ea9fd70d48abeaa2b38a1ed1c1a4e5a933b722d82af25d3e889f84e サイズ: 2206

Python で書かれた Web アプリケーションの Docker デプロイメントに関するこの記事はこれで終わりです。Python Web アプリケーションの Docker デプロイメントに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Docker を使用した Python Web アプリケーションの開発

<<:  HTML ウェブページのメタビューポート属性の説明

>>:  163 メールボックスログインボックスインタラクティブデザインの改善体験と共有

推薦する

MySQL で union all を使用してユニオンソートを取得する方法

プロジェクトでは、何らかの不可逆的な理由により、テーブルに保存されたデータがページの表示要件を満たす...

開発効率の向上に役立つ 56 個の実用的な JavaScript ツール関数

目次1. デジタルオペレーション(1)指定された範囲内で乱数を生成する2. 配列操作(1)配列の順序...

ドロップダウンリスト選択ボックスを実装するJavaScript

この記事の例では、ドロップダウンリスト選択ボックスを実装するためのJavaScriptの具体的なコー...

impress.js プレゼンテーション層フレームワーク (デモツール) - 初めての体験

半年もブログを書いていなかったので、少し恥ずかしいです... 正月休みは、Dota をプレイしたり ...

Vue のループフォーム項目例の詳細な説明

場合によっては、ユーザーがボタンをクリックして同様のフォームを追加し、クリックごとに 1 回追加でき...

Windows 7 で Python 3.4 を使って MySQL データベースを使用する

Python 3.4でMySQLデータベースを使用する詳細なプロセスは次のとおりです。 Window...

Avue でカスタム検索バーを実装し、検索イベントをクリアする実践

目次1. 検索バーの内容をカスタマイズする2. 検索ボタンをカスタマイズする検索バーをカスタマイズし...

さまざまな種類のMySQLインデックス

インデックスとは何ですか?インデックスは、データベース ストレージ エンジンが指定されたデータをすば...

HTML 5 プレビュー

<br />オリジナル: http://www.alistapart.com/artic...

MySQLデータベースのQPSとTPSの意味と計算方法

DB ベンチマーク テストを実行する場合、qps と tps はデータベースのパフォーマンスを測定す...

ElementUI の this.$notify.close() 呼び出しが機能しない問題の解決方法

目次要件の説明問題の説明問題分析問題解決質問の拡張要件の説明このプロジェクトでは、まずユーザーが質問...

Node.js における非同期プログラミングの知識ポイントの詳細な説明

導入JavaScript はデフォルトでシングルスレッドであるため、コードは並列実行するための新しい...

VMwareでCentOSがインターネットにアクセスできない問題を素早く解決

昨日、VMware に CentOS7 をインストールしました。Tomcat パッケージを転送するた...

MySQL の文字セットの不一致によって発生する異常な接続テーブルの解決方法

目次1. 解決策2. MySQLの文字セット文字セット検証ルール次のように簡単なテーブルクエリを実行...

Nginx ロケーション ディレクティブ URI マッチング ルールの詳細な概要

1. はじめにロケーション命令は、http モジュールのコア構成です。事前に定義された URL マッ...