Run Apama Development Containers Natively on Apple Silicon

Run Apama Development Containers Natively on Apple Silicon

Development containers (dev containers) are the recommended way to develop Apama applications and custom Analytics Builder blocks. The Apama extension for VS Code and the custom blocks workflow both assume a container that provides the Apama installation, the Analytics Builder Block SDK and the EPL Apps tools.

The published apama-builder image is built for x86-64 only. On an Apple Silicon Mac it therefore runs under emulation, which makes builds, correlator start-up and PySys test runs considerably slower. Apama also publishes arm64 Debian packages, so you can build an image that runs natively instead.

This article describes how to set up Colima as the container runtime on macOS and how to build a native arm64 Apama dev container image.

Advantages of this setup:

  • Containers run natively on arm64, without QEMU or Rosetta emulation
  • Noticeably faster correlator start-up and test execution
  • No Docker Desktop installation or license required
  • The VS Code Dev Containers workflow stays unchanged

Regarding the performance improvements specifically: in my experience, native arm64 containers run tests 5–10 times faster.

Prerequisites

  • An Apple Silicon Mac (M1 or later) running macOS 13 or later
  • Homebrew
  • Visual Studio Code with the Dev Containers and Apama extensions
  • Docker Desktop is not required. If it is installed, stop it before starting Colima.

Install Colima and the Docker CLI

Colima runs a Linux VM and a container runtime on macOS. It does not bundle a Docker client, so install the CLI separately:

brew install colima docker docker-buildx

Register the Buildx plugin with the Docker CLI:

mkdir -p ~/.docker/cli-plugins
ln -sfn "$(brew --prefix)/opt/docker-buildx/bin/docker-buildx" ~/.docker/cli-plugins/docker-buildx

Buildx is optional for plain docker build, but the Dev Containers extension uses BuildKit features, so it is worth installing up front.

Start the virtual machine

colima start --vm-type vz --mount-type virtiofs --cpu 4 --memory 8 --disk 100

This creates a VM using Apple’s Virtualization.framework (vz, macOS 13 or later) with virtiofs for bind mounts, which gives the best file system performance. The architecture defaults to that of the host, so the VM is arm64 and containers run natively. Do not pass --vz-rosetta unless you also need to run x86-64 images.

Verify the runtime:

colima status
docker context show
docker run --rm arm64v8/debian:12-slim uname -m

The last command must print aarch64. The settings are persisted, so later you only need colima start. Use colima stop to shut the VM down and colima delete to discard it.

The Dockerfile

Place the following as .devcontainer/Dockerfile.apple:

FROM arm64v8/debian:12-slim

USER root
RUN apt update && apt install curl -y && apt clean
RUN curl https://download.cumulocity.com/Apama/Debian/apama-27.sources -o /etc/apt/sources.list.d/apama-27.sources && curl https://download.cumulocity.com/Apama/Debian/apamarepo.gpg -o /usr/share/keyrings/apamarepo.gpg
ARG ADDITIONAL_PACKAGES=
RUN apt update && apt install git tar apama apama-python ${ADDITIONAL_PACKAGES} -y && apt clean

RUN useradd -ms /bin/bash apama

RUN mkdir "/workspaces" && chown -R apama:apama "/workspaces"

USER apama
ENV APAMA_HOME=/opt/cumulocity/Apama APAMA_WORK=/workspaces
ENV LD_LIBRARY_PATH="${APAMA_WORK}/lib:${APAMA_HOME}/lib:${APAMA_HOME}/third_party/python/lib"
ENV PATH="${APAMA_HOME}/bin:${APAMA_HOME}/third_party/python/bin:$PATH"
ENV PYTHONPATH=${APAMA_HOME}/third_party/python/lib/python3.13

# Clone the SDKs. We clone under APAMA_WORK because "/workspaces" gets overwritten by the mount
# (and devcontainer.json workspaceMount is not respected in many cases - https://github.com/microsoft/vscode-remote-release/issues/3034)
ARG APAMA_ANALYTICS_BUILDER_SDK_BRANCH=main
RUN git clone https://github.com/Cumulocity-IoT/apama-analytics-builder-block-sdk.git --branch ${APAMA_ANALYTICS_BUILDER_SDK_BRANCH} ${APAMA_WORK}/apama-analytics-builder-block-sdk

ARG APAMA_EPLAPPS_TOOLS_BRANCH=main
RUN git clone https://github.com/Cumulocity-IoT/apama-eplapps-tools.git ${APAMA_WORK}/apama-eplapps-tools --branch ${APAMA_EPLAPPS_TOOLS_BRANCH}

# Link the SDKs to the root dir so we can find them from /workspaces/projectdir using a relative path
USER root
RUN ln -s ${APAMA_WORK}/apama-analytics-builder-block-sdk /apama-analytics-builder-block-sdk \
  && ln -s ${APAMA_WORK}/apama-eplapps-tools /apama-eplapps-tools

