<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:schema="http://schema.org/" xmlns:sioc="http://rdfs.org/sioc/ns#" xmlns:sioct="http://rdfs.org/sioc/types#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" version="2.0" xml:base="http://badzilla.co.uk/">
  <channel>
    <title>Drupal 9</title>
    <link>http://badzilla.co.uk/</link>
    <description/>
    <language>en</language>
    
    <item>
  <title>Hosting Drupal 9 on AWS Fargate Part 2: Bitbucket Pipeline</title>
  <link>http://badzilla.co.uk/hosting-drupal-9-aws-fargate-part-2-bitbucket-pipeline</link>
  <description>
&lt;span&gt;Hosting Drupal 9 on AWS Fargate Part 2: Bitbucket Pipeline&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Sun, 17/10/2021 - 09:31&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Introduction&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;In the first instalment of this sequence of blogs we talked about how imperative it is to create an industrial strength local dev environment when AWS Fargate is your target deployment platform. In this blog we discuss something equally important - the deploy and build process. This needs to be automated for Drupal since security patches are issued on a weekly basis by the Drupal Security Group, and an automated solution is the only way to keep on top of these updates.&lt;/p&gt;
&lt;p&gt;Over the last two years I have become accustomed  to using Atlassian's Bitbucket Pipelines, and I am really liking this CI/CD delivery mechanism. It is particularly suited to containerised solutions since the pipeline itself runs in a Docker container, and often times the solution Docker image can be used for the build process - case in point this project! This tutorial will show how the official Drupal PHP Docker container can be used as the pipeline for delivering Drupal 9 projects to AWS Fargate. Let's see how!&lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Bitbucket Pipeline&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-10/Pipeline.jpeg?itok=JFTezBU3 202w, https://assets.badzilla.co.uk/styles/max_650x650/s3/2021-10/Pipeline.jpeg?itok=lB6wJnbM 404w, https://assets.badzilla.co.uk/styles/max_1300x1300/s3/2021-10/Pipeline.jpeg?itok=ICDrDamw 808w, https://assets.badzilla.co.uk/styles/max_2600x2600/s3/2021-10/Pipeline.jpeg?itok=0UNx4Vgp 1616w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-10/Pipeline.jpeg?itok=JFTezBU3" alt="Pipeline" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The diagram above shows the basic steps the pipeline follows. Let's have a look at these in turn with narrative and then see how that transposes into the Pipeline code.A few trivial housekeeping activities have been omitted from the diagram for clarity but will be discussed when we look at the code. &lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Since my Badzilla blog is a hobby project, I don't have multiple environments, and merge all new features into the git master branch. Any merge into master triggers the build process. Commercial pipelines tend to trigger builds on feature branch commits too which may be a consideration depending upon your circumstances.&lt;/li&gt;
	&lt;li&gt;I've already mentioned that the Docker image selected for the pipeline will be the official Drupal / PHP release - and thus contains &lt;em&gt;composer&lt;/em&gt; which is used to build out the codebase.&lt;/li&gt;
	&lt;li&gt;Once the codebase has been built the testing can be undertaken. I have identified two parallel steps in the pipeline - &lt;a href="http://badzilla.co.uk/aws-fargate-automated-testing-cucumber-gherkin-java-maven-selenium-grid-hub-and-chrome-and-firefox"&gt;automated testing&lt;/a&gt; and &lt;a href="http://badzilla.co.uk/aws-fargate-static-analysis-php"&gt;static testing&lt;/a&gt;. I have covered the configuration for these in earlier blogs - so click through for further reading. &lt;/li&gt;
	&lt;li&gt;The next steps involve building the two Docker image artefacts we need for our Fargate bundles - the PHP / FPM / Codebase image, and the NGINX Web Server image. The latter is required since we need to load a configuration for Drupal 9 and for serving the S3 / CloudFront assets. &lt;/li&gt;
	&lt;li&gt;The artefacts are pushed into AWS ECR after being tagged &lt;em&gt;latest&lt;/em&gt;. &lt;/li&gt;
	&lt;li&gt;We are now ready to deploy the images to our ECS Cluster - but before we do this, we provide the opportunity to run any pre-deploy hooks. This would typically be activities such as &lt;em&gt;drush&lt;/em&gt; putting the web app into maintenance mode to prevent public access during updates.&lt;/li&gt;
	&lt;li&gt;One the pre-deploy scripts have completed, the deploy script is invoked. This forces an ECS service update on the cluster. The script loops to determine whether the update fails or completes, and upon a successful completion will move onto the final step. &lt;/li&gt;
	&lt;li&gt;The post-deploy scripts are now run. These would be further &lt;em&gt;drush&lt;/em&gt; commands to update the database schema for example, and to remove the maintenance mode flag. &lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Pipeline Code&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The pipeline code is saved in &lt;strong&gt;bitbucket-pipelines.yml&lt;/strong&gt; and is show below.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;image:
  name: drupal:9.2.6-php7.4-fpm
 
clone:
  depth: full
 
definitions:
  services:
    docker:
      memory: &lt;span style="color: #000000;"&gt;2048&lt;/span&gt;
 
  steps:
    - step: &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt;build-environment
        name: Build Environment
        script:
          &lt;span style="color: #666666; font-style: italic;"&gt;# Install git &amp; unzip for composer&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;unzip&lt;/span&gt; &lt;span style="color: #660033;"&gt;-y&lt;/span&gt;
          &lt;span style="color: #666666; font-style: italic;"&gt;# Install dependencies&lt;/span&gt;
          - &lt;span style="color: #7a0874; font-weight: bold;"&gt;export&lt;/span&gt; &lt;span style="color: #007800;"&gt;COMPOSER_ALLOW_SUPERUSER&lt;/span&gt;=&lt;span style="color: #000000;"&gt;1&lt;/span&gt;
          - composer &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt;
          &lt;span style="color: #666666; font-style: italic;"&gt;# Copy project settings file in place&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;cp&lt;/span&gt; storage&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;settings.php web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;settings.php
          &lt;span style="color: #666666; font-style: italic;"&gt;# Remove all non-essential dirs and files from top level directory&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;-rf&lt;/span&gt; assets backup databases .git
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;rm&lt;/span&gt; Makefile README.md docker-compose.yml composer.json composer.lock .env .csslintrc .eslintignore .eslintrc.json
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;rm&lt;/span&gt; .gitignore
          &lt;span style="color: #666666; font-style: italic;"&gt;# Add the bind mount VOLUME so in Fargate the nginx container can do a VOLUME_FROM and load /opt/drupal docroot&lt;/span&gt;
          &lt;span style="color: #666666; font-style: italic;"&gt;# from the core-drupal container&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-i&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'/^FROM.*/a VOLUME ["/opt/drupal"]'&lt;/span&gt; Dockerfile &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;dev&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;null &lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;
        caches:
          - composer
        artifacts:
          - &lt;span style="color: #ff0000;"&gt;'**'&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Automated Tests placeholder&lt;/span&gt;
    - step: &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt;automated-tests
        name: Automated Tests
        script:
          - &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Add automated tests here"&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Static Analysis tests placeholder&lt;/span&gt;
    - step: &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt;static-tests
        name: Static Analysis Tests
        script:
          - &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Add static analysis here"&lt;/span&gt;
 
