7

chef環境を構成し、capistranoを使用してアプリケーションをデプロイできます。今度は、シェフにcapistranoを処理してアプリをデプロイさせたいと思います。どのようにそれを行うことができますか?

4

3 に答える 3

3

私は反対のことをします。Capistrano を介して Chef レシピをデプロイします。私はそれをお勧めします。

#config/deploy.rb
...
before 'bundle:install', "provision:default", "deploy:config_db_yml_symlink"
...

多くの gem は OS にインストールされるパッケージに依存しているため、これは重要です。

#config/deploy/provision.rb
Capistrano::Configuration.instance(:must_exist).load do
  namespace :provision do
    task :default do
      provision.setup
      provision.web
      provision.db
      provision.db_slave
    end

    task :setup, once: true do
      provision.get_environment_variables
      provision.update_cookbooks
    end

    task :db, :roles => :db do
      next if find_servers_for_task(current_task).empty?
      if rails_env == 'staging'
        run %{cd #{release_path}/provision; sudo chef-solo -c solo.rb -j db.json -l debug}
      else
        run %{cd #{release_path}/provision; sudo chef-solo -c solo.rb -j db_master.json -l debug}
      end
    end

    task :db_slave, :roles => :db_slave do
      next if find_servers_for_task(current_task).empty?
      run %{cd #{release_path}/provision; sudo chef-solo -c solo.rb -j db_slave.json -l debug}
    end

    task :web, :roles => :web do
      next if find_servers_for_task(current_task).empty?
      run %{cd #{release_path}/provision; sudo chef-solo -c solo.rb -j web.json -l debug}
    end

    task :get_environment_variables do
      run "if [ -d ~/.config ]; then " +
        "cd ~/.config && git fetch && git reset origin/master --hard; " +
        "else git clone git@github.com:mycompany/config.git .config; fi"
      run "sudo cp ~/.config/secureshare/#{rails_env}/environment /etc/environment"
    end

    task :update_cookbooks do
      run "if [ -d /u/chef ]; then " +
        "cd /u/chef && git fetch && git reset origin/master --hard; " +
        "else git clone git@github.com:mycompany/chef.git /u/chef; fi"
    end
  end

  namespace :deploy do
    task :setup, :except => { :no_release => true } do
      dirs = [deploy_to, releases_path, shared_path]
      dirs += shared_children.map { |d| File.join(shared_path, d.split('/').last) }
      dirs += [File.join(shared_path, 'sockets')]
      run "#{try_sudo} mkdir -p #{dirs.join(' ')}"
      run "#{try_sudo} chmod g+w #{dirs.join(' ')}" if fetch(:group_writable, true)
      run "#{try_sudo} chown -R ubuntu:ubuntu #{dirs.join(' ')}" if fetch(:group_writable, true)
    end

    task :config_db_yml_symlink do
      run "ln -s #{shared_path}/database.yml #{release_path}/config/database.yml"
    end
  end
end

レシピは別のリポジトリにありますが、シェフの役割の定義を処理するために、provision という名前のフォルダーがプロジェクトにあります。

#provision/solo.rb
root = File.absolute_path(File.dirname(__FILE__))
cookbook_path '/u/chef'
role_path root + "/roles"
log_level :debug
log_location STDOUT

ノードはプロジェクトで定義されます

#provision/db_slave.json
{
  "run_list": ["role[db_slave]"]
}

そして役割

#provision/roles/db_slave.rb
name "db_slave"
description 'A postgresql slave.'
run_list(["recipe[base]", "recipe[postgresql::slave]", "recipe[rails]","recipe[papertrail]", "recipe[fail2ban]"])
override_attributes(
  'kernel' => {
  'shmmax' => ENV['KERNEL_SHMMAX'],
  'shmall' => ENV['KERNEL_SHMALL'],
  'msgmax' => ENV['KERNEL_MSGMAX'],
  'msgmnb' => ENV['KERNEL_MSGMNB']  
},
'postgresql' => {
  'user'     => ENV['PG_USER'],
  'password' => ENV['PG_PASSWORD'],
  'database' => ENV['PG_DATABASE'],
  'master_host' => ENV['PG_HOST']
},
'app_dir' => ENV['APP_DIR'],
'papertrail' => {
  'port' => ENV['PAPERTRAIL_PORT'],
  'log_files' => [
    "#{ENV['APP_DIR']}/shared/log/*.log",
    "/var/log/*.log",
    "/var/log/syslog",
    "/var/log/upstart/*.log",
    "/var/log/postgresql/*.log"
  ]
},
'new_relic' => {
  'key' => ENV['NEW_RELIC_LICENSE_KEY']
})

アプリ内に機密情報を保持する必要はありません。また、EC2 セキュリティ グループを使用してサーバーをロールにマッピングするために capistrano-ec2group も使用します。

group :myapp_web, :web
group :myapp_web, :app
group :myapp_db, :db, :primary=>true
group :myapp_db_slave, :db_slave

したがって、基本的には、シェフのレシピを 1 つのリポジトリに、環境変数を別のリポジトリに、アプリを別のリポジトリに保持し、Capistrano を使用してサーバーのプロビジョニングとアプリのデプロイの両方を行います。

シェフのレシピをアプリケーション リポジトリに保持することもできますが、それではプロジェクト間の再利用が妨げられます。重要なのは、すべての変更を環境変数に入れ、それらをアプリとレシピに分けて保存することです。

これが正しく構成されている場合、新しいサーバーを追加するには、EC2 でサーバーを起動し、目的のセキュリティ グループを適用してから、

cap deploy
于 2013-03-13T05:39:13.583 に答える
2

アプリケーションの展開に関するFoodfightshowのエピソードを見ることができます。

たとえば、Capistranoを使用してソースコードをプッシュしながら、Chefを使用して構成ファイル(データベースのクレデンシャルなどを含む)をサーバーに配置できます。

于 2013-03-12T14:23:46.180 に答える
2

できません。または、少なくともそれほど単純ではありません。

Chef はプル システムです。クライアントは Chef サーバーから情報をプルし、それに基づいてアクションを実行します。

Capistrano はプッシュ システムです。サーバーにログインしてそこでタスクを実行するように指示します。

それらを統合する唯一の方法は、Capistrano を各マシンでローカルに実行することですが、その理由はわかりません。

Chef の deploy リソースは、Capistrano を統合しなくても、おそらく必要なことすべてを実行できます。Chef-client の実行とは別にデプロイをサーバーにプッシュしたい場合は、Chef 経由でデプロイせず、現在のシステムを維持した方がよいでしょう。

継続的な配信が必要な場合は、Capistrano スクリプトを CI サーバーに接続し、パイプラインの最後で実行します。

@StephenKing が参照しているポッドキャストは、この問題に関する優れた情報源です。

于 2013-03-12T21:17:36.547 に答える