Deploy hooks are Ruby scripts that you write which are executed at designated points in the deployment process. This allows you to customize the deployment of your application to meet its particular needs.
For example, if your application uses Resque, then deploy hooks provide a way for you to restart your Resque workers when you deploy a new version of your application. Rollbar users can use deploy hooks to notify Rollbar of a deploy.
Deploy hooks live in the APP_ROOT/deploy
directory of your application. The order in which they run is specified in the documentation for the ey deploy
command.
Important: When you add a new instance, Engine Yard automatically runs the deploy hooks. input_ref
will not be available and the deploy hooks will fail if you use it. This is a known issue and we are working on a fix. In the meantime, confirm that input_ref
is not nil and repo
is nil.
Best Practices
Engine Yard recommends that you use deploy hooks to run rake tasks or scripts that perform the necessary tasks, rather than including all the logic in the hook itself. You should use deploy hooks mostly to trigger shell commands whenever possible. Using deploy hooks in this way allows you to write tests for your rake tasks and scripts, then the hook simply triggers these tasks and scripts.
You should avoid using deploy hooks as part of your application code because they are instance_eval'd
into a running copy of the deploy system. This means if you you try to use hooks as part of your code, you will be battling with all the context in the deploy code.
Structure and sequence
To use deploy hooks, create an APP_ROOT/deploy
directory in your application and save named hook files in this directory which will be triggered at the appropriate times during the deployment process. The files are defined as follows and run in the order listed:
APP_ROOT/
deploy/
before_bundle.rb
after_bundle.rb
before_compile_assets.rb
after_compile_assets.rb
before_migrate.rb
after_migrate.rb
before_symlink.rb
after_symlink.rb
before_restart.rb
after_restart.rb
Remember that, in order for migrations to run, your entire environment is loaded. So if you have any symlinks that need to be created in order for the application to start properly, put them in before_migrate.rb
instead of before_symlink.rb
, because before_symlink.rb
runs after the migration.
Any deploy hooks that you have defined are called, even if they are hooking into a step that is not necessary for the deployment. For example, after_migrate
is called even if there are no new migrations in your deployment.
Shell commands
Besides the usual ruby syntax, you also have access to run
, run!
, sudo
, and sudo!
to run commands. See Deploy Hooks API.
Command | Runs as | Exit zero | Non-zero exit |
---|---|---|---|
run | deploy user | returns true | returns false |
run! | deploy user | returns true | aborts deploy |
sudo | root | returns true | returns false |
sudo! | root | returns true | aborts deploy |
For example:
run "echo ‘config.release_path: #{config.release_path}’ >> #{config.shared_path}/logs.log"
run "ln -nfs #{config.shared_path}/config/foo.yml #{config.release_path}/config/foo.yml"
sudo "echo ‘sudo works’ >> /root/sudo.log"
Calling git commands
Here’s an example where you can call a git command from a deploy hook:
run "exec ssh-agent bash -c 'ssh-add /home/deploy/.ssh/<app>-deploy-key && git clone git@github.com:foo/bar.git #{current_path}/tmp/foo'"
Replace <app>
with the name of your app and change the path for your git repository.
Logging
Deploy hooks can output to STDERR, which will be written to the deploy log and you can use the warning command do this.
For example, this line on a deploy hook:
warning "Hello there, STDERR!"
will produce this output in the log:
+ 00s !> WARNING: Hello there, STDERR!
Another option which you might prefer is to run an echo command that outputs to STDERR:
run "echo 'Hello from run, STDERR!' 1>&2"
The above code in a deploy hook will output:
+ 00s Hello from run, STDERR!
which is a litter more appropriate because it does not include the WARNING string.
Deploy hooks API
Engine Yard has deprecated the use of the @configuration
variable directly. Instead,use the config
object for compatibility with future releases.
The following methods are Ruby specific and should be accessed through the config
object: For non-Ruby specific deploy hook variables, see Use non-Ruby Deploy Hooks
-
config.account_name
The name of the account that owns the environment where the application is deploying: e.g.
myaccount
-
config.all_releases
Array of paths to the deployments on this instance, ordered from oldest to newest.
-
config.app
This is the name of the application: e.g.
myapp
-
config.current_name
On a utility instance, the name of the utility instance. On non-utility instances, nil.
-
config.current_path
Path to the current deployment. This is the deployment pointed to by the
current
symlink, so the value ofcurrent_path()
will change after thesymlink
step is executed. -
config.current_role
The role of the current instance. Possible values:
-
solo
: the sole instance for the environment -
app_master
: the application master -
app
: a non-master application server -
util
: a utility server. Thecurrent_name
method will allow you to distinguish between different types of utility servers.
-
-
config.deployed_by
The name of the user who triggered the deployment: e.g.
John Smith
. Not available on rollback. -
config.framework_env
The value of the
RAILS_ENV
,RACK_ENV
, andMERB_ENV
environment variable. -
config.environment_name
This is the name of the environment that the application is deploying on: e.g.
myenvironment
ormyapp_staging
. -
config.input_ref
The name of the branch that was given as input to the deploy: e.g.
master
orbranch
. Not available on rollback.Note: Roll back is ideal for simple deployments with no database migrations or complex deploy hooks. When a data transformation has been deployed, rolling forward by deploying a corrected release may be best.
-
config.latest_release
Path to the most recent deployment.
-
config.migrate?
True if migrations are being run in this deployment, false otherwise.
-
config.node
Various information about the current instance and other instances in the environment. See
/etc/chef/dna.json
on an instance for an example of whatnode
will return. If the information you require is available via some other method, it is preferable to use the other method to get it.node
is just here as a catch-all.
Note: There were some changes in the dna.json structure on V5. Most of the keys have been moved under the 'dna' key. For example, on V4 you refer to the environment asconfig.node[:environment][:name]. F
or V5 you should change that toconfig.node[:dna][:environment][:name]
. In this case, it is better to useconfig.environment_name
instead, because that works for both V4 and V5. -
config.previous_release(current=latest_release)
Path to the deployment prior to
current
. If nil, thencurrent
is the newest deployment. -
config.oldest_release
Path to the oldest deployment
-
config.release_dir
Path to the directory containing the deployments
-
config.release_path
Path to the deployment that is currently being deployed: e.g.
/data/appname/releases/12345678
-
config.repo
The URL of this application’s git repository.
-
config.repository_cache
The path to the local clone of this application’s git repository.
-
config.active_revision
The SHA of the commit currently being deployed.
-
config.shared_path
Path to the shared dir: e.g.
/data/appname/shared
-
config.stack
The web server stack for this environment. Possible values:
-
nginx_mongrel
: Nginx web server and Mongrel application server -
nginx_passenger
: Nginx web server and Passenger application server -
nginx_unicorn
: Nginx web server and Unicorn application server
-
Helper Methods
The following are helper methods in the deploy hook:
-
debug()
Logs messages to STDOUT and allows you to add log-in capabilities to your deploy hooks. Only shows when verbose is true.
-
info()
Logs messages to STDOUT and allows you to add log-in capabilities to your deploy hooks.
-
on_app_master(&block)
Executes
block
only on the environment’s application master or single instance. -
on_app_servers(&block)
Executes
block
only on the environment’s application servers (master and slaves) or single instance. -
on_app_servers_and_utilities(&block)
Executes
block
only on the environment’s application servers and utility servers -
on_utilities(*utility_names, &block)
Executes
block
on utility servers whose names are included inutility_names
.utility_names
can be passed as an array or as multiple arguments.- If called like
on_utilities() { ... }
, the block will be executed on all utility servers. -
on_utilities("alpha") { ... }
executes the block on all utility servers named “alpha”. -
on_utilities("a", "b") { ... }
is equivalent toon_utilities(%w[a b]) { ... }
.
- If called like
NOTE: Use strings, not symbols, to specify the utility instance names, otherwise your on_utilities block will not be executed. For example: on_utilities(:alpha) will not be executed on a utility instance named "alpha".
-
run(command)
Executes
command
as a nonprivileged user (deploy
by default). -
run!(command)
Executes
command
as a nonprivileged user. Aborts the deployment if it fails.
Note: This command can only be used with the CLI and the engineyard gem 2.0. Deployment fails if you try to use run! when deploying your application from the dashboard. -
sudo(command)
Executes
command
as root. -
sudo!(command)
Executescommand
as root. Aborts the deployment if it fails.
Note: This command can only be used with the CLI and the engineyard gem 2.0. Deployment fails if you try to use sudo! when deploying your application from the dashboard. -
warning()
Logs messages to STDERR and allows you to add log-in capabilities to your deploy hooks.
More Information
These other resources might help you:
For more information about ... | See ... |
---|---|
Customizing your deployment | Customize your Deployment |
If you have feedback or questions about this page, add a comment below. If you need help, submit a ticket with Engine Yard Support.
Comments
Article is closed for comments.