
{"id":7146,"date":"2021-01-08T17:33:51","date_gmt":"2021-01-08T17:33:51","guid":{"rendered":"https:\/\/rax-stg-wp-aws.com\/blogs\/how-to-use-the-appdeploy-filesystem-hook\/"},"modified":"2026-11-03T19:27:55","modified_gmt":"2026-11-03T19:27:55","slug":"how-to-use-the-appdeploy-filesystem-hook","status":"publish","type":"blogs","link":"https:\/\/www.rackspace.com\/de\/blogs\/how-to-use-the-appdeploy-filesystem-hook\/","title":{"rendered":"How to use the Appdeploy Filesystem hook"},"content":{"rendered":"<p><em>Originally published in Apr 2017, at the Onica <a href=\"https:\/\/onica.com\/blog\/\">blog<\/a>.<\/em><\/p>\n<p>It seems as if the Appdeploy Filesystem hooks go largely unnoticed with&nbsp;<a href=\"https:\/\/onica.com\/blog\/how-to-call-and-export-variables-in-elastic-beanstalk\">Amazon Elastic Beanstalk<\/a>, so we set to find out more about this system and how to use it more effectively.<\/p>\n<p><strong>Working with Filesystem hooks in Amazon Elastic Beanstalk<\/strong><br \/>\n<em>Here is an example of a tree output from a base PHP AMI. Many of these directories and file names are well-named, so we can make educated guesses about what they do:<\/em><\/p>\n<p><em>&nbsp; $ tree \/opt\/elasticbeanstalk\/hooks\/<br \/>\n&nbsp; &nbsp; \/opt\/elasticbeanstalk\/hooks\/<br \/>\n&nbsp; &nbsp; \u251c\u2500\u2500 appdeploy<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 enact<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 01_flip.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u2502 &nbsp; \u2514\u2500\u2500 99_reload_app_server.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 post<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u2502 &nbsp; \u2514\u2500\u2500 01_monitor_httpd_pid.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u2514\u2500\u2500 pre<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; &nbsp; &nbsp; \u251c\u2500\u2500 01_unzip.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; &nbsp; &nbsp; \u251c\u2500\u2500 02_setup_envvars.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; &nbsp; &nbsp; \u251c\u2500\u2500 05_configure_php.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; &nbsp; &nbsp; \u251c\u2500\u2500 10_composer_install.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; &nbsp; &nbsp; \u2514\u2500\u2500 12_update_permissions.sh<br \/>\n&nbsp; &nbsp; \u251c\u2500\u2500 configdeploy<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 enact<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u2502 &nbsp; \u2514\u2500\u2500 99_reload_app_server.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 post<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u2514\u2500\u2500 pre<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; &nbsp; &nbsp; \u251c\u2500\u2500 10_setup_envvars.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; &nbsp; &nbsp; \u2514\u2500\u2500 20_configure_php.sh<br \/>\n&nbsp; &nbsp; \u251c\u2500\u2500 postinit<br \/>\n&nbsp; &nbsp; \u251c\u2500\u2500 preinit<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 01_setup_envvars.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 02_web_user.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 03_packages.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 04_configure_php.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 05_composer.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 10_layout.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 11_logging.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 22_pear.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u251c\u2500\u2500 23_apache.sh<br \/>\n&nbsp; &nbsp; \u2502 &nbsp; \u2514\u2500\u2500 30_permissions.sh<br \/>\n&nbsp; &nbsp; \u2514\u2500\u2500 restartappserver<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;\u251c\u2500\u2500 enact<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;\u2502 &nbsp; \u2514\u2500\u2500 01_restart.sh<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;\u251c\u2500\u2500 post<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;\u2514\u2500\u2500 pre<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u2514\u2500\u2500 10_configure_php.sh<\/em><\/p>\n<p><em>appdeploy\/post<\/em><\/p>\n<p>\nThis blog post focuses on the <strong>appdeploy<\/strong>&nbsp;directory. We use the Appdeploy Filesystem hook, especially the <strong>post&nbsp;<\/strong>directory, when we want to fire off a script that takes place after the application deploys.<\/p>\n<p>For example, we want to install a custom varnish daemon into our Beanstalk server with a custom <strong>ebextensions\/xxx.config<\/strong> file:&nbsp;<\/p>\n<p>&nbsp;<em> &nbsp; $commands:&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp;create_post_dir:&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; command: &#8220;mkdir -p \/opt\/elasticbeanstalk\/hooks\/<br \/>\n&nbsp; &nbsp; appdeploy\/post&#8221;&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; ignoreErrors: true&nbsp;<br \/>\n&nbsp; &nbsp; files:&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &#8220;\/opt\/elasticbeanstalk\/hooks\/appdeploy\/post\/<br \/>\n&nbsp; &nbsp; varnish_script.sh&#8221;:&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; mode: &#8220;000770&#8221;&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; owner: root&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; group: root&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; content: | #!\/bin\/bash echo&nbsp;<br \/>\n&nbsp; &nbsp; &#8220;&#8212;&#8212;&#8211;Starting Varnish Script&#8212;&#8212;&#8212;&#8212;&#8221;&nbsp;<\/em><\/p>\n<p>\nChange this to &#8220;restart&#8221; to flush cache<strong>&nbsp;<\/strong>on every deploy&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp;<em> start_cmd=&#8221;reload&#8221;&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; if ! which varnishd &gt;\/dev\/null&nbsp;<br \/>\n&nbsp; &nbsp; 2 1 ; then&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; echo &#8220;Installing Varnish&#8221;&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; rpm &#8211;nosignature -i &nbsp;<br \/>\n&nbsp; &nbsp; https:\/\/repo.varnish-cache.org\/redhat\/<br \/>\n&nbsp; &nbsp; varnish-4.1.el6.rpm&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; yum install -y varnish &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8211;disablerepo=amzn-updates &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8211;disablerepo=amzn-main &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8211;enablerepo=epel&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;start_cmd=&#8221;start&#8221;&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;fi&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;echo &#8220;Starting Varnish&#8221;&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;service varnish ${start_cmd}&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;service varnishncsa ${start_cmd}&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;rm &#8212; &#8220;$0&#8221;<\/em><\/p>\n<p>Notice how we use commands to make sure the directory is there? We have found that the directory might not exist on some older EB AMIs, so we create it while ignoring errors&#8212;;the <em>-p<\/em> should ignore the error, but we add the extra <em>ignoreErrors<\/em>&nbsp;just to be complete.<\/p>\n<p>When you unzip the application, the <strong>\/opt\/elasticbeanstalk\/hooks\/appdeploy\/post\/varnish_script.sh<\/strong>&nbsp;file drops into place but doesn&#8217;t execute when a command would be. The script is set to be executable, and Elastic Beanstalk handles the<br \/>\nrest. The HTTPS server restarts, executes the script, and runs <em>post\/01_monitor_httpd_pid.sh<\/em>.<\/p>\n<p>Also, notice the <em>rm &#8212; &#8220;$0&#8221;<\/em> at the end of this script. That tells the script to delete itself. If you don&#8217;t remove the script, it is left over in subsequent installations&amp;mdash;especially if you remove it from your <strong>.ebextensions\/xxx.config&nbsp;<\/strong>file. If you do not remove the script on every run, or at least manage your system appropriately, you have inconsistent&nbsp;systems and unintended consequences.<\/p>\n<p>\n<em>appdeploy\/pre<\/em><\/p>\n<p>Notice that the <em>01_unzip.sh<\/em>&nbsp;is as early as you can get into the hooks. For example, this runs after unzipping files:<\/p>\n<p>&nbsp;&#8220;\/opt\/elasticbeanstalk\/hooks\/appdeploy\/pre\/02-aa.sh&#8221;:<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; mode: &#8220;000770&#8221;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; owner: root<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; group: root<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; content: |<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #!\/bin\/bash<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo &#8220;ran 02-aa&#8221; &gt; \/tmp\/02-aa.txt<\/p>\n<p>You end up with a <strong>\/tmp\/02-aa.txt<\/strong> file because of the last line where we echoed <em>ran 02-aa<\/em>&nbsp;into the temp file. Notice how our script ran immediately after the <em>01_unzip.sh<\/em> script:<\/p>\n<p>&nbsp; &nbsp;$ tree \/opt\/elasticbeanstalk\/hooks\/ | head -10&nbsp;<br \/>\n&nbsp; &nbsp; \/opt\/elasticbeanstalk\/hooks\/<br \/>\n&nbsp; &nbsp; &nbsp;\u251c\u2500\u2500 appdeploy \u2502<br \/>\n&nbsp; &nbsp; &nbsp;\u251c\u2500\u2500 enact<br \/>\n&nbsp; &nbsp; &nbsp;\u2502 \u2502 \u251c\u2500\u2500 01_flip.sh<br \/>\n&nbsp; &nbsp; &nbsp;\u2502 \u2502 \u2514\u2500\u2500 99_reload_app_server.sh<br \/>\n&nbsp; &nbsp; &nbsp;\u2502 \u251c\u2500\u2500 post<br \/>\n&nbsp; &nbsp; &nbsp;\u2502 \u2502 \u2514\u2500\u2500 01_monitor_httpd_pid.sh<br \/>\n&nbsp; &nbsp; &nbsp;\u2502 \u2514\u2500\u2500 pre<br \/>\n&nbsp; &nbsp; &nbsp;\u2502 \u251c\u2500\u2500 01_unzip.sh<br \/>\n&nbsp; &nbsp; &nbsp;\u2502 \u251c\u2500\u2500 02-aa.sh<br \/>\n&nbsp; &nbsp; &nbsp;$ cat \/tmp\/02-aa.txt&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp;ran 02-aa&nbsp;<\/p>\n<p><em>appdeploy\/enact<\/em><\/p>\n<p>If you want to do something with the system after swapping around the <strong>\/var\/app\/current<\/strong>&nbsp;directory but before restarting the web server, drop in a file between <em>01<\/em> and <em>99<\/em>&nbsp;(non-inclusive). For example, you might need to have a shell script that works with <em>\/var\/app\/current<\/em>&nbsp;before Apache reloads.<\/p>\n<p><strong>All done using the Appdeploy Filesystem hook<\/strong><\/p>\n<p>Feel free to dive in and create your scripts to figure out exactly when they run. It is easiest to watch&nbsp;<strong>\/var\/log\/eb-activity.log<\/strong>&nbsp;to see when things are complete. This log contains some very good logging about what scripts trigger in which order.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to use the Appdeploy Filesystem hook<\/p>\n","protected":false},"author":2,"featured_media":7148,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","format":"standard","meta":{"content-type":"","nid":"26282","content_type":"blog","created_by":"10130","authored_on":"2023-11-22T17:33:51+00:00","field_article_industries":"","tag_category":"Technical","field_blog_author_text":"by Rackspace Technology Staff","seo_description":"Explore the significance of the appdeploy directory. Dive into the Appdeploy Filesystem hook. Optimize deployment processes and scripting.","field_featured_image":"","insights_image":"\/wp-content\/uploads\/2026\/blog_technical_images\/26282-insights_image-aws-technical-blog-1-insights.png","field_partners":"","rxt_platforms":"Amazon Web Services (AWS)","product":"","publisheddate":"2021-01-08T17:33:51","rxt_solutions":"Onica by Rackspace Technology","opengraph_tag":"","x_tag":"","teaser_flag":"Technical Blog","seo_titile":"How to Use the Appdeploy Filesystem Hook | Rackspace Technology","field_topics":"","field_slug":"how-to-use-the-appdeploy-filesystem-hook","footnotes":""},"categories":[178],"tags":[204],"class_list":["post-7146","blogs","type-blogs","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-technical"],"_links":{"self":[{"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/blogs\/7146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/blogs"}],"about":[{"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/types\/blogs"}],"author":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/comments?post=7146"}],"version-history":[{"count":1,"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/blogs\/7146\/revisions"}],"predecessor-version":[{"id":7147,"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/blogs\/7146\/revisions\/7147"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/media\/7148"}],"wp:attachment":[{"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/media?parent=7146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/categories?post=7146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rackspace.com\/de\/wp-json\/wp\/v2\/tags?post=7146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}