Docker Compose: dynamically change the image architecture based on running host machine

Hi! quick question: is it possible to dynamically change the image’s arch based on the host’s machine instead of create 2 separate docker compose file?

Currently I have 2 files:

For arm64 (osx)

services:
  typesense:
    image: docker.io/typesense/typesense:0.25.2-arm64
    container_name: typesense
    restart: on-failure
    ports:
      - "8108:8108"
    volumes:
      - ./typesense-data:/data
    command: '--data-dir /data --api-key=xyz --enable-cors'

For non arm64

services:
  typesense:
    image: docker.io/typesense/typesense:0.25.2
    container_name: typesense
    restart: on-failure
    ports:
      - "8108:8108"
    volumes:
      - ./typesense-data:/data
    command: '--data-dir /data --api-key=xyz --enable-cors'

The only difference here is the image, and ideally running them e.g. docker compose up -d then let the engine decide which arch is appropriate in the host’s machine instead of using docker compose -f <FILE> up -d.

1 Like

I doubt that you can do this dynamically. Or maybe I am wrong. :slight_smile: But using separate files might be the simplest way.

2 Likes

But it is kinda interesting to know if it is possible :slight_smile:

1 Like

I haven’t tried it myself but I guess you can use environment variables

image: docker.io/typesense/${MY_VARIABLE}"

Then in your shell you declare a variable called MY_VARIABLE according to your system

You can read more here:

2 Likes

That’s my thoughts too. That’s the closest thing I can do aside from separate compose files.

1 Like

more info: StackOverflow answer thread

TLDR; So the closest thing is to uname -m it to know if it’s arm or non-arm, then run it as a script:

services:
  typesense:
    image: ${TYPESENSE_IMAGE}
    container_name: typesense
    restart: on-failure
    ports:
      - "8108:8108"
    volumes:
      - ./typesense-data:/data
    command: '--data-dir /data --api-key=xyz --enable-cors'
#!/bin/bash

ARCH=$(uname -m)
if [ -z "$ARCH" ]; then
  echo "Error: Unable to determine architecture"
  exit 1
fi

if [ "$ARCH" = "arm64" ]; then
  export TYPESENSE_IMAGE=${TYPESENSE_IMAGE:-"docker.io/typesense/typesense:0.25.2-arm64"}
else
  export TYPESENSE_IMAGE=${TYPESENSE_IMAGE:-"docker.io/typesense/typesense:0.25.2"}
fi

docker-compose up -d

Then

chmod +x filename.sh

source filename.sh
1 Like

@jaeyson Have you tried building a multi-platform Docker image for your application? If not, I recommend checking out the docs on the subject here:

2 Likes

I’m confused @conradwt (please enlighten me), how will this translate to docker compose? I’m not using a dockerfile for this specific problem. What I’m after here is that the official typesense image will use the appropriate arch based on the host machine, ideally I can docker compose up -d without telling it what arch is on.

1 Like

or if there’s another way of passing multiple platforms:

services:
  typesense:
    image: typesense/typesense:0.25.2
    platform: [linux/arm64/v8, linux/amd64]      # <--- ideally like this
    container_name: typesense
    restart: on-failure
    ports:
      - "8108:8108"
    volumes:
      - ./typesense-data:/data
    command: '--data-dir /data --api-key=xyz --enable-cors'
1 Like

@jaeyson The image that you’re using is already a multi-platform image. For example, it supports both linux/amd64 and linux/arm64.

Next, when you perform docker compose up -d, it will pull the image and run the appropriate platform variant for your host architecture without having to specify the platform. BTW, this is mentioned at the top of the page of the documentation link I sent in the previous post.

Finally, you can check the ‘Architecture’ and ‘Os’ of the running Docker image or container by doing the following:

docker inspect <container-id>

Or

docker inspect <your-image>

e.g.

docker inspect typesense/typesense:0.25.2

I hope that this helps and all the best.

1 Like

There’s no platform option for docker compose. Thus, what you’re looking for here is something even easier. For example, you’ll want to do the following:

services:
  typesense:
    image: typesense/typesense:0.25.2
    container_name: typesense
    restart: on-failure
    ports:
      - "8108:8108"
    volumes:
      - ./typesense-data:/data
    command: '--data-dir /data --api-key=xyz --enable-cors'

Now, the above should run the appropriate Docker image platform variant for the host architecture.

2 Likes

Ah that makes perfect sense, thanks for clearing that up! :pray:t5:

According to spec file there is, it’s just that it accepts string instead of list of multiple archs.

1 Like