AWS CodeBuild is a fully managed build service that compiles source code, runs tests, and produces software packages ready for deployment. Out of the box, CodeBuild ships with curated build environments for common runtimes including Java, Ruby, Python, Go, Node.js, Android, and Docker. When your project requires a runtime not covered by these defaults — such as PHP, Rust, or a bespoke internal toolchain — you can supply your own Docker image as a custom build environment.
Build environments are Docker images that contain a complete file system with everything required to build and test a project. To use a custom environment, you:
- Build a Docker image that contains your required tools.
- Push the image to a container registry — typically Amazon Elastic Container Registry (ECR).
- Reference that image in your CodeBuild project configuration.
When a build runs, CodeBuild pulls the specified Docker image from the registry and uses it to compile source code, run tests, and package the application.
This article walks through creating a custom PHP build environment and wiring it into a CodeBuild project, following the pattern published by the AWS CodeBuild team. The companion repository used throughout is awslabs/codebuild-images on GitHub.
Prerequisites
Before starting, make sure the following tools are installed and configured on your workstation:
- Docker — to build and push container images.
- AWS CLI — to interact with CloudFormation, ECR, and CodeBuild.
- Git — to clone the example repository and push sample code to CodeCommit.
- An IAM user or role with permissions to create CloudFormation stacks, push to ECR, write to CodeCommit, and create CodeBuild projects.
Step 1 — Create the Demo Resources with CloudFormation
The awslabs/codebuild-images repository contains a CloudFormation template (template.yml) that provisions two resources:
- A CodeCommit repository to host the PHP sample application source code.
- An ECR repository to host the custom Docker build environment image.
Clone the repository and deploy the stack:
git clone https://github.com/awslabs/codebuild-images.git
cd codebuild-imagesCode language: PHP (php)
aws cloudformation create-stack \
--stack-name codebuild-php \
--parameters ParameterKey=EnvName,ParameterValue=php \
--template-body file://template.yml > /dev/null && \
awscloudformation wait stack-create-complete \
--stack-name codebuild-php && \
aws cloudformation describe-stacks \
--stack-name codebuild-php \
--output table \
--query Stacks[0].OutputsCode language: JavaScript (javascript)
Once the stack is created, CloudFormation outputs two values that you will use in subsequent steps:
- BuildImageRepositoryUri — the URI of the ECR repository that will host the build environment image.
- SourceCodeRepositoryCloneUrl — the HTTPS clone URL of the CodeCommit repository for the sample PHP application.
Step 2 — Build and Push the Custom Docker Image
The PHP build environment image is defined by the Dockerfile inside the php/ directory of the cloned repository. It extends the official PHP 7 Docker image and adds the tooling needed for a typical CI pipeline:
FROM php:7
ARG composer_checksum=55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30
ARG composer_url=https://raw.githubusercontent.com/composer/getcomposer.org/ba0141a67b9bd1733409b71c28973f7901db201d/web/installer
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV PATH=$PATH:vendor/bin
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
python-dev \
python-pip \
zlib1g-dev \
&& pip install awscli \
&& docker-php-ext-install zip \
&& curl -o installer "$composer_url" \
&& echo "$composer_checksum *installer" | shasum -c -a 384 \
&& php installer --install-dir=/usr/local/bin --filename=composer \
&& rm -rf /var/lib/apt/lists/*Code language: PHP (php)
This image layers the following on top of the official PHP runtime:
- Composer — the PHP dependency manager, installed with checksum verification.
- AWS CLI — enables build steps to interact with AWS services (for example, publishing an SNS notification on build completion or writing artifacts to S3).
- Git — enables build steps such as tagging a release commit after a successful build.
- zip extension — required by many PHP projects and Composer plugins.
The final rm -rf /var/lib/apt/lists/* instruction removes the APT package index to reduce image size, following Dockerfile best practices.
To build and push the image, first authenticate the local Docker daemon with ECR:
aws ecr get-login-password | docker login \
--username AWS \
--password-stdin <account-id>.dkr.ecr.<region>.amazonaws.comCode language: HTML, XML (xml)
Then build and push the image, substituting the BuildImageRepositoryUri value from the CloudFormation outputs:
cd php
docker build -t [BuildImageRepositoryUri] .
docker push [BuildImageRepositoryUri]Code language: CSS (css)
Once the push completes, the image is available in ECR and ready to be referenced by CodeBuild.
Step 3 — Configure the Source Repository
The cloned repository includes a small PHP sample application that converts Roman numerals to Arabic numerals, together with a PHPUnit test. It also contains a buildspec.yml file — the YAML manifest CodeBuild reads to determine what commands to run:
version: 0.1
phases:
pre_build:
commands:
- composer install
build:
commands:
- phpunit testsCode language: CSS (css)
This build spec instructs CodeBuild to:
- Run
composer installduring thepre_buildphase to fetch declared dependencies, including PHPUnit. - Run
phpunit testsduring thebuildphase to execute the test suite.
Push the sample application to the CodeCommit repository created by the CloudFormation stack. Before doing so, ensure your IAM user has the necessary CodeCommit permissions and that your Git client is configured with the correct credentials. See the CodeCommit HTTPS setup guide for detailed instructions.
cd sample
git init
git add .
git commit -m "Initial commit"
git remote add origin [SourceCodeRepositoryCloneUrl]
git push origin masterCode language: JavaScript (javascript)
Step 4 — Configure the CodeBuild Project
With the Docker image in ECR and the source code in CodeCommit, create and configure the CodeBuild project from the AWS Management Console:
- Open the AWS CodeBuild console and choose Create project.
- Set Project name to
php-demo. - Under Source provider, choose AWS CodeCommit, then select the codebuild-sample-php repository.
- Under Environment image, select Specify a Docker image. Set Custom image type to Amazon ECR, choose the codebuild/php ECR repository, and select the latest image tag.
- Under Build specification, select Use the buildspec.yml in the source code root directory.
- Set Artifacts type to No artifacts (this demo only runs tests).
- Choose Continue, then Save and Build.
- On the start build page, select the master branch and choose Start build.
CodeBuild will pull the custom PHP image from ECR and execute the build spec commands. The console shows the status of each build phase, the last 20 lines of build output, and a link to the full log stream in Amazon CloudWatch Logs.

How Custom Environments Fit into a Broader CI/CD Pipeline
Custom build environments unlock several practical use cases beyond language support:
- Pinned tool versions — Embed a specific version of a compiler, linter, or test framework so every build uses identical tooling regardless of when it runs.
- Internal toolchains — Package proprietary or licensed software that cannot be installed from public package managers.
- Pre-warmed dependencies — Bake large dependency sets into the image to reduce per-build install time.
- Security hardening — Strip unnecessary packages from the base image and apply your organisation’s security baselines before builds run.
Images should be rebuilt and re-pushed to ECR whenever underlying dependencies (OS packages, runtimes, Composer, AWS CLI) receive security updates. Tag images with explicit version strings rather than relying solely on latest for production pipelines, so you can roll back to a known-good environment if a new image introduces a regression.
Summary
AWS CodeBuild’s support for custom Docker build environments means the service is not limited to its bundled runtimes. Any language or toolchain that can be containerised can be used as a CodeBuild environment. The process follows three consistent steps: build a Docker image with your required tools, push it to Amazon ECR, and reference it in your CodeBuild project configuration. The PHP walkthrough above demonstrates this pattern end-to-end, from provisioning infrastructure with CloudFormation to triggering a passing build in the console.
The same approach applies to any runtime — Go versions not yet curated by AWS, older JDKs, niche testing frameworks, or heavily customised base images — making CodeBuild a flexible foundation for continuous integration across heterogeneous technology stacks.