It is a completely working recipe tested on Windows 7 using denwer. The recipe assumes you have basic skills of working with Git. github.com is used as a basic repository in the recipe.
Attention! While the article was being written, Capistrano 3 had been released, but Capistrano 2 will be used in the recipe.
Installation
Install Ruby latest version. You can download Ruby by the link: http://rubyinstaller.org/downloads/. Having installed it, make sure Ruby path got into Path (Properties "My Computer"-> System Advanced Settings ->Environment Settings -> System Settings -> C:\Ruby200-x64\bin;...).
Install RubyGems. You can download it by the link: https://rubygems.org/pages/download. Extract archive with RubyGems into the place suitable for you. Open command line and go to directory where RubyGems is extracted. For example, we have extracted RubyGems into folder: C:/rubygems-2.4.5
.
cd c:/ cd rubygems-2.4.5
And run an installation command:
ruby setup.rb install gem update --system
Now, let's pass to installing Capistrano:
gem install capistrano --version 2.15.5
Now, it is turn for Capifony to be installed:
gem install capifony
Let's install capistrano_rsync_with_remote_cache
to work comfy with scm (subversion, git):
gem install capistrano_rsync_with_remote_cache
Capistrano assumes we have already got folder config
in the project root, as configuration files are placed in this very folder in Ruby
, but we do not have that one. We need to create it. For example, our application is placed in folder: d:/web/home/deploy.test.local/www
.
d: cd /web/home/deploy.test.local/www mkdir config
We can create folder config
with the help of Windows Explorer without using console.
If the folder where catalogue config
was created in is a root folder for the server, then it is necessary to create file .htaccess
for Apache therein that will disable viewing catalogue contents. An example of file .htaccess
:
Options All -Indexes
Capification
Having installed Capistrano, the first thing we need to do is to execute command capify .
for our application. The command will settle Capistrano configurations for application to further deploy them on the server. Prior running the command, it is necessary to ensure you are in the root folder of your application and then start the command in console:
capify .
Command capify .
will create two files:
Capfile
is a master file needed to Capistrano. It is very Capfile
. that Capistrano searches and downloads by default. In its unmodified view, generated Capfile
is very flat: it downloads file config/deploy.rb
. We do not need to know anything else about that. At this stage, let’s leave it and pass to the second file.
config/deploy.rb
is a deploy configuration file of our application.
In its original state, file deploy.rb
will look like that:
set :application, "set your application name here" set :repository, "set your repository location here" set :scm, :subversion # Or: `accurev`, `bzr`, `vcs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none` role :web, "your web-server here" # Your HTTP server, Apache/etc role :app, "your app-server here" # This may be the same as your `Web` server role :db, "your primary db-server here", :primary => true # This is where Rails migrations will run role :db, "your slave db-server here" # If you are using Passenger mod_rails uncomment this: # if you're still using the script/reapear helper you will need # these http://github.com/rails/irs_process_scripts # namespace :deploy do # task :start do ; end # task :stop do ; end # task :restart, :roles => :app, :except => { :no_release => true } do # run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}" # end # end
Let’s recompile this configuration file suitably for our needs.
Configuration
The first thing we have got to do is to name out application, e.g. "my php app":
set :application, "my php app"
Then, we need to specify repository where our application code is located. You need to have an access to this repository from your local PC and hosting where you are going to deploy your project. Now, let’s specify repository:
set :repository, "https://userName:userPassword@github.com/userName/repoName.git"
Here is an example when repository is connected with transferring username and password. It is not safe, thus, it is better not to do like that, though it suites quite well as an example.
If url
for access to repository from local PC or server differ (e.g. connection via ssh is located on the other port), then it is necessary to specify both addresses. Example:
set :repository, "ssh://git@example.com:22100/repoName.git" set :local_repository, "ssh://git@example:repoName.git"
As we use Git (by default, it is Subversion), then it is necessary to add the following line:
set :scm, :git
Now, let's specify a folder for Capistrano on the server where we need to deploy our application in. Let's consider structure of files and folders used by Capistrano to post application in order to understand those better.
An application successfully deployed via Capistrano will have the following structure (where deployTo is a catalogue where we are going to deploy application into):
deployTo deployTo/releases deployTo/releases/12345678901234 deployTo/releases/... deployTo/shared deployTo/shared/log deployTo/shared/pids deployTo/shared/system deployTo/current -> [deploy_to]/releases/12345678901234
Every time when deploying the project, a new directory with application last version will be created in folder releases
. After that, a symbolic link current
will only point to a newly created directory with a current application version. If architecture of your application is the same as the architecture of applications in Ruby on Rails where web directory and root folder of the project are different, then it is necessary to make sure that the server is set just for this directory (it is deployTo/current/public
in Ruby on Rails).
Let’s get back to our configuration file. Specify the folder in which our application is posted on the server. By default, it is folder /u/apps/#{application}
(where #{application}
is a name of our application specified in variable: application
). Our directory differs from the directory specified by default, therefore, we need to clearly specify it. For example, let’s deploy the application into folder /var/www/userSrvName/data/deployTest
:
set :deploy_to, "/var/www/userSrvName/data/deployTest"
We specify username for ssh
or ftp
access.
set :user, "userName"
We specify number of stored releases on the server (number of stored copies in folder releases
):
set :keep_releases, 3
We specify username to get access to repository. Some vcs
do not support this parameter. If version control system you use does not support this parameter than you need to specify username in parameter :repository
as shown above.
set :scm_username, "userName"
Basically, option below saves clone of your application on the server and then simply draws up changes.
set :repository_cache, "git_cache"
If you need to let Capistrano use sudo
access to perform operations, then specify true
:
set :use_sudo, false
We specify data copy protocol:
set :via, "scp"
We specify project branch where application deploy code will be taken from.
set :branch, "master"
We specify that it is necessary to save last cash version on the server and when performing a new deploy, one needs to download only updates:
set :deploy_via, :remote_cache
We disable copying specified files or catalogues:
set :copy_exclude, [".git"]
Now, we specify where our servers are located. By default, Capistrano uses three roles to post applications: web
, app
and db
. As we use only one server and role functionality is unnecessary for us, then let’s use the following syntax:
role :web, "example.com"
ssh-settings. You can set up ssh-connection by yourself but we are going to turn it off in this recipe:
set :ssh_options, { config: false #Other options... }
Let's try that
Let's try to interconnect Capistrano with our server. As a first step, we create basic folder structure by executing command (we have to stay in project root, if we did not change anything, we stay just right there):
cap deploy:setup
When executing cap deploy:setup
command, Capistrano connects to our server and consecutively performs a number of commands mkdir
to create basic structure (make sure beforehand that you have access rights to the directory you are going to deploy your application into).
We pass to dependency check. Now, when we have created basic directories and files, we request Capistrano whether everything is ready to go on with deploying application:
cap deploy:check
Command cap deploy:check
checks readiness of local and remote servers and outputs a corresponding message to us. If something goes wrong, then you will get an error message (for example, you do not have rights to make entries into a folder or etc.).
We can try to send code to the server (The code should already be in the repository specified above and the branch specified above, therefore, the branch should be created). It will not be a major deploy but simply a test of downloading code to the server. Let’s make sure everything is OK:
cap deploy:update
Command cap deploy:update
downloads code from repository to the server and installs a symbolic link current
to a new folder.
Application Deploy
At last, we have come to a real application deploy. Deploy command is only an envelope over a sequence of other commands.
As deploy:update
and deploy:finalize_update
commands are specific for Ruby on Rails applications, we need to redefine those. Except for these two commands, it is better to redefine commands deploy:start
and deploy:stop
, as they are coded for Ruby on Rails, and, if started, they will most likely lead to an error (there are other specific commands but we are not going to redefine them as we are going to cover only the basic ones):
namespace :deploy do task :start do end task :stop do end task :restart do end task :finalize_update do end end
Now, let’s automate our application deploy:
after "deploy:update", "deploy:moveToSrv" namespace :deploy do task :moveToSrv do run "cp -r /var/www/userSrvName/data/deployTest/current/* /var/www/userSrvName/data/deployTest/current/.[a-zA-Z0-9]* /var/www/userSrvName/data/www/example.com/"; end task :start do ; end task :stop do ; end task :restart do ; end end
We have stated here that after command update
, we need to start command moveToSrv
that copies files from the current release version directly into the web-site folder. You can add needed commands by yourself based on this example.
Thus, the final file looks like this:
set :application, "my php app" set :repository, "https://userName:userPassword@github.com/userName/repoName.git" set :scm, :git set :deploy_to, "/var/www/userSrvName/data/deployTest" set :user, "userName" set :keep_releases, 3 set :scm_username, "userName" set :repository_cache, "git_cache" set :use_sudo, false set :via, "scp" set :branch, "master" set :deploy_via, :remote_cache #set :copy_exclude, [".git", ".gitignore", "log", "public", "REVISION"] set :copy_exclude, [".git"] role :web, "example.com" # Your HTTP server, Apache/etc after "deploy:update", "deploy:moveToSrv" namespace :deploy do task :moveToSrv do run "cp -r /var/www/userSrvName/data/deployTest/current/* /var/www/userSrvName/data/deployTest/current/.[a-zA-Z0-9]* /var/www/userSrvName/data/www/example.com/"; end task :start do ; end task :stop do ; end task :restart do ; end end set :ssh_options, { config: false }
Now, deployer is ready for work. We execute command from application root.
cap deploy:update
or
cap deploy
Done, our application from the defined repository and defined branch have been moved into our site (example.com), now we do not need to copy files via ftp
any more. There is one problem about this recipe: it does not deploy changes in Data Base structure, though if you do wish to do that, the issue can be solved.
Application Deploy into test server/domain (multistage)
Quite often when developing an application, it is necessary to test it on a test server or sub-domain before deploying it. Extension capistrano-ext
is used for this purpose, it allows using individual configuration files and deploying for the needed server from a definite branch.
In order to install an extension, it is needed to input a command in console:
gem install capistrano-ext
Then, we create a new catalogue /path/deploy/from/config/<code> in folder <code>/path/deploy/from/config/
:
mkdir deploy
We can create folder deploy
out of Windows Explorer not using console.
Now, we place out configuration files into folder deploy
, for example production.rb
(downloading code from a wizard branch to a real server) and develop.rb
(downloading code from branch develop to a test server), and set up those according to the guidelines above. Then we compile the following two lines into file /path/deploy/from/config/deploy.rb
:
set :stages, %w(develop production) require 'capistrano/ext/multistage'
What is left is to create a basic structure for new configuration files:
cap production deploy:setup
and
cap develop deploy:setup
Now we can deploy application using commands cap production deploy
(to a real server) and cap develop deploy
(to a test server). If you need to use one more configuration, then simply create it in catalogue deploy
, set it up and add its name into variable :stages
:
set :stages, %w(test production develop)
Now, when executing command cap deploy
, Capistrano will inform that you need to specify a recipe with the help of which application deployment will be done, and then it will stop performance. To avoid such a situation, we can specify deploy recipe by default. We need to specify variable default_stage
for that. For example, application will be deployed by default from branch develop
into the test server:
set :stages, %w(test production develop) set :default_stage, "develop" require 'capistrano/ext/multistage'
After these changes, command cap deploy
will be equal to command cap develop deploy
.
Additionally
Capistrano commands. You may need some of the following commands:
Show list of possible options:
cap -h
Show list of all options and detailed description to each of them.
cap -H
Show list of all tasks and a short description to each of them.
cap -T
Show detailed information on the task set.
cap -e deploy:moveToSrv
Possible errors and ways to solve them
When calling command gem install capistrano-ext
or gem install capistrano – version 2.15.5
, an error appears:
ERROR: Could not find a valid gem 'capistrano-ext' (>= 0), here is why: Unable to download data from https://rubygems.org/ - SSL_connect retur ned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://rubygems.org/latest_specs.4.8.gz)
Run the command in console:
gem sources --add http://rubygems.org/