CARVIEW |
Every repository with this icon (

Every repository with this icon (

Description: | git deployment made easy edit |
Homepage: | edit |
Public Clone URL: |
git://github.com/mislav/git-deploy.git
Give this clone URL to anyone.
git clone git://github.com/mislav/git-deploy.git
|
Your Clone URL: |
Use this clone URL yourself.
git clone git@github.com:mislav/git-deploy.git
|
tree d650ea875f15dc73d892a8d6e9731d61349871f3
parent e20787bc2e5d23d7483e32def1a1081d3d11d3a4
name | age | message | |
---|---|---|---|
![]() |
README.markdown | Loading commit data... ![]() |
|
![]() |
deps.rip | Tue Sep 08 06:25:27 -0700 2009 | git deployment made easy [mislav] |
![]() |
lib/ |
Capistrano strategy for smart git deployment
Let's set up a straightforward, Heroku-style, push-based deployment, shall we? The goal is that our deployments look like this:
$ git push origin production
Assumptions are that you are using git for your Rails app and Passenger on the server. For now, we're going to deploy on a single host.
Setup steps
Create a git remote for where you'll push the code on your server. The name of this remote in the examples is "origin", but it can be whatever you wish ("online", "website", or other).
The "/path/to/myapp" is the directory where your code will reside. It doesn't have to exist; it will be created for you during this setup.$ git remote add origin user@example.com:/path/to/myapp
Create/overwrite the following files in your project:
config/deploy.rb (entire file):
# set to the name of git remote you intend to deploy to set :remote, "origin" # specify the deployment branch set :branch, "master" # sudo will only be used to create the deployment directory set :use_sudo, true # the remote host is read automatically from your git remote specification server remote_host, :app, :web, :db, :primary => true
Capfile:
Test it by runningrequire 'git_deploy' load 'config/deploy'
cap -T
. You should see several deploy tasks listed.Run the setup task:
This will initialize a git repository in the target directory, install the push hook and push the branch you specified to the server.$ cap deploy:setup
Login to your server to perform necessary one-time administrative operations. This might include:
- set up the Apache/nginx virtual host for this application;
- check out the branch which you will push production code into (often this is "production");
- check your config/database.yml and create or import the production database.
Deployment
After you've set everything up, visiting "https://example.com" in your browser should show your app up and running. Subsequent deployments are done simply by pushing to the branch that is currently checked out on our server (see step 4.). The branch is by default "master", but it's suggested to have production code in another branch like "production" or other. This, of course, depends on your git workflow.
We've reached our goal; our deployment now looks like:
$ git push origin production
In fact, running "cap deploy" does exactly this. So what does it do?
The "deploy:setup" task installed a couple of hooks in the remote git repository: "post-receive" and "post-reset". The former is a git hook which is invoked after every push to your server, while the latter is a custom hook that's called asynchronously by "post-receive" when we updated the deployment branch. This is how your working copy on the server is kept up-to-date.
Thus, on first push your server automatically:
- creates the "log" and "tmp" directories;
- copies "config/database.example.yml" or "config/database.yml.example" to "config/database.yml".
On every subsequent deploy, the "post-reset" script analyzes changes and:
- clears cached css and javascript assets if any versioned files under "public/stylesheets" and "public/javascripts" have changed, respectively;
- runs "rake db:migrate" if new migrations have been added;
- sync submodule urls if ".gitmodules" file has changed;
- initialize and update submodules;
- touches "tmp/restart.txt" if app restart is needed.
Finally, these are the conditions that dictate an app restart:
- css/javascript assets have been cleared;
- the database has migrated;
- one or more files/submodules under "app", "config", "lib", "public", or "vendor" changed.
The output of "post-reset" is logged to "log/deploy.log" in your application.
It's worth remembering that "post-reset" is done asynchronously from your push operation. This is because migrating the database and updating submodules might take a long time and we don't want to wait for all that while we're doing a git push. But, this means that when the push is done, the server has not yet restarted. You might need to wait a few seconds or a minute, depending on what you pushed.
In the future
Next steps for this library are:
- Support for deployment on multiple hosts. This is a slightly different strategy based on git pull instead of push; something in-between regular "remote cache" strategy and the aforementioned
- Better configurability
- Steps forward to supporting more existing 3rd-party Capistrano tasks, like that of the EngineYard gem
- Support for multiple environments on the same server: production, staging, etc.
- Automatic submodule conflict resolving