views:

368

answers:

4

I am getting ready to deploy to a true production environment. When I say true I mean that my current production environment will now be staging because there is other crap on the server and I am creating a new larger slice for what will actually be my production machine.

The capistrano-ext gem has made separating the deploy recipes quite easy. However, one issue I run into is getting my code from one slice to another. I have a git repo set up on my staging slice that I will be using for production. The flow will be:

Develop locally Test locally Push from local to stage Test on stage Push from stage to production ...

Therefore I obviously need a way to establish a secure connection between staging and production. When deploying to production, I get a "Permission denied (publickey)." error because this is not set up. How can I establish this connection? Do I need to generate keys on my production server and put the public on my staging? How do I know what user on my production server is trying to connect to my staging server?

+1  A: 

I find that branching or version tagging works much better for differentiating staging vs. production when using Capistrano.

For example, set up a 'staging' and 'production' branch for your application and use your source control tools to manage migrating changes from one to the next. During deployment simply deploy as you usually would, but with a particular branch instead of the main one.

It's not necessary to promote directly from staging to production, and in fact, this may be considered a bad idea since anyone with access to the staging machine potentially has access to the production server. In most environments a staging server is treated much more casually than the production site, so the security profile is usually quite different.

tadman
Those are some good points but even if I use tags, I still need to connect my production server to my staging server because my git repository is hosted on my staging server.
Tony
+1  A: 

Branches and capistrano multistage are your friends.

To solve the production not having access to the git repo issue, try…

set :deploy_via, :copy

…this deploys by checking out locally, and pushing a tar ball.

cwninja
+1  A: 

Do I need to generate keys on my production server and put the public on my staging?

Yes.

How do I know what user on my production server is trying to connect to my staging server?

The productionuser will be whatever user you connect with (see :user). The staginguser will be from the git url (see :repository).

When you use

set :deploy_via, :remote_cache

(which is the default), two ssh connections are actually occurring. The first one is from your local machine to production, and it uses the 'user' as configured in your recipe.

set :user, 'www-data'

The second ssh connection is made by that user, on production, to your git origin. So if git origin is on staging, the production user is trying to connect back to staging to pull code from git.

set :repository, "[email protected]:project.git"

Try this: ssh to production as the user. Then run the failing command by hand. You'll see the "permission denied" and maybe a prompt for a password. Add the public key of the staging server user to the production box and things should work better.

Jonathan Julian
A: 

There's also:

set :gateway, 'staging server ip'

which should allow you to tunnel all the way through to your firewalled production box. But if you're deploying from staging you need to set up keys on the staging box if you're going to go through it that way.

On a side note, it's important to be able to do this whole process from your home box, staging really shouldn't need to have a capistrano gem, the hope is that you can do the whole process without ever having to actually log into a server. That includes logging in to your staging server. :)

If there's an issue of data pushing between the two this could easily be added onto just the production config so that it automatically takes data from staging and rsync's it over.

Chuck Vose
I can do it from my home box. The issue is that the repository is on a different server than production. I solved the issue by setting up keys for my production box to access the git repo on my staging box.
Tony