急にデプロイできなくなった
zappa deploy
済みのアプリに対してzappa update
できていたはずが、急に update できなくなった。
CloudWatchのログをみるとcryptographyがちゃんと入っていないことが原因のようだが、ちゃんと入っているはず(と思ってた)
[ERROR] ModuleNotFoundError: No module named 'cryptography'
Traceback (most recent call last):
File "/var/task/handler.py", line 655, in lambda_handler
return LambdaHandler.lambda_handler(event, context)
File "/var/task/handler.py", line 249, in lambda_handler
handler = global_handler or cls()
File "/var/task/handler.py", line 146, in __init__
self.app_module = importlib.import_module(self.settings.APP_MODULE)
仮想環境を作り直して update したり、 zappa undeploy
してから zappa deploy
しても改善せず。
原因はキャッシュ
情報を探していたらそれっぽいのを見つけた。
Add a command to clear the wheel cache
zappaでdeployするとwheelファイルがキャッシュされ、次のdeploy時にキャッシュ済みのwheelファイルを使用しようとするのだが、
このwheelファイルちゃんと作成できていないことがある。
私の場合は通信タイムアウトが原因だった。特にデプロイ中にPyPIにアクセスしたりすると発生しやすいっぽい。
Downloading and installing dependencies..
- cryptography==37.0.3: Downloading
0%| | 13.3k/4.04M [00:04<22:30, 2.98kB/s]
HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
Packaging project as zip.
0%| | 0.00/27.9M [00:00<?, ?B/s]
一度こうなるとまともなwheelファイルじゃないのに「キャッシュあるやんけ!使ったろ!」とzipにパッケージングしてしまう。
結果、Lambda上でModuleNotFoundError
になってしまうのでした。
実際にファイルを確認したが、本来4MBあるはずのwheelファイルが13KBしかなく明らかにおかしかった。
対策
キャッシュを削除してからデプロイすればいい。
私はキャッシュが保持されているフォルダを削除するプログラムを作って、デプロイのフローに組み込んだ。
import shutil
import tempfile
def delete_cached_wheels():
# zappaがwheelのキャッシュを作成する場所
# Macでの例: '/var/folders/vj/dcgw_0kj26ncm1lp7cshdqt40000gp/T/cached_wheels'
# Windowsでの例: 'C:¥Users¥ユーザー名¥AppData¥Local¥Temp¥cached_wheels'
temp_dir = tempfile.gettempdir()
cached_wheels_path = os.path.join(temp_dir, 'cached_wheels')
if os.path.isdir(cached_wheels_path):
shutil.rmtree(cached_wheels_path)
急にデプロイできなったのでヒヤヒヤしました。
別の人の助けになれば。