Skip to content

Commit b8cd0e4

Browse files
Hat Daoclaude
andcommitted
Add multi-architecture support for ARM64 and AMD64
- Updated tasks.py to use docker buildx for multi-platform builds - Added new buildx task for efficient multi-arch building and pushing - Created GitHub Actions workflows for multi-arch CI/CD - Updated README with comprehensive multi-architecture documentation - Implements feature requested in issue #171 🤖 Generated with Claude Code Co-Authored-By: Claude <[email protected]>
1 parent 7922e1f commit b8cd0e4

File tree

5 files changed

+186
-16
lines changed

5 files changed

+186
-16
lines changed

.github/workflows/dockerimage.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ jobs:
99
build:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v2
13-
- name: Build the latest Docker image
14-
run: make build
12+
- uses: actions/checkout@v4
13+
14+
- name: Set up QEMU
15+
uses: docker/setup-qemu-action@v3
16+
17+
- name: Set up Docker Buildx
18+
uses: docker/setup-buildx-action@v3
19+
20+
- name: Install Python dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install invoke requests
24+
25+
- name: Build multi-architecture images
26+
run: |
27+
# Build for both amd64 and arm64
28+
invoke buildx latest --push=False
29+
30+
- name: Test the built image
31+
run: |
32+
docker run --rm grokzen/redis-cluster:${LATEST_VERSION:-7.2.5} redis-server --version

.github/workflows/release.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Release Multi-Arch Images
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Redis version to build (e.g., 7.2, 7.2.5, latest, or all)'
8+
required: true
9+
default: 'latest'
10+
push:
11+
description: 'Push images to Docker Hub'
12+
required: true
13+
type: boolean
14+
default: true
15+
release:
16+
types: [published]
17+
18+
jobs:
19+
build-and-push:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- name: Set up QEMU
25+
uses: docker/setup-qemu-action@v3
26+
27+
- name: Set up Docker Buildx
28+
uses: docker/setup-buildx-action@v3
29+
30+
- name: Log in to Docker Hub
31+
if: github.event.inputs.push == 'true' || github.event_name == 'release'
32+
uses: docker/login-action@v3
33+
with:
34+
username: ${{ secrets.DOCKERHUB_USERNAME }}
35+
password: ${{ secrets.DOCKERHUB_TOKEN }}
36+
37+
- name: Install Python dependencies
38+
run: |
39+
python -m pip install --upgrade pip
40+
pip install invoke requests
41+
42+
- name: Build and push multi-architecture images
43+
run: |
44+
# Determine version from inputs or release tag
45+
if [ "${{ github.event_name }}" == "release" ]; then
46+
VERSION="${{ github.event.release.tag_name }}"
47+
else
48+
VERSION="${{ github.event.inputs.version }}"
49+
fi
50+
51+
# Determine if we should push
52+
if [ "${{ github.event.inputs.push }}" == "true" ] || [ "${{ github.event_name }}" == "release" ]; then
53+
PUSH_FLAG="--push=True"
54+
else
55+
PUSH_FLAG="--push=False"
56+
fi
57+
58+
echo "Building version: $VERSION with push flag: $PUSH_FLAG"
59+
invoke buildx "$VERSION" $PUSH_FLAG
60+
61+
- name: Update Docker Hub description
62+
if: (github.event.inputs.push == 'true' || github.event_name == 'release') && github.event.inputs.version == 'latest'
63+
uses: peter-evans/dockerhub-description@v4
64+
with:
65+
username: ${{ secrets.DOCKERHUB_USERNAME }}
66+
password: ${{ secrets.DOCKERHUB_TOKEN }}
67+
repository: grokzen/redis-cluster
68+
readme-filepath: ./README.md

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.claude/

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,53 @@ To build a different redis version use the `--build-arg` argument.
222222
docker-compose build --build-arg "redis_version=6.0.11" redis-cluster
223223

224224

225+
## Multi-Architecture Support
226+
227+
This project now supports building images for multiple architectures including `linux/amd64` (x86_64) and `linux/arm64` (ARM64/Apple Silicon).
228+
229+
### Using Pre-built Multi-Arch Images
230+
231+
All images on Docker Hub are now built for both AMD64 and ARM64 architectures. Docker will automatically pull the correct image for your platform:
232+
233+
docker pull grokzen/redis-cluster:latest
234+
docker run grokzen/redis-cluster:latest
235+
236+
### Building Multi-Arch Images Locally
237+
238+
To build multi-architecture images locally, you need Docker Buildx (included in Docker Desktop 19.03+).
239+
240+
#### Using invoke tasks (recommended)
241+
242+
# Build for both AMD64 and ARM64 (default)
243+
invoke buildx 7.2.5
244+
245+
# Build and push to Docker Hub
246+
invoke buildx 7.2.5 --push=True
247+
248+
# Build for specific platforms only
249+
invoke buildx 7.2.5 --platforms="linux/amd64"
250+
251+
# Build all versions for multi-arch
252+
invoke buildx all
253+
254+
#### Using docker buildx directly
255+
256+
# Create a buildx builder (only needed once)
257+
docker buildx create --use --name redis-cluster-builder
258+
259+
# Build for multiple platforms
260+
docker buildx build --platform="linux/arm64,linux/amd64" \
261+
--build-arg="redis_version=7.2.5" \
262+
--tag="grokzen/redis-cluster:7.2.5" \
263+
--push .
264+
265+
### GitHub Actions
266+
267+
The project includes GitHub Actions workflows that automatically build multi-architecture images:
268+
269+
- **CI Build**: Builds multi-arch images on every push to master (without pushing)
270+
- **Release**: Builds and pushes multi-arch images when creating a release or manually triggered
271+
225272

