npm private repository を Chef で作る (Chef Solo 入門を読みました)。
入門Chef Solo - Infrastructure as Code
- 作者: 伊藤直也
- 出版社/メーカー: 伊藤直也
- 発売日: 2013/03/11
- メディア: Kindle版
- 購入: 16人 クリック: 1,027回
- この商品を含むブログ (12件) を見る
今までKnifeとかChefとかVagrantとか色々聞いてたんですけど、便利そうだなーと思いながらも全然手を付けられていませんでした。
丁度先日開催されたLL祭りの時にも話題になってましたね。
Chef Solo入門を読んでみて思いましたが、非常によくまとまっていて、かつそれぞれの位置づけがはっきりと分かる良書でした。
せっかくなので、これを読んでnpm private repositoryを作ってみようと思ったので、作ってみました。
あと、作るまでにやったインストール等の事をまとめていきます。
ちなみに、 npmのprivate repositoryを作るChefのコードはつい10日前くらいにOpsCodeに上がったので、ただprivate repositoryを作りたい人はそれを見たほうが早いかも。ちなみにnpm private repositoryは大体80〜90GB程度の容量が必要になるのでそれ以下の容量の場合は増設を検討してください。
npm registry: Chef Cookbook: npm_registry - Opscode Community
何はともあれ、環境構築
1. Chef
サーバーの状態を記述するツール、状態、というのは例えば nginx が入ってたり、 zsh が入ってたり、といったソフトウェアのインストールされているかどうかやそれらのnginx.conf等の設定ファイルのカスタマイズがそろっている状態のことを指す。
■インストール方法
$ curl -L http://www.opscode.com/chef/install.sh | sudo bash
gemからインストールする方法もあるみたい。
$ gem install chef
2. Vagrant
仮想サーバをCLIで作成、起動、破棄するためのツール。
非常に簡単にイメージを構築できるため、Chefのテスト・確認に使うことが可能。
インストール方法
vagrant はhttp://downloads.vagrantup.com/からインストール可能。
もちろん、これもgemからインストールできます。
$ gem install vagrant
また本書内ではvagrantのイメージを構築するVagrantプラグインとしてsaharaの紹介がされていたが、最近はsaharaよりも vagrant-vbox-snapshot の方がスナップショットに名前を付けられるので良いとのことが書いてあった。
vagrant-vbox-snapshot
//install $ vagrant plugin install vagrant-vbox-snapshot # install $ vagrant snapshot take init # initという名前でスナップショットを作成 $ vagrant snapshot back # 最新のスナップショットにロールバック $ vagrant snapshot go init # initを指定してロールバック
3. Knife
Chefのテンプレート作成したり、ローカルで準備したレシピをリモートで実行する際に利用するツール。基本的に直接Chefを実行するというよりもknife経由で実行することが多い。
install
$ gem install knife-solo
4. Berkshelf (入れなくても使えるけど入れておくと便利)
Gemfile風に記述して、bundle execする事で第三者が作ったレシピをローカルに持ってくることができるツール。Berksfileと呼ばれる設定ファイルを書くことでRubyistなら慣れている手順でレシピを持ってくることができる。
install
$ gem install berkshelf
npm private repositoryを Chef で作る
環境を構築したところで手順的に何をどういうステップでやったのか記述していきます。
0. vagrantで仮想マシンを作成する
まずは雛形を作成しましょう。
$ knife solo init npm-repo
次にテスト用の環境を構築しましょう。
Vagrantの設定ファイルであるVagrantfileをプロジェクトの直下に配置しておきます。
vagrant initコマンドを利用するとVagrantfileの雛形を作成してくれます。
$ cd npm-repo $ vagrant init
Vagrantfile
VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "centos63" config.vm.network :forwarded_port, guest: 80, host: 8080 end
$ vagrant box add centos63 https://s3.amazonaws.com/itmat-public/centos-6.3-chef-10.14.2.box $ vagrant up
これだけで vagrantを使ってCentOS 6.3の環境が簡単に手に入ります。ログインを試す場合は以下の方法で試しましょう。
$ vagrant ssh
あとでも使うのでvagrant sshの設定をssh configに書いておきます。
ここでは、npmというホスト名でログインできるようにしておきます。
$ vagrant ssh-config --host npm >> ~/.ssh/config $ ssh npm
1. knifeでテンプレートを作る。
まずはknifeの設定をします。
$ knife configure
いくつか質問されるので適当に回答しましょう。
その後、chefのリモート実行準備用のスクリプトを流しておきましょう。
$ knife solo prepare npm
準備が終わったらいよいよrecipeの作成に入ります。
2. Berkshelfを実行し、npm repositoryに必要なrecipeを持ってくる
Bekrshelfを使う前にOpsCode Communityからクックブックをインポートするための設定をしましょう。
OpsCode CommunityのサイトからSign upを行い、private keyをDLしてください。
DLしたprivate keyは ~/.chef/username.pem のような形式で保存し、最後に ~/.chef/knife.rb のclient_keyの所にそのパスを保存してください。
Berkshelfを使う前にGemfileを作ります。以下の様な要領でGemfileをプロジェクトのルートに作成してください。
Gemfile
# Gemfile source :rubygems gem 'berkshelf'
作ったら下記のコマンドを実行します。
$ bundle --path vendor/bundle
これでBerkshelfを使う準備は完了です。
終了したら今度はBerksfileを作成します。
npm repositoryにはcouchdbとnodejsが必要なのでインストールしておきます。
後は一応gitがあると色々と便利なので入れておきます。
Berksfile
site :opscode cookbook 'couchdb' cookbook 'nodejs' cookbook 'git'
作ったら下記のコマンドを実行します。
$ bundle exec berks --path cookbooks
couchdbの設定ファイルを少しだけ編集します。
もっとクールなやり方があるのかもしれませんが、今のところ直接cookbooksを修正する方法しか思いつきませんでした。。
cookbooks/couchdb/attributes/default.rb
# # Author:: Joshua Timberman <joshua@opscode.com> # Cookbook Name:: couchdb # Attributes:: couchdb # # Copyright 2010, Opscode, Inc # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. default['couch_db']['src_checksum'] = "b54e643f3ca5f046cfd2f329a001efeaae8a3094365fa6c1cb5dcf68c1b25ccd" default['couch_db']['src_version'] = "1.2.1" default['couch_db']['src_mirror'] = "http://archive.apache.org/dist/couchdb/#{node['couch_db']['src_version']}/apache-couchdb-#{node['couch_db']['src_version']}.tar.gz" default['couch_db']['install_erlang'] = true # Attributes below are used to configure your couchdb instance. # These defaults were extracted from this url: # http://wiki.apache.org/couchdb/Configurationfile_couch.ini # # Configuration file is now removed in favor of dynamic # generation. default['couch_db']['config']['couchdb']['max_document_size'] = 4294967296 # In bytes (4 GB) default['couch_db']['config']['couchdb']['max_attachment_chunk_size'] = 4294967296 # In bytes (4 GB) default['couch_db']['config']['couchdb']['os_process_timeout'] = 5000 # In ms (5 seconds) default['couch_db']['config']['couchdb']['max_dbs_open'] = 100 default['couch_db']['config']['couchdb']['delayed_commits'] = true default['couch_db']['config']['couchdb']['batch_save_size'] = 1000 default['couch_db']['config']['couchdb']['batch_save_interval'] = 1000 # In ms (1 second) default['couch_db']['config']['httpd']['port'] = 5984 default['couch_db']['config']['httpd']['bind_address'] = "127.0.0.1" default['couch_db']['config']['httpd']['secure_rewrites'] = false #ここにsecure_rewritesを追記。 default['couch_db']['config']['log']['level'] = "info" default['couch_db']['config']['vhosts']['npm.yourcompany.co.jp'] = "/registry/_design/scratch/_rewrite"
3. npm リポジトリ作成用のレシピを作る
site-cookbooksフォルダ以下にレシピを作成します。
$ knife cookbook create npm-repo -o site-cookbooks
次にsite-cookbooks/npm-repo/recipesの下にあるdefault.rbを以下のように変更します。
site-cookbooks/npm-repo/recipes/default.rb
# # Cookbook Name:: npm-repo # Recipe:: default # # Copyright 2013, YOUR_COMPANY_NAME # # All rights reserved - Do Not Redistribute # git "#{Chef::Config['file_cache_path']}/npmjs.org" do repository "git://github.com/isaacs/npmjs.org.git" reference "master" action :sync end execute "npm install couchapp -g" do command "npm install couchapp -g" cwd "#{Chef::Config['file_cache_path']}/npmjs.org" action :run end execute "npm install semver" do command "npm install semver" cwd "#{Chef::Config['file_cache_path']}/npmjs.org" action :run end execute "npm install couchapp" do command "npm install couchapp" cwd "#{Chef::Config['file_cache_path']}/npmjs.org" action :run end bash "curl put" do cwd "#{Chef::Config['file_cache_path']}/npmjs.org" code <<-EOH curl -X PUT http://localhost:5984/registry EOH end execute 'push.sh' do command './push.sh' cwd "#{Chef::Config['file_cache_path']}/npmjs.org" environment({'npm_package_config_couch' => 'http://localhost:5984/registry'}) action :run end execute 'load-views.sh' do command './load-views.sh' cwd "#{Chef::Config[:file_cache_path]}/npmjs.org" environment({'npm_package_config_couch' => 'http://localhost:5984/registry'}) action :run end bash 'COPY _design/app' do code <<-EOH curl http://localhost:5984/registry/_design/scratch -X COPY -H destination:'_design/app' EOH end execute "setup_couchapp push repository" do cwd "#{Chef::Config['file_cache_path']}/npmjs.org" command "couchapp push registry/app.js http://localhost:5984/registry" action :run end execute "setup_couchapp push app.js" do cwd "#{Chef::Config['file_cache_path']}/npmjs.org" command "couchapp push www/app.js http://localhost:5984/registry" action :run end bash "curl post" do cwd "#{Chef::Config['file_cache_path']}/npmjs.org" code <<-EOH nohup curl -X POST http://localhost:5984/_replicate -d '{"source":"http://isaacs.iriscouch.com/registry/", "target":"registry" }' -H "Content-Type: application/json" & EOH end
次にnodes/npm.jsonを以下のように変更します。
nodes/npm.json
{ "run_list": [ "couchdb", "nodejs", "git", "npm-repo" ] }
4. レシピ実行
以下のコマンドでレシピを実行します。
$ knife solo cook npm
完成、、ですが、npmのリポジトリがクローンされるまでには非常に長い時間がかかるので手放しで終わりにできません。大体1日位放置してその後、サーバーにログインしてnpmコマンドを打ち、思い通りの結果が返ってくれば成功です。
$ ssh npm $ npm --registry http://localhost:5984/registry/_design/scratch/_rewrite search
まとめ
Chef楽しいです。npm repositoryのような大物を作るのにはやっぱり時間がかかりますが、環境のセットアップする程度であれば全然時間も手間もかからずに作成できますし、3rd partyの作ったレシピが使えるのはやっぱり嬉しい。
Yeomanと併用する話やそれぞれのツールの位置づけを色々まとめたいなと思ったのですが、また後で書きます。