Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,34 @@ and it will run the build step on all versions that starts with 6.0.

The only other optional usefull argument is `--cpu=N` and it will set how many paralell processes will be used. By default you will use n - 1 number of cpu cores that is available on your system. Commands like pull and push aare not very cpu intensive so using a higher number here might speed things up if you have good network bandwidth.

## Multi-architecture Support (ARM64/x86)

The build system now supports multi-architecture builds using Docker Buildx. You can build images for both AMD64 and ARM64 platforms:

### Platform Options

- `amd64` - Build for AMD64/x86_64 only
- `arm64` - Build for ARM64 only
- `both` or `multi` - Build for both platforms (default)

### Building for ARM64

```bash
# Build for ARM64 only
invoke build 7.2.5 --platforms=arm64

# Build for both AMD64 and ARM64 (default)
invoke build 7.2.5 --platforms=both

# Push multi-arch images
invoke push 7.2.5 --platforms=both

# Use the dedicated buildx command
invoke buildx 7.2.5 --platforms=arm64
```

The `buildx` command provides additional control over multi-architecture builds and uses Docker Buildx builder instances for cross-platform compilation.


## Makefile (legacy)

Expand Down
90 changes: 77 additions & 13 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@

latest_version_string = "7.2.5"

# Platform mapping for simplified platform arguments
platform_mapping = {
"amd64": "linux/amd64",
"arm64": "linux/arm64",
"both": "linux/amd64,linux/arm64",
"multi": "linux/amd64,linux/arm64"
}

def get_platforms(platform_arg):
"""
Convert simplified platform argument to full platform string
"""
if platform_arg in platform_mapping:
return platform_mapping[platform_arg]
# If it's already a full platform string, return as-is
return platform_arg

# Unpublished versions
version_config_mapping = []
version_config_mapping += [f"3.0.{i}" for i in range(0, 8)]
Expand Down Expand Up @@ -72,19 +89,23 @@ def _docker_build(config):
"""
Internal multiprocess method to run docker build command
"""
c, version = config
print(f" -- Starting docker build for version : {version}")
build_command = f"docker build --build-arg redis_version={version} -t grokzen/redis-cluster:{version} ."
c, version, platforms = config
print(f" -- Starting docker build for version : {version} on platforms: {platforms}")
# Create buildx builder if it doesn't exist
c.run("docker buildx create --use --name redis-cluster-builder || docker buildx use redis-cluster-builder", warn=True)
build_command = f"docker buildx build --platform={platforms} --build-arg redis_version={version} -t grokzen/redis-cluster:{version} ."
c.run(build_command)


def _docker_push(config):
"""
Internal multiprocess method to run docker push command
Internal multiprocess method to run docker push command with multi-arch support
"""
c, version = config
print(f" -- Starting docker push for version : {version}")
build_command = f"docker push grokzen/redis-cluster:{version}"
c, version, platforms = config
print(f" -- Starting docker push for version : {version} with platforms: {platforms}")
# Use buildx to build and push multi-arch images
c.run("docker buildx create --use --name redis-cluster-builder || docker buildx use redis-cluster-builder", warn=True)
build_command = f"docker buildx build --platform={platforms} --build-arg redis_version={version} -t grokzen/redis-cluster:{version} --push ."
c.run(build_command)


Expand All @@ -103,33 +124,76 @@ def pull(c, version, cpu=None):


@task
def build(c, version, cpu=None):
print(f" -- Docker building version : {version}")
def build(c, version, cpu=None, platforms="both"):
platforms = get_platforms(platforms)
print(f" -- Docker building version : {version} for platforms : {platforms}")

pool = Pool(get_pool_size(cpu))
pool.map(
_docker_build,
[
[c, version]
[c, version, platforms]
for version in version_name_to_version(version)
],
)


@task
def push(c, version, cpu=None):
print(f" -- Docker push version to docker-hub : {version}")
def push(c, version, cpu=None, platforms="both"):
platforms = get_platforms(platforms)
print(f" -- Docker push version to docker-hub : {version} for platforms : {platforms}")

pool = Pool(get_pool_size(cpu))
pool.map(
_docker_push,
[
[c, version]
[c, version, platforms]
for version in version_name_to_version(version)
],
)


@task
def buildx(c, version, cpu=None, platforms="both"):
"""
Build multi-architecture images using docker buildx without pushing.
Use the separate push command to push the images after building.

Usage:
invoke buildx 7.2.5 # Build both platforms (default)
invoke buildx 7.2.5 --platforms=amd64 # Build only AMD64
invoke buildx 7.2.5 --platforms=arm64 # Build only ARM64
"""
platforms = get_platforms(platforms)
print(f" -- Docker buildx for version : {version} on platforms : {platforms}")

# Create buildx builder if it doesn't exist
c.run("docker buildx create --use --name redis-cluster-builder || docker buildx use redis-cluster-builder", warn=True)

pool = Pool(get_pool_size(cpu))
pool.map(
_docker_buildx,
[
[c, version, platforms]
for version in version_name_to_version(version)
],
)


def _docker_buildx(config):
"""
Internal multiprocess method to run docker buildx command
"""
c, version, platforms = config

# Build without loading to local Docker daemon by default
action = ""

print(f" -- Starting docker buildx for version : {version} on platforms: {platforms}")
build_command = f"docker buildx build --platform={platforms} --build-arg redis_version={version} -t grokzen/redis-cluster:{version} ."
c.run(build_command)


@task
def list(c):
from pprint import pprint
Expand Down