pipelines:
  &lt;span style="color: #666666; font-style: italic;"&gt;# Run when code is merged / pushed into specific branches.&lt;/span&gt;
  branches:
    master:
      - step: &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;build-environment
 
      - parallel:
          - step: &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;automated-tests
          - step: &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;static-tests
 
      - step:
          name: Build &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt; Deploy
          deployment: AWS Prod
          script:
            &lt;span style="color: #666666; font-style: italic;"&gt;# Install AWS CLI&lt;/span&gt;
            - apt update &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; &lt;span style="color: #660033;"&gt;-y&lt;/span&gt; jq &lt;span style="color: #c20cb9; font-weight: bold;"&gt;unzip&lt;/span&gt; python3 python-dev python3-dev build-essential libssl-dev libffi-dev libxml2-dev libxslt1-dev zlib1g-dev python-pip
            - curl &lt;span style="color: #ff0000;"&gt;"https://s3.amazonaws.com/aws-cli/awscli-bundle-1.18.200.zip"&lt;/span&gt; &lt;span style="color: #660033;"&gt;-o&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awscli-bundle.zip"&lt;/span&gt;
            - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;unzip&lt;/span&gt; awscli-bundle.zip
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;awscli-bundle&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; &lt;span style="color: #660033;"&gt;-b&lt;/span&gt; ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;aws
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;export&lt;/span&gt; &lt;span style="color: #007800;"&gt;PATH&lt;/span&gt;=~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin:&lt;span style="color: #007800;"&gt;$PATH&lt;/span&gt;
            &lt;span style="color: #666666; font-style: italic;"&gt;# Build the codebase + FPM&lt;/span&gt;
            - docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; badzilla-core-drupal .
            &lt;span style="color: #666666; font-style: italic;"&gt;# Authenticate with ECR&lt;/span&gt;
            - aws configure &lt;span style="color: #000000; font-weight: bold;"&gt;set&lt;/span&gt; aws_access_key_id &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_ACCESS_KEY}&lt;/span&gt;"&lt;/span&gt;
            - aws configure &lt;span style="color: #000000; font-weight: bold;"&gt;set&lt;/span&gt; aws_secret_access_key &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_SECRET_KEY}&lt;/span&gt;"&lt;/span&gt;
            - aws ecr get-login &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_REGION}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/^.*-p \(.*\)\s\-\e.*$/\1/'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;  docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;login&lt;/span&gt; &lt;span style="color: #660033;"&gt;--password-stdin&lt;/span&gt; &lt;span style="color: #660033;"&gt;-u&lt;/span&gt; AWS &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CORE_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            &lt;span style="color: #666666; font-style: italic;"&gt;# Tag and push to the repo&lt;/span&gt;
            - docker tag badzilla-core-drupal:latest &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CORE_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            - docker push &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CORE_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            &lt;span style="color: #666666; font-style: italic;"&gt;# NGINX_DRUPAL_REPO_URL&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; docker&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;fargate
            - docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; badzilla-nginx-drupal .
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; -
            &lt;span style="color: #666666; font-style: italic;"&gt;# Authenticate with ECR&lt;/span&gt;
            - aws ecr get-login &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_REGION}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/^.*-p \(.*\)\s\-\e.*$/\1/'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;  docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;login&lt;/span&gt; &lt;span style="color: #660033;"&gt;--password-stdin&lt;/span&gt; &lt;span style="color: #660033;"&gt;-u&lt;/span&gt; AWS &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${NGINX_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            &lt;span style="color: #666666; font-style: italic;"&gt;# Tag and push to the repo&lt;/span&gt;
            - docker tag badzilla-nginx-drupal:latest &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${NGINX_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            - docker push &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${NGINX_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            &lt;span style="color: #666666; font-style: italic;"&gt;# Pre deploy Drush Commands&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; deploy-scripts
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;deploy-parser.sh ..&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;webhooks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;pre-deploy&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; -
            &lt;span style="color: #666666; font-style: italic;"&gt;# Deploy script&lt;/span&gt;
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;deploy-scripts&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ecs-service-deploy.sh
            &lt;span style="color: #666666; font-style: italic;"&gt;# Post deploy Drush Commands&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; deploy-scripts
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;deploy-parser.sh ..&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;webhooks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;post-deploy&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; -
          services:
            - docker
          caches:
            - docker&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Now let's inspect the code per section. Firstly the declaration of the Docker image to use for the pipeline. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;image:
  name: drupal:9.2.6-php7.4-fpm&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
You'll note that I'm using the same image as I used for my development environment with one small change. In the pipeline I have abandoned the use of the ultra lightweight Alpine image - the image being used is standard Ubuntu. Why so? Firstly there is less necessity for keeping the image small since Atlassian don't charge for storage of the image, and secondly I will want to add additional Linux packages to this image for the pipeline process, and thus I want to use a package manager I am familiar with - &lt;em&gt;apt&lt;/em&gt;.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;clone:
  depth: full
 
definitions:
  services:
    docker:
      memory: &lt;span style="color: #000000;"&gt;2048&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Here I'm saying I want a full clone of the repository in the pipeline. This is a little unnecessary and causes an overhead. In the future I will consider a more shallow clone for greater performance. The Docker memory setting should provide enough headroom for Drupal builds.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;  steps:
    - step: &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt;build-environment
        name: Build Environment
        script:
          &lt;span style="color: #666666; font-style: italic;"&gt;# Install git &amp; unzip for composer&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;unzip&lt;/span&gt; &lt;span style="color: #660033;"&gt;-y&lt;/span&gt;
          &lt;span style="color: #666666; font-style: italic;"&gt;# Install dependencies&lt;/span&gt;
          - &lt;span style="color: #7a0874; font-weight: bold;"&gt;export&lt;/span&gt; &lt;span style="color: #007800;"&gt;COMPOSER_ALLOW_SUPERUSER&lt;/span&gt;=&lt;span style="color: #000000;"&gt;1&lt;/span&gt;
          - composer &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Steps are defined in the pipeline that are invoked later in the script. This step &lt;em&gt;&amp;build-environment&lt;/em&gt; will build out the environment by installing the packages I will need and then running &lt;em&gt;composer install&lt;/em&gt; to build out the codebase.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;          &lt;span style="color: #666666; font-style: italic;"&gt;# Copy project settings file in place&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;cp&lt;/span&gt; storage&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;settings.php web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;settings.php
          &lt;span style="color: #666666; font-style: italic;"&gt;# Remove all non-essential dirs and files from top level directory&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;-rf&lt;/span&gt; assets backup databases .git
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;rm&lt;/span&gt; Makefile README.md docker-compose.yml composer.json composer.lock .env .csslintrc .eslintignore .eslintrc.json
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;rm&lt;/span&gt; .gitignore&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Every Drupal site needs a &lt;em&gt;settings.php&lt;/em&gt; file. I decided to have mine saved in the repository in the directory &lt;em&gt;storage&lt;/em&gt; since there is no confidential data. All settings use environmental variables. Your mileage may vary here - other strategies are possible for injecting the &lt;em&gt;settings.php&lt;/em&gt; into the build. &lt;br /&gt;&lt;br /&gt;
I then delete files and directories from the build which won't be needed in a production environment.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;          &lt;span style="color: #666666; font-style: italic;"&gt;# Add the bind mount VOLUME so in Fargate the nginx container can do a VOLUME_FROM and load /opt/drupal docroot&lt;/span&gt;
          &lt;span style="color: #666666; font-style: italic;"&gt;# from the core-drupal container&lt;/span&gt;
          - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-i&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'/^FROM.*/a VOLUME ["/opt/drupal"]'&lt;/span&gt; Dockerfile &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;dev&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;null &lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
This snippet is a kludge to fix a difference between the local environment &lt;em&gt;docker-compose&lt;/em&gt; and the production Fargate Task Definition. Fargate shared volumes use &lt;em&gt;bind mounts&lt;/em&gt; which are created by initially using the &lt;em&gt;VOLUME&lt;/em&gt; instruction in the &lt;em&gt;Dockerfile&lt;/em&gt; and settings in the Task Definition (to be discussed in a later blog). Here I use interactive &lt;em&gt;sed&lt;/em&gt; to inject the &lt;em&gt;VOLUME&lt;/em&gt; into the &lt;em&gt;Dockerfile&lt;/em&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;        caches:
          - composer
        artifacts:
          - &lt;span style="color: #ff0000;"&gt;'**'&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Closing the build step I ensure that Docker is cached to save time next time the pipeline is invoked and the artifact (American spelling) setting tells the pipeline to save the all my work in that pipeline step for steps that follow it.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# Automated Tests placeholder&lt;/span&gt;
    - step: &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt;automated-tests
        name: Automated Tests
        script:
          - &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Add automated tests here"&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Static Analysis tests placeholder&lt;/span&gt;
    - step: &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt;static-tests
        name: Static Analysis Tests
        script:
          - &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Add static analysis here"&lt;/span&gt;
 
pipelines:
  &lt;span style="color: #666666; font-style: italic;"&gt;# Run when code is merged / pushed into specific branches.&lt;/span&gt;
  branches:
    master:
      - step: &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;build-environment
 
      - parallel:
          - step: &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;automated-tests
          - step: &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;static-tests&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Here I have defined the testing steps (both of which are currently placeholders), and then started the 'implementation' section of the code. The steps will be invoked on the master branch, initially the build and then the the two testing steps in parallel.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;      - step:
          name: Build &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&lt;/span&gt; Deploy
          deployment: AWS Prod
          script:
            &lt;span style="color: #666666; font-style: italic;"&gt;# Install AWS CLI&lt;/span&gt;
            - apt update &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; &lt;span style="color: #660033;"&gt;-y&lt;/span&gt; jq &lt;span style="color: #c20cb9; font-weight: bold;"&gt;unzip&lt;/span&gt; python3 python-dev python3-dev build-essential libssl-dev libffi-dev libxml2-dev libxslt1-dev zlib1g-dev python-pip
            - curl &lt;span style="color: #ff0000;"&gt;"https://s3.amazonaws.com/aws-cli/awscli-bundle-1.18.200.zip"&lt;/span&gt; &lt;span style="color: #660033;"&gt;-o&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awscli-bundle.zip"&lt;/span&gt;
            - &lt;span style="color: #c20cb9; font-weight: bold;"&gt;unzip&lt;/span&gt; awscli-bundle.zip
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;awscli-bundle&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; &lt;span style="color: #660033;"&gt;-b&lt;/span&gt; ~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;aws
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;export&lt;/span&gt; &lt;span style="color: #007800;"&gt;PATH&lt;/span&gt;=~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin:&lt;span style="color: #007800;"&gt;$PATH&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Once testing has completed successfully we commence the inline deploy step. We are going to need the AWS CLI installing here since the CLI is necessary to issue the correct sequence of commands to AWS to commit and deploy. &lt;br /&gt;&lt;br /&gt;
Note I am also installing the amazing utility &lt;em&gt;jq&lt;/em&gt; - a JSON query language utility. This is imperative for inspecting the output of the CLI commands since their responses are sent in JSON format.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;            &lt;span style="color: #666666; font-style: italic;"&gt;# Build the codebase + FPM&lt;/span&gt;
            - docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; badzilla-core-drupal .
            &lt;span style="color: #666666; font-style: italic;"&gt;# Authenticate with ECR&lt;/span&gt;
            - aws configure &lt;span style="color: #000000; font-weight: bold;"&gt;set&lt;/span&gt; aws_access_key_id &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_ACCESS_KEY}&lt;/span&gt;"&lt;/span&gt;
            - aws configure &lt;span style="color: #000000; font-weight: bold;"&gt;set&lt;/span&gt; aws_secret_access_key &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_SECRET_KEY}&lt;/span&gt;"&lt;/span&gt;
            - aws ecr get-login &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_REGION}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/^.*-p \(.*\)\s\-\e.*$/\1/'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;  docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;login&lt;/span&gt; &lt;span style="color: #660033;"&gt;--password-stdin&lt;/span&gt; &lt;span style="color: #660033;"&gt;-u&lt;/span&gt; AWS &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CORE_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            &lt;span style="color: #666666; font-style: italic;"&gt;# Tag and push to the repo&lt;/span&gt;
            - docker tag badzilla-core-drupal:latest &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CORE_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            - docker push &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CORE_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now I've got all I need installed I can build the Docker image artefacts. Firstly I build out the Drupal codebase image which also contains PHP and FPM. I then authenticate with AWS ECR where I will push the artefact once its been tagged.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;            &lt;span style="color: #666666; font-style: italic;"&gt;# NGINX_DRUPAL_REPO_URL&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; docker&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;fargate
            - docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; badzilla-nginx-drupal .
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; -
            &lt;span style="color: #666666; font-style: italic;"&gt;# Authenticate with ECR&lt;/span&gt;
            - aws ecr get-login &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_REGION}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/^.*-p \(.*\)\s\-\e.*$/\1/'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;  docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;login&lt;/span&gt; &lt;span style="color: #660033;"&gt;--password-stdin&lt;/span&gt; &lt;span style="color: #660033;"&gt;-u&lt;/span&gt; AWS &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${NGINX_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            &lt;span style="color: #666666; font-style: italic;"&gt;# Tag and push to the repo&lt;/span&gt;
            - docker tag badzilla-nginx-drupal:latest &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${NGINX_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;
            - docker push &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${NGINX_DRUPAL_REPO_URL}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
I now repeat the process for the NGINX web server Docker image. Note I have the configuration for this in my codebase repo under the directory &lt;em&gt;docker/nginx/fargate&lt;/em&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;            &lt;span style="color: #666666; font-style: italic;"&gt;# Pre deploy Drush Commands&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; deploy-scripts
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;deploy-parser.sh ..&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;webhooks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;pre-deploy&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; -
            &lt;span style="color: #666666; font-style: italic;"&gt;# Deploy script&lt;/span&gt;
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;deploy-scripts&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ecs-service-deploy.sh
            &lt;span style="color: #666666; font-style: italic;"&gt;# Post deploy Drush Commands&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; deploy-scripts
            - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;deploy-parser.sh ..&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;webhooks&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;post-deploy&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
            - &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; -&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
This is the fun part! I now run the deploy shell scripts which are listed with narratives later in the blog. Firstly I run the pre-deploy commands, then the deploy commands and the post-deploy commands. All will be revealed...&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;          services:
            - docker
          caches:
            - docker&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
To use Docker commands in a pipeline, you need to list &lt;em&gt;Docker&lt;/em&gt; under the &lt;em&gt;services&lt;/em&gt; setting. Installing Docker in the pipeline itself and then invoking it will not work! I tried and failed! Note I am also using caching for greater performance.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Repository Environmental Variables&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-10/Screenshot%202021-10-17%20at%2013.48.33.png?itok=EYhOiCH9 126w, https://assets.badzilla.co.uk/styles/max_650x650/s3/2021-10/Screenshot%202021-10-17%20at%2013.48.33.png?itok=SINiOcxN 252w, https://assets.badzilla.co.uk/styles/max_1300x1300/s3/2021-10/Screenshot%202021-10-17%20at%2013.48.33.png?itok=7E76dh4f 505w, https://assets.badzilla.co.uk/styles/max_2600x2600/s3/2021-10/Screenshot%202021-10-17%20at%2013.48.33.png?itok=YYfDNJB3 536w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-10/Screenshot%202021-10-17%20at%2013.48.33.png?itok=EYhOiCH9" alt="Env Vars" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The pipeline and the shell scripts heavily use environmental variables that are set in the repository in Bitbucket. Their names are self-evident and listed in their entirety above. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Pre- and Post-deploy shell script&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The pre- and post-deploy shell script is defined below. Currently it only works on &lt;em&gt;drush&lt;/em&gt; commands but could be extended to include shell scripts easily enough. The idea is it scans the directory passed as a parameter and it looks for lines in any file that starts with the word &lt;em&gt;drush&lt;/em&gt;. It then takes the runtime arguments of that &lt;em&gt;drush&lt;/em&gt; command and converts it into a Docker &lt;em&gt;cmd&lt;/em&gt; syntax. Once that is done the command is executed as a Fargate task using the codebase image with parameter overrides. This task runs to completion and exits. The status of the command can be captured and reported back to the pipeline. Obviously this isn't as quick as running a &lt;em&gt;drush&lt;/em&gt; command in a terminal shell since the Fargate task needs to be provisioned which takes time. It is however a fiendish way of reusing an existing Docker image since the official Drupal Docker image already contains the &lt;em&gt;drush&lt;/em&gt; command. &lt;br /&gt;&lt;strong&gt;deploy-scripts/deploy-parser.sh&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Parse the passed files and issue commands in accordance.&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# Currently only supports drush commands.&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# This can be expanded out to other shell scripts.&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Output directory to be parsed&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Directory: $1 to be parsed"&lt;/span&gt;
 
set_network_configuration&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
&lt;span style="color: #007800;"&gt;NETWORK&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
    {
        "awsvpcConfiguration":
            {
                "subnets": [
                    $1,
                    $2
                ],
                "securityGroups": [
                    $3
                ],
                "assignPublicIp": "ENABLED"
            }
    }
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${NETWORK}&lt;/span&gt;"&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
 
 
set_overrides_command&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
&lt;span style="color: #007800;"&gt;OVERRIDES&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
	{
		"containerOverrides": [
		    {
		        "name": $1,
		        "command": [
		            $2
		        ]
		    }
		]
	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${OVERRIDES}&lt;/span&gt;"&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Process each line in a selected file&lt;/span&gt;
parse_line&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# All lines to be processed must start with the word drush to be considered&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# This grep / sed combination will turn the drush command into docker cmd syntax&lt;/span&gt;
    &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"^drush"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${1}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;read&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; line ; &lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
        &lt;span style="color: #007800;"&gt;cmd&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #007800;"&gt;$line&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/[^ ][^ ]*/"&amp;"/g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/\s+/,/g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/drush/vendor\/bin\/drush/'&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
        &lt;span style="color: #666666; font-style: italic;"&gt;# @BUG with quoting in dotenv and how I load into environment. Appears to add newlines making it difficult to add quotes later.&lt;/span&gt;
        &lt;span style="color: #666666; font-style: italic;"&gt;# So already added quotes for $CORE_TASK_DEFINITION_NAME in .env file but need the unquoted version in&lt;/span&gt;
        &lt;span style="color: #666666; font-style: italic;"&gt;# --task-definition flag so unquote here&lt;/span&gt;
        &lt;span style="color: #007800;"&gt;TASK_DEF_UNQUOTE&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #800000;"&gt;${CORE_TASK_DEFINITION_NAME}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; s&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;\"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;g&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
        &lt;span style="color: #666666; font-style: italic;"&gt;# Now execute the command to start the container with the drush cmd&lt;/span&gt;
        &lt;span style="color: #007800;"&gt;FARGATE_TASK&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs run-task \
            &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECS_CLUSTER_NAME}&lt;/span&gt;"&lt;/span&gt; \
            &lt;span style="color: #660033;"&gt;--task-definition&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${TASK_DEF_UNQUOTE}&lt;/span&gt;"&lt;/span&gt; \
            &lt;span style="color: #660033;"&gt;--network-configuration&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$(set_network_configuration  ${ECS_SUBNET_1} ${ECS_SUBNET_2}  ${ECS_SECURITY_GROUP})&lt;/span&gt;"&lt;/span&gt; \
            &lt;span style="color: #660033;"&gt;--launch-type&lt;/span&gt; FARGATE \
            &lt;span style="color: #660033;"&gt;--platform-version&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'1.4.0'&lt;/span&gt; \
            &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_DEFAULT_REGION}&lt;/span&gt;"&lt;/span&gt; \
            &lt;span style="color: #660033;"&gt;--overrides&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$(set_overrides_command ${CORE_TASK_DEFINITION_NAME} ${cmd})&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.taskArn -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
        &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;!&lt;/span&gt;= &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
            &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Fargate Run Task Failed."&lt;/span&gt;
            &lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;elif&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt;  &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${FARGATE_TASK}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
            &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Unspecified Fargate Run Task Failure."&lt;/span&gt;
            &lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt;
            &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Cmd run is &lt;span style="color: #007800;"&gt;${cmd}&lt;/span&gt;"&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
        &lt;span style="color: #666666; font-style: italic;"&gt;# Loop round to check on the status of the task. Can't run in parallel so have to wait for each task to finish&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;true&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
            &lt;span style="color: #007800;"&gt;FARGATE_STATUS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECS_CLUSTER_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${FARGATE_TASK}&lt;/span&gt;"&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.lastStatus -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
            &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${FARGATE_STATUS}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
                &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Unspecified Fargate Describe Task Failure."&lt;/span&gt;
                &lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
            &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
            &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${FARGATE_STATUS}&lt;/span&gt;"&lt;/span&gt;
 
            &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${FARGATE_STATUS}&lt;/span&gt;"&lt;/span&gt; == &lt;span style="color: #ff0000;"&gt;"STOPPED"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;||&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${FARGATE_STATUS}&lt;/span&gt;"&lt;/span&gt; == &lt;span style="color: #ff0000;"&gt;"DEPROVISIONING"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
                  &lt;span style="color: #7a0874; font-weight: bold;"&gt;break&lt;/span&gt;
            &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
            &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;20&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
 
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Drush command completed"&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get a list of all the files in the directory and process&lt;/span&gt;
parse_directory&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# loop though all the files in the directory&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;file&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${1}&lt;/span&gt;"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
        &lt;span style="color: #007800;"&gt;base&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$(basename ${file})&lt;/span&gt;"&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${base}&lt;/span&gt; being parsed"&lt;/span&gt;
        parse_line &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${file}&lt;/span&gt;"&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
