Files
git.stella-ops.org/devops/docker/build-all.sh

147 lines
4.4 KiB
Bash

#!/usr/bin/env bash
# Build hardened images for the core services using the shared template/matrix.
# The default path publishes .NET services locally and builds runtime-only
# images from small temporary contexts to avoid repeatedly sending the full
# monorepo into Docker.
set -uo pipefail
FAILED=()
SUCCEEDED=()
ROOT=${ROOT:-"$(git rev-parse --show-toplevel)"}
MATRIX=${MATRIX:-"${ROOT}/devops/docker/services-matrix.env"}
REGISTRY=${REGISTRY:-"stellaops"}
TAG_SUFFIX=${TAG_SUFFIX:-"dev"}
SDK_IMAGE=${SDK_IMAGE:-"mcr.microsoft.com/dotnet/sdk:10.0-noble"}
RUNTIME_IMAGE=${RUNTIME_IMAGE:-"mcr.microsoft.com/dotnet/aspnet:10.0-noble"}
USE_LEGACY_REPO_CONTEXT=${USE_LEGACY_REPO_CONTEXT:-"false"}
PUBLISH_NO_RESTORE=${PUBLISH_NO_RESTORE:-"false"}
SERVICES=${SERVICES:-""}
FAST_CONTEXT_ROOT=${FAST_CONTEXT_ROOT:-"${TMPDIR:-/tmp}/stellaops-fast-images"}
RUNTIME_DOCKERFILE="${ROOT}/devops/docker/Dockerfile.hardened.runtime"
HEALTHCHECK_SCRIPT="${ROOT}/devops/docker/healthcheck.sh"
if [[ ! -f "${MATRIX}" ]]; then
echo "matrix file not found: ${MATRIX}" >&2
exit 1
fi
echo "Building services from ${MATRIX} -> ${REGISTRY}/<service>:${TAG_SUFFIX}" >&2
if [[ -n "${SERVICES}" ]]; then
echo "Service filter: ${SERVICES}" >&2
fi
cleanup_context() {
local context_dir="${1:-}"
[[ -n "${context_dir}" && -d "${context_dir}" ]] && rm -rf "${context_dir}"
}
should_build_service() {
local service="$1"
[[ -z "${SERVICES}" ]] && return 0
IFS=',' read -r -a requested <<< "${SERVICES}"
for candidate in "${requested[@]}"; do
local trimmed="${candidate// /}"
[[ "${trimmed}" == "${service}" ]] && return 0
done
return 1
}
build_published_service_image() {
local service="$1"
local project="$2"
local binary="$3"
local port="$4"
local image="$5"
local context_dir="${FAST_CONTEXT_ROOT}/${service}"
cleanup_context "${context_dir}"
mkdir -p "${context_dir}/app"
local publish_args=(
publish "${ROOT}/${project}"
-c Release
-o "${context_dir}/app"
/p:UseAppHost=false
/p:PublishTrimmed=false
--nologo
)
if [[ "${PUBLISH_NO_RESTORE}" == "true" ]]; then
publish_args+=(--no-restore)
fi
dotnet "${publish_args[@]}" || {
cleanup_context "${context_dir}"
return 1
}
cp "${RUNTIME_DOCKERFILE}" "${context_dir}/Dockerfile"
cp "${HEALTHCHECK_SCRIPT}" "${context_dir}/healthcheck.sh"
docker build \
-f "${context_dir}/Dockerfile" "${context_dir}" \
--build-arg "RUNTIME_IMAGE=${RUNTIME_IMAGE}" \
--build-arg "APP_BINARY=${binary}" \
--build-arg "APP_PORT=${port}" \
-t "${image}"
local build_status=$?
cleanup_context "${context_dir}"
return ${build_status}
}
while IFS='|' read -r service dockerfile project binary port; do
[[ -z "${service}" || "${service}" =~ ^# ]] && continue
should_build_service "${service}" || continue
image="${REGISTRY}/${service}:${TAG_SUFFIX}"
df_path="${ROOT}/${dockerfile}"
if [[ ! -f "${df_path}" ]]; then
echo "skipping ${service}: dockerfile missing (${df_path})" >&2
continue
fi
if [[ "${dockerfile}" == *"Dockerfile.console"* ]]; then
echo "[console] ${service} -> ${image}" >&2
docker build \
-f "${df_path}" "${ROOT}" \
--build-arg APP_DIR="${project}" \
--build-arg APP_PORT="${port}" \
-t "${image}"
elif [[ "${USE_LEGACY_REPO_CONTEXT}" != "true" && "${dockerfile}" == *"Dockerfile.hardened.template"* ]]; then
echo "[service fast] ${service} -> ${image}" >&2
build_published_service_image "${service}" "${project}" "${binary}" "${port}" "${image}"
else
echo "[service] ${service} -> ${image}" >&2
docker build \
-f "${df_path}" "${ROOT}" \
--build-arg SDK_IMAGE="${SDK_IMAGE}" \
--build-arg RUNTIME_IMAGE="${RUNTIME_IMAGE}" \
--build-arg APP_PROJECT="${project}" \
--build-arg APP_BINARY="${binary}" \
--build-arg APP_PORT="${port}" \
-t "${image}"
fi
if [[ $? -eq 0 ]]; then
SUCCEEDED+=("${service}")
else
FAILED+=("${service}")
echo "FAILED: ${service}" >&2
fi
done < "${MATRIX}"
echo "" >&2
echo "=== BUILD RESULTS ===" >&2
echo "Succeeded (${#SUCCEEDED[@]}): ${SUCCEEDED[*]:-none}" >&2
echo "Failed (${#FAILED[@]}): ${FAILED[*]:-none}" >&2
echo "" >&2
if [[ ${#FAILED[@]} -gt 0 ]]; then
echo "Some builds failed. Fix the issues and re-run." >&2
exit 1
fi
echo "Build complete. Remember to enforce readOnlyRootFilesystem at deploy time and run sbom_attest.sh (DOCKER-44-002)." >&2