Configuring Docker Operations
1. Setting Up Remote Docker
| Property | Value | Description |
|---|---|---|
| docker | remote |
Specifies that CircleCI should use remote Docker execution environment |
| image | circleci/node:18 |
Docker image to run the job in |
| working_directory | /home/circleci/project |
Working directory inside the container |
Example: Basic Remote Docker Configuration
version: 2.1
jobs:
build:
docker:
- image: circleci/node:18
environment:
NODE_ENV: test
working_directory: /home/circleci/project
steps:
- checkout
- run: npm install
Note: Remote Docker is the default execution environment in CircleCI 2.1 and later.
Warning: Ensure that your Docker image includes all necessary dependencies for your build process.
2. Enabling Docker Layer Caching
Note: Docker layer caching in CircleCI significantly reduces build times by reusing previously downloaded or built layers.
| Configuration Key | Description | Values | Notes |
|---|---|---|---|
| docker | Enables Docker support in the job | true |
Required to enable Docker layer caching |
| cache-from | Specifies Docker images to use for layer caching | circleci/<image-name>:<tag> |
Can be a list of images |
Example: Using cache-from in a CircleCI config
version: 2.1
jobs:
build:
docker:
- image: circleci/<span class="highlight">node</span>:18
environment:
<span class="highlight">DOCKER_BUILDKIT</span>: 1
- image: circleci/<span class="highlight">postgres</span>:13
steps:
- checkout
- run: |
docker build --cache-from circleci/<span class="highlight">node</span>:18 -t my-app .
- save_cache:
key: v1-dependencies-{{ checksum <span class="highlight">"package-lock.json"</span> }}
paths:
- <span class="highlight">node_modules</span>
Example: Using cache-from with multiple images
version: 2.1
jobs:
build:
docker:
- image: circleci/<span class="highlight">node</span>:18
environment:
<span class="highlight">DOCKER_BUILDKIT</span>: 1
- image: circleci/<span class="highlight">postgres</span>:13
steps:
- checkout
- run: |
docker build --cache-from circleci/<span class="highlight">node</span>:18 --cache-from circleci/<span class="highlight">postgres</span>:13 -t my-app .
- save_cache:
key: v1-dependencies-{{ checksum <span class="highlight">"package-lock.json"</span> }}
paths:
- <span class="highlight">node_modules</span>
Key Benefits of Docker Layer Caching
- Reduces build times by reusing layers from previous builds
- Improves CI/CD pipeline efficiency
- Works best with
DOCKER_BUILDKIT=1
Warning: Ensure that the cache keys are stable and consistent to avoid cache misses.
3. Building Docker Images
| Property | Description | Example |
|---|---|---|
| build | Defines the Docker image build configuration | build: . |
| context | Specifies the build context directory | context: ./app |
| dockerfile | Path to the Dockerfile | dockerfile: ./Dockerfile.prod |
| tags | Tags to apply to the built image | tags: [latest, v1.0] |
Note: The
context is the directory from which Docker reads files to build the image.
Warning: Ensure Dockerfile is in the correct path and context is set properly to avoid build errors.
4. Tagging Docker Images
| Tag Type | Description | Example | Notes |
|---|---|---|---|
| circleci/docker-tag | Standard Docker image tag format | circleci/docker-tag:latest |
Used for versioning Docker images in CircleCI |
| circleci/docker-tag:branch | Tag based on Git branch name | circleci/docker-tag:feature-branch |
Helps identify images built from specific branches |
| circleci/docker-tag:commit | Tag based on Git commit SHA | circleci/docker-tag:abc12345 |
Ensures uniqueness for each build |
Example: Using CircleCI's built-in Docker tagging
version: 2.1
jobs:
build:
docker:
- image: circleci/python:3.9
steps:
- checkout
- setup_remote_docker
- run:
name: Build Docker image with tag
command: |
docker build -t circleci/python:3.9-${CIRCLE_SHA1} .
Note: CircleCI automatically sets
CIRCLE_SHA1 to the short Git commit hash, which is useful for uniquely tagging Docker images.
Warning: Avoid using
latest as a tag in production environments, as it can lead to unpredictable behavior when images are updated.
5. Pushing to Registries
| Registry | Push Command | Notes |
|---|---|---|
| Docker Hub | docker push <username>/<image> |
Requires Docker Hub account and image repository |
| Amazon ECR | docker push <aws-account-id>.dkr.ecr.<region>.amazonaws.com/<repository> |
Needs AWS CLI configured with appropriate permissions |
| Google Container Registry (GCR) | docker push gcr.io/<project-id>/<image> |
Requires gcloud CLI and project setup |
| Azure Container Registry (ACR) | docker push <registry-name>.azurecr.io/<image> |
Authentication via Azure CLI or service principal |
Example: Pushing to Docker Hub
docker build -t myapp .
docker tag myapp <username>/myapp:latest
docker push <username>/myapp:latest
Example: Pushing to Amazon ECR
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<region>.amazonaws.com
docker build -t <aws-account-id>.dkr.ecr.<region>.amazonaws.com/<repository> .
docker push <aws-account-id>.dkr.ecr.<region>.amazonaws.com/<repository>
Note: Ensure that your CircleCI environment has the necessary credentials and permissions to push to the target registry.
6. Authenticating with Docker Hub
| Option | Values | Notes |
|---|---|---|
| docker.login | true |
Enables automatic login to Docker Hub |
| docker.username | process.env.DOCKER_USERNAME |
Environment variable for Docker Hub username |
| docker.password | process.env.DOCKER_PASSWORD |
Environment variable for Docker Hub password |
Example: Configuring Docker Login in CircleCI
version: 2.1
jobs:
build:
docker:
- image: circleci/node:16
steps:
- checkout
- run:
name: Login to Docker Hub
command: |
echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
- run:
name: Build and Push Image
command: |
docker build -t my-app .
docker push my-app
Note: Store Docker credentials as CircleCI environment variables to avoid exposing them in config files.
Warning: Using
docker login with a password is less secure than using a personal access token (PAT). Consider using PATs for better security.
7. Using Private Registries
| Registry Type | Authentication Method | Configuration Example | Notes |
|---|---|---|---|
| Docker Hub | docker login |
docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD |
Requires Docker Hub credentials stored as CircleCI environment variables |
| Amazon ECR | AWS credentials via aws configure |
eval $(aws ecr get-login --region us-east-1 --no-include-email) |
Uses AWS CLI to fetch temporary login credentials |
| Google Container Registry (GCR) | Service account key JSON | gcloud auth activate-service-account --key-file=service-account.json |
Requires GCP project and service account setup |
| Azure Container Registry (ACR) | Azure CLI login | az acr login --name myregistry |
Uses Azure CLI to authenticate with ACR |
Example: Using a Private Docker Image from ECR
version: 2.1
jobs:
build:
docker:
- image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
steps:
- checkout
- run:
name: Run application
command: |
echo "Running application from private ECR image"
Note: Ensure that the CircleCI project has appropriate AWS IAM permissions to access ECR repositories.
Warning: Never hardcode credentials in CircleCI configuration files. Always use environment variables or CircleCI context secrets.
8. Using Docker Compose
| Property | Description | Example |
|---|---|---|
| docker-compose.yml | File defining services, networks, and volumes for Docker Compose | version: '3.8' |
| services | Defines the containers to run in the CircleCI job | app: |
| image | Specifies the Docker image to use for a service | image: node:18 |
| ports | Maps container ports to host ports | ports: ["3000:3000"] |
| volumes | Mounts directories or files into the container | volumes: ['./:/app'] |
| environment | Sets environment variables in the container | environment: NODE_ENV: production |
Example: Running a Node.js App with Docker Compose
version: '3.8'
services:
app:
image: node:18
working_dir: /app
command: npm run start
ports:
- "3000:3000"
volumes:
- .:/app
environment:
NODE_ENV: production
Note: CircleCI supports Docker Compose v2 and v3 formats. Ensure your
docker-compose.yml is compatible with the version used by CircleCI.
Warning: Avoid using
docker-compose up in CircleCI workflows. Use the circleci/cli or setup_remote_docker steps instead.
Key Points
- Docker Compose files define multi-container applications.
- CircleCI supports
docker-compose.ymlfor defining services and dependencies. - Use
setup_remote_dockerto enable Docker Compose in CircleCI. - Environment variables and volumes can be configured in the
docker-compose.yml.
9. Running Multi-Container Tests
| Option | Values | Notes |
|---|---|---|
| docker | docker |
Use Docker for multi-container testing |
| service | service |
Define services to run in containers |
| test | test |
Run tests in the container environment |
Example: Running Multi-Container Tests
version: 2.1
jobs:
test:
docker:
- image: circleci/node:16
environment:
NODE_ENV: test
- image: circleci/mongo:4.0
environment:
MONGO_INITDB_ROOT_USERNAME: testuser
MONGO_INITDB_ROOT_PASSWORD: testpass
steps:
- checkout
- run:
name: Run Tests
command: npm test
Note: Ensure that your test containers are properly configured to communicate with each other using service names as hostnames.
10. Optimizing Docker Builds
| Optimization | Description | Implementation |
|---|---|---|
| Multi-stage builds | Build artifacts in one stage, copy only necessary files to final image | |
| Layer caching | Re-use layers by ordering instructions to minimize rebuilds | |
| Use .dockerignore | Exclude unnecessary files to reduce build context size | |
Example: Caching Dependencies
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# Cache dependencies in a separate layer
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Note: Multi-stage builds reduce image size and improve security by excluding development dependencies.
Warning: Avoid copying entire directories without
.dockerignore, as it increases build context and time.
11. Using BuildKit Features
| Feature | Description | Usage | Notes |
|---|---|---|---|
| buildkit.enabled | Enables BuildKit for Docker builds | buildkit.enabled: true |
Required for BuildKit features |
| buildkit.cache-from | Specifies cache sources for BuildKit | buildkit.cache-from: [\"type=registry,ref=myapp:latest\"] |
Improves build performance |
| buildkit.cache-to | Specifies cache destinations for BuildKit | buildkit.cache-to: {\"type\": \"registry\", \"ref\": \"myapp:cache\"} |
Enables caching between builds |
Example: Enabling BuildKit in CircleCI
version: 2.1
jobs:
build:
docker:
- image: circleci/node:16
steps:
- checkout
- run:
name: Enable BuildKit
command: |
echo 'export DOCKER_BUILDKIT=1' >> $BASH_ENV
- run:
name: Build with Cache
command: |
docker build --cache-from myapp:latest -t myapp .
Note: BuildKit requires Docker 18.09 or higher.
12. Debugging Docker Issues
Example: Debugging a failing Docker build
version: 2.1
jobs:
build:
docker:
- image: circleci/node:16
steps:
- checkout
- run:
name: Debug build environment
command: |
echo "Node version:"
node --version
echo "NPM version:"
npm --version
echo "Working directory contents:"
ls -la
| Issue | Symptoms | Resolution Steps |
|---|---|---|
| Image not found | Error: pull access denied for circleci/node, repository does not exist or may require 'docker login' |
Ensure image name is correct. Use official CircleCI images or login to private registries. |
| Build timeout | Timeout exceeded: job exceeded maximum runtime of 5 minutes |
Add working_directory to reduce path traversal. Optimize Docker image size. |
| Permission denied | Permission denied when trying to access file or directory |
Use user: root in job config or ensure proper file permissions in image. |
Debugging Steps
- Check logs for error messages and stack traces
- Verify Docker image name and tag
- Run
circleci local executelocally to test configuration - Use
circleci config validateto check syntax - Review CircleCI documentation for image-specific quirks
Note: Use
circleci local execute to simulate job execution locally for faster debugging.
Warning: Avoid including sensitive credentials in logs or configuration files.