parse_directory &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${1}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;ECS Deploy Script&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The main ECS deploy shell script uses AWS CLI &lt;em&gt;ecs update-service &lt;/em&gt; to force a new deployment. This means that when the Fargate bundles are recycling any new codebase and NGINX Docker image will be used from AWS ECR. The process can take a few minutes so I have added a loop facility which uses AWS CLI &lt;em&gt;ecs describe-services&lt;/em&gt; to capture the current deployment status and act accordingly. Note I am using the previously mentioned &lt;em&gt;jq&lt;/em&gt; utility to interrogate the long JSON response from the CLI and whittle it down to the status field which should contain the word "COMPLETED" or "FAILED" or "IN_PROGRESS".&lt;br /&gt;&lt;strong&gt;deploy-scripts/ecs-service-deploy.sh&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Use the aws cli to force deploy Fargate task running in ECS service&lt;/span&gt;
aws ecs update-service &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECS_CLUSTER_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--service&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECS_SERVICE_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--force-new-deployment&lt;/span&gt; &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_DEFAULT_REGION}&lt;/span&gt;"&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Give it a few seconds to take effect&lt;/span&gt;
&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;5&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the deployment status by looping over the deployment&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# Try for a maximum of 20 minutes then give up. Chances are after 20 minutes of incomplete&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# deployment there is a problem in the task definition&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;4&lt;/span&gt; &lt;span style="color: #000000;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;8&lt;/span&gt; &lt;span style="color: #000000;"&gt;9&lt;/span&gt; &lt;span style="color: #000000;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt;21&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${i}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eq&lt;/span&gt; &lt;span style="color: #000000;"&gt;21&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Timed out before could determine if deployment succeeded"&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
    &lt;span style="color: #007800;"&gt;STATUS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-services &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECS_CLUSTER_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--services&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECS_SERVICE_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AWS_DEFAULT_REGION}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .services&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.deployments&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.rolloutState -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Was it successful?&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${STATUS}&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;"COMPLETED"&lt;/span&gt;  &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Deployment succeeded"&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# Anything we need to be concerned about?&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;elif&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${STATUS}&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;"FAILED"&lt;/span&gt;  &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Deployment failed"&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# If still deploying echo this&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;elif&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${STATUS}&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;"IN_PROGRESS"&lt;/span&gt;  &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Deployment in progress"&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Unknown status "&lt;/span&gt;&lt;span style="color: #800000;"&gt;${STATUS}&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;" so quitting"&lt;/span&gt;
        &lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Wait a minute before retrying&lt;/span&gt;
    &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;60&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Ad hoc Drush Commands&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The solution provides the capability to run &lt;em&gt;drush&lt;/em&gt; during the pre- and post-deploy scripts. But what about running &lt;em&gt;drush&lt;/em&gt; commands on an ad hoc basis from a remote laptop? This is often required by developers or devops and would be crucial for the management of a Drupal 9 website. Stay tuned for a future blog on how to achieve this! &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/php" hreflang="en"&gt;PHP&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/drupal" hreflang="en"&gt;Drupal&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/taxonomy/term/121" hreflang="en"&gt;Drupal 9&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Sun, 17 Oct 2021 08:31:46 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">182 at http://badzilla.co.uk</guid>
    </item>
