Deploy aplicatii web cu Capistrano
Postat la Sat 31 October 2015 in tutoriale
Am prezentat anterior efectuarea deploy-ului la aplicatiile web folosind git. Este o solutie simpla ce se aplica la proiectele mici si one-man job. Dar in cazul proiectelor mai mari/complexe situatia e diferita:
- exista un risc mai mare ca un bug sa scape;
- e nevoie de un sistem de deploy pe mai multe stagii de dezvoltare (devel, testare, productie);
- e nevoie de un sistem de deploy pe mai multe servere simultan;
- e nevoie de un sistem care sa permita un rollback rapid si usor al codului la o versiune stabila anterioara.
O aplicatie ce rezolva cu success astfel de probleme este Capistrano, scris in Ruby si folosit intens de aceasta comunitate.
Instalarea este usoara daca avem instalata pe sistem un versiune de Ruby >= 1.9.3 sau daca folosim RVM:
gem install capistrano
Scriptul de de deploy poate fi instalat oriunde de exemplu in folderul cap-deploy. in care initializam configuratia de deploy cu comanda:
cap install
sau in cazul multii stage:
cap install STAGES=devel,test,productie
ce va produce urmatoarea structura:
.
├── Capfile
├── config
│ ├── deploy
│ │ ├── devel.rb
│ │ ├── productie.rb
│ │ └── test.rb
│ └── deploy.rb
└── lib
└── capistrano
└── tasks
Setarile generale legate de proiect se regasesc in fisierul config/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 | config valid only for current version of Capistrano lock '3.4.0' #nume aplicatie set :application, 'proiect' # locatia repo git ptr poiect set :repo_url, 'git@github.com:user/proiect_repo.git' # locatia unde se face deploy pe server set :deploy_to, '/var/www/#{fetch(:application)}' # tipul repo, default git set :scm, :git # fisierele comune ce nu se regasesc in repo din motive de securitate si se face link set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml') # foldere comune ce nu se regasesc in repo (upload, logs, cache etc) set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system') # Numar de deploy-uri ce se pastreaza pe server, default sunt 5 # set :keep_releases, 5 |
La nivel de stagiu se definesc serverele, de exemplu in fisierul config/deploy/productie.rb
1 2 3 4 5 6 7 8 9 | # Definire la nivel de server server 'fe-1.domeniu.ro', user: 'deploy', roles: %w{app} server 'fe-2.domeniu.ro', user: 'deploy', roles: %w{app web} # Definire servere dupa rol role :app, %w{deploy@fe-1.domeniu.ro deploy@fe-2.domeniu.ro}, role :web, %w{deploy@fe-2.domeniu.ro}, |
Trebuie sa ne asiguram ca:
- cheia noastra publica se regaseste pe fiecare server de deploy
- serverul are o cheie valida cu care se poate conecta la serverul de git unde este gazduit poiectul
Ca masura suplimentara de protectie se recomanda folosirea metodei de forward a cheii private (utilizate de user-ul ce face deploy), dupa cum este explicat aici.
Deploy-ul propriu zis se face usor cu comanda cap in folderul de pe calculatorul master (ce controleaza operatia de deploy)
1 2 3 4 5 6 7 8 | # deploy pe serverele de dezvoltare cap devel deploy # deploy pe serverele de testare cap test deploy # deploy pe serverele de productie cap productie deploy |
Comanda va crea urmatoarea structura de foldere pe servere:
├── current -> /var/www/proiect/releases/20151018104909
├── releases
│ └── 20151018104909
├── repo
├── revisions.log
└── shared
├── config
└── tmp
├── pids
├── cache
└── vendors
unde gasim:
- releases - versiunile de cod puse pe server in foldere cu data si ora efectuarii deploy-ului
- repo - copia locala a repo-ului
- shared - foldere si fisiere comune tuturor deploy-urilor
- current - o legatura simbolica la versiunea curenta a codului. De accea directorul radacina a aplicatiei este pecificat acesta
- revision.log - un log al operatiilor efectuate
Spor la deploy.