# syntax=docker/dockerfile:1.7
# Build context: repository root.
# Targets are independent L0 release images:
#   docker build --target runtime-api -f infra/runtime.Dockerfile .
#   docker build --target runtime-worker -f infra/runtime.Dockerfile .
# The Runtime API image also carries the one-shot app-blind Controlplane CLI;
# selecting that entrypoint does not create another serving role or image.

FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder

ARG TARGETOS=linux
ARG TARGETARCH
ARG VERSION=dev
ARG SOURCE_REVISION=dev

# Release versions are human-facing aliases. A release build must also carry
# the exact source revision used by Runtime admission; older signers that only
# pass VERSION fail here before they can publish a partially valid image.
RUN if printf '%s\n' "$VERSION" | grep -Eq '^dev-[0-9]{8}-[0-9]+\.[0-9]+\.[0-9]+-[0-9a-f]{8}$'; then \
      printf '%s\n' "$SOURCE_REVISION" | grep -Eq '^[0-9a-f]{40}$'; \
    fi

RUN apk add --no-cache ca-certificates git openssh-client \
    && mkdir -p /root/.ssh \
    && chmod 700 /root/.ssh \
    && ssh-keyscan github.com >> /root/.ssh/known_hosts \
    && git config --global url."git@github.com-nexuscrm-connectors:pingcap-inc/nexuscrm-connectors".insteadOf "https://github.com/pingcap-inc/nexuscrm-connectors" \
    && git config --global url."git@github.com-nexuscrm-api-host:pingcap-inc/nexuscrm-api-host".insteadOf "https://github.com/pingcap-inc/nexuscrm-api-host" \
    && git config --global url."git@github.com-nexuscrm-contract:pingcap-inc/nexuscrm-contract".insteadOf "https://github.com/pingcap-inc/nexuscrm-contract" \
    && git config --global url."git@github.com-nexuscrm-controlplane:pingcap-inc/nexuscrm-controlplane".insteadOf "https://github.com/pingcap-inc/nexuscrm-controlplane"

ENV GOPRIVATE=github.com/pingcap-inc/nexuscrm-connectors,github.com/pingcap-inc/nexuscrm-api-host,github.com/pingcap-inc/nexuscrm-contract,github.com/pingcap-inc/nexuscrm-controlplane
ENV GONOSUMDB=github.com/pingcap-inc/nexuscrm-connectors,github.com/pingcap-inc/nexuscrm-api-host,github.com/pingcap-inc/nexuscrm-contract,github.com/pingcap-inc/nexuscrm-controlplane

WORKDIR /src

# Copy the app-blind backend module and its L0 local-replace graph. No
# distribution, app-pack, tenant overlay, frontend, or fixture enters this build.
COPY shared/go.mod shared/go.sum ./shared/
COPY backend/go.mod backend/go.sum ./backend/
COPY nexuscrm-analytics/go.mod ./nexuscrm-analytics/
COPY nexuscrm-audit/go.mod ./nexuscrm-audit/
COPY nexuscrm-auth/go.mod ./nexuscrm-auth/
COPY nexuscrm-automation/go.mod ./nexuscrm-automation/
COPY nexuscrm-db/go.mod ./nexuscrm-db/
COPY nexuscrm-events/go.mod ./nexuscrm-events/
COPY nexuscrm-files/go.mod ./nexuscrm-files/
COPY nexuscrm-kernel/go.mod ./nexuscrm-kernel/
COPY nexuscrm-metadata/go.mod ./nexuscrm-metadata/
COPY nexuscrm-outbound/go.mod ./nexuscrm-outbound/
COPY nexuscrm-permissions/go.mod ./nexuscrm-permissions/
COPY nexuscrm-persistence/go.mod ./nexuscrm-persistence/
COPY nexuscrm-records/go.mod ./nexuscrm-records/
COPY nexuscrm-storage/go.mod ./nexuscrm-storage/
COPY nexuscrm-worker/go.mod ./nexuscrm-worker/

WORKDIR /src
COPY shared/ ./shared/
COPY backend/ ./backend/
COPY nexuscrm-analytics/ ./nexuscrm-analytics/
COPY nexuscrm-audit/ ./nexuscrm-audit/
COPY nexuscrm-auth/ ./nexuscrm-auth/
COPY nexuscrm-automation/ ./nexuscrm-automation/
COPY nexuscrm-db/ ./nexuscrm-db/
COPY nexuscrm-events/ ./nexuscrm-events/
COPY nexuscrm-files/ ./nexuscrm-files/
COPY nexuscrm-kernel/ ./nexuscrm-kernel/
COPY nexuscrm-metadata/ ./nexuscrm-metadata/
COPY nexuscrm-outbound/ ./nexuscrm-outbound/
COPY nexuscrm-permissions/ ./nexuscrm-permissions/
COPY nexuscrm-persistence/ ./nexuscrm-persistence/
COPY nexuscrm-records/ ./nexuscrm-records/
COPY nexuscrm-storage/ ./nexuscrm-storage/
COPY nexuscrm-worker/ ./nexuscrm-worker/