<item>
  <title>Hosting Drupal 9 on AWS Fargate Part 1: Local Development </title>
  <link>http://badzilla.co.uk/hosting-drupal-9-aws-fargate-part-1-local-development</link>
  <description>
&lt;span&gt;Hosting Drupal 9 on AWS Fargate Part 1: Local Development &lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Sun, 19/09/2021 - 09:46&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Introduction&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Welcome to a series of blogs on hosting Drupal 9 (or legacy Drupal 8) sites on AWS Fargate. Fargate can now be considered a mature product, and provides a simple serverless containerised platform for hosting web apps. It offers considerable savings over traditional Virtual servers without, if configured correctly, loss of performance. Furthermore it offers greater simplicity of operation and setup then its AWS sibling offering ECS over EC2, and again a cost saving. &lt;/p&gt;

&lt;p&gt;The blogs in this series will cover important considerations such as the pipelines to deploy your codebase within Docker images, and their storage; set up of the Drupal S3FS module along with the CloudFront accelerator and S3 object store; auto scaling of the Fargate tasks; load testing your app to ensure you are fully optimised; and how to run your Drush commands in short living Fargate tasks. &lt;/p&gt;

&lt;p&gt;This first blog will cover your team's local environment and how its build will ensure your path to Fargate deploy is smooth, with as much reuse of the configuration in production as possible. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Objective&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-09/FargateServices_1.jpeg?itok=fq097hDo 325w, https://assets.badzilla.co.uk/styles/max_650x650/s3/2021-09/FargateServices_1.jpeg?itok=SeCQrttM 650w, https://assets.badzilla.co.uk/styles/max_1300x1300/s3/2021-09/FargateServices_1.jpeg?itok=vTdoq1tf 1300w, https://assets.badzilla.co.uk/styles/max_2600x2600/s3/2021-09/FargateServices_1.jpeg?itok=TaitKa6l 1581w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-09/FargateServices_1.jpeg?itok=fq097hDo" alt="Fargate Services and Tasks" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The objective is to stand up a Fargate task running as a service which will be the web app, and it will persist and auto scale. Also have Fargate tasks to run which will run Drush commands, stood up on a per Drush command basis, and terminating after each Drush command completes. The diagram above shows the Docker images requires to achieve our goal. &lt;/p&gt;
&lt;h3&gt;Drupal Core + FPM PHP + Codebase&lt;/h3&gt;
&lt;p&gt;The intention is to use the official Drupal FPM Docker image using Alpine, and be as up to date as possible with the versioning. Note that the Alpine build has been chosen since it's an extremely lightweight version of Linux, based on busybox which has a very small footprint. This comes at a price - those with Ubuntu experience will have to learn new commands. For instance Alpine uses the &lt;em&gt;apk&lt;/em&gt; package manager instead of &lt;em&gt;apt-get&lt;/em&gt;. The web app's codebase - ie all the configuration and custom modules and themes created by the dev team - will be copied into this image. &lt;/p&gt;
&lt;h3&gt;Drupal Core + FPM PHP + Codebase + Exec command&lt;/h3&gt;
&lt;p&gt;This will be the Fargate task to run one off Drush commands. Since the codebase will already contain Drush binaries in &lt;em&gt;vendor/bin/drush&lt;/em&gt;, it will be the same as the previously mentioned image. Notwithstanding this, it won't persist. It will use the Fargate equivalent of the Docker command to &lt;em&gt;exec&lt;/em&gt; a particular command and then quit. &lt;/p&gt;
&lt;h3&gt;Memcached&lt;/h3&gt;
&lt;p&gt;I have elected to run individual Memcached caching in each task running in the Web App service. Memcached will be used for caching the Drupal MySQL cache tables and for page caching for anonymous users. There is an alternative strategy to this - centralise the caching using for instance the AWS ElastiCache with Memcached product. Each task in the web service would have an endpoint to the same centralised ElastiCache instance. This would be the preferred option if your website is largely serving logged in traffic, and if you are running an eCommerce site with the users' baskets stored in Memcached. Since that doesn't apply to my own site, and I would like to keep costs down too, my feeling is having Memcached as part of the Fargate task is a better fit. &lt;/p&gt;
&lt;h3&gt;nginx&lt;/h3&gt;
&lt;p&gt;A web server is needed, and I've elected for &lt;em&gt;nginx&lt;/em&gt; although &lt;em&gt;Apache&lt;/em&gt; would also be a good choice. My rationale for selecting nginx is I would like to add the feature of nginx serving slightly stale cached pages when the origin is returning 5xx errors. This would give a seamless switch-over when a task becomes unhealthy - during the period AWS determines that a task is returning errors and has crossed the unhealthy threshold, nginx could still serve pages which would be less than 5 minutes old. The task would then be drained and removed from the pool with no problem noticeable to the end user. This will be the subject of a blog at a later date. &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Using a local Virtual Machine&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Those who know me well will know I am not an advocate of using my laptop's OS for development purposes. The reason being that with multiple clients and with multiple projects in each, my host OS would quickly become a mess of different development tooling and versions which could collide and could also generate inconsistencies with other devs in the team should say different versions of bin files end up in the $PATH. &lt;/p&gt;

