Cache composer dependencies for faster builds in aws codebuild.
Tags: howto, aws, php, devops
Published: 2020-04-30 08:16:37

Sometimes it is good idea to cache anything you download continiously in your builds so you can speed up things. So le us asume we have the following buildspec.yml for your php project (and to spice things up let us assume that it is a laravel project, though it does not matter):

```
version: 0.2

phases:
  build:
    commands:
        - composer install

artifacts:
  files:
    - app/**/*
    - bootstrap/**/*
    - config/**/*
    - database/**/*
    - machine/**/*
    - public/**/*
    - resources/**/*
    - routes/**/*
    - scripts/**/*
    - vendor/**/*
    - .env
    - artisan
    - composer.json
```

In the build above `composer install` will download its dependencies on every build. Keep in mind that in aws codebuild, builds are executed in isolated, disposable containers. So sometimes `composer install` can fail especially on frequent builds due to composer's throttling.

So as a countermeasure we need to cache the composers folders that uses on its own as cache. Also to keep it available on each build we will st ore it into an s3 as well. 

So in order to do that we need to follow these maijor steps:
1. Edit our build so the build can use the s3 as cache. In this step is assumes that there's already a bucket for caching.
2. Specify the folders that uses the composer as cache.

# Edit our codebuild to use s3 as caching:

In order to do so edit your build's artifacts as the screenshot shows

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/x01sje3h4v4cgxgg8uow.png)

And specify an s3 bucket to codebuild. In order to avoid using multiple buckets specify a prefix as well:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ipsqwgxfduyd0zki2w55.png)

In case you haver the error:
>  The policy's default version, v5, was not created by enhanced zero click role creation or was not the most recent version created by enhanced zero click role creation

Untick the `Allow AWS Codebuild to modify this service role so it can be used with this build project.`. 

# Specify composer's caching folder as a folder that needs caching:

The composer uses the environmental variable `COMPOSER_CACHE_DIR` in order to knows where to cache its dependencies. So we need to specify this environmental variable into an appropriate path. Then we need to specify this path as a folder to be cached with any subfolders inside.

Also I need specify a path in the `COMPOSER_CACHE_DIR` variable, because the aws codebuild can't cache any folder outside the ones that the codebuild uses to store the source code pulled from previous steps.

So in our case the `buildspec.yml` will be as follows:

```
version: 0.2

env:
  variables:
    COMPOSER_CACHE_DIR: .cache/composer

phases:
  install:
    commands:
      - mkdir -p .cache/composer
  
  build:
    commands:
      - composer install

cache:
  paths:
    - .cache/composer/**/*
```

The `COMPOSER_CACHE_DIR: .cache/composer` populates the enviromental variable with the path that the compoiser needs to use as a cache.

Also with this part of `buildspec.yml`:

```
cache:
  paths:
    - .cache/composer/**/*
```

We specify the folders that we need to cache.