DjangoアプリをCapistrano使ってデプロイする
2015/11/30
Railsアプリでデプロイする、といえばCapistranoが定番感ある。
ではDjangoの場合はどうなんだ。
と、思ってググってみるも有用な情報を見いだせなかった。。
なので、Capistranoを使ってデプロイタスクを雑に書いてみる。
Contents
デプロイタスクで何をすべきか
こんな感じだろうか。
- ブランチからソースコードをpullする
- 追加ライブラリをインストール
- DBのマイグレーション
- 画像,js,cssといったアセットファイルたちを加工したり・特定の場所に移動したり
- アプリケーションサーバー(ここではgunicorn)を再起動
業務プロジェクトでデプロイするなら『Slackに通知』とかもあるだろう。
Fabricは?
Fabricでもいいんだけど、FabricってRailsでいうところのSinatraなイメージがあって、上記のタスクを実現しようとすると結構手を動かさないとダメかも&単純な構成のアプリなのでFabricほどの小回りはいらない、というで理由で不採用。
Capistranoをプロジェクトに導入
cap install
でOK
Capfile
やらdeploy.rb
やら必要なファイルたちが生成される。
deploy.rbを編集
デプロイタスクの共通部分ですね。
こんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# config valid only for current version of Capistrano lock '3.4.0' set :application, 'awesome-project' set :repo_url, 'git@github.com:hogehuga/awesome.git' set :deploy_to, '/var/www/awesome' set :scm, :git # Default value for linked_dirs is [] set :linked_dirs, fetch(:linked_dirs, []).push('static') # Default value for keep_releases is 5 set :keep_releases, 3 set :ssh_options, keys: [File.expand_path('~/.ssh/id_rsa')], forward_agent: true, auth_methods: %w(publickey) after 'deploy:updated', 'django:bundle' after 'deploy:updated', 'django:migrate' after 'deploy:updated', 'django:assets' after 'deploy:publishing', 'gunicorn:restart' |
set :linked_dirs, fetch(:linked_dirs, []).push('static')
はpython manage.py collectstatic
でアセットファイルを集約して転送する先をstaticというディレクトリをリリースバージョン間で共有したかったので指定してる。
指定しないと各バージョンごとにアセットファイルを保有するので無駄にストレージを消費しちゃうよ。
after XXX, XXX
な部分が独自に追加したタスク。
こちらは後述する。
production.rbを編集
ステージングは不要だったのでプロダクションだけ弄った。
超シンプルですね。
1 2 3 4 |
set :stage, :production set :branch, 'master' server 'XXX.XXX.XXX.XXX', user: 'deployer', roles: %w(app), primary: true |
Django関連のタスク(django.cap)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
namespace :django do task :bundle do on roles(:app) do |h| sudo "pip install -r #{release_path}/requirements.txt" end end task :migrate do on roles(:app) do |app| execute "python #{release_path}/manage.py migrate" end end task :assets do on roles(:app) do |app| execute "yes yes | python #{release_path}/manage.py collectstatic" end end end |
bundle
,migrate
,assets
のやってることは超シンプル。
Djangoやってる人なら必ず使うだろうコマンドを実行してるだけ。
Gunicorn関連のタスク(gunicorn.cap)
Gunicornの起動・停止・再起動のタスクをつらつら書いてる。
Gunicornそのものがわりとメジャーな存在だと思うので送ってるシグナルに見覚えあるはず。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
namespace :gunicorn do task :environment do set :gunicorn_pid, '/tmp/gunicorn.pid' end def start_unicorn within current_path do execute "gunicorn", "-b unix:/tmp/gunicorn.sock", "thisyou.wsgi:application", "--pid=#{fetch(:gunicorn_pid)}", "--daemon" end end def stop_unicorn execute :kill, "-TERM $(< #{fetch(:gunicorn_pid)})" execute "rm #{fetch(:gunicorn_pid)}" end def reload_unicorn execute :kill, "-HUP $(< #{fetch(:gunicorn_pid)})" end desc "Start unicorn server" task :start => :environment do on roles(:app) do start_unicorn end end desc "Restart gunicorn server gracefully" task :restart => :environment do on roles(:app) do if test("[ -f #{fetch(:gunicorn_pid)} ]") reload_unicorn else start_unicorn end end end desc "Stop unicorn server gracefully" task :stop => :environment do on roles(:app) do stop_unicorn end end end |
デプロイしてみる
cap production deploy
でOK
ログがつらつら流れてくるので、しばらく放置してると完了するはず。
336px
336px
関連記事
-
-
PythonでEnumに状態を追加する
この …