(Updated on 3/31/08 with new “edge” branch checkout)
In a previous post I wrote about how to get git installed on CentOS. Now that git is installed it’s time to actually set up a remote repository with git. In this tutorial I’ll explain how to:
- create a git user on the remote server and configure the new git user correctly
- configure the deploy user correctly
- create a rails app locally and push it to the remote git server
- set up capistrano for deploying the app using git
Assumptions
- you deploy under the user “deploy”
- your domain name is example.com
- you have installed git at /usr/local/bin/git
- you have root access (otherwise it might have to skip the part about setting up the git user’s shell)
Prepare the remote server
First, log into your server as deploy, create the git user and setup your ssh keys.
sudo adduser git
sudo passwd git
ssh-keygen -t rsa -f ~/.ssh/id_rsa -C "deploy@example.com"
ssh git@example.com 'mkdir ~/.ssh;chmod 700 ~/.ssh'
scp ~/.ssh/id_rsa.pub git@example.com:~/.ssh/authorized_keys
ssh git@example.com 'chmod 600 ~/.ssh/authorized_keys'
As a convenience, you may want to add your ssh key to the git user’s authorized_keys. To do so, execute the following on your local machine:
cat ~/.ssh/id_rsa.pub | ssh git@example.com 'sh -c "cat - >>~/.ssh/authorized_keys"'
(you may have to change this to id_dsa.pub – or whatever your public key name is).
Back on the server, if you haven’t already, you’ll also want to set up your git config files for the deploy user:
git config --global user.name "Deploy"
git config --global user.email "deploy@example.com"
That name and username can be anything you want it to be.
Next, you’ll have to add a shell to /etc/shells. To do so you’ll need to be root:
su -
echo '/usr/local/bin/git-shell'>> /etc/shells
exit
To make sure this worked, you can type
cat /etc/shells
Now log in as the git user and set a few things up:
su - git
git config --global user.name "Git"
git config --global user.email "git@example.com"
chsh
[when prompted - enter /usr/local/bin/git-shell]
exit
Create the app
So now you have a git user with a slightly more secure git shell and your ssh keys are set up from both your local machine and your deploy user’s account. It’s time to create the rails app on your local machine. For this to work, you’ll need to make sure that you have the capistrano and railsmachine gems installed. Next create a rails app, capify and railsmachinify it and type a few git commands.
sudo gem install capistrano railsmachine --no-ri --no-rdoc
rails git_import_test
cd git_import_test
capify .
railsmachine --apply-to . --name git_import_test --domain example.com
Now go into config/deploy.rb and add the following task to the bottom of the file (you can also add this to your ~/.caprc file to use it across all of your rails apps):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
require 'fileutils' Capistrano::Configuration.instance(:must_exist).load do namespace :git do desc "Setup directory structure and initialize git repository on remote server" task :setup, :roles => :scm do dir = "#{deploy_to}/git" run "mkdir -p #{dir}" sudo "chown -R deploy:deploy #{dir}" run "cd #{dir} && git --bare init" run "chmod 770 #{dir}" sudo "chown -R git:git #{dir}" end desc "Import code into remote git repository." task :import do puts "Initializing local git repository" system "git init" puts "Adding remote server pointing to #{repository}" system "git remote add origin #{repository}" puts "Adding .gitignore file" system "echo 'log/*'>> .gitignore" system "echo 'tmp/*'>> .gitignore" system "echo '.DS_Store'>> .gitignore" system "echo 'public/cache/**/*'>> .gitignore" system "git add .gitignore" puts "Committing application locally" system "git add *" system 'git commit -a -v -m "initial import of site"' puts "Pushing application to the remote server. The name of the branch is:" system "git remote" system "git push origin master" puts "Creating edge branch on remote" system "git push origin master:refs/heads/edge" puts "create a local tracking edge branch" system "git branch --track edge origin/edge" puts "checking out edge repository" system "git checkout edge" puts "git setup complete" puts "You can clone this repository with git clone #{repository}" end end end |
This will
- Create the local repository
- Add an ignore file
- Add all files
- Push to the master
- Create a new edge branch on the local and remote
- Switch the local branch to edge
Next, update your deploy.rb file to point to your new git repository and you’ll be ready to deploy. Make sure your deploy.rb file has entries that look like:
1 2 |
set :repository, "ssh://git@example.com#{deploy_to}/git" set :scm, :git |
Deploy
To deploy you can use the tasks that come with the railsmachine gem, along with your new git capistrano task:
cap deploy:setup
cap git:setup
cap apache:configure
cap mongrel:cluster:configure
cap git:import
If you are using mysql, you will have to also run
cap mysql:setup
Now you can deploy, run migrations, start your mongrels and restart your web server with
cap deploy:cold
References:
This post heavily references:
- https://support.railsmachine.com/index.php?pg=kb.page&id=12
- http://toolmantim.com/article/2007/12/5/setting_up_a_new_remote_git_repository
- http://blog.nanorails.com/git-rails
This step
cat /.ssh/id_rsa.pub | ssh git@example.com ‘sh -c “cat – >>/.ssh/authorized_keys”’
Didn’t work because u change the shell
@dyma – Thanks. I’ve updated the post to correct the order of operations there (just have to put that before you set the new shell).
When I run cap git:setup, the line:
Capistrano::Configuration.instance(:must_exist).load do
is causing the following error message:
/Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/configuration/loading.rb:18:in `instance’: Please require this file from within a Capistrano recipe (LoadError) from ./config/deploy.rb:134:in `load’ from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/configuration/loading.rb:173:in `load_from_file’ from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/configuration/loading.rb:89:in `load’ from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/configuration/loading.rb:86:in `load’ from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/configuration/loading.rb:86:in `each’ from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/configuration/loading.rb:86:in `load’ from ./Capfile:3:in `load’ from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/configuration/loading.rb:173:in `load_from_file’ ... 8 levels… from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/lib/capistrano/cli/execute.rb:14:in `execute’ from /Library/Ruby/Gems/1.8/gems/capistrano-2.2.0/bin/cap:4 from /usr/bin/cap:19:in `load’ from /usr/bin/cap:19
How can I fix this error? TIA.
To fix the error I commented out the following line
and the matching end statement
It looks to me like the line is unneeded as well as creating an error.