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
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.git
**/bin
**/obj
**/out
**/TestResults
.env
.env.*
74 changes: 74 additions & 0 deletions .github/workflows/container-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Container build

on:
pull_request:
paths:
- Dockerfile
- .dockerignore
- .github/workflows/container-build.yml
- scripts/publish-container.sh
- src/**
- schemas/**
- Nuget.config
- global.json
push:
branches: [main]
paths:
- Dockerfile
- .dockerignore
- .github/workflows/container-build.yml
- scripts/publish-container.sh
- src/**
- schemas/**
- Nuget.config
- global.json
workflow_dispatch:

permissions:
contents: read

jobs:
build:
strategy:
fail-fast: false
matrix:
target: [runtime, runtime-nonroot]
runner: [ubuntu-24.04, ubuntu-24.04-arm]
include:
- runner: ubuntu-24.04
platform: linux/amd64
arch: x64
- runner: ubuntu-24.04-arm
platform: linux/arm64
arch: arm64
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Check publishing script syntax
run: bash -n scripts/publish-container.sh
- name: Build image
uses: docker/build-push-action@v6
with:
context: .
target: ${{ matrix.target }}
platforms: ${{ matrix.platform }}
load: true
tags: dab:container-test
- name: Check runtime and application architecture
env:
ARCH: ${{ matrix.arch }}
TARGET: ${{ matrix.target }}
run: |
docker run --rm --entrypoint sh dab:container-test -ec '
dotnet --info
test -s /App/dab-config.json
grep -F "\"name\": \".NETCoreApp,Version=v10.0/linux-$1\"" \
/App/Azure.DataApiBuilder.Service.deps.json
if [ "$2" = runtime-nonroot ]; then
test "$(id -u)" = "$APP_UID"
touch /App/logs/container-test
else
test "$(id -u)" = 0
fi
' sh "$ARCH" "$TARGET"
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Version values referenced from https://hub.docker.com/_/microsoft-dotnet-aspnet

FROM mcr.microsoft.com/dotnet/sdk:10.0-azurelinux3.0 AS build
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0-azurelinux3.0 AS build

ARG TARGETARCH

WORKDIR /src
COPY [".", "./"]
RUN dotnet build "./src/Service/Azure.DataApiBuilder.Service.csproj" -c Docker -o /out -r linux-x64
RUN dotnet publish "./src/Service/Azure.DataApiBuilder.Service.csproj" \
-c Docker -o /out -a "$TARGETARCH" --self-contained false -p:UseAppHost=false

# ---------------------------------------------------------------------------
# Common runtime base.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ Data API builder (DAB) is an open-source, no-code tool that creates secure, full

Use the [Getting Started](https://learn.microsoft.com/azure/data-api-builder/get-started/get-started-with-data-api-builder) tutorial to quickly explore the core tools and concepts.

For source builds, see [building and publishing multi-architecture container images](docker/README.md).

### 1. Install the `dotnet` [command line](https://get.dot.net)

https://get.dot.net
Expand Down
67 changes: 67 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Building and publishing container images

The Dockerfile supports `linux/amd64` and `linux/arm64`. The SDK runs on the
builder's native architecture and cross-compiles for the requested platform;
the ASP.NET runtime base image is selected for that platform. Both the default
`runtime` target and the opt-in `runtime-nonroot` target support these platforms.

## Local build

Build and load a single platform into the local Docker image store:

```sh
docker buildx build --platform linux/arm64 --target runtime --load -t dab:local .
```

Omit `--platform` to build for the local builder's default platform. Running an
image for another architecture requires emulation. Cross-building
`runtime-nonroot` also requires emulation (or native builder nodes for both
architectures) because its permissions setup executes in the target image.

## Release publishing

Use a Buildx builder with multi-platform support, for example:

```sh
docker buildx create --name dab-multiarch --driver docker-container --use
docker buildx inspect --bootstrap
```

Authenticate to the release pipeline's **writable registry**, then publish all
tags for a variant in one build. Replace the example registry and version with
the release pipeline's existing destination and version:

```sh
docker login <registry>
bash scripts/publish-container.sh runtime \
<registry>/data-api-builder:<version> \
<registry>/data-api-builder:latest
bash scripts/publish-container.sh runtime-nonroot \
<registry>/data-api-builder:<version>-nonroot \
<registry>/data-api-builder:latest-nonroot
```

The script pushes both platform images and their shared image index for each
supplied tag. Do not push the architectures separately to the same tag: the
last push would replace the earlier architecture instead of publishing an
index. A multi-platform build uses `--push`, not `--load`.

The official MCR release pipeline is not defined in this repository. Its
maintainers must replace the existing single-platform build/push with this
script (or the equivalent `docker buildx build --platform
linux/amd64,linux/arm64 --push` command), preserving their existing registry
authentication, tag selection, and MCR promotion process. Every promoted tag
must retain the multi-platform index and both referenced platform images.
Changing the Dockerfile alone does not make existing MCR tags multi-platform.

Verify the resulting tag in the writable registry and again after MCR promotion:

```sh
docker buildx imagetools inspect <registry>/data-api-builder:<version>
docker buildx imagetools inspect mcr.microsoft.com/azure-databases/data-api-builder:<version>
```

Both must list `linux/amd64` and `linux/arm64`. Provenance attestations may also
appear as `unknown/unknown`; these do not replace the required platform images.
The `Container build` workflow builds both variants on native x64 and ARM64
runners and checks the application's runtime identifier and non-root log access.
26 changes: 26 additions & 0 deletions scripts/publish-container.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

set -euo pipefail

if [[ $# -lt 2 || ( "$1" != runtime && "$1" != runtime-nonroot ) ]]; then
echo "Usage: $0 <runtime|runtime-nonroot> <image:tag> [<image:tag> ...]" >&2
exit 1
fi

target=$1
shift
tags=()
for tag in "$@"; do
tags+=(--tag "$tag")
done

repo_root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
docker buildx build \
--file "$repo_root/Dockerfile" \
--platform linux/amd64,linux/arm64 \
--target "$target" \
"${tags[@]}" \
--push \
"$repo_root"
Loading