『入る学科間違えた高専生』の日記

プログラミングのコードを書いたりする予定です。あとは日記等。あといつまで高専生やねん

Fabricを使ったプロダクトをデプロイするやつ改訂版

はじめに

nnsnodnb.hatenablog.jp

以前にこんな記事を書いたんですが、どうやら古すぎて結局使えなくなってしまっていたので、
新しくまた勉強してなんとか調べまくってできるようになったので書き直しましまし

今回使う Fabric もこれです。

pypi.org

環境

開発 & ローカル

  • Python 3.7.0
    • pip 18.1
    • fabric 2.4.0
    • pipenv 2018.11.26
  • macOS 10.14.2

サーバ

準備

今回は、 fabfile.py と同ディレクトリに ssh_config を作成して設定をしておきます。

Host server_name
    Hostname example.com
    User ec2-user
    Port 22
    IdentitiesOnly yes
    IdentityFile ~/.ssh/ec2_instance.pem

それぞれは置き換えてください。

とりあえずコードドーン!!

from fabric import Config, Connection
from fabric import task
from pathlib import Path

import os
import zipfile


BASE_DIR = Path(__file__).parent
# サーバ側のpipの場所を設定
PIP = '/home/ec2-user/.pyenv/shims/pip'
# 同じくサーバ側のpipenvの場所
PIPENV = '/home/ec2-user/.pyenv/shims/pipenv'
Config.ssh_config_path = BASE_DIR / 'ssh_config'


@task
def deploy():
    with zipfile.ZipFile('./deploy_package.zip', 'w', compression=zipfile.ZIP_STORED) as new_zip:
        # fabfile.py 以外の Python スクリプトをデプロイパッケージとして zip にまとめる
        # ここらへんは、 git archive や GitPython を使って zip 化しても良し
        for code in [item for item in os.listdir(BASE_DIR) if item.endswith('.py') and item != 'fabfile.py']:
            new_zip.write(code)
        new_zip.write('Pipfile')
        new_zip.write('Pipfile.lock')

    with Connection(host='server_name') as connector:
        # 一旦、 product_dir を削除してもう一度作成
        connector.run('rm -rf /home/ec2-user/product_dir && mkdir /home/ec2-user/product_dir')

        connector.put(BASE_DIR / 'deploy_package.zip', '/home/ec2-user/product_dir')

        # ディレクトリを変更
        with connector.cd('/home/ec2-user/product_dir'):
            connector.run('unzip deploy_package.zip', pty=True)
            connector.run('rm deploy_package.zip', pty=True)
            connector.run(f'{PIP} install -U pip', pty=True)
            connector.run(f'{PIP} install pipenv==2018.11.26', pty=True)
            connector.run(f'{PIPENV} install --python 3.7.0', pty=True)

    os.remove(BASE_DIR / 'deploy_package.zip')

というような感じでポイポイーってやる。

実行方法

今回は、 deploy 関数しかないのでこれしかないですが、下の感じ。

$ pipenv run fab deploy

ちなみに、以下のように関数を用意しておくと

@task
def product_deploy():
    ・・・
$ pipenv run fab product-deploy

みたいな感じで、 - でつなげることになりました。

最後に

前回やったようなコネクションの仕方よりもどっちに対して ( ローカル なのか サーバ なのか) がはっきりしてわかりやすいなぁって感じがしました。

日記

現在は、Amazonプライムビデオでダーリン・イン・ザ・フランキスを観てます。