&lt;p&gt;My ethos has always been &lt;em&gt;do not pollute your host OS! Always use VMs for development!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have created my own VM for Docker based implementations. My belief is if the target deploy is using Docker containers then the local development environment should match this as much as is practicable. In fact it's impossible to match the ECS/Fargate environment exactly, but it is certainly possible to use Docker with &lt;em&gt;docker-compose&lt;/em&gt; to simulate closely what will be seen in prod. &lt;/p&gt;

&lt;p&gt;My VM can be found in GitHub by clicking on &lt;a href="https://github.com/sanddevil/dockervm"&gt;this link&lt;/a&gt;. It is a very lightweight VM and can be orchestrated easily using Vagrant and Ansible. PHP and MySQL are deliberately not included in the playbook since all development work will be undertaken by using Docker containers.&lt;/p&gt;

&lt;p&gt;All my localhost config examples in this blog will have come from using my DockerVM mentioned above. If you intend to follow this blog closely, you will need to install it, but read the instructions in the README.md carefully!&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Composer&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Once you've got a lightweight VM up and running (hopefully mine), and ssh'd into it, and cloned your repo, you will need to build out the dependencies using &lt;em&gt;composer install&lt;/em&gt;. So how do we go about this when there is no composer and no PHP in the VM? There are two choices:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Use the official Docker Composer image&lt;/li&gt;
	&lt;li&gt;Use the latest official Docker Drupal image (9.2.6-php7.4-fpm-alpine.3.14 at time of writing this blog)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I chose the official Docker Composer image purely because (a) there was more documentation on it readily available, and (b) I wasn't sure at the time whether the Drupal image bundled Composer. It does, and it will be used in the Bitbucket Pipeline later so you may want to select that instead for consistency, but if you do, you'll have to change my composer commands slightly.&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Ok so let's build our composer image. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ docker run &lt;span style="color: #660033;"&gt;--rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;--interactive&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tty&lt;/span&gt; &lt;span style="color: #660033;"&gt;--volume&lt;/span&gt; &lt;span style="color: #007800;"&gt;$PWD&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;app composer &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; &lt;span style="color: #660033;"&gt;--ignore-platform-reqs&lt;/span&gt;
Unable to &lt;span style="color: #c20cb9; font-weight: bold;"&gt;find&lt;/span&gt; image &lt;span style="color: #ff0000;"&gt;'composer:latest'&lt;/span&gt; locally
latest: Pulling from library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;composer
a0d0a0d46f8b: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
153eea49496a: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
11efd0df1fcb: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
b3f3214c344d: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
9abd2f85688c: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
83d85b95eb4c: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
923d73ddadfa: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
711b5c4b02a7: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
ee08fa481788: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
5f9f812bf61d: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
28b3ecec72d5: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
a5ffb14bc4f9: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
d92aff3e5aec: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
cd0274c84e75: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
Digest: sha256:33d2c1d9fb7311cb8f215a8f52669894ef534292ac5d331347f929c27e317bb1
Status: Downloaded newer image &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; composer:latest
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; DrupalProject\composer\ScriptHandler::checkComposerVersion
Installing dependencies from lock &lt;span style="color: #c20cb9; font-weight: bold;"&gt;file&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;including require-dev&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
Verifying lock &lt;span style="color: #c20cb9; font-weight: bold;"&gt;file&lt;/span&gt; contents can be installed on current platform.
  - Downloading composer&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;installers &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;v2.0.1&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;---- SNIPPED ----&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;
  - Copy &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;web-root&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;profiles&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;README.txt from assets&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;scaffold&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;profiles.README.txt
  - Copy &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;web-root&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;themes&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;README.txt from assets&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;scaffold&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;themes.README.txt
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; DrupalProject\composer\ScriptHandler::createRequiredFiles
Created a sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files directory with &lt;span style="color: #c20cb9; font-weight: bold;"&gt;chmod&lt;/span&gt; 0777&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Success! Note that there is a requirement to use the composer flag --ignore-platform-reqs since it expects ext-gd locally which obviously we don't have.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;docker-compose: Codebase + FPM&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;In preparation for creating a docker-compose file we'll need to build out an image containing the latest Drupal 9 Docker image + our codebase once composer install has been run.  This will need a Dockerfile, and we can add APCu caching in the Dockerfile for greater Drupal performance. I also noted that Memcached API library needs to be added to Dockerfile since it is my intention to connect to a Memcached server for cache management in the container bundle.  The Dockerfile is listed below. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;FROM drupal:9.2.6-php7.4-fpm-alpine3.14
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Copy the artefact (on Bitbucket) or local files into the image&lt;/span&gt;
COPY .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;opt&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;drupal&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
 
