deployment kodu z capistrano
TRANSCRIPT
Deployment kodu z Capistrano
Typowy proces• Aktualizacja kodu
• Konfiguracja
• Instalacja zależności
• Aktualizacja bazy danych
• Uruchomienie aplikacji
Proste rozwiązanie
1. Pobierz najnowszą wersje kodu
2. Zaktualizuj wartości w plikach konfiguracyjnych
3. Zainstaluj zależne biblioteki A, B i C
4. Uruchom w bazie plik migrate.sql
5. Zrestartuj serwer
Problemy
• Plan awaryjny
• Aktualizacja wielu serwerów jednocześnie
• Współdzielenie plików pomiędzy releasami
• Zero downtime
Capistrano• Narzędzie do zautomatyzowanego zarządzania
zdalnymi serwerami
• Pozwala w przyjazny sposób definiować i wykonywać zadania lub całe ciągi zadań na zdalnych maszynach
• Ruby gem
• Nakładka na gem SSHKit
Instalacja
$ gem install capistrano
$ cap install
!
Instalacja"## Capfile"## config$ "## deploy$ $ "## production.rb$ $ %## staging.rb$ %## deploy.rb%## lib %## capistrano %## tasks
Capfile# Load DSL and Setup Up Stagesrequire 'capistrano/setup'!# Includes default deployment tasksrequire 'capistrano/deploy'!# Includes tasks from other gems included in your Gemfile## require 'capistrano/rails'# require 'capistrano/laravel'# require 'capistrano/symfony'# require 'capistrano/npm'!# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
deploy.rb
set :application, "my_app"set :scm, "git"set :repo_url, "[email protected]/me/my_app.git"!
set :branch, "master"set :deploy_to, "/var/www/my_app"
deploy.rb
set :application, "my_app"set :scm, "git"set :repo_url, "[email protected]/me/my_app.git"!
set :branch, "master"set :deploy_to, "/var/www/#{fetch(:application)}"
production.rb
role :app, %w{[email protected] [email protected]}role :web, %w{[email protected]}role :db, %w{[email protected]}
Zadania
$ cap -Tcap deploycap deploy:checkcap deploy:rollback!
$ cap production deploy$ cap production deploy:check
Setup serwera
$ mkdir -p /var/www/my_app$ chown -R deploy /var/www/my_app
Setup serwera/var/www/my_app"## releases%## shared "## bin "## config "## log "## public "## tmp %## vendor
Deployment
/var/www/my_app"## current (-> releases/20140521130616)"## releases$ %## 20140521130616"## repo"## releases.log %## shared
revisions.log
$ cat revisions.logBranch master (at 3fa7748) deployed as release 20140521130616 by michal
Przydatne opcjeset :linked_files, %w{config/database.yml}!
set :linked_dirs, %w{bin log tmp vendor public/system}!
set :keep_releases, 5!
ask :branch, "master"
Zadania
namespace :deploy do task :my_task do # treść endend
check_uptime
on release_roles(:all) do |host| info "Running my task on #{host}" execute :uptimeend
Flow# check everything, start a deploymentdeploy:starting !# update server(s) with a new releasedeploy:updating !# publish the new releasedeploy:publishing!# finish the deployment, clean up everythingdeploy:finishing
Flowdeploy:startingdeploy:starteddeploy:updating deploy:updateddeploy:publishingdeploy:publisheddeploy:finishingdeploy:finished!before :starting, :my_taskafter :finishing, :my_other_task
Rollback
deploy:startingdeploy:starteddeploy:revertingdeploy:reverteddeploy:publishingdeploy:publisheddeploy:finishing_rollbackdeploy:finished
Ruby on Rails Flow
deploy deploy:starting deploy:started deploy:updating deploy:updated deploy:publishing deploy:published deploy:finishing deploy:finished
Ruby on Rails Flowdeploy deploy:starting [before] deploy:ensure_stage deploy:set_shared_assets deploy:check deploy:started deploy:updating deploy:updated deploy:publishing deploy:published deploy:finishing deploy:finished
Ruby on Rails Flowdeploy deploy:starting deploy:started deploy:updating git:create_release deploy:symlink:shared deploy:updated deploy:publishing deploy:published deploy:finishing deploy:finished
Ruby on Rails Flowdeploy deploy:starting deploy:started deploy:updating deploy:updated [before] deploy:bundle [after] deploy:migrate deploy:compile_assets deploy:normalize_assets deploy:publishing deploy:published deploy:finishing deploy:finished
Ruby on Rails Flowdeploy deploy:starting deploy:started deploy:updating deploy:updated deploy:publishing deploy:symlink:release deploy:restart deploy:published deploy:finishing deploy:finished
Ruby on Rails Flowdeploy deploy:starting deploy:started deploy:updating deploy:updated deploy:publishing deploy:published deploy:finishing deploy:cleanup deploy:finished
Ruby on Rails Flowdeploy deploy:starting deploy:started deploy:updating deploy:updated deploy:publishing deploy:published deploy:finishing deploy:finished deploy:log_revision
Best practices• Trzymać konfigurację deploymentu w repozytorium
• Nie trzymać wrażliwych danych w repozytorium, tylko w shared na serwerze
• Kompilować kod na serwerze zamiast trzymać skompilowany kod w repozytorium
• Dla customowych zadań napisać hooki do deploy:starting i deploy:reverting
• Rozbudować deploy:check o sprawdzanie zależnych bibliotek
• Nie próbować zautomatyzować absolutnie wszystkiego
Pytania?
Michał Szajbe !
monterail.com !
@szajbus