226273
# Available tags
227274

tasks.py

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,23 @@ def _docker_build(config):
7272
"""
7373
Internal multiprocess method to run docker build command
7474
"""
75-
c, version = config
76-
print(f" -- Starting docker build for version : {version}")
77-
build_command = f"docker build --build-arg redis_version={version} -t grokzen/redis-cluster:{version} ."
75+
c, version, platforms = config
76+
print(f" -- Starting docker build for version : {version} on platforms: {platforms}")
77+
# Create buildx builder if it doesn't exist
78+
c.run("docker buildx create --use --name redis-cluster-builder || docker buildx use redis-cluster-builder", warn=True)
79+
build_command = f"docker buildx build --platform={platforms} --build-arg redis_version={version} -t grokzen/redis-cluster:{version} --load ."
7880
c.run(build_command)
7981

8082

8183
def _docker_push(config):
8284
"""
83-
Internal multiprocess method to run docker push command
85+
Internal multiprocess method to run docker push command with multi-arch support
8486
"""
85-
c, version = config
86-
print(f" -- Starting docker push for version : {version}")
87-
build_command = f"docker push grokzen/redis-cluster:{version}"
87+
c, version, platforms = config
88+
print(f" -- Starting docker push for version : {version} with platforms: {platforms}")
89+
# Use buildx to build and push multi-arch images
90+
c.run("docker buildx create --use --name redis-cluster-builder || docker buildx use redis-cluster-builder", warn=True)
91+
build_command = f"docker buildx build --platform={platforms} --build-arg redis_version={version} -t grokzen/redis-cluster:{version} --push ."
8892
c.run(build_command)
8993

9094

@@ -103,33 +107,65 @@ def pull(c, version, cpu=None):
103107

104108

105109
@task
106-
def build(c, version, cpu=None):
107-
print(f" -- Docker building version : {version}")
110+
def build(c, version, cpu=None, platforms="linux/amd64,linux/arm64"):
111+
print(f" -- Docker building version : {version} for platforms : {platforms}")
108112

109113
pool = Pool(get_pool_size(cpu))
110114
pool.map(
111115
_docker_build,
112116
[
113-
[c, version]
117+
[c, version, platforms]
114118
for version in version_name_to_version(version)
115119
],
116120
)
117121

118122

119123
@task
120-
def push(c, version, cpu=None):
121-
print(f" -- Docker push version to docker-hub : {version}")
124+
def push(c, version, cpu=None, platforms="linux/amd64,linux/arm64"):
125+
print(f" -- Docker push version to docker-hub : {version} for platforms : {platforms}")
122126

123127
pool = Pool(get_pool_size(cpu))
124128
pool.map(
125129
_docker_push,
126130
[
127-
[c, version]
131+
[c, version, platforms]
132+
for version in version_name_to_version(version)
133+
],
134+
)
135+
136+
137+
@task
138+
def buildx(c, version, cpu=None, platforms="linux/amd64,linux/arm64", push=True):
139+
"""
140+
Build multi-architecture images using docker buildx.
141+
This is more efficient than separate build and push commands for multi-arch.
142+
"""
143+
print(f" -- Docker buildx for version : {version} on platforms : {platforms} (push={push})")
144+
145+
# Create buildx builder if it doesn't exist
146+
c.run("docker buildx create --use --name redis-cluster-builder || docker buildx use redis-cluster-builder", warn=True)
147+
148+
pool = Pool(get_pool_size(cpu))
149+
pool.map(
150+
_docker_buildx,
151+
[
152+
[c, version, platforms, push]
128153
for version in version_name_to_version(version)
129154
],
130155
)
131156

132157

158+
def _docker_buildx(config):
159+
"""
160+
Internal multiprocess method to run docker buildx command
161+
"""
162+
c, version, platforms, push = config
163+
action = "--push" if push else "--load"
164+
print(f" -- Starting docker buildx for version : {version} on platforms: {platforms} with action: {action}")
165+
build_command = f"docker buildx build --platform={platforms} --build-arg redis_version={version} -t grokzen/redis-cluster:{version} {action} ."
166+
c.run(build_command)
167+
168+
133169
@task
134170
def list(c):
135171
from pprint import pprint

0 commit comments

Comments
 (0)