Fabric이 뭔지도 모르던 내가 터미널에 fab deploy를 쳤다?!

Fabric & Flask 사용기

참고사이트 목록


Fabric

파이썬(2.5-2.7) 라이브러리이자 커맨드 라인 도구배포, 시스템 관리와 관련된 일들을 처리할 수 있게 해준다.

서버에 직접 접속 하지 않고, 로컬에서 Fabric 명령어를 통해 서버에 명령을 내릴 수 있다.(로컬 명령 또한 가능) Prompt input 도 받을 수 있고, 중단 역시 가능하다.

배포자동화에 사용할 수 있는 라이브러리로 간주하고 넘어가겠습니다.

Before Fabric을 알기 전…

배포를 하기위해
로컬에서 작업한 내용을 Git에 올리고 AWS EC2에 접속해서 Git으로 불러온다.
그리고 uwsgi를 다시 restart해서 변경 내용을 실제 서비스에 반영시켰다.

$ git push origin master
$ ssh -i ec2-user@xxx.xx.xx.xxx
$ cd project
$ git pull
$ sudo service uwsgi restart

ec2 인스턴스 1개 배포시 5줄 이상 명령어를 처야한다. 사실 인스턴스를 1개 쓰던 시절엔 Fabric의 필요성을 느끼지 못했다.(지금도 인스턴스가 많지는 않다..)
만약 운영중인 서비스가 대박(날수있을까?)이 나서 인스턴스의 개수가 늘어난다면? 그때도 서버 하나 하나 접속해서 명령어를 직접 입력하기에는 귀찮기도 하고, 실수할 수도 있기에 Fabric을 쓰는가보다.

After Fabric을 알고난 후!

로컬에서 두 줄 만 입력하면 배포가 끝난다.

$ fab pack
$ fab deploy

물론 어느정도 세팅을 마친 후의 이야기다.

Fabric 설치

$ pip install fabric

Fabric 설정

파일명은 다음과 같이 fabfile.py로 만든다. fabfile.py는 프로젝트의 루트 경로에 두는것을 추천한다.

– fabfile.py

from fabric.api import env, local, settings, cd, run

AWS_EC2_01 = '172.31.xx.xxx'  # Running
AWS_EC2_02 = '172.31.xx.xxx'  # Running
AWS_UTIL = '172.31.x.xx'  # Running

PROJECT_DIR = '/var/www/project'
APP_DIR = '%s/app' % PROJECT_DIR

env.user = 'ubuntu'
env.hosts = [AWS_EC2_01, AWS_EC2_02]
env.key_filename = '/Users/User/xxx.pem'


def pack():
    local('git push origin master', capture=False)


def deploy():
    with settings(warn_only=True):
        with cd(APP_DIR):
            run('sudo ./deploy.sh')
  • pack() : local 명령어를 통해 git push를 대신 수행.
  • deploy() : cd 명령어로 경로를 이동하고, run 명령어로 deploy.sh 파일을 실행한다. deploy.sh 파일에는 경로 이동 및 git pull, kill uwsgi processes, start uswgi 관련 내용이 있다.
  • env : 환경변수를 입력
  • env.hosts : 명령어를 수행할 서버의 주소의 리스트
  • env.key_filename : ssh 접속 시 사용될 키의 경로
  • env.user : 유저이름
  • run : 원격에서 쉘 명령어를 실행.
  • cd : 원격에서 경로를 변경. 원격 명령이 실행되는 동안 변경된 디렉토리에 있을 수 있도록 해주는 컨텍스트 매니저. 로컬에서는 lcd()를 사용.
  • local : 이름대로 로컬에서 명령어를 대신 실행시킨다. 위 코드에서는 git push origin master를 fab pack 이라는 명령어로 실행할 수 있다.
  • run : 원격에서 명령어를 실행한다.
  • settings : 컨텍스트 매니저, 특정 절(블럭)에서 기존의 변수에 다른 값을 적용시켜 사용할 수 있게 해준다. env의 값을 일시적으로 변경해 사용할 때 사용.
  • warn_only : Failure handling과 관련된 옵션으로 warn_only는 False를 기본값으로 가지고 있다. Fabric은 실행 중 에러를 만나면 즉시 정지되도록 되어있다.
    에러를 만날때마다 정지되면 언제 원하는 작업을 다 할 수 있을지 걱정이 되니 그럴땐 warn_only=True로 두고 실행하면 에러를 만나도 끝까지 작업을 완수할 수 있다.
    위의 deploy() 메소드에서 settings(warn_only=True)로 사용되는 것을 볼 수 있다.
env.user = 'foo'

def deploy():
    with settings(user='bar'):
        run('uwsgi --uwsgi.ini')
        run('sudo service nginx restart')

1번줄 user는 foo
4번줄에서 user를 bar로 세팅하고, 5번줄에서 user가 bar인 상태로 uwsgi 명령어를 실행한다.
with settings 절이 끝나고 나면 다시 user의 값은 초기 값(foo)으로 돌아온다.

Fabric 실행 방법

프로젝트의 루트 경로에서 ‘fab 메소드명‘을 입력한다.
각 줄에 명령어를 입력할 수도, 한 줄에 입력할 수도 있다.

$ fab pack
$ fab deploy
$ fab pack deploy     

Arguments가 필요한 메소드 실행

Fabric 공식 홈페이지에 있는 예제를 보여드립니다.

def new_user(username, admin='no', comment="No comment provided"):
    print("New User (%s): %s" % (username, comment))
    pass

username만 입력하는 경우

$ fab new_user:myusername

명시적 키워드 입력

$ fab new_user:username=myusername

순서에 맞춰 입력(구분기호 ,컴마 사용)

$ fab new_user:myusername,yes

섞어서 사용해도 무방합니다.

$ fab new_user:myusername,admin=yes

만약 print 명령어에서 컴마를 입력 해야할 경우가 있다면 \(역슬래쉬) + , 를 사용해 입력 가능합니다.

$ fab new_user:myusername,admin=no,comment='Gary\, new developer (starts Monday)'

종료 시 반환값, Exit Status

  • fab을 통한 모든 명령이 문제 없이 실행되면, 0을 반환.
  • 유효하지 않은 명령이나 옵션이 입력되면, 1을 반환.
  • 호스트 연결에 실패하면, 1을 반환하고 다음 호스트로 연결을 시도하지 않는다.
  • 로컬, 원격 명령이 실패시 1을 반환.

그냥 성공시 0 실패시 1로 생각하면 되겠군요…