WORKDIR /src/backend
RUN --mount=type=secret,id=nexuscrm_connectors_deploy_key,target=/run/secrets/nexuscrm_connectors_deploy_key,mode=0600 \
    --mount=type=secret,id=nexuscrm_api_host_deploy_key,target=/run/secrets/nexuscrm_api_host_deploy_key,mode=0600 \
    --mount=type=secret,id=nexuscrm_contract_deploy_key,target=/run/secrets/nexuscrm_contract_deploy_key,mode=0600 \
    --mount=type=secret,id=nexuscrm_controlplane_deploy_key,target=/run/secrets/nexuscrm_controlplane_deploy_key,mode=0600 \
    --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build <<'EOF'
set -e
connectors_key="$(mktemp)"
api_host_key="$(mktemp)"
contract_key="$(mktemp)"
controlplane_key="$(mktemp)"
ssh_config="$(mktemp)"
trap 'rm -f "$connectors_key" "$api_host_key" "$contract_key" "$controlplane_key" "$ssh_config"' EXIT
for pair in \
  "nexuscrm_connectors_deploy_key:$connectors_key" \
  "nexuscrm_api_host_deploy_key:$api_host_key" \
  "nexuscrm_contract_deploy_key:$contract_key" \
  "nexuscrm_controlplane_deploy_key:$controlplane_key"; do
  source="${pair%%:*}"
  destination="${pair#*:}"
  tr -d '\r' < "/run/secrets/$source" > "$destination"
  printf '\n' >> "$destination"
  chmod 600 "$destination"
done
cat > "$ssh_config" <<CONFIG
Host github.com-nexuscrm-connectors
  HostName github.com
  User git
  IdentityFile $connectors_key
  IdentitiesOnly yes
Host github.com-nexuscrm-api-host
  HostName github.com
  User git
  IdentityFile $api_host_key
  IdentitiesOnly yes
Host github.com-nexuscrm-contract
  HostName github.com
  User git
  IdentityFile $contract_key
  IdentitiesOnly yes
Host github.com-nexuscrm-controlplane
  HostName github.com
  User git
  IdentityFile $controlplane_key
  IdentitiesOnly yes
CONFIG
GIT_SSH_COMMAND="ssh -F $ssh_config" CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
  go build -trimpath -ldflags="-s -w -X main.version=${SOURCE_REVISION}" -o /out/runtime-api ./cmd/runtime-api/
GIT_SSH_COMMAND="ssh -F $ssh_config" CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
  go build -trimpath -ldflags="-s -w -X main.version=${SOURCE_REVISION}" -o /out/runtime-worker ./cmd/runtime-worker/
GIT_SSH_COMMAND="ssh -F $ssh_config" CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
  go build -trimpath -ldflags="-s -w" -o /out/l0-controlplane ./cmd/setup/
EOF

FROM alpine:3.20 AS runtime-base
RUN apk add --no-cache ca-certificates git tzdata \
    && addgroup -S -g 10001 runtime \
    && adduser -S -D -H -u 10001 -G runtime runtime \
    && mkdir -p /etc/nexuscrm \
    && chown -R runtime:runtime /etc/nexuscrm
USER 10001:10001

FROM runtime-base AS runtime-api
ARG VERSION=dev
ARG SOURCE_REVISION=dev
LABEL org.opencontainers.image.title="NexusCRM Runtime API" \
      org.opencontainers.image.version="${VERSION}" \
      org.opencontainers.image.revision="${SOURCE_REVISION}" \
      dev.nexuscrm.runtime.role="runtime-api"
COPY --from=builder /out/runtime-api /usr/local/bin/runtime-api
COPY --from=builder /out/l0-controlplane /usr/local/bin/l0-controlplane
COPY --from=builder /src/backend/internal/runtimeconfig/schema/runtime-api.schema.json /etc/nexuscrm/config-schema.json
COPY --from=builder /src/backend/internal/runtimeproduction/host-compatibility.json /etc/nexuscrm/host-compatibility.json
EXPOSE 9090 9091
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD wget -qO- http://127.0.0.1:9091/livez >/dev/null || exit 1
ENTRYPOINT ["/usr/local/bin/runtime-api"]

FROM runtime-base AS runtime-worker
ARG VERSION=dev
ARG SOURCE_REVISION=dev
LABEL org.opencontainers.image.title="NexusCRM Runtime Worker" \
      org.opencontainers.image.version="${VERSION}" \
      org.opencontainers.image.revision="${SOURCE_REVISION}" \
      dev.nexuscrm.runtime.role="runtime-worker"
COPY --from=builder /out/runtime-worker /usr/local/bin/runtime-worker
COPY --from=builder /src/backend/internal/runtimeconfig/schema/runtime-worker.schema.json /etc/nexuscrm/config-schema.json
EXPOSE 9191
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD wget -qO- http://127.0.0.1:9191/livez >/dev/null || exit 1
ENTRYPOINT ["/usr/local/bin/runtime-worker"]