&lt;span style="color: #666666; font-style: italic;"&gt;# PHP Memcached which needs the libmemcached API&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# Bug in Apline - creates extensions in the wrong directory so add them in correct location&lt;/span&gt;
RUN apk add php7-igbinary php7-pecl-memcached libmemcached \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"extension=memcached.so"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;conf.d&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docker-php-ext-memcached.ini \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"extension=igbinary.so"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;conf.d&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docker-php-ext-igbinary.ini \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mv&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php7&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;memcached.so &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;extensions&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;no-debug-non-zts-&lt;span style="color: #000000;"&gt;20190902&lt;/span&gt; \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mv&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php7&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;igbinary.so &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;extensions&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;no-debug-non-zts-&lt;span style="color: #000000;"&gt;20190902&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# APCu cache&lt;/span&gt;
RUN apk add &lt;span style="color: #660033;"&gt;--update&lt;/span&gt; &lt;span style="color: #660033;"&gt;--no-cache&lt;/span&gt; &lt;span style="color: #660033;"&gt;--virtual&lt;/span&gt; .build-dependencies &lt;span style="color: #007800;"&gt;$PHPIZE_DEPS&lt;/span&gt; \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; pecl &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; apcu \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-enable apcu \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; pecl clear-cache \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; apk del .build-dependencies&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;docker-compose: nginx image&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;We will also need to build out an nginx image with the standard Drupal configuration. To do this I created a docker directory at the top level of the repo (i.e. a sibling of web directory) as such:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;tree&lt;/span&gt; docker
docker
├── core-drupal
├── memcached
└── nginx
    ├── fargate
    │   ├── default.conf
    │   ├── Dockerfile
    │   └── nginx.conf
    └── &lt;span style="color: #7a0874; font-weight: bold;"&gt;local&lt;/span&gt;
        ├── default.conf
        ├── Dockerfile
        └── nginx.conf
 
&lt;span style="color: #000000;"&gt;5&lt;/span&gt; directories, &lt;span style="color: #000000;"&gt;6&lt;/span&gt; files&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
You'll note that I have two sets of config files - one for AWS Fargate and one for local development. In fact the differences are minimal and will be discussed later. The local files are below&lt;br /&gt;
&lt;strong&gt;nginx.conf&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;user  nginx;
worker_processes  auto;
 
error_log  &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;log&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;error.log notice;
pid        &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;run&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx.pid;
 
 
events &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
    worker_connections  &lt;span style="color: #000000;"&gt;1024&lt;/span&gt;;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
 
