mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
fix layout
indentation for pygments must start at column 0 lines wrapped at column 80-ish
This commit is contained in:
parent
dc24096bb8
commit
85a8d1fac8
17 changed files with 421 additions and 423 deletions
|
@ -2,24 +2,28 @@
|
||||||
title: Capistrano in ruby script
|
title: Capistrano in ruby script
|
||||||
layout: default
|
layout: default
|
||||||
---
|
---
|
||||||
Instead of building a config folder and deploy, you may want to programmatically set everything in a single ruby script. This could be done as follows:
|
|
||||||
|
Instead of building a config folder and deploy, you may want to
|
||||||
|
programmatically set everything in a single ruby script. This could be done as
|
||||||
|
follows:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
require 'capistrano/all'
|
require 'capistrano/all'
|
||||||
|
|
||||||
stages = "production"
|
stages = "production"
|
||||||
set :application, 'my_app_name'
|
set :application, 'my_app_name'
|
||||||
set :repo_url, 'git@github.com:capistrano/capistrano.git'
|
set :repo_url, 'git@github.com:capistrano/capistrano.git'
|
||||||
set :deploy_to, '/var/www/'
|
set :deploy_to, '/var/www/'
|
||||||
set :stage, :production
|
set :stage, :production
|
||||||
role :app, %w{}
|
role :app, %w{}
|
||||||
|
|
||||||
require 'capistrano/setup'
|
require 'capistrano/setup'
|
||||||
require 'capistrano/deploy'
|
require 'capistrano/deploy'
|
||||||
Dir.glob('capistrano/tasks/*.rake').each { |r| import r }
|
Dir.glob('capistrano/tasks/*.rake').each { |r| import r }
|
||||||
|
|
||||||
Capistrano::Application.invoke("production")
|
Capistrano::Application.invoke("production")
|
||||||
Capistrano::Application.invoke("deploy")
|
Capistrano::Application.invoke("deploy")
|
||||||
{% endhighlight%}
|
{% endhighlight%}
|
||||||
|
|
||||||
Note that the require order is important as the stage needs to be set before you load setup and deploy.
|
Note that the require order is important as the stage needs to be set before
|
||||||
|
you load setup and deploy.
|
||||||
|
|
|
@ -35,7 +35,7 @@ Capistrano will read the host filter from the environment variable `HOSTS`
|
||||||
if it is set. You can set it inline:
|
if it is set. You can set it inline:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
HOSTS=server1,server2 cap production deploy
|
HOSTS=server1,server2 cap production deploy
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Specify multiple hosts by separating them with a comma.
|
Specify multiple hosts by separating them with a comma.
|
||||||
|
@ -46,7 +46,7 @@ You can set the host filter inside your deploy configuration. For example,
|
||||||
you can set the following inside `config/deploy.rb`:
|
you can set the following inside `config/deploy.rb`:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
set :filter, :host => %w{server1 server2}
|
set :filter, :host => %w{server1 server2}
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Note that you specify the filter as an array rather than as a comma-separated
|
Note that you specify the filter as an array rather than as a comma-separated
|
||||||
|
@ -58,7 +58,7 @@ In a similar way to using the environment variable, you can set the role
|
||||||
filter by specifying it as a command line argument to `cap`:
|
filter by specifying it as a command line argument to `cap`:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
cap --hosts=server1,server2 production deploy
|
cap --hosts=server1,server2 production deploy
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Like the environment variable method, specify multiple servers by separating
|
Like the environment variable method, specify multiple servers by separating
|
||||||
|
|
|
@ -3,7 +3,9 @@ title: Overriding Capistrano tasks
|
||||||
layout: default
|
layout: default
|
||||||
---
|
---
|
||||||
|
|
||||||
When re-defining a task in Capistrano v2, the original task was replaced. The Rake DSL on which Capistrano v3 is built is additive however, which means that given the following definitions
|
When re-defining a task in Capistrano v2, the original task was replaced. The
|
||||||
|
Rake DSL on which Capistrano v3 is built is additive however, which means that
|
||||||
|
given the following definitions
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
task :foo do
|
task :foo do
|
||||||
|
@ -17,13 +19,18 @@ end
|
||||||
|
|
||||||
Will print both `foo` and `bar`.
|
Will print both `foo` and `bar`.
|
||||||
|
|
||||||
But it is also possible to completely clear a task and then re-defining it from scratch. A `Rake::Task` provides the `clear` method for this, which internally performs three separate actions:
|
But it is also possible to completely clear a task and then re-defining it
|
||||||
|
from scratch. A `Rake::Task` provides the `clear` method for this, which
|
||||||
|
internally performs three separate actions:
|
||||||
|
|
||||||
- `clear_prerequisites`
|
- `clear_prerequisites`
|
||||||
- `clear_actions`
|
- `clear_actions`
|
||||||
- `clear_comments`
|
- `clear_comments`
|
||||||
|
|
||||||
Clearing the prerequisites (i.e. any dependencies that may have been defined for a task) is probably not what you want, though. Let's say, for example, that you want to re-define the `deploy:revert_release` task, which is defined as follows:
|
Clearing the prerequisites (i.e. any dependencies that may have been defined
|
||||||
|
for a task) is probably not what you want, though. Let's say, for example,
|
||||||
|
that you want to re-define the `deploy:revert_release` task, which is defined
|
||||||
|
as follows:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
task :revert_release => :rollback_release_path do
|
task :revert_release => :rollback_release_path do
|
||||||
|
@ -31,9 +38,12 @@ task :revert_release => :rollback_release_path do
|
||||||
end
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Calling `clear` on this task and then re-defining it results in `rollback_release_path` never being called, thus breaking rollback behavior.
|
Calling `clear` on this task and then re-defining it results in
|
||||||
|
`rollback_release_path` never being called, thus breaking rollback behavior.
|
||||||
|
|
||||||
Under most circumstances, you will simply want to use `clear_actions`, which removes the specified task's behaviour, but does not alter it's dependencies or comments:
|
Under most circumstances, you will simply want to use `clear_actions`, which
|
||||||
|
removes the specified task's behaviour, but does not alter it's dependencies
|
||||||
|
or comments:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
task :init do
|
task :init do
|
||||||
|
|
|
@ -3,21 +3,25 @@ title: PTYs
|
||||||
layout: default
|
layout: default
|
||||||
---
|
---
|
||||||
|
|
||||||
There is a configuration option which asks the backend driver to ask the remote host
|
There is a configuration option which asks the backend driver to ask the
|
||||||
to assign the connection a *pty*. A *pty* is a pseudo-terminal, which in effect means
|
remote host to assign the connection a *pty*. A *pty* is a pseudo-terminal,
|
||||||
*tell the backend that this is an __interactive__ session*. This is normally a bad idea.
|
which in effect means *tell the backend that this is an __interactive__
|
||||||
|
session*. This is normally a bad idea.
|
||||||
|
|
||||||
Most of the differences are best explained by [this page](https://github.com/sstephenson/rbenv/wiki/Unix-shell-initialization) from the author of *rbenv*.
|
Most of the differences are best explained by [this
|
||||||
|
page](https://github.com/sstephenson/rbenv/wiki/Unix-shell-initialization)
|
||||||
|
from the author of *rbenv*.
|
||||||
|
|
||||||
**When Capistrano makes a connection it is a *non-login*, *non-interactive* shell.
|
**When Capistrano makes a connection it is a *non-login*, *non-interactive*
|
||||||
This was not an accident!**
|
shell. This was not an accident!**
|
||||||
|
|
||||||
It's often used as a band aid to cure issues related to RVM and rbenv not loading login
|
It's often used as a band aid to cure issues related to RVM and rbenv not
|
||||||
and shell initialisation scripts. In these scenarios RVM and rbenv are the tools at fault,
|
loading login and shell initialisation scripts. In these scenarios RVM and
|
||||||
or at least they are being used incorrectly.
|
rbenv are the tools at fault, or at least they are being used incorrectly.
|
||||||
|
|
||||||
Whilst, especially in the case of language runtimes (Ruby, Node, Python and friends in
|
Whilst, especially in the case of language runtimes (Ruby, Node, Python and
|
||||||
particular) there is a temptation to run multiple versions in parallel on a single server
|
friends in particular) there is a temptation to run multiple versions in
|
||||||
and to switch between them using environmental variables, this is an anti-pattern, and
|
parallel on a single server and to switch between them using environmental
|
||||||
symptomatic of bad design (e.g. you're testing a second version of Ruby in production because
|
variables, this is an anti-pattern, and symptomatic of bad design (e.g. you're
|
||||||
your company lacks the infrastructure to test this in a staging environment).
|
testing a second version of Ruby in production because your company lacks the
|
||||||
|
infrastructure to test this in a staging environment).
|
||||||
|
|
|
@ -9,16 +9,15 @@ As an example, this task can be used to ensure that files to be linked exist
|
||||||
before running the check:linked_files task:
|
before running the check:linked_files task:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
namespace :deploy do
|
namespace :deploy do
|
||||||
namespace :check do
|
namespace :check do
|
||||||
task :linked_files => 'config/newrelic.yml'
|
task :linked_files => 'config/newrelic.yml'
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
remote_file 'config/newrelic.yml' => '/tmp/newrelic.yml', roles: :app
|
remote_file 'config/newrelic.yml' => '/tmp/newrelic.yml', roles: :app
|
||||||
|
|
||||||
file '/tmp/newrelic.yml' do |t|
|
|
||||||
sh "curl -o #{t.name} https://rpm.newrelic.com/accounts/xx/newrelic.yml"
|
|
||||||
end
|
|
||||||
|
|
||||||
|
file '/tmp/newrelic.yml' do |t|
|
||||||
|
sh "curl -o #{t.name} https://rpm.newrelic.com/accounts/xx/newrelic.yml"
|
||||||
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
|
@ -28,7 +28,7 @@ Capistrano will read the role filter from the environment variable `ROLES`
|
||||||
if it is set. You can set it inline:
|
if it is set. You can set it inline:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
ROLES=app,web cap production deploy
|
ROLES=app,web cap production deploy
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Specify multiple roles by separating them with a comma.
|
Specify multiple roles by separating them with a comma.
|
||||||
|
@ -39,7 +39,7 @@ You can set the role filter inside your deploy configuration. For example,
|
||||||
you can set the following inside `config/deploy.rb`:
|
you can set the following inside `config/deploy.rb`:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
set :filter, :roles => %w{app web}
|
set :filter, :roles => %w{app web}
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Note that you specify the filter as an array rather than as a comma-separated
|
Note that you specify the filter as an array rather than as a comma-separated
|
||||||
|
@ -51,7 +51,7 @@ In a similar way to using the environment variable, you can set the role
|
||||||
filter by specifying it as a command line argument to `cap`:
|
filter by specifying it as a command line argument to `cap`:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
cap --roles=app,web production deploy
|
cap --roles=app,web production deploy
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Like the environment variable method, specify multiple roles by separating them
|
Like the environment variable method, specify multiple roles by separating them
|
||||||
|
|
|
@ -5,7 +5,7 @@ layout: default
|
||||||
|
|
||||||
Configuration variables are access with the fetch method, like so:
|
Configuration variables are access with the fetch method, like so:
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
local = fetch(:configuration_variable, _default_value_)
|
local = fetch(:configuration_variable, _default_value_)
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This works fine when accessing configuration variables defined within the same file. For example accessing a previously set configuration variable defined in deploy.rb or accessing a set configuration variable in a stage file.
|
This works fine when accessing configuration variables defined within the same file. For example accessing a previously set configuration variable defined in deploy.rb or accessing a set configuration variable in a stage file.
|
||||||
|
|
|
@ -61,21 +61,21 @@ First, we'll try a *real* SSH session, logging in via our terminal, and seeing
|
||||||
what happens:
|
what happens:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh me@remote
|
me@localhost $ ssh me@remote
|
||||||
me@remote $ [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
|
me@remote $ [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
|
||||||
Interactive
|
Interactive
|
||||||
me@remote $ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
|
me@remote $ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
|
||||||
Login shell
|
Login shell
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Contrast that with what happens when we hand the command to run to the SSH
|
Contrast that with what happens when we hand the command to run to the SSH
|
||||||
command line without logging in first...
|
command line without logging in first...
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh me@remote "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"
|
me@localhost $ ssh me@remote "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"
|
||||||
Interactive
|
Interactive
|
||||||
me@localhost $ ssh me@remote "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"
|
me@localhost $ ssh me@remote "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"
|
||||||
Not login shell
|
Not login shell
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Here we can see that Bash is still starting in **interactive** mode when we're
|
Here we can see that Bash is still starting in **interactive** mode when we're
|
||||||
|
@ -87,26 +87,26 @@ can have a very simple, Capfile, we don't even need to load the default
|
||||||
recipes to test this:
|
recipes to test this:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
# Capistrano 3.0.x
|
# Capistrano 3
|
||||||
task :query_interactive do
|
task :query_interactive do
|
||||||
on 'me@remote' do
|
on 'me@remote' do
|
||||||
info capture("[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'")
|
info capture("[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
task :query_login do
|
task :query_login do
|
||||||
on 'me@remote' do
|
on 'me@remote' do
|
||||||
info capture("shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'")
|
info capture("shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Gives us the following:
|
Gives us the following:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ cap query_login
|
me@localhost $ cap query_login
|
||||||
INFO Not login shell
|
INFO Not login shell
|
||||||
me@localhost $ cap query_interactive
|
me@localhost $ cap query_interactive
|
||||||
INFO Not interactive
|
INFO Not interactive
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
## <a id="which_startup_files_loaded"></a>Which shell startup files do get loaded?
|
## <a id="which_startup_files_loaded"></a>Which shell startup files do get loaded?
|
||||||
|
|
|
@ -3,18 +3,19 @@ title: Authentication & Authorisation
|
||||||
layout: default
|
layout: default
|
||||||
---
|
---
|
||||||
|
|
||||||
**Note:** In the documentation we simply recommend creating a single deployment user,
|
**Note:** In the documentation we simply recommend creating a single
|
||||||
and sharing it between team members. If you know why this is a bad idea (or
|
deployment user, and sharing it between team members. If you know why this is
|
||||||
why this may be against regulations in your jurisdiction in some cases, we
|
a bad idea (or why this may be against regulations in your jurisdiction in
|
||||||
assume that you know well enough how to use groups, umasking and setgid bits
|
some cases, we assume that you know well enough how to use groups, umasking
|
||||||
to make this work reliably for unique logins across team members)
|
and setgid bits to make this work reliably for unique logins across team
|
||||||
|
members)
|
||||||
|
|
||||||
To create this deploy user we'll assume something like the following has been
|
To create this deploy user we'll assume something like the following has been
|
||||||
done:
|
done:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
root@remote $ adduser deploy
|
root@remote $ adduser deploy
|
||||||
root@remote $ passwd -l deploy
|
root@remote $ passwd -l deploy
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
The first line creates a completely standard user, it has a home directory,
|
The first line creates a completely standard user, it has a home directory,
|
||||||
|
@ -54,7 +55,7 @@ quits or gets fired, you can remove their key from that file, and the rest of
|
||||||
you can keep on shipping!
|
you can keep on shipping!
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh-keygen -t rsa -C 'me@my_email_address.com'
|
me@localhost $ ssh-keygen -t rsa -C 'me@my_email_address.com'
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
You'll be prompted for a passphrase, that's fine. Type one and keep it safe.
|
You'll be prompted for a passphrase, that's fine. Type one and keep it safe.
|
||||||
|
@ -72,15 +73,15 @@ minutes upwards.)
|
||||||
We can see which keys are loaded in the SSH agent by running `ssh-add -l`
|
We can see which keys are loaded in the SSH agent by running `ssh-add -l`
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh-add -l
|
me@localhost $ ssh-add -l
|
||||||
2048 af:ce:7e:c5:93:18:39:ff:54:20:7a:2d:ec:05:7c:a5 /Users/me/.ssh/id_rsa (RSA)
|
2048 af:ce:7e:c5:93:18:39:ff:54:20:7a:2d:ec:05:7c:a5 /Users/me/.ssh/id_rsa (RSA)
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
If you don't see any keys listed, you can simply run `ssh-add`:
|
If you don't see any keys listed, you can simply run `ssh-add`:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh-add
|
me@localhost $ ssh-add
|
||||||
Identity added: /Users/me/.ssh/id_rsa (/Users/me/.ssh/id_rsa)
|
Identity added: /Users/me/.ssh/id_rsa (/Users/me/.ssh/id_rsa)
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Typically, ssh-add will ask you for the passphrase when you add a key.
|
Typically, ssh-add will ask you for the passphrase when you add a key.
|
||||||
|
@ -98,8 +99,8 @@ At this point with the key loaded into the agent, we need to put the
|
||||||
we can ask our local key agent for the public parts of the keys it has loaded:
|
we can ask our local key agent for the public parts of the keys it has loaded:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh-add -L
|
me@localhost $ ssh-add -L
|
||||||
ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa
|
ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This will be a lot longer when you run it, I snipped the output because it
|
This will be a lot longer when you run it, I snipped the output because it
|
||||||
|
@ -116,13 +117,13 @@ If you are on linux there often exists a command
|
||||||
process, otherwise the workflow is something like:
|
process, otherwise the workflow is something like:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh root@remote
|
me@localhost $ ssh root@remote
|
||||||
root@remote $ su - deploy
|
root@remote $ su - deploy
|
||||||
deploy@remote $ cd ~
|
deploy@remote $ cd ~
|
||||||
deploy@remote $ mkdir .ssh
|
deploy@remote $ mkdir .ssh
|
||||||
deploy@remote $ echo "ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa" >> .ssh/authorized_keys
|
deploy@remote $ echo "ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa" >> .ssh/authorized_keys
|
||||||
deploy@remote $ chmod 700 .ssh
|
deploy@remote $ chmod 700 .ssh
|
||||||
deploy@remote $ chmod 600 .ssh/authorized_keys
|
deploy@remote $ chmod 600 .ssh/authorized_keys
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
**Remember:** This needs to be done on every server you want to use, you can
|
**Remember:** This needs to be done on every server you want to use, you can
|
||||||
|
@ -132,9 +133,9 @@ use the same key for each one, but only one key per developer is recommended.
|
||||||
If we did all that correctly, we should now be able to do something like this:
|
If we did all that correctly, we should now be able to do something like this:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime'
|
me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime'
|
||||||
one-of-my-servers.com
|
one-of-my-servers.com
|
||||||
19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05
|
19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
That should happen without having to enter a passphrase for your SSH key, or
|
That should happen without having to enter a passphrase for your SSH key, or
|
||||||
|
@ -192,8 +193,8 @@ Github.
|
||||||
Here's how we can check if that works, first get the URL of the repository:
|
Here's how we can check if that works, first get the URL of the repository:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ git config remote.origin.url
|
me@localhost $ git config remote.origin.url
|
||||||
git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
|
git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Here we're listing our private (for testing purposes) fork of the
|
Here we're listing our private (for testing purposes) fork of the
|
||||||
|
@ -203,11 +204,11 @@ Tutorials project.
|
||||||
We can try to access the repository via our server by doing the following:
|
We can try to access the repository via our server by doing the following:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
# List SSH keys that are loaded into the agent
|
# List SSH keys that are loaded into the agent
|
||||||
me@localhost $ ssh-add -l
|
me@localhost $ ssh-add -l
|
||||||
# Make sure they key is loaded if 'ssh-add -l' didn't show anything
|
# Make sure they key is loaded if 'ssh-add -l' didn't show anything
|
||||||
me@localhost $ ssh-add
|
me@localhost $ ssh-add
|
||||||
me@localhost $ ssh -A deploy@one-of-my-servers.com 'git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
|
me@localhost $ ssh -A deploy@one-of-my-servers.com 'git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
We first check that the agent has the keys loaded. If not we simply load it
|
We first check that the agent has the keys loaded. If not we simply load it
|
||||||
|
@ -225,15 +226,15 @@ to the list of known hosts.
|
||||||
From the SSH documentation:
|
From the SSH documentation:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
-A Enables forwarding of the authentication agent connection. This can also be
|
-A Enables forwarding of the authentication agent connection. This can also be
|
||||||
specified on a per-host basis in a configuration file.
|
specified on a per-host basis in a configuration file.
|
||||||
|
|
||||||
Agent forwarding should be enabled with caution. Users with the ability to
|
Agent forwarding should be enabled with caution. Users with the ability to
|
||||||
bypass file permissions on the remote host (for the agent's UNIX-domain
|
bypass file permissions on the remote host (for the agent's UNIX-domain
|
||||||
socket) can access the local agent through the forwarded connection. An
|
socket) can access the local agent through the forwarded connection. An
|
||||||
attacker cannot obtain key material from the agent, however they can perform
|
attacker cannot obtain key material from the agent, however they can perform
|
||||||
operations on the keys that enable them to authenticate using the identities
|
operations on the keys that enable them to authenticate using the identities
|
||||||
loaded into the agent.
|
loaded into the agent.
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
In layman's terms, you shouldn't use SSH agent forwarding to machines where you
|
In layman's terms, you shouldn't use SSH agent forwarding to machines where you
|
||||||
|
@ -254,9 +255,9 @@ Github, we'll be prompted for a username and password:
|
||||||
##### 1.2.2.1 With a regular username/password
|
##### 1.2.2.1 With a regular username/password
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
|
me@localhost $ git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
|
||||||
Username for 'https://github.com': myownusername
|
Username for 'https://github.com': myownusername
|
||||||
Password for 'https://capistrano@github.com':
|
Password for 'https://capistrano@github.com':
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This challenge response prompt doesn't work well for automating things, so
|
This challenge response prompt doesn't work well for automating things, so
|
||||||
|
@ -269,9 +270,9 @@ HTTPS not plain ol' HTTP is to embed the username and password in the URL,
|
||||||
note this won't work well if your password has special characters:
|
note this won't work well if your password has special characters:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
|
me@localhost $ git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
|
||||||
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
|
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
|
||||||
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
|
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
The bigger problem with passwords, whether inlined into the URL, or entered
|
The bigger problem with passwords, whether inlined into the URL, or entered
|
||||||
|
@ -286,9 +287,9 @@ Tokens](https://github.com/blog/1509-personal-api-tokens) which allow you to
|
||||||
do something like this:
|
do something like this:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ git ls-remote https://XXXX:@github.com/capistrano/rails3-bootstrap-devise-cancan.git
|
me@localhost $ git ls-remote https://XXXX:@github.com/capistrano/rails3-bootstrap-devise-cancan.git
|
||||||
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
|
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
|
||||||
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
|
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Where `XXXX` is a personal API token, as such:
|
Where `XXXX` is a personal API token, as such:
|
||||||
|
@ -338,16 +339,16 @@ To configure this hierarchy, ignoring for the moment the passwordless `sudo`
|
||||||
access that you may or may not need depending how well your servers are setup:
|
access that you may or may not need depending how well your servers are setup:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh root@remote
|
me@localhost $ ssh root@remote
|
||||||
# Capistrano will use /var/www/....... where ... is the value set in
|
# Capistrano will use /var/www/....... where ... is the value set in
|
||||||
# :application, you can override this by setting the ':deploy_to' variable
|
# :application, you can override this by setting the ':deploy_to' variable
|
||||||
root@remote $ deploy_to=/var/www/rails3-bootstrap-devise-cancan-demo
|
root@remote $ deploy_to=/var/www/rails3-bootstrap-devise-cancan-demo
|
||||||
root@remote $ mkdir -p ${deploy_to}
|
root@remote $ mkdir -p ${deploy_to}
|
||||||
root@remote $ chown deploy:deploy ${deploy_to}
|
root@remote $ chown deploy:deploy ${deploy_to}
|
||||||
root@remote $ umask 0002
|
root@remote $ umask 0002
|
||||||
root@remote $ chmod g+s ${deploy_to}
|
root@remote $ chmod g+s ${deploy_to}
|
||||||
root@remote $ mkdir ${deploy_to}/{releases,shared}
|
root@remote $ mkdir ${deploy_to}/{releases,shared}
|
||||||
root@remote $ chown deploy ${deploy_to}/{releases,shared}
|
root@remote $ chown deploy ${deploy_to}/{releases,shared}
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
**Note:** The `chmod g+s` is a really handy, and little known Unix feature, it
|
**Note:** The `chmod g+s` is a really handy, and little known Unix feature, it
|
||||||
|
@ -362,11 +363,11 @@ files from Apache, or our web server by running the web server in the `deploy`
|
||||||
group namespace.
|
group namespace.
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
root@remote # stat -c "%A (%a) %n" ${deploy_to}/
|
root@remote # stat -c "%A (%a) %n" ${deploy_to}/
|
||||||
drwx--S--- (2700) /var/www/rails3-bootstrap-devise-cancan-demo
|
drwx--S--- (2700) /var/www/rails3-bootstrap-devise-cancan-demo
|
||||||
|
|
||||||
root@remote # stat -c "%A (%a) %n" ${deploy_to}/*
|
root@remote # stat -c "%A (%a) %n" ${deploy_to}/*
|
||||||
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/releases
|
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/releases
|
||||||
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/shared
|
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/shared
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
|
|
@ -21,17 +21,17 @@ technologies.
|
||||||
### 1. Checking the directory structure on the remote machine:
|
### 1. Checking the directory structure on the remote machine:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh deploy@remote 'ls -lR /var/www/my-application'
|
me@localhost $ ssh deploy@remote 'ls -lR /var/www/my-application'
|
||||||
my-application:
|
my-application:
|
||||||
total 8
|
total 8
|
||||||
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 releases
|
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 releases
|
||||||
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 shared
|
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 shared
|
||||||
|
|
||||||
my-application/releases:
|
my-application/releases:
|
||||||
total 0
|
total 0
|
||||||
|
|
||||||
my-application/shared:
|
my-application/shared:
|
||||||
total 0
|
total 0
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This checks in one simple command that the ssh keys you setup are working (you
|
This checks in one simple command that the ssh keys you setup are working (you
|
||||||
|
@ -45,16 +45,16 @@ quickly introduce ourselves to a quick Cap task to check these things on all
|
||||||
the machines for us:
|
the machines for us:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
desc "Check that we can access everything"
|
desc "Check that we can access everything"
|
||||||
task :check_write_permissions do
|
task :check_write_permissions do
|
||||||
on roles(:all) do |host|
|
on roles(:all) do |host|
|
||||||
if test("[ -w #{fetch(:deploy_to)} ]")
|
if test("[ -w #{fetch(:deploy_to)} ]")
|
||||||
info "#{fetch(:deploy_to)} is writable on #{host}"
|
info "#{fetch(:deploy_to)} is writable on #{host}"
|
||||||
else
|
else
|
||||||
error "#{fetch(:deploy_to)} is not writable on #{host}"
|
error "#{fetch(:deploy_to)} is not writable on #{host}"
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Running this should give you a pretty decent overview, one line of output for
|
Running this should give you a pretty decent overview, one line of output for
|
||||||
|
@ -71,20 +71,20 @@ something like `access_check.rake`, and run `cap -T` from the top directory and
|
||||||
we'll be able to see the task listed:
|
we'll be able to see the task listed:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ bundle exec cap -T
|
me@localhost $ bundle exec cap -T
|
||||||
# ... lots of other tasks ...
|
# ... lots of other tasks ...
|
||||||
cap check_write_permissions # Check that we can access everything
|
cap check_write_permissions # Check that we can access everything
|
||||||
# ... lots of other tasks ...
|
# ... lots of other tasks ...
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Then we simply call it:
|
Then we simply call it:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ bundle exec cap staging check_write_permissions
|
me@localhost $ bundle exec cap staging check_write_permissions
|
||||||
DEBUG [82c92144] Running /usr/bin/env [ -w /var/www/my-application ] on myserver.com
|
DEBUG [82c92144] Running /usr/bin/env [ -w /var/www/my-application ] on myserver.com
|
||||||
DEBUG [82c92144] Command: [ -w /var/www/my-application ]
|
DEBUG [82c92144] Command: [ -w /var/www/my-application ]
|
||||||
DEBUG [82c92144] Finished in 0.456 seconds command successful.
|
DEBUG [82c92144] Finished in 0.456 seconds command successful.
|
||||||
INFO /var/www/my-application is writable on myserver.com
|
INFO /var/www/my-application is writable on myserver.com
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
If we've done something wrong, that won't happen and we'll know that we need
|
If we've done something wrong, that won't happen and we'll know that we need
|
||||||
|
@ -99,7 +99,7 @@ Capistrano does just this, so to check if the Git access is working, we can
|
||||||
simply call:
|
simply call:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ cap staging git:check
|
me@localhost $ cap staging git:check
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This task is defined in the default Git SCM-strategy and looks a lot like what
|
This task is defined in the default Git SCM-strategy and looks a lot like what
|
||||||
|
@ -112,24 +112,24 @@ for us by Capistrano. (This is one of the pieces we inherit from Rake)
|
||||||
If this fails we'll see:
|
If this fails we'll see:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ cap staging git:check
|
me@localhost $ cap staging git:check
|
||||||
cap staging git:check
|
cap staging git:check
|
||||||
DEBUG Uploading /tmp/git-ssh.sh 0%
|
DEBUG Uploading /tmp/git-ssh.sh 0%
|
||||||
INFO Uploading /tmp/git-ssh.sh 100%
|
INFO Uploading /tmp/git-ssh.sh 100%
|
||||||
INFO [118bd3e4] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
|
INFO [118bd3e4] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
|
||||||
DEBUG [118bd3e4] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
|
DEBUG [118bd3e4] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
|
||||||
INFO [118bd3e4] Finished in 0.049 seconds command successful.
|
INFO [118bd3e4] Finished in 0.049 seconds command successful.
|
||||||
INFO [a996463f] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on harrow
|
INFO [a996463f] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on harrow
|
||||||
DEBUG [a996463f] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
|
DEBUG [a996463f] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
|
||||||
DEBUG [a996463f] Warning: Permanently added 'github.com,204.232.175.90' (RSA) to the list of known hosts.
|
DEBUG [a996463f] Warning: Permanently added 'github.com,204.232.175.90' (RSA) to the list of known hosts.
|
||||||
DEBUG [a996463f] Permission denied (publickey).
|
DEBUG [a996463f] Permission denied (publickey).
|
||||||
DEBUG [a996463f] fatal: The remote end hung up unexpectedly
|
DEBUG [a996463f] fatal: The remote end hung up unexpectedly
|
||||||
cap aborted!
|
cap aborted!
|
||||||
git stdout: Nothing written
|
git stdout: Nothing written
|
||||||
git stderr: Nothing written
|
git stderr: Nothing written
|
||||||
|
|
||||||
Tasks: TOP => git:check
|
Tasks: TOP => git:check
|
||||||
(See full trace by running task with --trace)
|
(See full trace by running task with --trace)
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This'll typically come out looking more beautiful depending on your terminal
|
This'll typically come out looking more beautiful depending on your terminal
|
||||||
|
@ -156,35 +156,35 @@ working by writing a tiny Cap task, or simply using SSH to do it for us, the
|
||||||
choice is yours:
|
choice is yours:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
# lib/capistrano/tasks/agent_forwarding.rake
|
# lib/capistrano/tasks/agent_forwarding.rake
|
||||||
desc "Check if agent forwarding is working"
|
desc "Check if agent forwarding is working"
|
||||||
task :forwarding do
|
task :forwarding do
|
||||||
on roles(:all) do |h|
|
on roles(:all) do |h|
|
||||||
if test("env | grep SSH_AUTH_SOCK")
|
if test("env | grep SSH_AUTH_SOCK")
|
||||||
info "Agent forwarding is up to #{h}"
|
info "Agent forwarding is up to #{h}"
|
||||||
else
|
else
|
||||||
error "Agent forwarding is NOT up to #{h}"
|
error "Agent forwarding is NOT up to #{h}"
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
That gave the output:
|
That gave the output:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
cap staging forwarding
|
cap staging forwarding
|
||||||
DEBUG [f1269276] Running /usr/bin/env env | grep SSH_AUTH_SOCK on example.com
|
DEBUG [f1269276] Running /usr/bin/env env | grep SSH_AUTH_SOCK on example.com
|
||||||
DEBUG [f1269276] Command: env | grep SSH_AUTH_SOCK
|
DEBUG [f1269276] Command: env | grep SSH_AUTH_SOCK
|
||||||
DEBUG [f1269276] SSH_AUTH_SOCK=/tmp/ssh-nQUEmyQ2nS/agent.2546
|
DEBUG [f1269276] SSH_AUTH_SOCK=/tmp/ssh-nQUEmyQ2nS/agent.2546
|
||||||
DEBUG [f1269276] Finished in 0.453 seconds command successful.
|
DEBUG [f1269276] Finished in 0.453 seconds command successful.
|
||||||
INFO Agent forwarding is up to example.com
|
INFO Agent forwarding is up to example.com
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
If you don't feel like writing a Capistrano task, one could simply do:
|
If you don't feel like writing a Capistrano task, one could simply do:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ ssh -A example.com 'env | grep SSH_AUTH_SOCK'
|
me@localhost $ ssh -A example.com 'env | grep SSH_AUTH_SOCK'
|
||||||
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934
|
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
If we see the `SSH_AUTH_SOCK` output, that's a pretty good indication that SSH
|
If we see the `SSH_AUTH_SOCK` output, that's a pretty good indication that SSH
|
||||||
|
@ -193,17 +193,17 @@ you an SSH key, then we're good to go. **Make sure that you're using the
|
||||||
`git@...` repository URL**
|
`git@...` repository URL**
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
cap staging git:check
|
cap staging git:check
|
||||||
DEBUG Uploading /tmp/git-ssh.sh 0%
|
DEBUG Uploading /tmp/git-ssh.sh 0%
|
||||||
INFO Uploading /tmp/git-ssh.sh 100%
|
INFO Uploading /tmp/git-ssh.sh 100%
|
||||||
INFO [21382716] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
|
INFO [21382716] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
|
||||||
DEBUG [21382716] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
|
DEBUG [21382716] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
|
||||||
INFO [21382716] Finished in 0.047 seconds command successful.
|
INFO [21382716] Finished in 0.047 seconds command successful.
|
||||||
INFO [f40edfbb] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on example.com
|
INFO [f40edfbb] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on example.com
|
||||||
DEBUG [f40edfbb] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
|
DEBUG [f40edfbb] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
|
||||||
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 HEAD
|
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 HEAD
|
||||||
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 refs/heads/master
|
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 refs/heads/master
|
||||||
INFO [f40edfbb] Finished in 3.319 seconds command successful.
|
INFO [f40edfbb] Finished in 3.319 seconds command successful.
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -40,7 +40,8 @@ deploy:finishing_rollback - finish the rollback, clean up everything
|
||||||
deploy:finished
|
deploy:finished
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
As you can see, rollback flow shares many tasks with deploy flow. But note that, rollback flow runs its own `:finishing_rollback` task because its
|
As you can see, rollback flow shares many tasks with deploy flow. But note
|
||||||
|
that, rollback flow runs its own `:finishing_rollback` task because its
|
||||||
cleanup process is usually different from deploy flow.
|
cleanup process is usually different from deploy flow.
|
||||||
|
|
||||||
### Flow examples
|
### Flow examples
|
||||||
|
@ -108,4 +109,3 @@ deploy
|
||||||
deploy:finished
|
deploy:finished
|
||||||
deploy:log_revision
|
deploy:log_revision
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,16 @@ therefore recommended to use an appropriate bundler.
|
||||||
The following command will install the latest released capistrano `v3` revision:
|
The following command will install the latest released capistrano `v3` revision:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
$ gem install capistrano
|
$ gem install capistrano
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Or grab the bleeding edge head from:
|
Or grab the bleeding edge head from:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
$ git clone https://github.com/capistrano/capistrano.git
|
$ git clone https://github.com/capistrano/capistrano.git
|
||||||
$ cd capistrano
|
$ cd capistrano
|
||||||
$ gem build *.gemspec
|
$ gem build *.gemspec
|
||||||
$ gem install *.gem
|
$ gem install *.gem
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
### Usage in a Rails project
|
### Usage in a Rails project
|
||||||
|
@ -35,9 +35,9 @@ Or grab the bleeding edge head from:
|
||||||
Add the following lines to the Gemfile:
|
Add the following lines to the Gemfile:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
group :development do
|
group :development do
|
||||||
gem 'capistrano-rails', '~> 1.1.1'
|
gem 'capistrano-rails', '~> 1.1.1'
|
||||||
end
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
The `capistrano-rails` gem includes extras specifically designed for Ruby on
|
The `capistrano-rails` gem includes extras specifically designed for Ruby on
|
||||||
|
@ -54,7 +54,7 @@ part, to get the best, and most sensible results, simply `require` in
|
||||||
Capfile, after the `require 'capistrano/deploy'` line:
|
Capfile, after the `require 'capistrano/deploy'` line:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
require 'capistrano/rails'
|
require 'capistrano/rails'
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ by mistake, then you can lock your Gem version for Capistrano at something
|
||||||
like:
|
like:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
gem 'capistrano', '~> 2.15' # Or whatever patch release you are using
|
gem 'capistrano', '~> 2.15' # Or whatever patch release you are using
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This is the [pessimistic operator][rubygems-pessimistic-operator] which
|
This is the [pessimistic operator][rubygems-pessimistic-operator] which
|
||||||
|
|
|
@ -35,8 +35,8 @@ The original `database.yml` should be added to the `.gitignore` (or your SCM's
|
||||||
parallel concept of ignored files)
|
parallel concept of ignored files)
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
$ cp config/database.yml{,.example}
|
$ cp config/database.yml{,.example}
|
||||||
$ echo config/database.yml >> .gitignore
|
$ echo config/database.yml >> .gitignore
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This should be done for any other secret files, we'll create the production
|
This should be done for any other secret files, we'll create the production
|
||||||
|
@ -45,22 +45,22 @@ version of the file when we deploy, and symlink it into place.
|
||||||
### 3. Initialize Capistrano in your application.
|
### 3. Initialize Capistrano in your application.
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
$ cd my-project
|
$ cd my-project
|
||||||
$ cap install
|
$ cap install
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
This will create a bunch of files, the important ones are:
|
This will create a bunch of files, the important ones are:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
├── Capfile
|
├── Capfile
|
||||||
├── config
|
├── config
|
||||||
│ ├── deploy
|
│ ├── deploy
|
||||||
│ │ ├── production.rb
|
│ │ ├── production.rb
|
||||||
│ │ └── staging.rb
|
│ │ └── staging.rb
|
||||||
│ └── deploy.rb
|
│ └── deploy.rb
|
||||||
└── lib
|
└── lib
|
||||||
└── capistrano
|
└── capistrano
|
||||||
└── tasks
|
└── tasks
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Your new Capfile will automatically include any tasks from any `*.rake` files
|
Your new Capfile will automatically include any tasks from any `*.rake` files
|
||||||
|
@ -88,26 +88,26 @@ common.
|
||||||
The example file generated will look something like this:
|
The example file generated will look something like this:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
set :stage, :staging
|
set :stage, :staging
|
||||||
|
|
||||||
# Simple Role Syntax
|
# Simple Role Syntax
|
||||||
# ==================
|
# ==================
|
||||||
# Supports bulk-adding hosts to roles, the primary
|
# Supports bulk-adding hosts to roles, the primary
|
||||||
# server in each group is considered to be the first
|
# server in each group is considered to be the first
|
||||||
# unless any hosts have the primary property set.
|
# unless any hosts have the primary property set.
|
||||||
role :app, %w{example.com}
|
role :app, %w{example.com}
|
||||||
role :web, %w{example.com}
|
role :web, %w{example.com}
|
||||||
role :db, %w{example.com}
|
role :db, %w{example.com}
|
||||||
|
|
||||||
# Extended Server Syntax
|
# Extended Server Syntax
|
||||||
# ======================
|
# ======================
|
||||||
# This can be used to drop a more detailed server
|
# This can be used to drop a more detailed server
|
||||||
# definition into the server list. The second argument
|
# definition into the server list. The second argument
|
||||||
# is something that quacks like a hash and can be used
|
# is something that quacks like a hash and can be used
|
||||||
# to set extended properties on the server.
|
# to set extended properties on the server.
|
||||||
server 'example.com', roles: %w{web app}, my_property: :my_value
|
server 'example.com', roles: %w{web app}, my_property: :my_value
|
||||||
|
|
||||||
# set :rails_env, :staging
|
# set :rails_env, :staging
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Both the simple role, and extended server syntaxes result in one or more
|
Both the simple role, and extended server syntaxes result in one or more
|
||||||
|
@ -133,10 +133,12 @@ These host strings are parsed and expanded out in to the equivalent of the
|
||||||
server line after the comment:
|
server line after the comment:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
role :web, %w{hello@world.com example.com:1234}
|
# using simple syntax
|
||||||
# ...is the same as doing...
|
role :web, %w{hello@world.com example.com:1234}
|
||||||
server 'world.com', roles: [:web], user: 'hello'
|
|
||||||
server 'example.com', roles: [:web], port: 1234
|
# using extended syntax (which is equivalent)
|
||||||
|
server 'world.com', roles: [:web], user: 'hello'
|
||||||
|
server 'example.com', roles: [:web], port: 1234
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
### 5. Set the shared information in `deploy.rb`.
|
### 5. Set the shared information in `deploy.rb`.
|
||||||
|
@ -150,9 +152,9 @@ self-documenting, commented-out configuration options, feel free to play with
|
||||||
them a little:
|
them a little:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
set :application, 'my app name'
|
set :application, 'my app name'
|
||||||
set :repo_url, 'git@example.com:me/my_repo.git'
|
set :repo_url, 'git@example.com:me/my_repo.git'
|
||||||
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
|
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Here we'd set the name of the application, ideally in a way that's safe for
|
Here we'd set the name of the application, ideally in a way that's safe for
|
||||||
|
@ -173,9 +175,9 @@ forked to the Capistrano repository, but you can find the (unchanged) original
|
||||||
[here](https://github.com/RailsApps/rails3-bootstrap-devise-cancan).
|
[here](https://github.com/RailsApps/rails3-bootstrap-devise-cancan).
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
set :application, 'rails3-bootstrap-devise-cancan-demo'
|
set :application, 'rails3-bootstrap-devise-cancan-demo'
|
||||||
set :repo_url, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan'
|
set :repo_url, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan'
|
||||||
set :branch, 'master'
|
set :branch, 'master'
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
I've simplified the `:branch` variable to simply be a `set` variable, not a
|
I've simplified the `:branch` variable to simply be a `set` variable, not a
|
||||||
|
|
|
@ -15,26 +15,42 @@ set :deploy_to, '/var/www/my_app_name'
|
||||||
Then inspecting the directories inside `/var/www/my_app_name` looks like this:
|
Then inspecting the directories inside `/var/www/my_app_name` looks like this:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
├── current -> /var/www/my_app_name/releases/20150120114500/
|
├── current -> /var/www/my_app_name/releases/20150120114500/
|
||||||
├── releases
|
├── releases
|
||||||
│ ├── 20150080072500
|
│ ├── 20150080072500
|
||||||
│ ├── 20150090083000
|
│ ├── 20150090083000
|
||||||
│ ├── 20150100093500
|
│ ├── 20150100093500
|
||||||
│ ├── 20150110104000
|
│ ├── 20150110104000
|
||||||
│ └── 20150120114500
|
│ └── 20150120114500
|
||||||
├── repo
|
├── repo
|
||||||
│ └── <VCS related data>
|
│ └── <VCS related data>
|
||||||
├── revisions.log
|
├── revisions.log
|
||||||
└── shared
|
└── shared
|
||||||
└── <linked_files and linked_dirs>
|
└── <linked_files and linked_dirs>
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
|
||||||
* `current` is a symlink pointing to the latest release. This symlink is updated at the end of a successful deployment. If the deployment fails in any step the `current` symlink still points to the old release.
|
* `current` is a symlink pointing to the latest release. This symlink is
|
||||||
* `releases` holds all deployments in a timestamped folder. These folders are the target of the `current` symlink.
|
updated at the end of a successful deployment. If the deployment fails in any
|
||||||
* `repo` holds the version control system configured. In case of a git repository the content will be a raw git repository (e.g. objects, refs, etc.).
|
step the `current` symlink still points to the old release.
|
||||||
* `revisions.log` is used to log every deploy or rollback. Each entry is timestamped and the executing user (username from local machine) is listed. Depending on your VCS data like branchnames or revision numbers are listed as well.
|
|
||||||
* `shared` contains the `linked_files` and `linked_dirs` which are symlinked into each release. This data persists across deployments and releases. It should be used for things like database configuration files and static and persistent user storage handed over from one release to the next.
|
|
||||||
|
|
||||||
|
* `releases` holds all deployments in a timestamped folder. These folders are
|
||||||
|
the target of the `current` symlink.
|
||||||
|
|
||||||
The application is completely contained within the path of `:deploy_to`. If you plan on deploying multiple applications to the same server, simply choose a different `:deploy_to` path.
|
* `repo` holds the version control system configured. In case of a git
|
||||||
|
repository the content will be a raw git repository (e.g. objects, refs,
|
||||||
|
etc.).
|
||||||
|
|
||||||
|
* `revisions.log` is used to log every deploy or rollback. Each entry is
|
||||||
|
timestamped and the executing user (username from local machine) is listed.
|
||||||
|
Depending on your VCS data like branchnames or revision numbers are listed as
|
||||||
|
well.
|
||||||
|
|
||||||
|
* `shared` contains the `linked_files` and `linked_dirs` which are symlinked
|
||||||
|
into each release. This data persists across deployments and releases. It
|
||||||
|
should be used for things like database configuration files and static and
|
||||||
|
persistent user storage handed over from one release to the next.
|
||||||
|
|
||||||
|
The application is completely contained within the path of `:deploy_to`. If
|
||||||
|
you plan on deploying multiple applications to the same server, simply choose
|
||||||
|
a different `:deploy_to` path.
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
title: Introductory Demo Video
|
|
||||||
layout: default
|
|
||||||
---
|
|
||||||
|
|
||||||
The video below was filmed on Mac OSX 10.8 using a more-or-less standard shell
|
|
||||||
without much previous setup.
|
|
||||||
|
|
||||||
It covers using Capistrano to install an example Rails project on a previously
|
|
||||||
unprepared server, covering all aspects of Github access, as well as
|
|
||||||
privisioning the server using *Chef Solo* and Capistrano with *Rake*.
|
|
||||||
|
|
||||||
#### Show Notes
|
|
||||||
|
|
||||||
The *Chef Solo* recipes can be reached at [this repository at
|
|
||||||
Github][capistrano-chef-solo-example-recipes], they rely on a fairly new
|
|
||||||
version of *Chef Solo*, spefically any including the results of [this
|
|
||||||
ticket][chef-issue-3365]. The aforementioned *Chef* issue adds environment
|
|
||||||
support to *Chef Solo*.
|
|
||||||
|
|
||||||
The provisioning can also be done using any other mechanism, it's generally
|
|
||||||
accepted however that there's not much point in automising your deploys,
|
|
||||||
unless you are also automating provisioning of your servers for a known,
|
|
||||||
consistent state.
|
|
||||||
|
|
||||||
Using `sudo` with any deployment can be tricky, so it's better to avoid it.
|
|
||||||
Rebooting services without `sudo` is typically the first place people run into
|
|
||||||
trouble using Capistrano. The [trouble shooting page for `sudo`
|
|
||||||
problems][troubleshooting-sudo-password] may help.
|
|
||||||
|
|
||||||
**Note:** Some long sequences have been shortened (nobody needs to sit and watch me
|
|
||||||
sitting and watching Ruby compile, for example!)
|
|
||||||
|
|
||||||
--
|
|
||||||
[chef-issue-3365]: https://github.com/opscode/chef/pull/359
|
|
||||||
[troubleshooting-sudo-password]: /troubleshooting/sudo-password/
|
|
|
@ -23,7 +23,7 @@ Ruby software to form part of a larger tool.
|
||||||
#### What does it look like?
|
#### What does it look like?
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
me@localhost $ cap staging deploy
|
me@localhost $ cap staging deploy
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
@ -99,49 +99,48 @@ There's lots of cool stuff in the Capistrano toy box:
|
||||||
* A sane, expressive API:
|
* A sane, expressive API:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
desc "Show off the API"
|
desc "Show off the API"
|
||||||
task :ditty do
|
task :ditty do
|
||||||
|
|
||||||
on roles(:all) do |host|
|
on roles(:all) do |host|
|
||||||
# Capture output from the remote host, and re-use it
|
# Capture output from the remote host, and re-use it
|
||||||
# we can reflect on the `host` object passed to the block
|
# we can reflect on the `host` object passed to the block
|
||||||
# and use the `info` logger method to benefit from the
|
# and use the `info` logger method to benefit from the
|
||||||
# output formatter that is selected.
|
# output formatter that is selected.
|
||||||
uptime = capture('uptime')
|
uptime = capture('uptime')
|
||||||
if host.roles.include?(:web)
|
if host.roles.include?(:web)
|
||||||
info "Your webserver #{host} has uptime: #{uptime}"
|
info "Your webserver #{host} has uptime: #{uptime}"
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
on roles(:app) do
|
|
||||||
# We can set environmental variables for the duration of a block
|
|
||||||
# and move the process into a directoy, executing arbitrary tasks
|
|
||||||
# such as letting Rails do some heavy lifting.
|
|
||||||
with({:rails_env => :production}) do
|
|
||||||
within('/var/www/my/rails/app') do
|
|
||||||
execute :rails, :runner, 'MyModel.something'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
on roles(:db) do
|
|
||||||
# We can even switch users, provided we have support on the remote
|
|
||||||
# server for switching to that user without being prompted for a
|
|
||||||
# passphrase.
|
|
||||||
as 'postgres' do
|
|
||||||
widgets = capture "echo 'SELECT * FROM widgets;' | psql my_database"
|
|
||||||
if widgets.to_i < 50
|
|
||||||
warn "There are fewer than 50 widgets in the database on #{host}!"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
on roles(:all) do
|
|
||||||
# We can even use `test` the way the Unix gods intended
|
|
||||||
if test("[ -d /some/directory ]")
|
|
||||||
info "Phew, it's ok, the directory exists!"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
on roles(:app) do
|
||||||
|
# We can set environmental variables for the duration of a block
|
||||||
|
# and move the process into a directoy, executing arbitrary tasks
|
||||||
|
# such as letting Rails do some heavy lifting.
|
||||||
|
with({:rails_env => :production}) do
|
||||||
|
within('/var/www/my/rails/app') do
|
||||||
|
execute :rails, :runner, 'MyModel.something'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
on roles(:db) do
|
||||||
|
# We can even switch users, provided we have support on the remote
|
||||||
|
# server for switching to that user without being prompted for a
|
||||||
|
# passphrase.
|
||||||
|
as 'postgres' do
|
||||||
|
widgets = capture "echo 'SELECT * FROM widgets;' | psql my_database"
|
||||||
|
if widgets.to_i < 50
|
||||||
|
warn "There are fewer than 50 widgets in the database on #{host}!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
on roles(:all) do
|
||||||
|
# We can even use `test` the way the Unix gods intended
|
||||||
|
if test("[ -d /some/directory ]")
|
||||||
|
info "Phew, it's ok, the directory exists!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
|
@ -4,87 +4,86 @@ layout: default
|
||||||
---
|
---
|
||||||
|
|
||||||
1.
|
1.
|
||||||
Update your Gemfile: `gem 'capistrano', '~> 3.0', require: false, group: :development`
|
Update your Gemfile: `gem 'capistrano', '~> 3.0', require: false, group: :development`
|
||||||
|
|
||||||
|
|
||||||
If you deploy Rails, you wil also need `capistrano-rails` and `capistrano-bundler` gems (Rails and Bundler integrations were moved out from Capistrano 3).
|
If you deploy Rails, you wil also need `capistrano-rails` and `capistrano-bundler` gems (Rails and Bundler integrations were moved out from Capistrano 3).
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
group :development do
|
group :development do
|
||||||
gem 'capistrano-rails', '~> 1.1', require: false
|
gem 'capistrano-rails', '~> 1.1', require: false
|
||||||
gem 'capistrano-bundler', '~> 1.1', require: false
|
gem 'capistrano-bundler', '~> 1.1', require: false
|
||||||
end
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
You can add idiomatic support for your preferred ruby version manager: rvm, rbenv, chruby.
|
You can add idiomatic support for your preferred ruby version manager: rvm, rbenv, chruby.
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
group :development do
|
group :development do
|
||||||
gem 'capistrano-rvm', '~> 0.1', require: false
|
gem 'capistrano-rvm', '~> 0.1', require: false
|
||||||
gem 'capistrano-rbenv', '~> 2.0', require: false
|
gem 'capistrano-rbenv', '~> 2.0', require: false
|
||||||
gem 'capistrano-chruby', github: 'capistrano/chruby', require: false
|
gem 'capistrano-chruby', github: 'capistrano/chruby', require: false
|
||||||
end
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
2.
|
2.
|
||||||
We recommend to capify the project from scratch and move definitions from old to new configs then.
|
We recommend to capify the project from scratch and move definitions from old to new configs then.
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
mkdir old_cap
|
mkdir old_cap
|
||||||
mv Capfile old_cap
|
mv Capfile old_cap
|
||||||
mv config/deploy.rb old_cap
|
mv config/deploy.rb old_cap
|
||||||
mv config/deploy/ old_cap # --> only for multistage setups
|
mv config/deploy/ old_cap # --> only for multistage setups
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
It's time to capify:
|
It's time to capify:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
cap install
|
cap install
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
3.
|
3.
|
||||||
Capistrano 3 is multistage by default, so you will have `config/deploy/production.rb` and `config/deploy/staging.rb` right after capifying.
|
Capistrano 3 is multistage by default, so you will have `config/deploy/production.rb` and `config/deploy/staging.rb` right after capifying.
|
||||||
If you need only one stage, remove these files and declare stage (for example `production`) and servers in `config/deploy.rb`.
|
If you need only one stage, remove these files and declare stage (for example `production`) and servers in `config/deploy.rb`.
|
||||||
|
|
||||||
4.
|
4.
|
||||||
Update `config/deploy/production.rb` and `config/deploy/staging.rb` to have relevant data there. You may also want to add more stages from old configs (`old_cap/deploy/`).
|
Update `config/deploy/production.rb` and `config/deploy/staging.rb` to have relevant data there. You may also want to add more stages from old configs (`old_cap/deploy/`).
|
||||||
|
|
||||||
5.
|
5.
|
||||||
If you had a gateway server set doing `set :gateway, "www.capify.org"` you should upgrade to
|
If you had a gateway server set doing `set :gateway, "www.capify.org"` you should upgrade to
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
require 'net/ssh/proxy/command'
|
require 'net/ssh/proxy/command'
|
||||||
|
|
||||||
set :ssh_options, proxy: Net::SSH::Proxy::Command.new('ssh mygateway.com -W %h:%p')
|
set :ssh_options, proxy: Net::SSH::Proxy::Command.new('ssh mygateway.com -W %h:%p')
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Or the per-server `ssh_options` equivalent.
|
Or the per-server `ssh_options` equivalent.
|
||||||
|
|
||||||
6.
|
6.
|
||||||
Now you need to refactor your old `deploy.rb` (also `Capfile`, but in most of cases developers didn't change it in Capistrano 2.x). Move parameters (like `set :deploy_to, "/home/deploy/#{application}"` or `set :keep_releases, 4`) to `config/deploy.rb` and tasks to `Capfile`.
|
Now you need to refactor your old `deploy.rb` (also `Capfile`, but in most of cases developers didn't change it in Capistrano 2.x). Move parameters (like `set :deploy_to, "/home/deploy/#{application}"` or `set :keep_releases, 4`) to `config/deploy.rb` and tasks to `Capfile`.
|
||||||
|
|
||||||
*Important: `repository` option was renamed to `repo_url`; `default_environment` option was renamed to `default_env`.*
|
*Important: `repository` option was renamed to `repo_url`; `default_environment` option was renamed to `default_env`.*
|
||||||
|
|
||||||
|
Notice that some parameters are not necessary anymore: `use_sudo`, `normalize_asset_timestamps`.
|
||||||
Notice that some parameters are not necessary anymore: `use_sudo`, `normalize_asset_timestamps`.
|
|
||||||
|
|
||||||
7.
|
7.
|
||||||
If you didn't use `deploy_to` before and deployed to `/u/apps/your_app_name`, you need one more change. Now default deploy path is `/var/www/app_name` and your config will be broken after upgrade. Just declare custom `deploy_to` option:
|
If you didn't use `deploy_to` before and deployed to `/u/apps/your_app_name`, you need one more change. Now default deploy path is `/var/www/app_name` and your config will be broken after upgrade. Just declare custom `deploy_to` option:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
set :deploy_to, "/u/apps/#{fetch(:application)}"
|
set :deploy_to, "/u/apps/#{fetch(:application)}"
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
But in advance, `/u/apps` is not the best place to store apps and we advice you to change it later.
|
But in advance, `/u/apps` is not the best place to store apps and we advice you to change it later.
|
||||||
|
|
||||||
8.
|
8.
|
||||||
Keep editing Capfile and uncomment addons you need, such as rbenv/rvm, bundler or rails.
|
Keep editing Capfile and uncomment addons you need, such as rbenv/rvm, bundler or rails.
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
require 'capistrano/rails'
|
require 'capistrano/rails'
|
||||||
require 'capistrano/bundler'
|
require 'capistrano/bundler'
|
||||||
require 'capistrano/rbenv'
|
require 'capistrano/rbenv'
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
9.
|
9.
|
||||||
Yay! Try to deploy with your new config set. If you discover any missing info in this upgrade guide, you're welcome to contribute to it.
|
Yay! Try to deploy with your new config set. If you discover any missing info in this upgrade guide, you're welcome to contribute to it.
|
||||||
|
|
||||||
# General recommendations
|
# General recommendations
|
||||||
|
|
||||||
|
@ -93,22 +92,22 @@ layout: default
|
||||||
Instead of:
|
Instead of:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
run <<-CMD.compact
|
run <<-CMD.compact
|
||||||
cd -- #{latest_release} &&
|
cd -- #{latest_release} &&
|
||||||
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
|
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
|
||||||
CMD
|
CMD
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
It's better to use:
|
It's better to use:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
on roles :all do
|
on roles :all do
|
||||||
within fetch(:latest_release_directory) do
|
within fetch(:latest_release_directory) do
|
||||||
with rails_env: fetch(:rails_env) do
|
with rails_env: fetch(:rails_env) do
|
||||||
execute :rake, 'assets:precompile'
|
execute :rake, 'assets:precompile'
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Note: 'within' blocks are required to be wrapped in an 'on' block for the dsl to recognize it
|
Note: 'within' blocks are required to be wrapped in an 'on' block for the dsl to recognize it
|
||||||
|
@ -116,11 +115,11 @@ Note: 'within' blocks are required to be wrapped in an 'on' block for the dsl to
|
||||||
You may only have one 'with' block per call. If you need more than one env set, use the syntax in the 'with' block arg like this (pass it a map):
|
You may only have one 'with' block per call. If you need more than one env set, use the syntax in the 'with' block arg like this (pass it a map):
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
on roles :all do
|
on roles :all do
|
||||||
within fetch(:latest_release_directory) do
|
within fetch(:latest_release_directory) do
|
||||||
with rails_env: fetch(:rails_env), rails_relative_url_root: '/home' do
|
with rails_env: fetch(:rails_env), rails_relative_url_root: '/home' do
|
||||||
execute :rake, 'assets:precompile', env: {rails_env: fetch(:rails_env), rails_relative_url_root: ''}
|
execute :rake, 'assets:precompile', env: {rails_env: fetch(:rails_env), rails_relative_url_root: ''}
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue