CI for Laravel

Using Docker

Chipper CI supports the use of Docker during builds.

Docker is currently only available as a paid feature.

Docker is most commonly used for Laravel Vapor deployments when using the Docker Runtime.

Chipper CI supports deploying Vapor ARM64 images.

Enable Docker

You can enable Docker in your .chipperci.yml file:

version: 1

environment:
  php: 8.3
  node: 18

# Add docker as a service to your build
services:
  - docker:

pipeline:
  - name: Setup
    cmd: composer install

You can see a complete Yaml example here.

If you are not using a .chipperci.yml file, Docker support needs to be enabled within your project settings.

Docker environment settings

Once that is enabled, future builds can use the docker command.

If you're using Docker for Vapor deployments, everything should Just Work™ without any docker-specific configuration within your Chipper CI builds.

Rate Limits and Authenticating

Docker Hub rate-limits how often we can run a docker pull to download images. They track this based on the IP address they see API calls made from. As a result, it's possible you'll receive an error similar to this:

ERROR: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit

To get around this, you can authenticate against a (free) Docker hub account. You can create a Docker account here.

Once your account is created, you can add the username/password as Secrets in Chipper CI, and use them to authenticate before running a vapor deploy or other action that results in pulling Docker images:

# Assuming DOCKER_USER and DOCKER_PASS are defined
# as env vars or, preferably, secrets in Chipper
# Format "docker login -u USERNAME -p PASSWORD" is likely to fail
echo -n $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin

Alternatively, you can authenticate using DOCKER_AUTH_CONFIG as an environment variable. The content of that variable should be the same as a ~/.docker/config.json file (which contains auth credentials in JSON). Example content for that env variable can be found here.

This can be set as a Secret within Chipper CI as well.

Remote Docker

For security, we run Docker on a remote server dedicated to each build. Anytime the docker command is run, it will be running commands against the assigned remote server.

This has certain ramifications explained below.

You can read some interesting details about how Chipper runs Remote Docker instances here.

Port Binding

Since Docker is run on a remote machine, you can't use localhost nor 127.0.0.1 to access a running container.

Instead, use the DOCKER_HOST_IP environment variable:

docker run --rm -d -p 80:80 nginx:alpine
sleep 3

curl http://$DOCKER_HOST_IP

Volume Mounting

Volume Mounting will not work - Docker cannot share volumes from the "local" build server to the remote Docker server.

The following commands, therefore, won't work as expected:

# This attempts to mount the current
# directory to /var/www/html in the container
docker run \
    -v $(pwd):/var/www/html \
    -p 80:80 some-image:latest

The equivalent docker-compose.yml configuration has the same issue.

However, building from a Dockerfile does work!

Using the COPY and ADD instructions in a Dockerfile, Docker will copy files between the build server and the remote Docker server.

This means you can build a docker image during a build to get application files into an image.

For example, pretend we have a file in our repository named ./docker/Dockerfile:

# A base image that has everything
# pre-installed onto it
FROM my-base-image:latest

# Copy current dir into the image
COPY . /var/www/html

# You may need a .env.ci file ready
# to copy in as well
COPY ./.env.ci /var/www/html/.env

This Dockerfile can be built into an image:

# Build a Docker image that copys
# our code base into it
docker build -t some-image:latest -f ./docker/Dockerfile .

# Run the newly built image
docker run --rm -d -p 80:80 some-image:latest

sleep 5 # Give the container time to start

# Make a request against the container
curl http://$DOCKER_HOST_IP

Currently, Chipper CI has no cache for Docker images.

Docker Environment Variables

If the docker command finds a DOCKER_HOST environment variable, it will attempt to send API requests to the value of that variable.

Since Chipper CI runs Docker on a remote server, it makes use of that environment variable.

We also include a few extra environment variables as well. The following environment variables are set in a build when Docker is enabled:

# The IP address will change on each build
DOCKER_HOST="111.11.11.111:2375"
DOCKER_HOST_IP="111.11.11.111"
DOCKER_HOST_PORT="2375"