http &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
    include       &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mime.types;
    default_type  application&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;octet-stream;
 
    fastcgi_buffers &lt;span style="color: #000000;"&gt;16&lt;/span&gt; 16k;
    fastcgi_buffer_size 32k;
 
    log_format  main  &lt;span style="color: #ff0000;"&gt;'$remote_addr - $remote_user [$time_local] "$request" '&lt;/span&gt;
                      &lt;span style="color: #ff0000;"&gt;'$status $body_bytes_sent "$http_referer" '&lt;/span&gt;
                      &lt;span style="color: #ff0000;"&gt;'"$http_user_agent" "$http_x_forwarded_for"'&lt;/span&gt;;
 
    access_log  &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;log&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;access.log  main;
 
    sendfile        on;
    &lt;span style="color: #666666; font-style: italic;"&gt;#tcp_nopush     on;&lt;/span&gt;
 
    keepalive_timeout  &lt;span style="color: #000000;"&gt;65&lt;/span&gt;;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;#gzip  on;&lt;/span&gt;
 
    include &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;conf.d&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;.conf;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;strong&gt;default.conf&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;  server &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
    server_name badzilla-fargate.test;
    root &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;opt&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;drupal&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;web; &lt;span style="color: #666666; font-style: italic;"&gt;## &lt;-- Your only path reference.&lt;/span&gt;
 
    location = &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;favicon.ico &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      log_not_found off;
      access_log off;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    location = &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;robots.txt &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      allow all;
      log_not_found off;
      access_log off;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    location ~ \..&lt;span style="color: #000000; font-weight: bold;"&gt;*/&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;\.php$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;403&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    location ~ ^&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;*/&lt;/span&gt;private&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;403&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Block access to scripts in site files directory&lt;/span&gt;
    location ~ ^&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;^&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;+&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;\.php$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      deny all;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Allow "Well-Known URIs" as per RFC 5785&lt;/span&gt;
    location ~&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt; ^&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.well-known&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      allow all;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Block access to "hidden" files and directories whose names begin with a&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# period. This includes directories used by version control systems such&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# as Subversion or Git to store control files.&lt;/span&gt;
    location ~ &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;^&lt;span style="color: #000000; font-weight: bold;"&gt;|/&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;\. &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;403&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    location &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      &lt;span style="color: #666666; font-style: italic;"&gt;# try_files $uri @rewrite; # For Drupal &lt;= 6&lt;/span&gt;
      try_files &lt;span style="color: #007800;"&gt;$uri&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;index.php?&lt;span style="color: #007800;"&gt;$query_string&lt;/span&gt;; &lt;span style="color: #666666; font-style: italic;"&gt;# For Drupal &gt;= 7&lt;/span&gt;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    location &lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;rewrite &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      &lt;span style="color: #666666; font-style: italic;"&gt;#rewrite ^/(.*)$ /index.php?q=$1; # For Drupal &lt;= 6&lt;/span&gt;
      rewrite ^ &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;index.php; &lt;span style="color: #666666; font-style: italic;"&gt;# For Drupal &gt;= 7&lt;/span&gt;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Don't allow direct access to PHP files in the vendor directory.&lt;/span&gt;
    location ~ &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;vendor&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;\.php$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      deny all;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;404&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Protect files and directories from prying eyes.&lt;/span&gt;
    location ~&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt; \.&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;engine&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;inc&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;module&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;profile&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;po&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sh&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;sql&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;theme&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;twig&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;tpl&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;\.php&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;?&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;xtmpl&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;yml&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;~&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;\.sw&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;op&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;\.bak&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;\.orig&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;\.save&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;?$&lt;span style="color: #000000; font-weight: bold;"&gt;|/&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;\.&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;?&lt;span style="color: #000000; font-weight: bold;"&gt;!&lt;/span&gt;well-known&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;Entries.&lt;span style="color: #000000; font-weight: bold;"&gt;*|&lt;/span&gt;Root&lt;span style="color: #000000; font-weight: bold;"&gt;|/&lt;/span&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {&lt;/span&gt;
      deny all;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;404&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# In Drupal 8, we must also match new paths where the '.php' appears in&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# the middle, such as update.php/selection. The rule we use is strict,&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# and only allows this pattern with the update.php front controller.&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# This allows legacy path aliases in the form of&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# blog/index.php/legacy-path to continue to route to Drupal nodes. If&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# you do not have any paths like that, then you might prefer to use a&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# laxer rule, such as:&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;#   location ~ \.php(/|$) {&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# The laxer rule will continue to work if Drupal uses this new URL&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# pattern with front controllers other than update.php in a future&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# release.&lt;/span&gt;
    location ~ &lt;span style="color: #ff0000;"&gt;'\.php$|^/update.php'&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      fastcgi_split_path_info ^&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;.+?\.php&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;|/&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;$;
      &lt;span style="color: #666666; font-style: italic;"&gt;# Ensure the php file exists. Mitigates CVE-2019-11043&lt;/span&gt;
      try_files &lt;span style="color: #007800;"&gt;$fastcgi_script_name&lt;/span&gt; =&lt;span style="color: #000000;"&gt;404&lt;/span&gt;;
      &lt;span style="color: #666666; font-style: italic;"&gt;# Security note: If you're running a version of PHP older than the&lt;/span&gt;
      &lt;span style="color: #666666; font-style: italic;"&gt;# latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.&lt;/span&gt;
      &lt;span style="color: #666666; font-style: italic;"&gt;# See http://serverfault.com/q/627903/94922 for details.&lt;/span&gt;
      include fastcgi_params;
      &lt;span style="color: #666666; font-style: italic;"&gt;# Block httpoxy attacks. See https://httpoxy.org/.&lt;/span&gt;
      fastcgi_param HTTP_PROXY &lt;span style="color: #ff0000;"&gt;""&lt;/span&gt;;
      fastcgi_param SCRIPT_FILENAME &lt;span style="color: #007800;"&gt;$document_root&lt;/span&gt;&lt;span style="color: #007800;"&gt;$fastcgi_script_name&lt;/span&gt;;
      fastcgi_param PATH_INFO &lt;span style="color: #007800;"&gt;$fastcgi_path_info&lt;/span&gt;;
      fastcgi_param QUERY_STRING &lt;span style="color: #007800;"&gt;$query_string&lt;/span&gt;;
      fastcgi_intercept_errors on;
      &lt;span style="color: #666666; font-style: italic;"&gt;# PHP 5 socket location.&lt;/span&gt;
      &lt;span style="color: #666666; font-style: italic;"&gt;#fastcgi_pass unix:/var/run/php5-fpm.sock;&lt;/span&gt;
      &lt;span style="color: #666666; font-style: italic;"&gt;# PHP 7 socket location.&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;#      fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;&lt;/span&gt;
      fastcgi_pass fpm:&lt;span style="color: #000000;"&gt;9000&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# S3FS Module&lt;/span&gt;
    location ~ ^&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;s3&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;styles&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      try_files &lt;span style="color: #007800;"&gt;$uri&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;rewrite;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    location ~&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt; \.&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;js&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;css&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;png&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;jpg&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;jpeg&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;gif&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;ico&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;svg&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      try_files &lt;span style="color: #007800;"&gt;$uri&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;rewrite;
      expires max;
      log_not_found off;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Fighting with Styles? This little gem is amazing.&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# location ~ ^/sites/.*/files/imagecache/ { # For Drupal &lt;= 6&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;#location ~ ^/sites/.*/files/styles/ { # For Drupal &gt;= 7&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;#  try_files $uri @rewrite;&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;#}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Handle private files through Drupal. Private file's path can come&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# with a language prefix.&lt;/span&gt;
    location ~ ^&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;a-z\-&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;+&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;?&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;system&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;# For Drupal &gt;= 7&lt;/span&gt;
      try_files &lt;span style="color: #007800;"&gt;$uri&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;index.php?&lt;span style="color: #007800;"&gt;$query_string&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #666666; font-style: italic;"&gt;# Enforce clean URLs&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# Removes index.php from urls like www.example.com/index.php/my-page --&gt; www.example.com/my-page&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# Could be done with 301 for permanent or other redirect codes.&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #007800;"&gt;$request_uri&lt;/span&gt; ~&lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"^(.*/)index\.php/(.*)"&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;307&lt;/span&gt; &lt;span style="color: #007800;"&gt;$1&lt;/span&gt;&lt;span style="color: #007800;"&gt;$2&lt;/span&gt;;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
  &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;strong&gt;Dockerfile&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;FROM nginx:1.21.1-alpine
COPY .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default.conf &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;conf.d&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
COPY .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx.conf &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Some commentary is required here. You'll see in the default.conf file there is a snippet:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# S3FS Module&lt;/span&gt;
    location ~ ^&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;s3&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;styles&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
      try_files &lt;span style="color: #007800;"&gt;$uri&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;rewrite;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
This is because the assets are not served locally - they are stored in an AWS S3 bucket with the AWS CloudFront accelerator providing edge capabilities. I will provide a further blog at a later date on setting all this up but in essence, assets shouldn't be kept in individual Fargate tasks, so either an AWS S3 / CloudFront solution needs to be utilised or an AWS EFS drive. &lt;br /&gt;&lt;br /&gt;
Now let's see what the differences are between the local configuration and Fargate. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;diff&lt;/span&gt; docker&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default.conf docker&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;fargate&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default.conf 
2c2
&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;     server_name badzilla-fargate.test;
&lt;span style="color: #660033;"&gt;---&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     server_name badzilla.co.uk www.badzilla.co.uk;
4a5,&lt;span style="color: #000000;"&gt;10&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     &lt;span style="color: #666666; font-style: italic;"&gt;# User Agent ELB-HealthChecker sends no headers with the request so nginx by default will respond with a 400&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     &lt;span style="color: #666666; font-style: italic;"&gt;# Fix with this&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     location = &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;health &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;         &lt;span style="color: #7a0874; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;200&lt;/span&gt;;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     &lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; 
92c98
&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;       fastcgi_pass fpm:&lt;span style="color: #000000;"&gt;9000&lt;/span&gt;;
&lt;span style="color: #660033;"&gt;---&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;       fastcgi_pass 127.0.0.1:&lt;span style="color: #000000;"&gt;9000&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Ok there are three differences. The first is obvious - I am using different server names dependent on the environment. The second difference is the AWS health checking capability that I have included for Fargate but not needed locally. I use the Drupal health_check module by the way, but the problem resides with the AWS Application Load Balancer health check feature. It sends requests to nginx without headers which nginx doesn't like - and always replies with a 400 response. This snippet fixes that problem. The third difference relates to how Fargate handles Docker networking. It is much simplified and all containers in the Fargate task use 127.0.0.1 for communication. Locally I am using a label named &lt;strong&gt;fpm&lt;/strong&gt; for fastcgi_pass communication between nginx and FPM.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;docker-compose: MariaDB and Memcached&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The use of MariaDB is the most significant difference between the local environment and Fargate. Fargate connects to a MariaDB instance in AWS RDS, whilst the local MariaDB persists its data in the VM. I did consider using another RDS instance for local development, but that would require public access to the database which I wasn't keen to do for security reasons. In addition there is a cost implication which isn't viable for a hobby project like my blog. I am using the standard Docker images for both MariaDB and Memcached locally.&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;docker-compose Configuration&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;strong&gt;docker-compose&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;version: &lt;span style="color: #ff0000;"&gt;"3"&lt;/span&gt;
 
services:
  mariadb:
    image: &lt;span style="color: #ff0000;"&gt;"mariadb:&lt;span style="color: #007800;"&gt;${MARIADB_VERSION}&lt;/span&gt;"&lt;/span&gt;
    restart: &lt;span style="color: #ff0000;"&gt;'always'&lt;/span&gt;
    container_name: mariadb-drupal
    volumes:
      - &lt;span style="color: #ff0000;"&gt;"/var/lib/mysql/data:&lt;span style="color: #007800;"&gt;${MARIADB_DATA_DIR}&lt;/span&gt;"&lt;/span&gt;
      - &lt;span style="color: #ff0000;"&gt;"/var/lib/mysql/logs:&lt;span style="color: #007800;"&gt;${MARIADB_LOG_DIR}&lt;/span&gt;"&lt;/span&gt;
      - &lt;span style="color: #ff0000;"&gt;"/var/docker/mariadb/conf:/etc/mysql"&lt;/span&gt;
    environment:
      MYSQL_ROOT_PASSWORD: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_ROOT_PASSWORD}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_DATABASE: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_DATABASE}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_USER: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_USER}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_PASSWORD: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_PASSWORD}&lt;/span&gt;"&lt;/span&gt;
  drupal:
    image: core-drupal:latest
    container_name: core-drupal
    depends_on:
      - mariadb
      - memcached
    volumes:
      - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;opt&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;drupal
    restart: &lt;span style="color: #ff0000;"&gt;'always'&lt;/span&gt;
    environment:
      MYSQL_DATABASE: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_DATABASE}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_USER: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_USER}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_PASSWORD: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_PASSWORD}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_HOSTNAME: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_HOSTNAME}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_NAMESPACE: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_NAMESPACE}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_DRIVER: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_DRIVER}&lt;/span&gt;"&lt;/span&gt;
      MYSQL_PORT: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MYSQL_PORT}&lt;/span&gt;"&lt;/span&gt;
      AH_SITE_ENVIRONMENT: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${AH_SITE_ENVIRONMENT}&lt;/span&gt;"&lt;/span&gt;
      S3FS_ACCESS_KEY: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_ACCESS_KEY}&lt;/span&gt;"&lt;/span&gt;
      S3FS_SECRET_KEY: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_SECRET_KEY}&lt;/span&gt;"&lt;/span&gt;
      S3FS_BUCKET: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_BUCKET}&lt;/span&gt;"&lt;/span&gt;
      S3FS_AWS_REGION: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_AWS_REGION}&lt;/span&gt;"&lt;/span&gt;
      S3FS_CLOUDFRONT_CNAME: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_CLOUDFRONT_CNAME}&lt;/span&gt;"&lt;/span&gt;
      S3FS_USE_S3_PUBLIC: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_USE_S3_PUBLIC}&lt;/span&gt;"&lt;/span&gt;
      S3FS_USE_CNAME: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_USE_CNAME}&lt;/span&gt;"&lt;/span&gt;
      S3FS_USE_HTTPS: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_USE_HTTPS}&lt;/span&gt;"&lt;/span&gt;
      S3FS_TWIG_PATH: &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${S3FS_TWIG_PATH}&lt;/span&gt;"&lt;/span&gt;
 
  nginx:
    image: nginx-drupal:latest
    container_name: nginx-drupal
    links:
      - drupal:fpm
    ports:
      - &lt;span style="color: #ff0000;"&gt;"80:80"&lt;/span&gt;
      - &lt;span style="color: #ff0000;"&gt;"443:443"&lt;/span&gt;
    depends_on:
      - drupal
    restart: &lt;span style="color: #ff0000;"&gt;'always'&lt;/span&gt;
    volumes:
      - .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;opt&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;drupal
  memcached:
    image: memcached:alpine3.14
    restart: &lt;span style="color: #ff0000;"&gt;'always'&lt;/span&gt;
    container_name: memcached-drupal
    ports:
      - &lt;span style="color: #ff0000;"&gt;"11211:11211"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Note I have all my settings held in the environment. I also use the vlucas/phpdotenv composer dependency so these environmental variables are accessible in Drupal through a dot env file.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Shortcuts&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-09/Screenshot%202021-09-26%20at%2011.33.54-scaled.png?itok=ZK1WZKNL 325w, https://assets.badzilla.co.uk/styles/max_650x650/s3/2021-09/Screenshot%202021-09-26%20at%2011.33.54-scaled.png?itok=5u4dc1HE 650w, https://assets.badzilla.co.uk/styles/max_1300x1300/s3/2021-09/Screenshot%202021-09-26%20at%2011.33.54-scaled.png?itok=4Rdov1w4 1300w, https://assets.badzilla.co.uk/styles/max_2600x2600/s3/2021-09/Screenshot%202021-09-26%20at%2011.33.54-scaled.png?itok=9Jbps5Ok 1500w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/styles/max_325x325/s3/2021-09/Screenshot%202021-09-26%20at%2011.33.54-scaled.png?itok=ZK1WZKNL" alt="start-web" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Remembering commands to build the Docker images, gain command line access to MariaDB, importing and exporting databases etc is an exercise in tedium I'd rather avoid. I have built a make file with shortcuts although command line aliases could also have been used.&lt;br /&gt;
