GCEでdocker-compose使ってdjangoのwebアプリをデプロイ

docker-composeでGCE上にサービスを構築します。
ローカルでやってることをデプロイ用に設定いじってあげるだけです。
公式に従っていきます。

cloud.google.com

その前に

docker

ちょっと自分のdockerfile等々を見直します。
昔見た記事を参考に、軽量化を行います。

お前のDockerイメージはまだ重い💢💢💢 - Speaker Deck

今のとこコンテナをめちゃくちゃ運用するわけではなく、特に必要性はないですが、スラッとしてるのは好みです。

世の中の無駄をなくしたい

記事の内容としては、alpineを使おう、RUNをチェインしてレイヤー数を減らそうなどなど*1*2

docker-composeのexposeとportsの違いわからんのでまた今度調べます

チェックとテスト

パッケージのバージョンが開発時に参考にしたサイトそのままだったりするので、最新バージョンのチェックとテストをします。*3

本当は最新版を入れてから開発すべきだったのですが、思い出したのがこのタイミングでした。今回は特にバグは出なかったです。

flake8*4がエラーはきまくって嫌になりますが、真面目に対応するのがこの先の労力の削減になると信じて地道に直します。

さて、本題

docker-composeの使い方の確認

インスタンス作成

公式に従いVMインスタンスの設定。OSはコンテナ専用OS。stableがいくつかあるけどデフォルトで選択されていたやつをそのまま。

HTTPSも将来的につける予定だがいつになるかわからないのでHTTPだけチェック

アカウントについて、自分で別のメンバーを作成して操作してるんですが、VMインスタンス作成に際してはいろいろ権限が必要で面倒でした。*5

インスタンスを立ち上げてssh接続します。

docker/compose イメージ

Docker container用のOSはいろいろ最適化されていて、この上でdocker-composeを通常通りインストールしてもうまく動きません。そこで、docker-composeのイメージがあるのでこちらを活用するそうです。なるほど*6

公式の手順からはずれますがalpineイメージがあるのでこちらを使ってみます

docker run docker/compose:alpine-1.25.5 version

docker-composeコンテナはRUNすることがdocker-composeコマンドと同値と理解すればよさそうです

動かしてみる

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD:$PWD" -w "$PWD" docker/compose:alpine-1.25.5 up

さてさてどうなるかな

f:id:timtoronto634:20200418230952p:plain
docker-compose_alpine_stop

!?!?
止まってる。。。

フリーズした。

ん?ああ、動いてるのか(何をやってたんだ俺は)。External IPにアクセスしたらちゃんとHello Docker Cloudがでてきました。

ここでほんとの問題発生

閉じようとおもったらctrl+Cが効きません。
ctrl+Cを押してターミナル上に(^C)と表示されるのに、コンテナが止まりません。

試しにExternal IPに接続したらログが追加で表示されました。
いや、しれっと動き続けないで笑

謎のアクセス

どうしたもんかなーと放置しながら考えてたら、自分ではないIPからのアクセスがありました。なにこれ?と思い調べたらブラジルからのアクセスで、何度も通報されてるみたいです。こわああああ

とりあえずインスタンスを強制的に閉じました。

ctrl+Cでコンテナが止まらないのはイメージの問題でしょうか。もし意図的に組み込まれたもんだったら怖いですねー、なんて

気を取り直して

docker/composeの最新版イメージを使ってるのが問題かと思ったので、試しにチュートリアルに乗ってるバージョンそのままでイメージプルしてコンテナ動かしてみました。

ctrl+Cでしっかり止まりました。
よかったよかった

余談ですが恐ろしいことに先ほどのIPからものの数秒の間にアクセスが飛んできてました。

f:id:timtoronto634:20200418235458p:plain
suspicious_access
IPアドレスをクロールして、見つかったときには集中的にアクセスみたいなことしてるんでしょうか。

いや怖すぎな?なにもされないだろうけども

自分のdocker-compose

ファイルコピー

gcloudツールでローカルからリモートに必要なファイルをコピーします。*7

ちゃんとやるときはGitHub経由しましょう

ファイアウォール設定

こちらを参考にしました。

muzirushi78.hateblo.jp

the input device is not a TTY

こちらの記事参照です

djangoで気を付けること

allowed hostsの設定

djangoのsettings.pyの中のallowed hostsにVMインスタンスIPアドレスを追加しておきましょう。*8

一回きりの動作確認とかでなければ、IPを固定しておきます。*9

困ったときはdebugをONにする

プロダクション環境ということでsettings.pyでDEBUG=0を設定していたんですが*10、エラーの内容が出ず、大変なので、開発環境で動いてるのにプロダクション環境動かないみたいな場合は少しの間デバッグ=1にするのもありかと思います。

その他参考

Alpine Linux で ユーザー/グループ を 追加/削除/一覧 する 方法 - galife

脚注/一言

*1:alpineが劇推しされてるんですが、こちら2016年の記事。今はalpineデフォルトのような印象です(俺だけ?)。時代の流れは速い。

*2:以前は理解すっ飛ばしてたalpine専用コマンドとかも確認

*3:Gunicornの最新版はいくつだろうと公式を見に行ってリリース履歴みたら、更新が不定期で結構間空いたりしてて、廃れていったりするのかなと思ったり。

*4:コードレビューツール

*5:この権限問題、足りない権限が英語で表示されるんですが、対応する権限が日本語だとわかりづらいです。権限付与する側の人は言語を英語にすることをおすすめします。

*6:そのうちdocker-composeもこの面倒な手順踏まなくてもよくなるかな

*7:インスタンスのユーザを指定しないと、新しいユーザのディレクトリが生成されます

*8:これを忘れた挙句400 Bad Requestを食らいつづけ、時間を無駄にしました

*9:VMインスタンスのページから編集をクリックして設定できます。インスタンスが動いている限りは無料みたいです。

*10:環境ファイルの中に書いてos.environ.getで取得してます