Build a container for the given platform
    :param platform: Platform
    :param docker_binary: docker binary to use (docker/nvidia-docker)
    :param registry: Dockerhub registry name
    :param num_retries: Number of retries to build the docker image
    :param no_cache: pass no-cache to docker to rebuild the images
    :return: Id of the top level image

def build_docker(platform: str, docker_binary: str, registry: str, num_retries: int, no_cache: bool) -> str:
    """
    Build a container for the given platform
    :param platform: Platform
    :param docker_binary: docker binary to use (docker/nvidia-docker)
    :param registry: Dockerhub registry name
    :param num_retries: Number of retries to build the docker image
    :param no_cache: pass no-cache to docker to rebuild the images
    :return: Id of the top level image
    """
    tag = get_docker_tag(platform=platform, registry=registry)
    logging.info("Building docker container tagged '%s' with %s", tag, docker_binary)
    #
    # We add a user with the same group as the executing non-root user so files created in the
    # container match permissions of the local user. Same for the group.
    #
    # These variables are used in the docker files to create user and group with these ids.
    # see: docker/install/ubuntu_adduser.sh
    #
    # cache-from is needed so we use the cached images tagged from the remote via
    # docker pull see: docker_cache.load_docker_cache
    #
    # This also prevents using local layers for caching: https://github.com/moby/moby/issues/33002
    # So to use local caching, we should omit the cache-from by using --no-dockerhub-cache argument to this
    # script.
    #
    # This doesn't work with multi head docker files.
    #
    cmd = [docker_binary, "build",
           "-f", get_dockerfile(platform),
           "--build-arg", "USER_ID={}".format(os.getuid()),
           "--build-arg", "GROUP_ID={}".format(os.getgid())]
    if no_cache:
        cmd.append("--no-cache")
    elif registry:
        cmd.extend(["--cache-from", tag])
    cmd.extend(["-t", tag, get_dockerfiles_path()])

    @retry(subprocess.CalledProcessError, tries=num_retries)
    def run_cmd():
        logging.info("Running command: '%s'", ' '.join(cmd))
        check_call(cmd)

    run_cmd()
    # Get image id by reading the tag. It's guaranteed (except race condition) that the tag exists. Otherwise, the
    # check_call would have failed
    image_id = _get_local_image_id(docker_binary=docker_binary, docker_tag=tag)
    if not image_id:
        raise FileNotFoundError('Unable to find docker image id matching with {}'.format(tag))
    return image_id