USER apama
ENV ANALYTICS_BUILDER_SDK=${APAMA_WORK}/apama-analytics-builder-block-sdk
ENV EPL_TESTING_SDK=${APAMA_WORK}/apama-eplapps-tools
ENV PATH="${APAMA_WORK}/apama-eplapps-tools/scripts:${APAMA_WORK}/apama-analytics-builder-block-sdk:${PATH}"

# Pin cryptography to a version whose ARM64 binary wheel works in the Docker VM on Apple Silicon.
# cryptography 45+ wheels use CPU instructions not exposed by the hypervisor (Illegal instruction crash).
RUN mkdir -p /home/apama/.config/pip \
 && printf '[global]\nconstraint = /home/apama/.config/pip/constraints.txt\n' > /home/apama/.config/pip/pip.conf \
 && echo 'cryptography<45.0.0' > /home/apama/.config/pip/constraints.txt

WORKDIR "/workspaces"

ENV SHELL=/bin/bash

What it does, step by step:

  1. Base image. arm64v8/debian:12-slim replaces the x86-64 apama-builder image. Everything above it is therefore native.
  2. Apama repository. The .sources file and the GPG keyring are fetched from download.cumulocity.com, then apama and apama-python are installed with apt. The repository publishes both arm64 and amd64 packages, so apt selects the arm64 build automatically. ADDITIONAL_PACKAGES lets you add project dependencies, for example build-essential unixodbc.
  3. Non-root user. An apama user is created and /workspaces is assigned to it. This must match remoteUser and containerUser in devcontainer.json; otherwise, files created in the workspace end up with the wrong owner.
  4. Environment. The Debian packages install Apama under /opt/cumulocity/Apama but do not set up a shell environment the way the builder image does, so APAMA_HOME, APAMA_WORK, PATH, LD_LIBRARY_PATH and PYTHONPATH are set explicitly. Check the Python version under $APAMA_HOME/third_party/python/lib and adjust PYTHONPATH if your Apama release ships a version other than python3.13.
  5. SDKs. The Analytics Builder Block SDK and the EPL Apps tools are cloned into APAMA_WORK and symlinked into /. The symlinks matter because /workspaces is replaced by the workspace bind mount at container start, which would otherwise hide the clones. ANALYTICS_BUILDER_SDK and EPL_TESTING_SDK are the variables the SDK scripts and the PySys test framework look for.
  6. Pip constraint. cryptography 45 and later ship aarch64 wheels that use CPU instructions the hypervisor does not expose, so they abort with Illegal instruction. A global pip constraint file pins the version, and because it is a constraint rather than a pinned install, it also applies to transitive dependencies pulled in later.

devcontainer.json

{
  "name": "apama-arm64",
  "build": {
    "dockerfile": "Dockerfile.apple",
    "args": {
      "ADDITIONAL_PACKAGES": "build-essential",
      "APAMA_ANALYTICS_BUILDER_SDK_BRANCH": "main",
      "APAMA_EPLAPPS_TOOLS_BRANCH": "main"
    }
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "apamacommunity.apama-extensions",
        "ms-python.python"
      ]
    }
  },
  "forwardPorts": [15903],
  "overrideCommand": true,
  "remoteUser": "apama",
  "containerUser": "apama"
}

Note that APAMA_IMAGE and APAMA_VERSION are not used here. The Apple Dockerfile does not derive from a published image, so the Apama version is determined by the repository suite in the .sources URL β€” apama-27 in the example above.

Verify the container

Open the folder in the container (Dev Containers: Reopen in Container), then in the container terminal:

uname -m
correlator --version

uname -m must print aarch64, confirming there is no emulation in the chain. After that, run your existing PySys tests as usual β€” they are the real check that the correlator, the Python plugin support and the SDKs work together.

Notes and limitations

  • If you still need x86-64 images alongside this one, restart Colima with --vz-rosetta. Those images then run under Rosetta with the corresponding performance penalty; the native Apama image is unaffected.
  • The image is one you build and maintain yourself. It is not an official Cumulocity image, and support statements that apply to the published apama-builder image do not apply to it.
  • To move to a different Apama release line, change the suite in the .sources URL and rebuild.

Summary

Colima provides a container runtime on macOS without Docker Desktop, and because Apama ships arm64 Debian packages you can build a dev container image that runs natively on Apple Silicon. The only differences from the standard setup are the base image and the environment variables the Debian packages do not set for you. Everything else β€” the Apama extension, the Block SDK, the EPL Apps tools and PySys β€” behaves as described in the existing articles.

References

The Dockerfile shown in this article is provided as-is and without warranty or support.

1 Like