{"id":789,"date":"2019-03-20T13:08:44","date_gmt":"2019-03-20T05:08:44","guid":{"rendered":"https:\/\/woohuiren.me\/blog\/?p=789"},"modified":"2019-03-20T13:08:53","modified_gmt":"2019-03-20T05:08:53","slug":"blue-green-laravel-deployment-to-pivotal-cloudfoundry","status":"publish","type":"post","link":"https:\/\/woohuiren.me\/blog\/blue-green-laravel-deployment-to-pivotal-cloudfoundry\/","title":{"rendered":"Blue-green Laravel deployment to Pivotal Cloudfoundry"},"content":{"rendered":"\n<p>This post shows how I do blue-green deployment of my Laravel project, that has a queue runner, through GitLab CI onto Pivotal Cloudfoundry. You&#8217;ll need to know some basics of GitLab CI, Laravel and Pivotal Cloudfoundry to better understand this post.<\/p>\n\n\n\n<p>More information about <a href=\"https:\/\/woohuiren.me\/blog\/laravel-worker-on-pivotal-cloudfoundry\/\">Laravel queue runner<\/a> is available in my other blog post!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Docker Image For Build<\/h2>\n\n\n\n<p>My Docker image, <a href=\"https:\/\/github.com\/GIANTCRAB\/laravel-pcf\">woohuiren\/laravel-pcf<\/a>, provides several installed tools. First off, woohuiren\/laravel-pcf image is based off my <a href=\"https:\/\/github.com\/GIANTCRAB\/php-laravel-env\">woohuiren\/php-laravel-env<\/a> image which contains whatever PHP libraries Laravel requires to operate. The PCF image comes with blue-green deploy, anti-freeze and PCF scheduler.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Blue-Green Deploy<\/h3>\n\n\n\n<p>A term used to describe a method of deployment in which ensures that there&#8217;s zero downtime whilst deploying a new application. Once the new application has been successfully deployed, the routes are reconfigured from the old application to the new one. Thereafter, the old application can be removed since there will no longer be routes pointing towards it. <\/p>\n\n\n\n<p>It is also a name of a tool by the Cloudfoundry community to do exactly the above said.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Anti Freeze<\/h3>\n\n\n\n<p>Anti freeze is an amazing tool to help prevent environment variable problems associated with blue-green deployments. <\/p>\n\n\n\n<p>Some of us might have created environment variables for the application via the PCF interface. This will result in the environment variable being removed upon recreating the application. Blue green deployments often create a new application, does some re-routing and destroy the old application.<\/p>\n\n\n\n<p>Anti-freeze helps to prevent this problem by checking and ensuring that all variables and services are bound via manifest. If they are not, the deployment will be stopped.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">PCF Scheduler<\/h3>\n\n\n\n<p>In some Laravel applications, we run scheduled tasks in our <em><strong>app\/Console\/Kernel.php schedule()<\/strong><\/em> method. And hence, we would need to run the scheduler every minute. Typically, we create a cronjob with the following ruleset.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>* * * * * php artisan schedule:run<\/code><\/pre>\n\n\n\n<p>However, for Pivotal Cloudfoundry, there&#8217;s a way which we create our jobs and schedule them. You can do so via the GUI but here&#8217;s the thing: it doesn&#8217;t persist either. There&#8217;s no way you can configure the manifest to persist it.<\/p>\n\n\n\n<p>The only way to &#8220;persist&#8221; it would be to recreate the job and reschedule it every time we do a blue-green deployment. So we would need to have something like this run after deployment.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cf blue-green-deploy $CF_MAIN_APP -f 'main-manifest.yml' --delete-old-apps\ncf create-job $CF_MAIN_APP laravel-scheduler \"php artisan schedule:run\"\ncf schedule-job laravel-scheduler \"* * ? * *\"<\/code><\/pre>\n\n\n\n<p>You would also notice that the ruleset used isn&#8217;t * * * * * but * * ? * *. This is an issue with Pivotal Cloudfoundry which it seems to not allow you to schedule jobs without including a question mark.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GitLab CI Config<\/h2>\n\n\n\n<p>Typically, folks would want the artefact from a build stage to be saved and once testing passes, they can deploy the entire artefact from build stage to production. Each stage would require initialization of GitLab runner, pulling of Docker image and pulling of your code committed onto GitLab. Having more stages might be better for clarity, processes, artefact management. However, it would also mean that your CI process will take a longer time.<\/p>\n\n\n\n<p>Through some experiments, I found that the fastest way to build and test my project was to use a &#8220;single stage&#8221;. This is not really recommended as we will not preserve the artefacts from the previous stage. But I still did it because my deployment doesn&#8217;t make use of the artefacts. <em>(*flaw &#8211; see room for improvement)<\/em><\/p>\n\n\n\n<p>The following is a GitLab CI configuration file that I&#8217;ve came up with that will help you do your blue-green deployment.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>image: woohuiren\/laravel-pcf\n\nstages:\n- build_and_test_and_deploy\n\n# Select what we should cache between builds\ncache:\n  paths:\n  - vendor\/\n\nservices:\n- mariadb:latest\n- redis:latest\n\nvariables:\n  # Configure mysql environment variables (https:\/\/hub.docker.com\/r\/_\/mariadb\/)\n  MYSQL_DATABASE: atomapi\n  MYSQL_ROOT_PASSWORD: api_password\n  REDIS_HOST: redis\n\nbuild_and_test_and_deploy_job:\n  stage: build_and_test_and_deploy\n  script:\n  - php -v\n  - ping -c 3 mariadb\n  - composer install --no-interaction --no-suggest\n  - vendor\/bin\/php-cs-fixer fix -v --dry-run --stop-on-violation --using-cache=no\n  - php artisan config:cache\n  - php artisan route:cache\n  - php artisan migrate --seed\n  - vendor\/bin\/phpunit --coverage-text --colors=never\n  - cf login -a $CF_API_ENDPOINT -u $CF_USERNAME -p $CF_PASSWORD -o $CF_ORGANIZATION -s $CF_SPACE\n  - cf check-manifest $CF_WORKER_APP -f 'worker-manifest.yml'\n  - cf check-manifest $CF_MAIN_APP -f 'main-manifest.yml'\n  - cf push $CF_WORKER_APP -f 'worker-manifest.yml'\n  - cf blue-green-deploy $CF_MAIN_APP -f 'main-manifest.yml' --delete-old-apps\n  - cf create-job $CF_MAIN_APP laravel-scheduler \"php artisan schedule:run\"\n  - cf schedule-job laravel-scheduler \"* * ? * *\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Room For Improvement<\/h2>\n\n\n\n<p>There are some things that I&#8217;m still trying out and working on right now to further improve this deployment method. <\/p>\n\n\n\n<p>Currently, I&#8217;m trying to swap from Buildpacks to Docker for the deployment environment on Pivotal Web Services. I&#8217;m looking at the possibility of using Buildah. This will help reduce the build time by not repeating builds. Other than that, it will also make the whole pipeline become immutable and highly consistent. This would help reduce potential errors that might be caused due to differing environments.<\/p>\n\n\n\n<p>If you have any other suggestions for me to improve, feel free to leave a comment below!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post shows how I do blue-green deployment of my Laravel project, that has a queue runner, through GitLab CI onto Pivotal Cloudfoundry. You&#8217;ll need to know some basics of GitLab CI, Laravel and Pivotal Cloudfoundry to better understand this post. More information about Laravel queue runner is available in my other blog post! Docker &hellip; <a href=\"https:\/\/woohuiren.me\/blog\/blue-green-laravel-deployment-to-pivotal-cloudfoundry\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Blue-green Laravel deployment to Pivotal Cloudfoundry&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":817,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Check out my new blog post on Blue-green Laravel deployment to Pivotal Cloudfoundry! #pivotal #cloudfoundry #laravel #php","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[2,5],"tags":[74,180,197,182,198],"class_list":["post-789","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-information-technology","category-programming","tag-cloud","tag-cloud-foundry","tag-pcf","tag-pivotal-cloud-foundry","tag-pws"],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/i0.wp.com\/woohuiren.me\/blog\/wp-content\/uploads\/2019\/03\/Screenshot_2019-03-20-deck.png?fit=1920%2C942&ssl=1","_links":{"self":[{"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/posts\/789"}],"collection":[{"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/comments?post=789"}],"version-history":[{"count":5,"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/posts\/789\/revisions"}],"predecessor-version":[{"id":818,"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/posts\/789\/revisions\/818"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/media\/817"}],"wp:attachment":[{"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/media?parent=789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/categories?post=789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/woohuiren.me\/blog\/wp-json\/wp\/v2\/tags?post=789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}