Deploy Jekyll "_site" from GitHub with Capistrano - capistrano

I'm trying to deploy just my Jekyll-generated "_site" folder to a "release" with Capistrano. I've confirmed that Capistrano works but it's currently deploying everything on my GitHub-hosted repo. Is what I want possible?
My deploy.rb file currently looks like this...
set :application, "kaidez.com"
set :repository, "git#github.com:kaidez/kaidez.com.git"
default_run_options[:pty] = true
set :scm, "git"
set :user, "myUsername"
set :scm_passphrase, "myPassword"
set :ssh_options, { :forward_agent => true }
set :branch, "master"
set :deploy_to, "/my/remote/branch/"
set :deploy_via, :remote_cache
set :use_sudo, false
role :web, "kaidez.com"
role :app, "kaidez.com"

Since Jekyll need to compile the website, you either need to:
compile the site locally and add the files to version control
compile the site locally prior to uploading
compile the site on the server after uploading
use something like rack-jekyll to compile your site when requested
After trying to do something similar to you, I ended up scraping Capistrano in favor of writing my own, simple rake task which compiled the site and used rsync to upload the changes.

Related

Capistrano: organizing folders for different environments

I'm approaching to Capistrano and I want to understand better how I have to organize the folder structure on the server.
Let's suppose I have two branch:
master
develop
That are visible respectively on:
www.example.org
develop.example.org
Actually (no-Capistrano), on the server I have:
/home/sites/example.org/www
/home/sites/example.org/develop
But, with Capistrano, I will have only /home/sites/example.org/current.
How can I manage the "production/development" situation with Capistrano?
Thanks
You can override the deployment folder in your environment config. For example, you have the default deployment location in config/deploy.rb using set :deploy_to, '/home/sites/example.org/www'. Then you set up config/develop.rb and config/production.rb (these names are arbitrary and don't need to map to the branch names):
server 'servername', user: 'username', roles: %w(app db web)
set :deploy_to, '/home/sites/example.org/develop'
In general, anything you set in deploy.rb can be overridden in deploy/[env].rb.

Capistrano in Open Source Projects and different environments

I consider to use Capistrano to deploy my rails app on my server. Currently I'm using a script, which does all the work for me. But Capistrano looks pretty nice and I want to give it a try.
My first problem/question now is: How to use Capistrano properly in open source projects? I don't want to publish my deploy.rb for several reasons:
It contains sensible informations about my server. I don't want to publish them :)
It contains the config for MY server. For other people, which deploy that open source project to their own server, the configuration may differ. So it's pretty senseless to publish my configuration, because it's useless for other people.
Second problem/question: How do I manage different environments?
Background: On my server I provide two different environments for my application: The stable system using the current stable release branch and located under www.domain.com. And a integration environment for the develop team under dev.domain.com running the master branch.
How do I tell Capistrano to deploy the stable system or the dev system?
The way I handle sensitive information (passwords etc.) in Capistrano is the same way I handle them in general: I use an APP_CONFIG hash that comes from a YAML file that isn't checked into version control. This is a classic technique that's covered e.g. in RailsCast #226, or see this StackOverflow question.
There are a few things you have to do a little differently when using this approach with Capistrano:
Normally APP_CONFIG is loaded from your config/application.rb (so it happens early enough to be usable everywhere else); but Capistrano cap tasks won't load that file. But you can just load it from config/deploy.rb too; here's the top of a contrived config/deploy.rb file using an HTTP repository that requires a username/password.
require 'bundler/capistrano'
APP_CONFIG = YAML.load_file("config/app_config.yml")
set :repo_user, APP_CONFIG['repo_user']
set :repo_password, APP_CONFIG['repo_password']
set :repository, "http://#{repo_user}:#{repo_password}#hostname/repositoryname.git/"
set :scm, :git
# ...
The config/app_config.yml file is not checked into version control (put that path in your .gitignore or similar); I normally check in a config/app_config.yml.sample that shows the parameters that need to be configured:
repo_user: 'usernamehere'
repo_password: 'passwordhere'
If you're using the APP_CONFIG for your application, it probably needs to have different values on your different deploy hosts. So have your Capistrano setup make a symlink from the shared/ directory to each release after it's checked out. You want to do this early in the deploy process, because applying migrations might need a database password. So in your config/deploy.rb put this:
after 'deploy:update_code', 'deploy:symlink_app_config'
namespace :deploy do
desc "Symlinks the app_config.yml"
task :symlink_app_config, :roles => [:web, :app, :db] do
run "ln -nfs #{deploy_to}/shared/config/app_config.yml #{release_path}/config/app_config.yml"
end
end
Now, for the second part of your question (about deploying to multiple hosts), you should configure separate Capistrano "stages" for each host. You put everything that's common across all stages in your config/deploy.rb file, and then you put everything that's unique to each stage into config/deploy/[stagename].rb files. You'll have a section in config/deploy.rb that defines the stages:
# Capistrano settings
require 'bundler/capistrano'
require 'capistrano/ext/multistage'
set :stages, %w(preproduction production)
set :default_stage, 'preproduction'
(You can call the stages whatever you want; the Capistrano stage name is separate from the Rails environment name, so the stage doesn't have to be called "production".) Now when you use the cap command, insert the stage name between cap and the target name, e.g.:
$ cap preproduction deploy #deploys to the 'preproduction' environment
$ cap production deploy #deploys to the 'production' environment
$ cap deploy #deploys to whatever you defined as the default

Capistrano config files location

Im using capistrano to deploy PHP projects which all works perfectly I am now introducing multistage, which I have also got working no problem
In my actual application setup I like to store the files in a differnt format
eg
/
..application/
....deploy/deploy.rb
....deploy/production.rb
..configs (etc)
I understand the default is config/deploy/production.rb
This dosent follow my applications say up, so is there anyway to define which path to use?
Capfile:
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
load 'application/deploy/deploy' # remove this line to skip loading any of the default tasks
I only use one file: config/deploy.rb with multiple tasks. Ignore the RVM business if you don't use it. Like this:
task :staging do
set :rails_env, 'staging'
role :app, "staging.example.com"
role :web, "staging.example.com"
role :db, "staging.example.com", :primary => true
end
task :production do
set :rails_env, 'production'
set :branch, 'master'
# RVM integration as specified at https://rvm.beginrescueend.com/integration/capistrano/
$:.unshift(File.expand_path('./lib', ENV['rvm_path'])) # Add RVM's lib directory to the load path.
require "rvm/capistrano"
set :rvm_ruby_string, 'ruby-version#gemset'
set :rvm_type, :user
role :app, "prod.example.com"
role :web, "prod.example.com"
role :db, "prod.example.com", :primary => true
end
Then you deploy with cap staging deploy and cap production deploy.

capistrano ssh connection - doesn't work when ran from cron or teamcity

I've been researching this all day and can't seem to find an answer so am posting here. We are using capistrano multistage to deploy our ruby on rails app and all is well, until we get to automated deployments.
Right now whenever this is ran interactively there are no issues, the deploy completes just fine. We are now looking at using ci (Teamcity) to deploy to our staging environment after each successful build.
On the CI server, running "ssh server1", or "ssh deploy#server1" works without issue.
my ci stage looks like this, and again works fine from command line
set :branch, "development"
set :rails_env, "staging"
set :user, "deploy"
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require 'rvm/capistrano'
set :rvm_ruby_string, 'ruby-1.9.2-p290'
set :rvm_bin_path, "/usr/local/rvm/bin/"
default_run_options[:pty] = true
ssh_options[:verbose] = :debug
default_run_options[:pty] = true
role :app, "server1"
role :web, "server1"
role :utility, "server2"
role :db, "server1", :primary => true
my deploy.rb is very large, but these are the relevant settings
# Repo Settings
set :repository, "git#github.com:myrepo/myrepo.git"
set :scm, "git"
set :checkout, 'export'
set :copy_exclude, ".git/*"
set :deploy_via, :remote_cache
# General Settings
default_run_options[:pty] = true
set :ssh_options, { :forward_agent => true }
set :keep_releases, 20
set :use_sudo, false
Under Team City as a final build step I have added a command line task which is simply "cap ci deploy:setup" - as an easier test than a full deploy
The cap log shows me this:
[03:27:38]: [Step 4/10] D, [2011-11-21T03:27:38.103284 #22035] DEBUG -- net.ssh.authentication.session[70ca88]: allowed methods: publickey,password
[03:27:38]: [Step 4/10] E, [2011-11-21T03:27:38.103328 #22035] ERROR -- net.ssh.authentication.session[70ca88]: all authorization methods failed (tried publickey)
The same thing seems to happen from a cronjob - however don't have the logs there
To me this seems like an environment issue as Teamcity and likely cron arent loading my full environment. I've tried specifying my ssh key directly in the cap file, among other things and it does not seem to have any effect.
The other odd thing is that on the remote server I am trying to deploy to, the auth.log shows no attempted connections, so troubleshooting this from the server side doesnt seem to be an option.
So my questions is, how do I get this working? Any ideas on tests to determine where the issue is, or environment variables I need to set appreciated.
Any answer that leads me to the solution will be accepted.
Thanks.
I fixed this by modifying the ssh connection in ssh/config, running ssh-agent with a specific pid, adding environment variables and adding a build step to add the key to the ssh agent in the running build.
http://petey5king.github.com/2011/12/09/deploying-with-capistrano-from-teamcity.html

How to deploy to multiple redundant production servers with "cap deploy"?

Capistrano is working great to deploy to a single server. However, I have multiple production API servers for my web application. When I deploy, my code needs to get deployed to every API server at once. Specifying each server manually is NOT the solution I am looking for (e.g. I don't want to do "cap api1 deploy; cap api2 deploy").
Is there a way, using Capistrano, to deploy to all servers at once, with just a simple "cap deploy"? I'm wondering what changes I would need to make to a typical deploy.rb file, whether I'd need to create a separate file for each server, and whether and how the Capfile would need to be changed. Also, I need to be able to specify a different deploy_to path for each server. And ideally, I wouldn't have to repeat things in different config files for different servers (eg. wouldn't have to specify :repository, :application, etc. multiple times).
I have spent hours searching Google on this and looking through tutorials, but I have found nothing helpful.
Here is a snippet from my current deploy.rb file:
set :application, "testapplication"
set :repository, "ssh://domain.com//srv/hg/#{application}"
set :scm, :mercurial
set :deploy_to, "/srv/www/#{application}"
role :web, "domain.com"
role :app, "domain.com"
role :db, "domain.com", :primary => true, :norelease => true
Should I just use the multistage extension and do this?
task :deploy_everything do
system "cap api1 deploy"
system "cap api2 deploy"
system "cap api2 deploy"
end
That could work, but I feel like this isn't what this extension is meant for...
It seems like you might be interested in the "Multiple Servers" heading on the Getting Started page. Is that what you're after?