diff --git a/_includes/metrics.html b/_includes/metrics.html new file mode 100644 index 00000000..338211ca --- /dev/null +++ b/_includes/metrics.html @@ -0,0 +1,30 @@ + + + + + diff --git a/_includes/navigation.html b/_includes/navigation.html index 5f2b2d80..c98a1420 100644 --- a/_includes/navigation.html +++ b/_includes/navigation.html @@ -8,7 +8,7 @@
Getting Started
  • Installation
  • Preparing Your Application
  • -
  • Authentication & Authorisation
  • +
  • Authentication & Authorisation
  • Cold Start
  • Rollbacks
  • diff --git a/_layouts/default.html b/_layouts/default.html index 5b72c195..bf92a55f 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -16,6 +16,36 @@ + + + + + {% include header.html %}
    diff --git a/_site/2013/06/01/release-announcement.html b/_site/2013/06/01/release-announcement.html index 460b418e..81ef9624 100644 --- a/_site/2013/06/01/release-announcement.html +++ b/_site/2013/06/01/release-announcement.html @@ -16,6 +16,36 @@ + + + + +
    @@ -33,28 +63,28 @@
  • Introductory Demo Video
  • Getting Started
    -
  • Installation
  • -
  • Preparing Your Application
  • -
  • Authentication & Authorisation
  • -
  • Cold Start
  • -
  • Rollbacks
  • +
  • Installation
  • +
  • Preparing Your Application
  • +
  • Authentication & Authorisation
  • +
  • Cold Start
  • +
  • Rollbacks
  • Troubleshooting
    -
  • SCM (Git) Authentication
  • -
  • Connectivity
  • - -
  • Agent Forwarding
  • -
  • `sudo` Password
  • -
  • RVM, `rbenv` And `nvm`
  • +
  • SCM (Git) Authentication
  • +
  • Connectivity
  • + +
  • Agent Forwarding
  • +
  • `sudo` Password
  • +
  • RVM, `rbenv` And `nvm`
  • FAQ
  • Why Does Something Work In An SSH Session, But Not In Capistrano?
  • -
  • Should I Use Capistrano To Provision My Servers?
  • + href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano? +
  • Should I Use Capistrano To Provision My Servers?
  • Power Use-Cases
    -
  • Integration With Rake
  • -
  • Driving Tools Such As Chef Solo
  • +
  • Integration With Rake
  • +
  • Driving Tools Such As Chef Solo
  • Recent Announcements
    diff --git a/_site/changes.html b/_site/changes.html index 9c8f0dd4..529575f4 100644 --- a/_site/changes.html +++ b/_site/changes.html @@ -16,6 +16,36 @@ + + + + +
    @@ -33,28 +63,28 @@
  • Introductory Demo Video
  • Getting Started
    -
  • Installation
  • -
  • Preparing Your Application
  • -
  • Authentication & Authorisation
  • -
  • Cold Start
  • -
  • Rollbacks
  • +
  • Installation
  • +
  • Preparing Your Application
  • +
  • Authentication & Authorisation
  • +
  • Cold Start
  • +
  • Rollbacks
  • Troubleshooting
    -
  • SCM (Git) Authentication
  • -
  • Connectivity
  • - -
  • Agent Forwarding
  • -
  • `sudo` Password
  • -
  • RVM, `rbenv` And `nvm`
  • +
  • SCM (Git) Authentication
  • +
  • Connectivity
  • + +
  • Agent Forwarding
  • +
  • `sudo` Password
  • +
  • RVM, `rbenv` And `nvm`
  • FAQ
  • Why Does Something Work In An SSH Session, But Not In Capistrano?
  • -
  • Should I Use Capistrano To Provision My Servers?
  • + href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano? +
  • Should I Use Capistrano To Provision My Servers?
  • Power Use-Cases
    -
  • Integration With Rake
  • -
  • Driving Tools Such As Chef Solo
  • +
  • Integration With Rake
  • +
  • Driving Tools Such As Chef Solo
  • Recent Announcements
    diff --git a/_site/css/capistrano.css b/_site/css/capistrano.css index 7be2c8fc..56e5f909 100644 --- a/_site/css/capistrano.css +++ b/_site/css/capistrano.css @@ -8,6 +8,7 @@ body { } h1, h2, h3, h4, h5, h6 { + font-weight: 400; font-family: 'Enriqueta', serif; } diff --git a/_site/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/index.html b/_site/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/index.html index 8a54e4ab..52cdd3c3 100644 --- a/_site/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/index.html +++ b/_site/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/index.html @@ -16,6 +16,36 @@ + + + + +
    @@ -33,28 +63,28 @@
  • Introductory Demo Video
  • Getting Started
    -
  • Installation
  • -
  • Preparing Your Application
  • -
  • Authentication & Authorisation
  • -
  • Cold Start
  • -
  • Rollbacks
  • +
  • Installation
  • +
  • Preparing Your Application
  • +
  • Authentication & Authorisation
  • +
  • Cold Start
  • +
  • Rollbacks
  • Troubleshooting
    -
  • SCM (Git) Authentication
  • -
  • Connectivity
  • - -
  • Agent Forwarding
  • -
  • `sudo` Password
  • -
  • RVM, `rbenv` And `nvm`
  • +
  • SCM (Git) Authentication
  • +
  • Connectivity
  • + +
  • Agent Forwarding
  • +
  • `sudo` Password
  • +
  • RVM, `rbenv` And `nvm`
  • FAQ
  • Why Does Something Work In An SSH Session, But Not In Capistrano?
  • -
  • Should I Use Capistrano To Provision My Servers?
  • + href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano? +
  • Should I Use Capistrano To Provision My Servers?
  • Power Use-Cases
    -
  • Integration With Rake
  • -
  • Driving Tools Such As Chef Solo
  • +
  • Integration With Rake
  • +
  • Driving Tools Such As Chef Solo
  • Recent Announcements
    diff --git a/_site/documentation/getting-started/authentication-and-authorisation/index.html b/_site/documentation/getting-started/authentication-and-authorisation/index.html new file mode 100644 index 00000000..cb544179 --- /dev/null +++ b/_site/documentation/getting-started/authentication-and-authorisation/index.html @@ -0,0 +1,774 @@ + + + + + + + Authentication & Authorisation + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +

    Authentication & Authorisation

    +

    Note: In the documentation we simply recommend creating a single deployment user, +and sharing it between team members. If you know why this is a bad idea (or +why this may be against regulations in your jurisdiction in some cases, we +assume that you know well enough how to use groups, umasking 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 +done:

    + +
    +
    root@remote $ adduser deploy
    +root@remote $ passwd -l deploy
    +
    + +

    The first line creates a completely standard user, it has a home directory, +which we'll need in a moment, and has a shell, so it may log in. This needs to +be done on every server in your environment.

    + +

    The second line locks the user, it changes the user's password to an +untypable string, guaranteeing that the user has no password which can be used +to log in.

    + +

    Authentication

    + +

    There are two places that we need automated, promptless authentication:

    + +
      +
    1. From our workstation/notebook/etc to our servers. We do this with SSH + keys, passphrase protected, ideally, using a key agent.
    2. +
    3. From our servers to the repository host. We do this so that our servers + can check out our application code from Github, or similar and install it + to the servers. This is usually done using SSH agent forwarding, HTTP + authentication, or with deploy keys.
    4. +
    + +

    1.1 SSH keys from workstation to servers

    + +

    Note: If you are on Windows, all bets are off, I'd love it if someone +could contribute a Windows guide to this, so we can include it here.

    + +

    An SSH key is a mechanism that allows a public half one key to be placed on +a server, when we want to authenticate with that server, our SSH client uses +the private part of that key to negotiate with the server, if the keys are +correct, then we need to create the key.

    + +

    Hint: If you have more than one developer in your team, they should all add their +public key to the deploy user's authorized_keys file, that way if someone +quits or gets fired, you can remove their key from that file, and the rest of +you can keep on shipping!

    + +
    +
    me@localhost $ ssh-keygen -t rsa -C 'me@my_email_address.com'
    +
    + +

    You'll be prompted for a passphrase, that's fine. Type one and keep it safe. +This passphrase ensures that if your computer is stolen, people still need a +passphrase to access your keys, in order to access your servers.

    + +

    To avoid having to type this passphrase every time you need to use a key, most +operating systems have a concept of a key agent. This key agent stores SSH +keys securely between uses, typically the first time a key is needed in a +given time period, the SSH agent will load the key, prompt you for your +passphrase and then the key agent will remember the key for a certain amount +of time (on OSX it tends to be indefinite, on linux this can vary from 15 +minutes updwards.)

    + +

    We can see which keys are loaded in the SSH agent by running 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)
    +
    + +

    If you don't see any keys listed, you can simply run ssh-add:

    + +
    +
    me@localhsot $ ssh-add
    +Identity added: /Users/me/.ssh/id_rsa (/Users/me/.ssh/id_rsa)
    +
    + +

    Typically, ssh-add will ask you for the passphrase when you add a key.

    + +

    Note: Although it's not mandatory to use an SSH agent (one could simply +use an unpassphrased key, and rely on SSH to find the key and exchange it). +Using an SSH agent makes things more secure, because we can use a passphrased +key without being prompts every time it is used. It also allows us to use +this same key to access the repository via the server without creating an +additional identity.

    + +

    At this point with the key loaded into the agent, we need to put the +public part of the key into a file on each remote server called +/home/users/deploy/.ssh/authorized_keys, to get the contents of that file, +we can ask our local key agent for the public parts of the keys it has loaded:

    + +
    +
    me@localhost $ ssh-add -L
    +ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa
    +
    + +

    This will be a lot longer when you run it, I snipped the output because it +looked bad.

    + +

    This line, as one line, needs to make it to the remote server and be added to +it's own line of the deploy user's ~/.ssh/authorized_keys file. This file +then needs to be changed to permission mode 0600 (owner read/write, group +none, other none), in the ~/.ssh directory which needs the permissions +0700 (owner read/write/execute, group none, other none).

    + +

    If you are on linux there often exists a command +ssh-copy-id which streamlines this +process, otherwise the worlflow is something like:

    + +
    +
    me@localhost $ ssh root@remote
    +root@remote $ su - deploy
    +deploy@remote $ cd ~
    +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 $ chmod 700 .ssh
    +deploy@remote $ chmod 600 .ssh/authorized_keys
    +
    + +

    Remember: This needs to be done on every server you want to use, you can +use the same key for each one, but only one key per developer is recommended. +Private keys are named as such for a reason!

    + +

    If we did all that correctly, we should now be able to do something like this:

    + +
    +
    me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime'
    +one-of-my-servers.com
    +19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05
    +
    + +

    That should happen without having to enter a passphrase for your SSH key, or +promoting you for an SSH password (which the deploy user doesn't have anyway).

    + +

    Verify that this works for all of your servers, and put your private key +somewhere safe. If you're working with multiple team members, it often pays to +collect everyone's public keys, indeed if your team is already using SSH keys +to access Github, you can reach any user's SSH keys at the following URL:

    + +
      +
    • https://github.com/theirusername.keys
    • +
    + +

    This can make getting user's keys onto servers much easier, as you can simply +curl/wget each user's key into the authorized keys file on the server +directly from Github.

    + + + + + +

    1.2 From our servers to the repository host

    + +

    With access from workstations to the servers settled, there is another hop to +contend with, which is letting the deploy user get access to the code +repository automatically. The options in order of preference:

    + +
    1.2.1 SSH Agent Forwarding
    + +

    As we've already set up an SSH agent, we can use the agent forwarding +feature of SSH to make this key agent available to further hops. In short, +we can use our own ssh key to authenticate ourselves from the server, to +Github.

    + +

    Here's how we can check if that works, first get the URL of the repository:

    + +
    +
    me@localhost $ git config remote.origin.url
    +git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
    +
    + +

    Here we're listing our private (for testing purposes) fork of the +rails3-bootstrap-devise-cancan repository forked from the Rails Examples and +Tutorials project.

    + +

    We can try to access the repository via our server by doing the following:

    + +
    +
    # List SSH keys that are loaded into the agent
    +me@localhost $ ssh-add -l
    +# Make sure they key is loaded if 'ssh-add -l' didn't show anything
    +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
    +
    + +

    We first check that the agent has the keys loaded, if not we simply load it, +and enter the passphrase when prompted.

    + +

    Finally we use ls-remote from Git to list the remote objects, this is the +exact same check that Capistrano does internally before attempting to deploy. +The -A option may, or may not be required on your system, it's worth trying +it both ways just to know how your system treats agent forwarding by default.

    + +

    From the SSH documentation:

    + +
    +
    -A  Enables forwarding of the authentication agent connection.  This can also be
    +    specified on a per-host basis in a configuration file.
    +
    +    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
    +    socket) can access the local agent through the forwarded connection.  An
    +    attacker cannot obtain key material from the agent, however they can perform
    +    operations on the keys that enable them to authenticate using the identities
    +    loaded into the agent.
    +
    + +

    In laymans terms, you should't use SSH agent forwarding to machines where you +don't trust the administrators, as they can can override the permissions on +the system and use your keys as if they were you. That said, if you can't +trust your server administrators, perhaps they shouldn't have access to your +servers!

    + +
    1.2.2 HTTP Authentication
    + +

    In the case of HTTP authentication be sure to use HTTPS, otherwise your +password will be sent in cleartext over the network, depending what your hosts +network infratructure looks like that might be very bad news.

    + +

    Typically when we try and list our remote objects, using the https method from +Github, we'll be prompted for a username and password:

    + +
    1.2.2.1 With a regular username/password
    + +
    +
    me@localhost $ git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
    +Username for 'https://github.com': myownusername
    +Password for 'https://capistrano@github.com':
    +
    + +

    This challenge response prompt doesn't work well for automating things, so +there are two ways to get around this depending on your server's host +operating system, the first is to use a netrc file, we won't talk about that +because the netrc is a global file that doesn't lend itself well to security.

    + +

    The other mechanism, and the reason that its very important to always use +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:

    + +
    +
    me@localhost $ git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
    +3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
    +3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
    +
    + +

    The bigger problem with passwords, whether inlined into the URL, or entered +into a netrc file, is that the password gives access to your entire Github +Account not just to one single repository.

    + +
    1.2.2.2 With an OAuth Personal API Token
    + +

    This mechanism still gives access to every repository you can access, but +at Github, they recently rolled out a feature called Personal API +Tokens which allow you to +do something like this:

    + +
    +
    me@localhost $ git ls-remote https://.....................@github.com/capistrano/rails3-bootstrap-devise-cancan.git
    +3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
    +3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
    +
    + +

    Where .... is a personal API token, as such:

    + +

    Github Personal API Token Page

    + +
    1.2.3 Deploy Keys
    + +

    Deploy keys, a feature of Github, and some other platforms allow you to +generate a second set of SSH keys for the connection between Github and +the servers themselves.

    + +

    Slightly perversely in this case the public key is uploaded to the repository +host, and the private key must be copied to each server that you want to +deploy to.

    + +

    Github has a quite excellent guide on this, much of which (unsurprisingly) +overlaps with the SSH key instructions above.

    + + + +

    Authorisation

    + +

    The second part of this topic is that our deploy user needs to be authorised +to work in the deployment directory, on the server. That means we need to be +able to work, ideally without sudo (none of the default Capistrano recipes +expect sudo to be available), or for your custom recipes, you will need to +have configured passwordless sudo. Configuring sudo to give some users +access to come commands under some circumstances is beyond the scope of this +documentation, but sufficed to say something like:

    + +
    +
    deploy ALL=NOPASSWD:/etc/init.d/mysqld, /etc/init.d/apache2
    +
    + +

    This example would give the user named deploy access to call sudo +/etc/init.d/mysql _________ and the same for the apache2 control script.

    + +

    Granting passwordless sudo should not be done lightly. It can be dangerous. +For example if an unprivilidged user can edit the script that they can run +as root, they can easily edit it to do anything they want that is evil. Use +this carefully, and ideally architect your systems so that non-privlidged +users can restart services, or that services restart themselves when they +notice change.

    + +
    +
    +
    + + + + + + + + + + + + + + + + + diff --git a/_site/documentation/getting-started/installation/index.html b/_site/documentation/getting-started/installation/index.html index b4867e2b..926dd651 100644 --- a/_site/documentation/getting-started/installation/index.html +++ b/_site/documentation/getting-started/installation/index.html @@ -16,6 +16,36 @@ + + + + +
    @@ -33,28 +63,28 @@
  • Introductory Demo Video
  • Getting Started
    -
  • Installation
  • -
  • Preparing Your Application
  • -
  • Authentication & Authorisation
  • -
  • Cold Start
  • -
  • Rollbacks
  • +
  • Installation
  • +
  • Preparing Your Application
  • +
  • Authentication & Authorisation
  • +
  • Cold Start
  • +
  • Rollbacks
  • Troubleshooting
    -
  • SCM (Git) Authentication
  • -
  • Connectivity
  • - -
  • Agent Forwarding
  • -
  • `sudo` Password
  • -
  • RVM, `rbenv` And `nvm`
  • +
  • SCM (Git) Authentication
  • +
  • Connectivity
  • + +
  • Agent Forwarding
  • +
  • `sudo` Password
  • +
  • RVM, `rbenv` And `nvm`
  • FAQ
  • Why Does Something Work In An SSH Session, But Not In Capistrano?
  • -
  • Should I Use Capistrano To Provision My Servers?
  • + href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano? +
  • Should I Use Capistrano To Provision My Servers?
  • Power Use-Cases
    -
  • Integration With Rake
  • -
  • Driving Tools Such As Chef Solo
  • +
  • Integration With Rake
  • +
  • Driving Tools Such As Chef Solo
  • Recent Announcements
    diff --git a/_site/documentation/getting-started/preparing-your-application/index.html b/_site/documentation/getting-started/preparing-your-application/index.html index 57689640..ee06746a 100644 --- a/_site/documentation/getting-started/preparing-your-application/index.html +++ b/_site/documentation/getting-started/preparing-your-application/index.html @@ -16,6 +16,36 @@ + + + + + -

    1. Commit your application to some externally available source control hosting provider.

    +

    1. Commit your application to some externally available source control hosting provider.

    If you are not doing already, you should host your code somewhere with a provuder such as Github, BitBucket, Codeplane, or repositoryhosting.com.

    @@ -83,7 +113,7 @@ contribute if you know these tools well, we don't and don't want to force our miscomprehended notions upon anyone.
    -

    2. Move secrets out of the repository.

    +

    2. Move secrets out of the repository.

    If you've accidentally committed state secrets to the repository, you might @@ -109,7 +139,7 @@ $ echo config/database.yml >> .gitignore

    This should be done for any other secret files, we'll create the production version of the file when we deploy, and symlink it into place.

    -

    3. Initialize Capistrano in your application.

    +

    3. Initialize Capistrano in your application.

    $ cd my-project
    @@ -130,6 +160,125 @@ $ cap install
    └── tasks
    +

    4. Configure your server addresses in the generated files.

    + +

    We'll just work with the staging environment here, so you can pretend that +config/deploy/production.rb doesn't exist, for the most part that's yoru +business.

    + +

    Capistrano breaks down common tasks into a notion of roles, that is, taking +a typical Rails application that we have roughly speaking three roles, web, +app, and db.

    + +

    It can be confusing, as the boundary of web and app servers is a bit blurry if +using Passenger with Apache, which in effect embeds your app server in the +web server (embeds Passenger in the Apache process itself), confusingly +Passenger can also be used in modes where this isn't true, so we'll ignore +that for the time being, and if you know the difference (i.e you are using +nginx as your web server, and puma/unicorn, or similar for your app server, +that should be fine) we can assume that they're the same, which is pretty +common.

    + +

    The example file generated will look something like this:

    + +
    +
    set :stage, :staging
    +
    +# Simple Role Syntax
    +# ==================
    +# Supports bulk-adding hosts to roles, the primary
    +# server in each group is considered to be the first
    +# unless any hosts have the primary property set.
    +role :app, %w{example.com}
    +role :web, %w{example.com}
    +role :db,  %w{example.com}
    +
    +# Extended Server Syntax
    +# ======================
    +# This can be used to drop a more detailed server
    +# definition into the server list. The second argument
    +# something that quacks like a has can be used to set
    +# extended properties on the server.
    +server 'example.com', roles: %w{web app}, my_property: :my_value
    +
    +# set :rails_env, :staging
    +
    + +

    Both the simple role, and extended server syntaxes result in one or more +servers for each role being defined. The app and db roles are just +placeholders, if you are using the capistrano/rails-* addons (more on +that later) then they have a meaning, but if you are deploying something +simpler, feel free to delete them if they're meaningless to you.

    + +

    The extended server syntax exists to allow the definition of arbitrary server +properties; it's there incase people want to build the server list more +comprehensively from something like the EC2 command line tools, and want to +use the extended properties for something that makes sense in their +environment.

    + +

    Servers can be defined in a bunch of ways, the following shows defining two +servers, one where we set the username, and another where we set the port. +These host strings are parsed and expanded out in to the equivilent of the +server line after the comment:

    + +
    +
    role :all, %w{hello@world.com example.com:1234}
    +# ...is the same as doing...
    +server 'world.com' roles: [:web], user: 'hello'
    +server 'example.com', roles: [:web], port: 1234
    +
    + +

    5. Set the shared information in deploy.rb.

    + +

    The deploy.rb is a place where the configuration common to each environment +can be specified, normally the repository URL and the user as whom to +deploy are specified here.

    + +

    The generated sample file starts with the following, and is followed by a few +self-documenting, commented-out configuration options, feel free to play with +them a little:

    + +
    +
    set :application, 'my app name'
    +set :repo, 'git@example.com:me/my_repo.git'
    +ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
    +
    + +

    Here we'd set the name of the application, ideally in a way that's safe for +filenames on your target operating system.

    + +

    Second we set the repository URL, this MUST be somewhere that the server we +are deploying to can reach.

    + +

    Here's how this might look in a typical example, note that we'll cover +authentication in the next chapter, for now we'll assume this repository is +open source, we'll take an example application from the Rails Examples and +Tutorials site; there we'll find maintained a +handful of typical Rails apps with typical dependencies.

    + +

    The Rails application they host, which uses Devise (for authentication) and +Cancan (for authorization) along side Twitter Bootstrap for assets has been +forked to the Capistrano repository, but you can find the (unchanged) original +here.

    + +
    +
    set :application, 'rails3-bootstrap-devise-cancan-demo'
    +set :repo, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan'
    +set :branch, 'master'
    +
    + +

    I've simplified the :branch varaible to simply be a set varaible, not a +question prompt, as this repository only has a master branch.

    + +

    Roundup

    + +

    At this point Capistrano knows where to find our servers, and where to find +our code.

    + +

    We've not covered how we authorise our servers to check out our code (there +are three pretty good ways of doing that with Git), nor have we determined how +to authorise Capistrano on our servers yet.

    +
    @@ -144,7 +293,7 @@ $ cap install here have parallels in Python, or PHP applications
    -

    1. Commit your application to some externally available source control hosting provider.

    +

    1. Commit your application to some externally available source control hosting provider.

    If you are not doing already, you should host your code somewhere with a provuder such as Github, BitBucket, Codeplane, or repositoryhosting.com.

    @@ -156,7 +305,7 @@ contribute if you know these tools well, we don't and don't want to force our miscomprehended notions upon anyone.
    -

    2. Move secrets out of the repository.

    +

    2. Move secrets out of the repository.

    If you've accidentally committed state secrets to the repository, you might @@ -182,7 +331,7 @@ $ echo config/database.yml >> .gitignore

    This should be done for any other secret files, we'll create the production version of the file when we deploy, and symlink it into place.

    -

    3. Initialize Capistrano in your application.

    +

    3. Initialize Capistrano in your application.

    $ cd my-project
    @@ -202,6 +351,125 @@ $ cap install
    └── capistrano └── tasks
    + +

    4. Configure your server addresses in the generated files.

    + +

    We'll just work with the staging environment here, so you can pretend that +config/deploy/production.rb doesn't exist, for the most part that's yoru +business.

    + +

    Capistrano breaks down common tasks into a notion of roles, that is, taking +a typical Rails application that we have roughly speaking three roles, web, +app, and db.

    + +

    It can be confusing, as the boundary of web and app servers is a bit blurry if +using Passenger with Apache, which in effect embeds your app server in the +web server (embeds Passenger in the Apache process itself), confusingly +Passenger can also be used in modes where this isn't true, so we'll ignore +that for the time being, and if you know the difference (i.e you are using +nginx as your web server, and puma/unicorn, or similar for your app server, +that should be fine) we can assume that they're the same, which is pretty +common.

    + +

    The example file generated will look something like this:

    + +
    +
    set :stage, :staging
    +
    +# Simple Role Syntax
    +# ==================
    +# Supports bulk-adding hosts to roles, the primary
    +# server in each group is considered to be the first
    +# unless any hosts have the primary property set.
    +role :app, %w{example.com}
    +role :web, %w{example.com}
    +role :db,  %w{example.com}
    +
    +# Extended Server Syntax
    +# ======================
    +# This can be used to drop a more detailed server
    +# definition into the server list. The second argument
    +# something that quacks like a has can be used to set
    +# extended properties on the server.
    +server 'example.com', roles: %w{web app}, my_property: :my_value
    +
    +# set :rails_env, :staging
    +
    + +

    Both the simple role, and extended server syntaxes result in one or more +servers for each role being defined. The app and db roles are just +placeholders, if you are using the capistrano/rails-* addons (more on +that later) then they have a meaning, but if you are deploying something +simpler, feel free to delete them if they're meaningless to you.

    + +

    The extended server syntax exists to allow the definition of arbitrary server +properties; it's there incase people want to build the server list more +comprehensively from something like the EC2 command line tools, and want to +use the extended properties for something that makes sense in their +environment.

    + +

    Servers can be defined in a bunch of ways, the following shows defining two +servers, one where we set the username, and another where we set the port. +These host strings are parsed and expanded out in to the equivilent of the +server line after the comment:

    + +
    +
    role :all, %w{hello@world.com example.com:1234}
    +# ...is the same as doing...
    +server 'world.com' roles: [:web], user: 'hello'
    +server 'example.com', roles: [:web], port: 1234
    +
    + +

    5. Set the shared information in deploy.rb.

    + +

    The deploy.rb is a place where the configuration common to each environment +can be specified, normally the repository URL and the user as whom to +deploy are specified here.

    + +

    The generated sample file starts with the following, and is followed by a few +self-documenting, commented-out configuration options, feel free to play with +them a little:

    + +
    +
    set :application, 'my app name'
    +set :repo, 'git@example.com:me/my_repo.git'
    +ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
    +
    + +

    Here we'd set the name of the application, ideally in a way that's safe for +filenames on your target operating system.

    + +

    Second we set the repository URL, this MUST be somewhere that the server we +are deploying to can reach.

    + +

    Here's how this might look in a typical example, note that we'll cover +authentication in the next chapter, for now we'll assume this repository is +open source, we'll take an example application from the Rails Examples and +Tutorials site; there we'll find maintained a +handful of typical Rails apps with typical dependencies.

    + +

    The Rails application they host, which uses Devise (for authentication) and +Cancan (for authorization) along side Twitter Bootstrap for assets has been +forked to the Capistrano repository, but you can find the (unchanged) original +here.

    + +
    +
    set :application, 'rails3-bootstrap-devise-cancan-demo'
    +set :repo, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan'
    +set :branch, 'master'
    +
    + +

    I've simplified the :branch varaible to simply be a set varaible, not a +question prompt, as this repository only has a master branch.

    + +

    Roundup

    + +

    At this point Capistrano knows where to find our servers, and where to find +our code.

    + +

    We've not covered how we authorise our servers to check out our code (there +are three pretty good ways of doing that with Git), nor have we determined how +to authorise Capistrano on our servers yet.

    --> diff --git a/_site/documentation/overview/introductory-demo-video/index.html b/_site/documentation/overview/introductory-demo-video/index.html index 25be9aad..26e23873 100644 --- a/_site/documentation/overview/introductory-demo-video/index.html +++ b/_site/documentation/overview/introductory-demo-video/index.html @@ -16,6 +16,36 @@ + + + + +
    @@ -33,28 +63,28 @@
  • Introductory Demo Video
  • Getting Started
    -
  • Installation
  • -
  • Preparing Your Application
  • -
  • Authentication & Authorisation
  • -
  • Cold Start
  • -
  • Rollbacks
  • +
  • Installation
  • +
  • Preparing Your Application
  • +
  • Authentication & Authorisation
  • +
  • Cold Start
  • +
  • Rollbacks
  • Troubleshooting
    -
  • SCM (Git) Authentication
  • -
  • Connectivity
  • - -
  • Agent Forwarding
  • -
  • `sudo` Password
  • -
  • RVM, `rbenv` And `nvm`
  • +
  • SCM (Git) Authentication
  • +
  • Connectivity
  • + +
  • Agent Forwarding
  • +
  • `sudo` Password
  • +
  • RVM, `rbenv` And `nvm`
  • FAQ
  • Why Does Something Work In An SSH Session, But Not In Capistrano?
  • -
  • Should I Use Capistrano To Provision My Servers?
  • + href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano? +
  • Should I Use Capistrano To Provision My Servers?
  • Power Use-Cases
    -
  • Integration With Rake
  • -
  • Driving Tools Such As Chef Solo
  • +
  • Integration With Rake
  • +
  • Driving Tools Such As Chef Solo
  • Recent Announcements
    @@ -73,7 +103,7 @@ without much previous setup.

    unprepared server, covering all aspects of Github access, as well as privisioning the server using Chef Solo and Capistrano with Rake.

    -

     Show Notes

    +

    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 @@ -112,7 +142,7 @@ without much previous setup.

    unprepared server, covering all aspects of Github access, as well as privisioning the server using Chef Solo and Capistrano with Rake.

    -

     Show Notes

    +

    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 diff --git a/_site/images/github-personal-api-token-page.png b/_site/images/github-personal-api-token-page.png new file mode 100644 index 00000000..2b12e3e8 Binary files /dev/null and b/_site/images/github-personal-api-token-page.png differ diff --git a/_site/index.html b/_site/index.html index a8f84b89..6358a5d8 100644 --- a/_site/index.html +++ b/_site/index.html @@ -16,6 +16,36 @@ + + + + +

    @@ -33,28 +63,28 @@
  • Introductory Demo Video
  • Getting Started
    -
  • Installation
  • -
  • Preparing Your Application
  • -
  • Authentication & Authorisation
  • -
  • Cold Start
  • -
  • Rollbacks
  • +
  • Installation
  • +
  • Preparing Your Application
  • +
  • Authentication & Authorisation
  • +
  • Cold Start
  • +
  • Rollbacks
  • Troubleshooting
    -
  • SCM (Git) Authentication
  • -
  • Connectivity
  • - -
  • Agent Forwarding
  • -
  • `sudo` Password
  • -
  • RVM, `rbenv` And `nvm`
  • +
  • SCM (Git) Authentication
  • +
  • Connectivity
  • + +
  • Agent Forwarding
  • +
  • `sudo` Password
  • +
  • RVM, `rbenv` And `nvm`
  • FAQ
  • Why Does Something Work In An SSH Session, But Not In Capistrano?
  • -
  • Should I Use Capistrano To Provision My Servers?
  • + href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano? +
  • Should I Use Capistrano To Provision My Servers?
  • Power Use-Cases
    -
  • Integration With Rake
  • -
  • Driving Tools Such As Chef Solo
  • +
  • Integration With Rake
  • +
  • Driving Tools Such As Chef Solo
  • Recent Announcements
    diff --git a/css/capistrano.css b/css/capistrano.css index 7be2c8fc..56e5f909 100644 --- a/css/capistrano.css +++ b/css/capistrano.css @@ -8,6 +8,7 @@ body { } h1, h2, h3, h4, h5, h6 { + font-weight: 400; font-family: 'Enriqueta', serif; } diff --git a/documentation/getting-started/authentication-and-authorisation/index.markdown b/documentation/getting-started/authentication-and-authorisation/index.markdown new file mode 100644 index 00000000..dd8c3576 --- /dev/null +++ b/documentation/getting-started/authentication-and-authorisation/index.markdown @@ -0,0 +1,314 @@ +--- +title: Authentication & Authorisation +layout: default +--- + +**Note:** In the documentation we simply recommend creating a single deployment user, +and sharing it between team members. If you know why this is a bad idea (or +why this may be against regulations in your jurisdiction in some cases, we +assume that you know well enough how to use groups, umasking 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 +done: + +{% prism bash %} + root@remote $ adduser deploy + root@remote $ passwd -l deploy +{% endprism %} + +The first line creates a completely standard user, it has a home directory, +which we'll need in a moment, and has a shell, so it may log in. This needs to +be done **on every server in your environment**. + +The second line *locks* the user, it changes the user's password to an +untypable string, guaranteeing that the user has no password which can be used +to log in. + +### Authentication + +There are two places that we need automated, promptless authentication: + + 1. **From our workstation/notebook/etc to our servers.** We do this with **SSH + keys**, passphrase protected, ideally, using a **key agent**. + 2. **From our servers to the repository host**. We do this so that our servers + can check out our application code from Github, or similar and install it + to the servers. This is usually done using **SSH agent forwarding**, HTTP + authentication, or with deploy keys. + +#### 1.1 SSH keys from workstation to servers + +**Note:** If you are on Windows, all bets are off, I'd love it if someone +could contribute a Windows guide to this, so we can include it here. + +An SSH key is a mechanism that allows a *public* half one key to be placed on +a server, when we want to authenticate with that server, our SSH client uses +the **private** part of that key to negotiate with the server, if the keys are +correct, then we need to create the key. + +**Hint:** If you have more than one developer in your team, they should all add their +public key to the `deploy` user's `authorized_keys` file, that way if someone +quits or gets fired, you can remove their key from that file, and the rest of +you can keep on shipping! + +{% prism bash %} + me@localhost $ ssh-keygen -t rsa -C 'me@my_email_address.com' +{% endprism %} + +You'll be prompted for a passphrase, that's fine. Type one and keep it safe. +This passphrase ensures that if your computer is stolen, people still need a +passphrase to access your keys, in order to access your servers. + +To avoid having to type this passphrase every time you need to use a key, most +operating systems have a concept of a *key agent*. This *key agent* stores SSH +keys securely between uses, typically the first time a key is needed in a +given time period, the SSH agent will load the key, prompt you for your +passphrase and then the key agent will remember the key for a certain amount +of time (on OSX it tends to be indefinite, on linux this can vary from 15 +minutes updwards.) + +We can see which keys are loaded in the SSH agent by running `ssh-add -l` + +{% prism bash %} + 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) +{% endprism %} + +If you don't see any keys listed, you can simply run `ssh-add`: + +{% prism bash %} + me@localhsot $ ssh-add + Identity added: /Users/me/.ssh/id_rsa (/Users/me/.ssh/id_rsa) +{% endprism %} + +Typically, ssh-add will ask you for the passphrase when you add a key. + +**Note:** Although it's not mandatory to use an SSH agent (one could simply +use an unpassphrased key, and rely on SSH to find the key and exchange it). +Using an SSH agent makes things more secure, because we can use a passphrased +key without being prompts every time it is used. It **also** allows us to use +this same key to access the repository *via* the server without creating an +additional identity. + +At this point with the key loaded into the agent, we need to put the +**public** part of the key into a file on each remote server called +`/home/users/deploy/.ssh/authorized_keys`, to get the contents of that file, +we can ask our local key agent for the public parts of the keys it has loaded: + +{% prism bash %} + me@localhost $ ssh-add -L + ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa +{% endprism %} + +This will be a lot longer when you run it, I snipped the output because it +looked bad. + +This line, as one line, needs to make it to the remote server and be added *to +it's own line* of the `deploy` user's `~/.ssh/authorized_keys` file. This file +then needs to be changed to permission mode `0600` (owner read/write, group +none, other none), in the `~/.ssh` directory which needs the permissions +`0700` (owner read/write/execute, group none, other none). + +If you are on linux there often exists a command +[`ssh-copy-id`](http://linux.die.net/man/1/ssh-copy-id) which streamlines this +process, otherwise the worlflow is something like: + +{% prism bash %} + me@localhost $ ssh root@remote + root@remote $ su - deploy + deploy@remote $ cd ~ + 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 $ chmod 700 .ssh + deploy@remote $ chmod 600 .ssh/authorized_keys +{% endprism %} + +**Remember:** This needs to be done on every server you want to use, you can +use the same key for each one, but only one key per developer is recommended. +*Private* keys are named as such for a reason! + +If we did all that correctly, we should now be able to do something like this: + +{% prism bash %} + me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime' + one-of-my-servers.com + 19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05 +{% endprism %} + +That should happen without having to enter a passphrase for your SSH key, or +promoting you for an SSH password (which the deploy user doesn't have anyway). + +Verify that this works for all of your servers, and put your private key +somewhere safe. If you're working with multiple team members, it often pays to +collect everyone's public keys, indeed if your team is already using SSH keys +to access Github, you can reach any user's SSH keys at the following URL: + + * `https://github.com/theirusername.keys` + +This can make getting user's keys onto servers much easier, as you can simply +`curl`/`wget` each user's key into the authorized keys file on the server +directly from Github. + + + + +#### 1.2 From our servers to the repository host + +With access from workstations to the servers settled, there is another hop to +contend with, which is letting the deploy user get access to the code +repository automatically. The options in order of preference: + +##### 1.2.1 SSH Agent Forwarding + +As we've already set up an SSH agent, we can use the *agent forwarding* +feature of SSH to make this key agent available to further *hops*. In short, +we can use **our own ssh key** to authenticate ourselves from the server, to +Github. + +Here's how we can check if that works, first get the URL of the repository: + +{% prism bash %} + me@localhost $ git config remote.origin.url + git@github.com:capistrano/rails3-bootstrap-devise-cancan.git +{% endprism %} + +Here we're listing our private (for testing purposes) fork of the +rails3-bootstrap-devise-cancan repository forked from the Rails Examples and +Tutorials project. + +We can try to access the repository via our server by doing the following: + +{% prism bash %} + # List SSH keys that are loaded into the agent + me@localhost $ ssh-add -l + # Make sure they key is loaded if 'ssh-add -l' didn't show anything + 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 +{% endprism %} + +We first check that the agent has the keys loaded, if not we simply load it, +and enter the passphrase when prompted. + +Finally we use `ls-remote` from Git to list the remote objects, this is the +exact same check that Capistrano does internally before attempting to deploy. +The `-A` option may, or may not be required on your system, it's worth trying +it both ways just to know how your system treats agent forwarding by default. + +From the SSH documentation: + +{% prism bash %} + -A Enables forwarding of the authentication agent connection. This can also be + specified on a per-host basis in a configuration file. + + 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 + socket) can access the local agent through the forwarded connection. An + attacker cannot obtain key material from the agent, however they can perform + operations on the keys that enable them to authenticate using the identities + loaded into the agent. +{% endprism %} + +In laymans terms, you should't use SSH agent forwarding to machines where you +don't trust the administrators, as they can can override the permissions on +the system and use your keys as if they were you. That said, if you can't +trust your server administrators, perhaps they shouldn't have access to your +servers! + +##### 1.2.2 HTTP Authentication + +In the case of HTTP authentication **be sure to use HTTPS**, otherwise your +password will be sent in cleartext over the network, depending what your hosts +network infratructure looks like that might be *very* bad news. + +Typically when we try and list our remote objects, using the https method from +Github, we'll be prompted for a username and password: + +##### 1.2.2.1 With a regular username/password + +{% prism bash %} + me@localhost $ git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git + Username for 'https://github.com': myownusername + Password for 'https://capistrano@github.com': +{% endprism %} + +This challenge response prompt doesn't work well for automating things, so +there are two ways to get around this depending on your server's host +operating system, the first is to use a `netrc` file, we won't talk about that +because the netrc is a global file that doesn't lend itself well to security. + +The other mechanism, and the reason that its **very** important to always use +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: + +{% prism bash %} + me@localhost $ git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git + 3419812c9f146d9a84b44bcc2c3caef94da54758HEAD + 3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master +{% endprism %} + +The bigger problem with passwords, whether inlined into the URL, or entered +into a `netrc` file, is that the password gives access to **your entire Github +Account** not just to one single repository. + +##### 1.2.2.2 With an OAuth Personal API Token + +This mechanism still gives access to **every repository** you can access, but +at Github, they recently rolled out a feature called [Personal API +Tokens](https://github.com/blog/1509-personal-api-tokens) which allow you to +do something like this: + +{% prism bash %} + me@localhost $ git ls-remote https://.....................@github.com/capistrano/rails3-bootstrap-devise-cancan.git + 3419812c9f146d9a84b44bcc2c3caef94da54758HEAD + 3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master +{% endprism %} + +Where `....` is a personal API token, as such: + +![Github Personal API Token Page](/images/github-personal-api-token-page.png) + +##### 1.2.3 Deploy Keys + +Deploy keys, a feature of Github, and some other platforms allow you to +generate a **second** set of SSH keys for the connection between Github and +the servers themselves. + +Slightly perversely in this case the public key is uploaded to the repository +host, and the private key must be copied to each server that you want to +deploy to. + +Github has a quite excellent guide on this, much of which (unsurprisingly) +overlaps with the SSH key instructions above. + + * [Github Help: Managing Deploy Keys](https://help.github.com/articles/managing-deploy-keys) + +### Authorisation + +The second part of this topic is that our deploy user needs to be authorised +to work in the deployment directory, on the server. That means we need to be +able to work, ideally without `sudo` (none of the default Capistrano recipes +expect `sudo` to be available), or for your custom recipes, you will need to +have configured *passwordless* `sudo`. Configuring `sudo` to give some users +access to come commands under some circumstances is beyond the scope of this +documentation, but sufficed to say something like: + +{% prism bash %} +deploy ALL=NOPASSWD:/etc/init.d/mysqld, /etc/init.d/apache2 +{% endprism %} + +This example would give the user named `deploy` access to call `sudo +/etc/init.d/mysql _________` and the same for the `apache2` control script. + +**Granting passwordless sudo should not be done lightly.** It can be dangerous. +For example if an unprivilidged user can *edit* the script that they can run +as root, they can easily edit it to do anything they want that is evil. Use +this carefully, and ideally architect your systems so that non-privlidged +users can restart services, or that services restart *themselves* when they +notice change. + diff --git a/documentation/getting-started/preparing-your-application/index.markdown b/documentation/getting-started/preparing-your-application/index.markdown index 3e7c8d33..217d8b00 100644 --- a/documentation/getting-started/preparing-your-application/index.markdown +++ b/documentation/getting-started/preparing-your-application/index.markdown @@ -8,7 +8,7 @@ layout: default here have parallels in Python, or PHP applications
    -## 1. Commit your application to some externally available source control hosting provider. +### 1. Commit your application to some externally available source control hosting provider. If you are not doing already, you should host your code somewhere with a provuder such as Github, BitBucket, Codeplane, or repositoryhosting.com. @@ -20,7 +20,7 @@ contribute if you know these tools well, we don't and don't want to force our miscomprehended notions upon anyone.
    -## 2. Move secrets out of the repository. +### 2. Move secrets out of the repository.
    If you've accidentally committed state secrets to the repository, you might @@ -46,7 +46,7 @@ parallel concept of ignored files) This should be done for any other secret files, we'll create the production version of the file when we deploy, and symlink it into place. -## 3. Initialize Capistrano in your application. +### 3. Initialize Capistrano in your application. {% prism bash %} $ cd my-project @@ -66,3 +66,122 @@ This will create a bunch of files, the important ones are: └── capistrano └── tasks {% endprism %} + +### 4. Configure your server addresses in the generated files. + +We'll just work with the staging environment here, so you can pretend that +`config/deploy/production.rb` doesn't exist, for the most part that's yoru +business. + +Capistrano breaks down common tasks into a notion of *roles*, that is, taking +a typical Rails application that we have roughly speaking three roles, `web`, +`app`, and `db`. + +It can be confusing, as the boundary of web and app servers is a bit blurry if +using [Passenger]() with Apache, which in effect embeds your app server in the +web server (embeds Passenger in the Apache process itself), confusingly +Passenger can also be used in modes where this isn't true, so we'll ignore +that for the time being, and if you know the difference (i.e you are using +nginx as your web server, and puma/unicorn, or similar for your app server, +that should be fine) we can assume that they're the same, which is pretty +common. + +The example file generated will look something like this: + +{% prism ruby %} + set :stage, :staging + + # Simple Role Syntax + # ================== + # Supports bulk-adding hosts to roles, the primary + # server in each group is considered to be the first + # unless any hosts have the primary property set. + role :app, %w{example.com} + role :web, %w{example.com} + role :db, %w{example.com} + + # Extended Server Syntax + # ====================== + # This can be used to drop a more detailed server + # definition into the server list. The second argument + # something that quacks like a has can be used to set + # extended properties on the server. + server 'example.com', roles: %w{web app}, my_property: :my_value + + # set :rails_env, :staging +{% endprism %} + +Both the simple role, and extended server syntaxes result in one or more +servers for each role being defined. The `app` and `db` roles are just +placeholders, if you are using the `capistrano/rails-*` addons (more on +that later) then they have a meaning, but if you are deploying something +simpler, feel free to delete them if they're meaningless to you. + +The extended server syntax exists to allow the definition of arbitrary server +properties; it's there incase people want to build the server list more +comprehensively from something like the *EC2* command line tools, and want to +use the extended properties for something that makes sense in their +environment. + +Servers can be defined in a bunch of ways, the following shows defining two +servers, one where we set the username, and another where we set the port. +These host strings are parsed and expanded out in to the equivilent of the +server line after the comment: + +{% prism ruby %} + role :all, %w{hello@world.com example.com:1234} + # ...is the same as doing... + server 'world.com' roles: [:web], user: 'hello' + server 'example.com', roles: [:web], port: 1234 +{% endprism %} + +### 5. Set the shared information in `deploy.rb`. + +The `deploy.rb` is a place where the configuration common to each environment +can be specified, normally the *repository URL* and the *user as whom to +deploy* are specified here. + +The generated sample file starts with the following, and is followed by a few +self-documenting, commented-out configuration options, feel free to play with +them a little: + +{% prism ruby %} + set :application, 'my app name' + set :repo, 'git@example.com:me/my_repo.git' + ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp } +{% endprism %} + +Here we'd set the name of the application, ideally in a way that's safe for +filenames on your target operating system. + +Second we set the repository URL, this *MUST* be somewhere that the server we +are deploying to can reach. + +Here's how this might look in a typical example, note that we'll cover +authentication in the next chapter, for now we'll assume this repository is +open source, we'll take an example application from the [Rails Examples and +Tutorials](http://railsapps.github.io/) site; there we'll find maintained a +handful of typical Rails apps with typical dependencies. + +The Rails application they host, which uses Devise (for authentication) and +Cancan (for authorization) along side Twitter Bootstrap for assets has been +forked to the Capistrano repository, but you can find the (unchanged) original +[here](https://github.com/RailsApps/rails3-bootstrap-devise-cancan). + +{% prism ruby %} + set :application, 'rails3-bootstrap-devise-cancan-demo' + set :repo, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan' + set :branch, 'master' +{% endprism %} + +I've simplified the `:branch` varaible to simply be a `set` varaible, not a +question prompt, as this repository only has a master branch. + +## Roundup + +**At this point Capistrano knows where to find our servers, and where to find +our code.** + +We've not covered how we authorise our servers to check out our code (there +are three pretty good ways of doing that with Git), nor have we determined how +to authorise Capistrano on our servers yet. diff --git a/documentation/overview/introductory-demo-video/index.markdown b/documentation/overview/introductory-demo-video/index.markdown index f7c5e04f..63577cd9 100644 --- a/documentation/overview/introductory-demo-video/index.markdown +++ b/documentation/overview/introductory-demo-video/index.markdown @@ -10,9 +10,7 @@ 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 +#### 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 diff --git a/images/github-personal-api-token-page.png b/images/github-personal-api-token-page.png new file mode 100644 index 00000000..2b12e3e8 Binary files /dev/null and b/images/github-personal-api-token-page.png differ