๐ Day 39: GitHub Actions โ Docker Layer Caching


Welcome to Day 39 of my #100DaysOfDevOps! Today, weโre diving into Docker Layer Caching in GitHub Actions to supercharge your CI/CD pipelines. By reusing previously built Docker layers, we can drastically reduce build times and optimize workflows. Letโs get started! ๐ณโก #DevOps #GitHubActions
๐ Project: Docker Layer Caching Demo
This project demonstrates how to implement Docker Layer Caching in GitHub Actions using a simple Node.js application. The goal is to showcase how caching Docker layers can speed up builds by avoiding redundant work. ๐ #Docker #CI/CD
๐ Project Structure
Hereโs how your project directory should look:
docker-layer-caching-demo/
โโโ app.js # Node.js application
โโโ Dockerfile # Docker configuration
โโโ package.json # Node.js dependencies and scripts
โโโ package-lock.json # Lock file for reproducible builds
โโโ .github/
โโโ workflows/
โโโ docker.yml # GitHub Actions workflow for Docker builds
๐ ๏ธ Step 1: Initialize the Project
Set up a new Node.js project:
mkdir docker-layer-caching-demo && cd docker-layer-caching-demo
npm init -y
npm install
The npm install
command ensures dependencies are set up, though our simple app doesnโt require additional packages for this demo. #NodeJS
๐งโ๐ป Step 2: Create the Node.js Application
app.js
Create a simple HTTP server in app.js
:
const http = require('http');
const PORT = 3000;
const server = http.createServer((req, res) => {
res.end('๐ Docker Layer Caching in GitHub Actions!');
});
server.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
This code sets up a Node.js server that responds with a message on port 3000. You can test it locally with:
node app.js
Visit http://localhost:3000 to see: "๐ Docker Layer Caching in GitHub Actions!" #JavaScript
๐ณ Step 3: Create the Dockerfile
Create a Dockerfile
to containerize the app:
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Why this structure?
- Copying
package*.json
and runningnpm install
before copying the app code ensures that the dependency layer is cached separately. This means changes toapp.js
wonโt trigger a reinstall of dependencies, leveraging Dockerโs layer caching. #Docker #Optimization
๐ฆ Step 4: Update package.json
Ensure your package.json
is set up correctly:
{
"name": "docker-layer-caching-demo",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"license": "ISC"
}
The package-lock.json
will be auto-generated when you run npm install
. This lock file is critical for consistent caching in GitHub Actions. #NodeJS #Dependencies
โ๏ธ Step 5: Set Up GitHub Actions Workflow
Create the workflow file at .github/workflows/docker.yml
:
name: ๐ Docker Layer Caching
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: โฌ๏ธ Checkout code
uses: actions/checkout@v4
- name: ๐ณ Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: ๐ฆ Docker Layer Cache
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-docker-${{ github.sha }}
restore-keys: |
${{ runner.os }}-docker-
- name: ๐๏ธ Build Docker image
run: |
docker build \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache \
-t myapp:latest .
Key Points:
Docker Buildx: Enables advanced build features, including layer caching.
Cache Configuration: Uses
actions/cache@v4
to store Docker layers in/tmp/.buildx-cache
.Cache Key: Combines
${{ runner.os }}-docker-
with the commit SHA (${{ github.sha }}
) for unique cache entries.Restore Keys: Allows fallback to previous caches if the exact SHA isnโt found.
Buildkit: The
--build-arg BUILDKIT_INLINE_CACHE=1
ensures cache metadata is included in the image. #GitHubActions #DockerBuild
๐ Step 6: Push to GitHub
Push your project to GitHub:
git init
git remote add origin https://github.com/ritesh355/docker-layer-caching-demo.git
git add .
git commit -m "Add Docker layer caching demo with GitHub Actions"
git push -u origin main
๐งช Step 7: Check Workflow and Cache
Go to your GitHub repo โ Actions tab.
Watch the Docker Layer Caching workflow run.
First Run (Cache Miss)
Output:
Cache not found for: Linux-docker-...
...
[+] Building 56.4s (10/10) FINISHED
Result:
Docker layers are built from scratch.
Cache is created and stored in
/tmp/.buildx-cache
.
Second Run (Cache Hit)
Output:
Cache hit for: Linux-docker-c860ffe0118cab7eaf0092ade240cec129459046
Cache restored successfully
...
[+] Building 5.3s (10/10) FINISHED
Result:
Cached layers are reused.
Build time drops significantly (e.g., from ~50s to ~5s). ๐
๐ Benefits of Docker Layer Caching
Build Stage | Time Without Cache | Time With Cache |
Initial Build | โณ ~50s | โ Cached |
Subsequent Builds | โก ~5s | ๐ Super Fast! |
Why it works:
Docker layers (e.g.,
npm install
) are cached and reused unlesspackage*.json
changes.The GitHub Actions cache persists layers between workflow runs, reducing redundant builds. #Optimization #Efficiency
๐ How to Check Cache Status
In the GitHub Actions logs, look under the Docker Layer Cache step:
โ Cache hit: Layers were reused, speeding up the build.
โ Cache not found: A new cache was created.
๐ What I Learned
How to implement Docker Layer Caching in GitHub Actions using
actions/cache@v4
.Using
docker/setup-buildx-action
and Buildkit for efficient Docker builds.Crafting cache keys with
package-lock.json
hashes or commit SHAs for reliability.Debugging cache hits/misses in GitHub Actions logs.
Optimizing CI/CD pipelines for faster, smarter builds. #Learning #DevOpsJourney
๐ Connect with Me
๐ GitHub: ritesh355
#Portfolio #Networking
๐ Congratulations!
Youโve mastered Docker Layer Caching in GitHub Actions, making your CI/CD pipelines faster and more efficient! Keep rocking your #100DaysOfDevOps journey! ๐ช #KeepLearning
Need help? Drop a comment or question, and Iโll guide you through any issues!
Subscribe to my newsletter
Read articles from Ritesh Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Ritesh Singh
Ritesh Singh
Hi, Iโm Ritesh ๐ Iโm on a mission to become a DevOps Engineer โ and Iโm learning in public every single day.With a full-time commitment of 8โ10 hours daily, Iโm building skills in: โ Linuxโ Git & GitHubโ Docker & Kubernetesโ AWS EC2, S3โ Jenkins, GitHub Actionsโ Terraform, Prometheus, Grafana I post daily blogs on Hashnode, push projects to GitHub, and stay active on LinkedIn and Twitter/X. Letโs connect, collaborate, and grow together ๐ #100DaysOfDevOps #LearningInPublic #DevOps