Build & Deploy Hooks
As applications are deployed on Pagoda Box, certain processes or tasks can be run in the form of Build & Deploy Hooks. These allow you to "hook" into the deploy process and execute specific scripts or commands. This can be extremely useful for tasks such as altering files for the production environment, loading dependencies, database migrations, clearing cache, or anything else your developer-brain can conjure up. After reading this doc, you should be familiar with:
- The deploy process
- The different types of build & deploy hooks
- Configuring build & deploy hooks in the Boxfile
Understanding the Deploy Process
When apps are deployed on Pagoda Box, there are really two main phases of the deploy process: the build and the deploy. During the build, code is built and prepped for deploy. In the deploy phase, as the name suggests, the prepped code is deployed to new instances.
Each takes place at different stages of the deployment process. To truly grasp how and when to use build & deploy hooks, you need to understand how the entire process works.
Build hooks allow you to customize the build of your code before it gets deployed to read-only instances. It's important to understand that these hooks are only for the modification of code. At this point of the process, you cannot access any of your app's data services (databases, caches, network storage). There are three different types of build hooks available to use:
Code is Only Built Once During a Deploy
During the deploy process, your code is only built once. A single codebase is then deployed to all code services (webs & workers). Builds are not unique to each code service.
before_exec build hooks run just after your code has been cloned into a build instance and git submodules have been loaded. These hooks can be used to prepare your code for its build process.
For example, if you have dependencies that are unique to your Pagoda environment, you can modify or replace your dependency declaration file:
mv pagoda/gemfile gemfile.
exec build hooks allow you to run custom build scripts for your app. These are typically used to load dependencies into your code base. The default build exec provided by Pagoda Box loads composer dependencies. The default build execs are covered in the Composer Dependency Management doc.
Configuring Build Hooks
Build hooks are configured in the build section of the Boxfile. Code is only built once, so if build actions are required for separate code services, the will all be included here.
Build Hook Timeout
You are able to define a
build_hook_timeout in your Boxfile. This specifies the number of seconds a build hook will run before timing out. If a build hook times out, it will exit and the build will abort.
Build Hooks in the Boxfile YAML
build: build_hook_timeout: 600 before_exec: - "mv pagoda/gemfile gemfile" exec: - "bundle install" after_exec: - "curl -o js/jquery.js http://code.jquery.com/jquery-2.1.1.min.js"
Deploy hooks run after your code has been prepped and deployed to new instances. These hooks have full access to your app's data services. Deploy hooks are unique to each service. There are two different types of deploy hooks available to use:
Deploy Hooks are Past the Point of No Return
At this point in the deploy process, code has already been deployed into new instances. If any deploy hooks fail, there is no way to back out of the deploy. Hooks will either fail altogether or eventually time out. Whatever state the hooks leave the instances in will be deployed.
before_deploy hooks run after your prepped code has been pushed to new instances, but before traffic has been routed to the new instances. In this phase of the process, traffic is still handled by the "old" instances, but the new instances have access to and can interact with your app's data services.
before_deploy hooks are handy for things like database migrations and unit tests. In multi-instance services, these hooks only run on a single instance.
before_deploy_all hooks are the same as
before_deploy hooks, except they run on all instances in the service. They become really handy when using nonpersistent writable directories, which are stored in the local filesystems of each instance. If a hook needs to interact with a nonpersistent writable directory, it needs to be in a
after_deploy hooks run after traffic has been routed to your new instances. They are handy for things like clearing your cache. In multi-instance services, these hooks only run on a single instance.
after_deploy_all hooks are the same as
after_deploy hooks, except they run on all instances in the service. If a hook needs to interact with a nonpersistent writable directory, it needs to be in a
Configuring Deploy Hooks
Deploy hooks are handled per service in your Boxfile. Each hook should be nested under the service on which it will run. When deploy hooks run, they will have access to and be subject to the settings and configuration of that service.
Deploy Hook Timeout
You are able to define a
deploy_hook_timeout in your Boxfile. This specifies the number of seconds a deploy hook will run before timing out. If a deploy hook times out, it will exit and the build will move on as if the hook completed successfully.
Deploy Hooks in the Boxfile YAML
web1: deploy_hook_timeout: 600 before_deploy: - "php artisan migrate" before_deploy_all: - "php scripts/clear_cache.php" after_deploy: - "bash checksum.sh" after_deploy_all: - "bash scripts/prime_cache.sh" web2: deploy_hook_timeout: 600 before_deploy: - "php artisan db:seed" before_deploy_all: - "php scripts/clear_cache.php" after_deploy: - "bash checksum2.sh" after_deploy_all: - "bash scripts/prime_cache.sh"
Note only certian executables are available to services and therefore deploy hooks. The Available Executables doc lists the most commonly used executables available to deploy hooks.
Things to Know About Build & Deploy Hooks
Hooks Run from the Root of Your Repo
Both build & deploy hooks are run from the root of your repo. For specific filepaths, you can use the relative path or the absolute server path (
/data) in your command.
Disable Any Interactivity
If there is any interactivity in your build or deploy hooks, you will need to disable it. There is no way to interact with a hook during the deploy process.
Modifications to Data Cannot Be Rolled Back
Any modifications deploy hooks make to data within data services (databases, network storage, caches) cannot be rolled back. It would be wise to have backups before running a deploy hooks that modifies data.
Table of Contents
- Code is Only Built Once During a Deploy
- Configuring Build Hooks
- Build Hook Timeout
- Build Hooks in the Boxfile
- Deploy Hooks are Past the Point of No Return
- Configuring Deploy Hooks
- Deploy Hook Timeout
- Deploy Hooks in the Boxfile
If you have any questions, suggestions, or corrections, let us know.