Files
missions/_docs/02_document/deployment/containerization.md
T
Oleksandr Bezdieniezhnykh 7025f4d075 refactor: enhance JWT authentication and CORS configuration
Updated JWT authentication to use configuration values instead of hardcoded secrets, improving security and flexibility. Enhanced CORS policy to conditionally allow origins based on configuration settings, with logging for permissive defaults. Updated README to reflect project renaming and clarify service context.
2026-05-14 19:48:25 +03:00

4.6 KiB

Containerization

NOTE (forward-looking): image tag, csproj name, and entrypoint reflect the post-rename state. Today's Dockerfile ENTRYPOINT is dotnet Azaion.Flights.dll and the image tag base is azaion/flights. Renames tracked under Jira AZ-EPIC children B5 (csproj/namespace) and B10 (Dockerfile entrypoint + Woodpecker image tag).

Source

./Dockerfile (single Dockerfile at the repo root). Multi-arch via build args.

Build strategy: multi-arch from a single Dockerfile

FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG TARGETARCH
WORKDIR /src
COPY . .
RUN arch=$([ "$TARGETARCH" = "amd64" ] && echo "x64" || echo "$TARGETARCH") && \
    dotnet publish -c Release -o /app --os linux --arch $arch

FROM mcr.microsoft.com/dotnet/aspnet:10.0
ARG CI_COMMIT_SHA=unknown
ENV AZAION_REVISION=$CI_COMMIT_SHA
WORKDIR /app
COPY --from=build /app .
EXPOSE 8080
ENTRYPOINT ["dotnet", "Azaion.Missions.dll"]   # post-B5 + B10

Key choices:

  • --platform=$BUILDPLATFORM on the build stage — the SDK runs on the builder's native architecture (typically AMD64 in CI), but dotnet publish --os linux --arch $arch cross-publishes for the target architecture (arm64 for Jetson / OPi; amd64 for operator-PC). This avoids needing QEMU emulation for the (slow) build phase.
  • Two-stage: SDK image (~800 MB) for the build, runtime image (mcr.microsoft.com/dotnet/aspnet:10.0, ~210 MB) for the published artifacts. Final image carries no SDK, no source code, no .csproj.
  • AZAION_REVISION env var baked from CI_COMMIT_SHA at build time — surfaces the source commit at runtime for support / triage. Not consumed by the application code today; visible only via docker inspect or env in the running container.
  • EXPOSE 8080 matches the ASP.NET Core default (no ASPNETCORE_URLS override) and the edge compose port mapping 5002:8080.

What the Dockerfile does NOT do (carry-forward improvements)

  • No .dockerignore — every file under the repo root is copied into the build context, including _docs/, .cursor/, and the previously-committed obj/ / bin/ (cleaned by dotnet publish but still copied across the wire). A .dockerignore would shrink the build context meaningfully on Jetson-class builders. Tracked as opportunistic improvement.
  • No HEALTHCHECK directive/health exists in the application (Flow F7) but the container itself does not declare a healthcheck. Compose-level healthcheck is the suite's expected mechanism.
  • No non-root USER — the runtime image runs as root. The aspnet:10.0 base image supports a non-root user (USER app) since .NET 8; switching is a one-line change on the next refresh and would tighten container isolation.
  • No build-time test pass — no dotnet test step. The repo has no test project today (tracked in ../../../suite/_docs/_process_leftovers/2026-04-22_ci-unit-test-lane-missing-projects.md); when a tests/Azaion.Missions.Tests/ project lands, a pre-publish dotnet test step is the natural next addition.

Image lifecycle on edge devices

  1. Woodpecker builds + pushes ${REGISTRY_HOST}/azaion/missions:${BRANCH}-arm (post-B10) on every push to dev / stage / main (see ci_cd_pipeline.md).
  2. Watchtower running on each edge device polls the registry; on a new digest for the device's pinned tag, it pulls and re-creates the container.
  3. flight-gate (per ../../../suite/_docs/00_top_level_architecture.md) prevents container restart mid-mission. Once the active mission completes, the new image becomes live.
  4. Container starts → Program.cs → migrator → app.Run() (Flow F6).

Image variants and tag strategy

Branch Tag (post-B10) Audience
dev azaion/missions:dev-arm Engineers; rolling latest-dev
stage azaion/missions:stage-arm Pre-prod customer demo devices
main azaion/missions:main-arm Production edge fleets

No semantic version tags today (no v1.2.3-style tags). Watchtower polls the named tags directly. Carry-forward improvement: add ${REGISTRY_HOST}/azaion/missions:${CI_COMMIT_SHA:0:8}-arm alongside the branch tag so rollback to a specific build is possible without rebuilding.

Multi-arch — current limitation

Today the Woodpecker pipeline (ci_cd_pipeline.md) builds only the arm64 variant (the runner is ARM64-labeled and the tag suffix is -arm). For AMD64 (operator-PC) deployments, a second pipeline / second runner / linux/amd64 build args would be needed. Out of this Epic — the current operator-PC deployment story uses local builds.