vagrant + ansible + fabric でpythonの開発環境作る
- vagrantで開発サーバ作って
- そこにansibleでpython環境作る
- flask + uwsgiを使用して
- fabricでデプロイできるように
みたいな。
あんま突っ込んだ内容には触れてないです。
中途半端だけど、一通りまとまった情報がなかなか無くてけっこう時間費やしたので、
その辺のまとめておいてもいいかなって。
ハマりどころとかtips的に。
最終的なファイル構成はこんな感じ。
.
├── Vagrantfile
├── ansible.cfg
├── fabfile.py
├── flask
│ ├── main.py
│ ├── reload.trigger
│ ├── runserver.py
│ └── uwsgi.ini
├── inventory
├── playbooks
│ └── python.yml
└── ssh.config
vagrantで開発用のvmを作る
box追加
centos6 って名前でvagrantのboxを追加。
vagrant box add centos6 http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
設定
特に理由は無いけど2つ作ってみる。
rsyncでまとめてデプロイしてみたいし。
1個でよければ node1 だけでおk。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.define :node1 do |node|
node.vm.box = "centos6"
node.vm.network :private_network, ip: "192.168.33.10"
node.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "512"]
end
end
config.vm.define :node2 do |node|
node.vm.box = "centos6"
node.vm.network :private_network, ip: "192.168.33.11"
node.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "512"]
end
end
end
vmの ssh-config を用意
sshで繋ぐ時に便利なので。
vagrant ssh-config > ssh.config
中身はこんな感じになるはず。
Host node1
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/kuryu/.vagrant.d/insecure_private_key
IdentitiesOnly yes
LogLevel FATAL
Host node2
HostName 127.0.0.1
User vagrant
Port 2200
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/kuryu/.vagrant.d/insecure_private_key
IdentitiesOnly yes
LogLevel FATAL
起動
vagrant up
ansibleでpython環境作る
長くなるので記事分けた。
こっちを参照。
http://qiita.com/arc279/items/44ac688a2df24569f8af
インベントリはこんな感じ。
[servers]
node1
node2
↑の記事には書いてないけど、
ansible でsshする時にconfigを参照する設定を、ansibleの設定ファイルに書いておく。
ついでにインベントリファイルの指定も。
[defaults]
hostfile = inventory
[ssh_connection]
ssh_args = -F ssh.config
ansible.cfg はカレントに置いておけば勝手に読んでくれる。
実行はこう。
ansible-playbook playbooks/python.yml
flask + uwsgiを使用
本体
# -*- coding:utf-8 -*-
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "hello flask!!"
@app.route("/foo")
def foo():
return "foo"
@app.route("/foo/bar")
def foo_bar():
return "foobar"
Werkzeug 起動ファイル
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from main import app
options = {
"debug": True,
"threaded": True,
"host": "0.0.0.0",
}
app.run(**options)
Werkzeugでデバッグ起動するならコレに実行権限付けて叩けばおk。
uwsgi 設定ファイル
touch-reload で、touchされたらuwsgiをリロードする用のファイルを指定。
必要なら daemonize の指定も入れるとよいと思う。
[uwsgi]
socket = /tmp/flask.wsgi.sock
master = true
uid = vagrant
gid = vagrant
http = :5000
python-path = . # uwsgi 起動ディレクトリがカレントになってる
wsgi = main:app
processes = 3
threads = 2
pidfile = ./flask.pid
touch-reload = ./reload.trigger
env = environment=development
なんかすごい不自然な書き方だけど、
ここで env = __[key]=[value]__の形で指定しておけば、
起動時に
import os
print os.environ["environment"]
で読める。
uwsgi 起動
↑でansibleでpyenv作った時に一緒にpipでuwsgiも入れてるはずなので、
flaskのカレントで
uwsgi uwsgi.ini
で起動するはず。
fabric + rsync でデプロイ
rsyncは syncする側 と syncされる側 両方に入ってないと駄目。
↑のansibleの記事でrsyncも一緒に入れてるので、
ちゃんとplaybookが通ってればvm側にrsync入ってるはず。
ansibleのインベントリをfabricでも使用したい
詳細はこちらを参考に。
http://qiita.com/shivaken/items/c679ae9d15ac1cbebd0b
ssh-config を参照したい
こう。
env.use_ssh_config = True
env.ssh_config_path = "ssh.config"
ssh-config の指定で _vagrant_ユーザで繋ぐようになってるので、
接続先の $HOME は /home/vagrant になってる。
なので、
-
local_dir='./flask/',
手元のflaskを -
remote_dir='~/flask',
vmの /home/vagrant/flask に
rsync_project()
でrysncする。
from fabric.api import *
from fabric.decorators import roles
from fabric.contrib.project import rsync_project
import ansible.inventory
env.use_ssh_config = True
env.ssh_config_path = "ssh.config"
inventory = ansible.inventory.Inventory('inventory')
env.roledefs = inventory.groups_list()
def hostname():
run("echo %s" % env.host)
def deploy():
rsync_project(
local_dir='./flask/',
remote_dir='~/flask',
exclude=['.DS_Tore', '*.tmp'],
delete=True
)
reload()
@roles('servers')
def deployall():
deploy()
def reload():
run('touch ~/flask/reload.trigger')
fab
ロールを指定して
-R オプションでroleを指定。
ansibleのインベントリのグループ名がroleになってるらしい。
#この辺あまりちゃんと調べてない。
fab -R servers deploy
@roles('servers')
デコレータ付けてるこっちでもおk。
fab deployall
単体ホスト名を指定して
fab -H node1 deploy
で
なんかまとまりの無い内容になってしまった。
デプロイはrsyncじゃなくて git pull にするとか、
モダンなアレにしてもよいと思う。
もっとやるなら、
- ansibleで一緒にnginx入れてuwsgiに繋ぐとか
- uwsgi の start/stop もfabでできるようにするとか
いろいろあると思うけど、まぁその辺は_開発環境作る_ってことでオミット。