diadia

興味があることをやってみる。自分のメモを残しておきます。

fabricでデプロイするために得られた知見

まずfabricでできることはなにか?

fabricでできることはshellスクリプトでもできる。シェルスクリプトが書ければfabricをあえて学習する必要ないと思われるが、fabricを使うのはpythonを使うので学習コストが低いし、pythonで書くのでコードの見通しが良くなりメンテナンス性が向上する。
そもそも現状の自分ではシェルスクリプトを満足に書くことができない。

fabricを使ってdocker-composeコマンドでデプロイするか、デプロイに必要な各コマンドを叩くかの選択肢がある。

自分の場合すでに稼働させているサーバーに対して各コマンドを叩いてデプロイを実施する。

fabricバージョン2と1がある。使い方がぜんぜん違うようだ。 旧使い方と新使い方でどのような違いがあるかチェックしたい。

fab オプションと引数 — Fabric ドキュメント

基本的な使い方

fabricのスクリプトをfabfile.pyとして記述する。fabfileというディレクトリを作成するパターンも見られル。
fabricをインストールするとfabコマンドを使うことができる。

fab fabfileの関数

これを使ってデプロイを実施していく。

fabfileの中で行うことは以下である。

  1. githubまたはbitbucketからコードをpullする。
  2. pullしたコードの中にあるrequirements.txtを読み込み、依存関係のあるパッケージをインストールする
  3. python manage.py makemigrationsを行う
  4. python manage.py migrateを行う
  5. python manage.py collectstaticを行う
  6. サービスを新たにする。

今までコードのpull, cloneはhttps通信を使っていた。この問題点はリポジトリにアクセスするとパスワードを入力される。この要求をパスしないとデプロイができないのでパスワードを聞かれないような方法でpullを実行するように変更しなければならない。 これについてはgithubやbitbucketにssh接続するとパスワードを要求されなくなることがわかった。

ではssh接続するためには何が必要か?

  1. pullを行うサーバー側においてリモートリポジトリの登録をsshバージョンで登録する
  2. サーバーにおいてssh接続を行うための秘密の鍵、公開鍵を生成する
  3. 上で生成した公開鍵をgithub, bitbucketに登録する

これをするとパスワードを要求されずにpullを実行する事ができる様になる。

軽くメモをすると、 git remote -vで表示されるリモートリポジトリの表示をsshバージョンに変更するには以下のコマンドを実行すれば良い。

git remote set-url origin git@github.com:[ユーザー名]/[リポジトリ名].git

githubで公開鍵を登録する際にはリポジトリごとに登録すると考えていたが、アカウント毎に登録する仕様になっていることが分かった。だからいくらリポジトリからsshキーの登録を探そうとしても見つからない。。。 以下にアクセスすること。
https://github.com/settings/keys

参考:
git パスワード を毎回聞かれる問題の解決方法 - Qiita
GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~ - Qiita

ディレクトリやファイルが存在するかどうかをチェックする場合について

fabricのrun関数の引数としてshellスクリプトの断片を書きまくれば良いと考えていたが、そうではなかった。fabricを使ってディレクトリの存在を確認するには以下の関数をインポートして使うようだ。そしてこれはshellスクリプトを書かないで済むからメンテナンスしやすくなってありがたい。。。

from fabric.contrib.files import exists

    def is_exist_dir(self):
        with cd("/"):
            if exists('/home/user/tet_dir'):
                print("存在する")
            else:
                print("存在しない")
fabricディレクトリの存在のチェックするには?の資料

python - Check If Path Exists Using Fabric - Stack Overflow

あと今思うのはcircleciを使わなくてもfabricだけで完結したほうがスッキリするし、circleciを利用する意義について理由を探さなければならないと思うくらい便利。

例えばgit pushを行うのはすべてfabric経由で実行する。 fabric内でテストを実行する。テストで失敗すればそのままデプロイがされないし、テスト成功したらデプロイ実行させる。
これで十分なんじゃないか...?

fabricでgunicorn のdaemonオプションが使えない時

--daemonをつけないと適切にgunicornが実行されるのに--daemonをつけたときだけうまく作動しない症状に出くわした。 これについては以下が参考になった。 Fabricでgunicornのデーモン化ができなかったアレ - Qiita

結論から言うとpty=Falseを付け加える。

run("/usr/local/bin/gunicorn --daemon --env DJANGO_SETTINGS_MODULE=config.settings.prod_settings config.wsgi:application -c {}".format(GUNICORN_CONF), pty=False)