Google Cloud Platform(GCP)でVMインスタンスを立ち上げ、Pythonファイルを常時稼働させる方法についてまとめました。半分以上は先輩から教えてもらったことの受け売りです。
状況
Discord上で動作するbotをPythonで作成しました。Jockey Musicなどと同様に、コマンドを入力するたびに何かしらのアクションを実行するタイプのbotなので、常時稼働させておく必要があります。ローカル環境で実行し続けるのは電気代が勿体ないので、以前はHerokuのような分かりやすいホスティングサービスを利用していました。そのHerokuが少し前に有料化してしまったので、今回はGoogle Cloud Platform(GCP)を使ってbotを動かすことにしました。
Google Cloud Platformで仮想マシンを作成する
まずは上のリンクからGoogle Cloudのアカウント登録を行います。
諸々同意して、「無料で利用開始」のところからクレジットカード情報を登録します(請求されないので大丈夫です)。
登録が終わると、MyFirstProjectというプロジェクトが勝手に作成されていると思います。もしなければ適当な名前のプロジェクトを作成します。
「VMを作成」からVMインスタンスの作成に入ります。
ここから仮想マシンの構成を決めていきます。(あまり無いと思いますが)無料枠の条件が変わってしまうこともあるかもしれないので、以下リンクから一応チェックしておくと良いかもしれません。
仮想マシンの名前は何でも良いです。リージョンをus-west1 (オレゴン)
に設定し、マシンタイプシリーズはE2
、マシンタイプはe2-micro
にします。us-central1 (アイオワ)
やus-east1 (サウスカロライナ)
も無料枠の対象ですが、日本に近いオレゴンを選ぶのが一般的なようです。ゾーンは何でも良いです。
ブートディスクの「変更」から、OS等の設定を行います。OSはUbuntu
、バージョンはLTS(長期サポート)のもののうち最新のものを選びます。2024年10月現在はUbuntu 24.04 LTS
です。Arm64
よりはx86/64
の方が良いと思います。ブートディスクの種類は標準永続ディスク
、サイズは30GB
とします。10GBのままでも良いですが、折角30GBまで無料なので。
HTTPトラフィック、HTTPSトラフィックを許可しておきます。これを許可しておくと、WEBサーバーとしての活用ができるようになります。その予定が無ければ許可しなくても大丈夫です。また、詳細オプションのネットワーキングからネットワークインターフェースの編集を行います。
外部IPv4アドレスはデフォルトでエフェメラルになっていますが、静的外部IPアドレスを予約しておきます。名前・説明は適当で良いです。
ここまで設定できたら、作成を押下して完了です。
月間予測が$7.31となっていますが、無料枠を利用していれば課金されることはありません。
公開鍵と秘密鍵を作る
PuTTYgenを使って、RSA暗号の公開鍵・秘密鍵の生成を行います。インストールは以下リンクから。
PuTTY Key Generatorを立ち上げてGenerateを押します。
この画面になったら、マウスカーソルを適当に動かしまくります。その軌道を使って暗号を作っているらしいです。
生成が終わるとこの画面になるので、Public Keyをコピーします。
以下リンクから、メタデータの設定に移ります。
SSH認証鍵1にペーストし、Enterを押下します。これで、MyFirstProject内のすべての仮想マシンがこの公開鍵を持つようになります。ユーザー名がKey commentの内容になっていることに注意(rsa-key-yyyymmddの形式)。
RSA暗号の仕組み上、公開鍵は外に漏れても問題ありません。仮想マシンに接続するためには、PuTTY Key Generatorで公開鍵と一緒に生成された秘密鍵が必要になります。
Save private keyを押して、ローカルに秘密鍵を保存します。
SSH接続する
WinSCPを使って接続します。インストールは以下リンクから。
ホスト名に先ほど立ち上げたVMインスタンスの外部IPを、ユーザー名にrsa-ssh-yyyymmdd形式のKey commentを入力します。入力したら「設定」を押します。
SSH -> 認証で、秘密鍵をセットします。拡張子は.ppkです。セットしたらOKを押し、ログインします。
左がローカル、右が仮想マシンのディレクトリとなっています。Pythonファイルを動かすためには、まず左から所望のPythonファイルを探してきて右にドラッグ&ドロップする必要があります。ただし、所有者がrootとなっているディレクトリは触れません。パーミッションがrwxr-xr-xとなっていて、我々はオーナーとしてではなくグループメンバとしてアクセスしているからです。
homeディレクトリの中に、ユーザー名のフォルダがあると思います。そこには書き込み可能(rwxrwxr-x)なので、discordという名前でディレクトリを作成し中にPythonファイルを放り込みます。
コマンドを打つ
あとはコマンドを打ってPythonファイルを動かすだけです。WinSCPでもコンソールが使えるのですが、永続的に動かすための必須コマンドnohup
がうまく動作しません(何故か接続を切られてしまいます)。そこで今回はPuTTY.exeを使います。インストールは以下リンクから。
やることはWinSCPとほぼ同じです。Host Nameには仮想マシンの外部IPアドレスを入力します。
Connection -> DataのLogin detailsでAuto-login usernameを設定します。
Connection -> SSH -> AuthのPrivate key file for authenticationに秘密鍵をセットします。
以上の設定が終わったらOpenを押します。コマンドラインが起動します。
まず、以下のコマンドを実行してpythonが入っていることを確認します。Ubuntuの最新版をイメージに設定していれば入っているはずですが、万が一なければ$ sudo apt install python3
を実行します。
$ python3 --version
Pythonファイルを実行するためには、色々モジュールをインストールしておく必要があります。特にDiscordのbotを動かす際には$ pip install discord.py
が必須です。
以下のコマンドを実行して、pipを使えるようにします。
$ sudo apt update
$ sudo apt install python3-pip
しかしおそらく、そのまま$ pip install discord.py
としても失敗します。これはroot権限でないと実行できないからです。システム全体にパッケージをインストールするのは何かと危ないので、それを阻止する設定になっています。
システム全体に影響を与えたくない場合は、Pythonの仮想環境を使ってパッケージをインストールできます。
以下は仮想環境を作成して有効化するコマンドです。
$ python3 -m venv venv
$ source venv/bin/activate
満を持して$ pip install discord.py
を実行します。私の場合は以下のモジュールをインストールしました。
$ pip install discord.py
$ pip install aiohttp
さて、あとはnohup
コマンドを打つだけです。プロセスは通常、仮想端末を閉じたりログアウトした瞬間にHUPシグナルを受け取って終了するようにできています。nohup
はそのHUPシグナルを無視するように命令するものです。すなわち、指定したプロセスがシェルを閉じた後も継続して動作するようになるのです。
Pythonファイルが置かれてあるディレクトリに移動して、nohup
コマンドを実行します。
$ cd discord
$ nohup python3 hogehoge.py &
最後に、実行できているかどうかを確かめてみます。以下は、python3で動いているプロセスを全て表示するコマンドです。
$ ps -ef | grep python3
以下のように目的のPythonファイルが動作していれば成功です。
rsa-key+ 6794 6319 1 18:11 pts/0 00:00:00 python3 hogehoge.py
この結果から、プロセス識別子(PID)が6794
であることも分かります。もうシェルを閉じようがPCを閉じようがPythonファイルは動き続けますが、実行を止めたいとなったら$kill 6794
とします。