&lt;strong&gt;Makefile&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;.DEFAULT_GOAL := &lt;span style="color: #7a0874; font-weight: bold;"&gt;help&lt;/span&gt;
 
 
help:
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"See the README.md for available options"&lt;/span&gt;
 
exportdb: set-env
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Exporting the database"&lt;/span&gt;
	docker &lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt; &lt;span style="color: #660033;"&gt;-i&lt;/span&gt; mariadb-drupal &lt;span style="color: #c20cb9; font-weight: bold;"&gt;bash&lt;/span&gt; &lt;span style="color: #660033;"&gt;-c&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'mysqldump -u $$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;file&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
importdb: set-env
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Importing the database"&lt;/span&gt;
	docker &lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt; &lt;span style="color: #660033;"&gt;-i&lt;/span&gt; mariadb-drupal &lt;span style="color: #c20cb9; font-weight: bold;"&gt;bash&lt;/span&gt; &lt;span style="color: #660033;"&gt;-c&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'mysql -u $$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt; $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;file&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
core-drupal: set-env
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Building Drupal Core Docker from Official Image"&lt;/span&gt;
	docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; core-drupal .
 
composer-require:
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Composer require running"&lt;/span&gt;
	docker run &lt;span style="color: #660033;"&gt;--rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;--interactive&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tty&lt;/span&gt; &lt;span style="color: #660033;"&gt;--volume&lt;/span&gt; $&lt;span style="color: #007800;"&gt;$PWD&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;app  &lt;span style="color: #660033;"&gt;--volume&lt;/span&gt; $&lt;span style="color: #800000;"&gt;${COMPOSER_HOME:-$$HOME/.composer}&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tmp composer require &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$(module)&lt;/span&gt;"&lt;/span&gt;  &lt;span style="color: #660033;"&gt;--ignore-platform-reqs&lt;/span&gt;
 
build-all: set-env
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Building all non-standard docker images ready for spinning up docker-compose"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; docker&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;local&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; nginx-drupal .
	docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; core-drupal .
 
start-web: set-env
	docker-compose up
 
stop-web:
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Stopping the web app gracefully. Please wait"&lt;/span&gt;
	docker-compose down
 
set-env:
	&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Setting the env variables"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;export&lt;/span&gt; $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; .env &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #660033;"&gt;-v&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'^#'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'\S'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;tr&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'\r'&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'\0'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;xargs&lt;/span&gt; &lt;span style="color: #660033;"&gt;-0&lt;/span&gt; -n1&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
So for instance should I want to build the codebase and nginx Docker images I would simply type:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; build-all&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
To add a new module using composer, the syntax would be:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; composer-require &lt;span style="color: #007800;"&gt;module&lt;/span&gt;=drupal&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;module_name&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Note the requirement to use key=value for parameter substitution in make. Similarly to import a database dump it would be:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; importdb &lt;span style="color: #007800;"&gt;file&lt;/span&gt;=mydump.sql&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Not included in the make commands because of its interactive nature, to gain access to MariaDB do:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;docker &lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt; &lt;span style="color: #660033;"&gt;-it&lt;/span&gt; mariadb-drupal mysql &lt;span style="color: #660033;"&gt;-uusername&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ppassword&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Finally when you do:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; start-web&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
you should see output similar to the screenshot above!&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Drush&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;It's important to have Drush available in your local environment. To achieve this, ensure that drush is a dependency requirement in your composer.json file. If not add it using my shortcut mentioned earlier. This will place drush in path /opt/drupal/vendor/bin inside the drupal-core container which obviously must be running for it to work. Exec-ing a command from the VM command line and escaping it correctly is hard work - so to save you the heartache I've created a shell function in my VM to make light work of it. If you are not using my VM, add this to the bottom of your &lt;strong&gt;/etc/bash.bashrc&lt;/strong&gt; file. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;drush&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
  &lt;span style="color: #007800;"&gt;PARAMS&lt;/span&gt;=$&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;
  &lt;span style="color: #007800;"&gt;CONTAINER&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"core-drupal"&lt;/span&gt;
  &lt;span style="color: #007800;"&gt;CMD&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"sh -c &lt;span style="color: #000099; font-weight: bold;"&gt;\"&lt;/span&gt;/opt/drupal/vendor/bin/drush &lt;span style="color: #007800;"&gt;${PARAMS}&lt;/span&gt;&lt;span style="color: #000099; font-weight: bold;"&gt;\"&lt;/span&gt;"&lt;/span&gt;
  &lt;span style="color: #007800;"&gt;DCMD&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"docker exec -it &lt;span style="color: #007800;"&gt;$CONTAINER&lt;/span&gt; &lt;span style="color: #007800;"&gt;$CMD&lt;/span&gt;"&lt;/span&gt;
  &lt;span style="color: #7a0874; font-weight: bold;"&gt;eval&lt;/span&gt; &lt;span style="color: #007800;"&gt;$DCMD&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now any Drush command is available to you (when the container is running!)
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;drush cr
 &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;success&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; Cache rebuild complete.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/php" hreflang="en"&gt;PHP&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/drupal" hreflang="en"&gt;Drupal&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/taxonomy/term/121" hreflang="en"&gt;Drupal 9&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Sun, 19 Sep 2021 08:46:14 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">181 at http://badzilla.co.uk</guid>
    </item>

  </channel>
</rss>
