Deployment kodu z Capistrano

Preview:

Citation preview

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, "git@github.com/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, "git@github.com/me/my_app.git"!

set :branch, "master"set :deploy_to, "/var/www/#{fetch(:application)}"

production.rb

role :app, %w{user@s1.com user@s2.com}role :web, %w{user@s1.com}role :db, %w{user@s1.com}

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