Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
registry=https://pkgs.dev.azure.com/agentaflow/agentbase/_packaging/python/npm/registry/
always-auth=true
9 changes: 9 additions & 0 deletions azure-pipelines/agentbase-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ stages:
displayName: 'Use Node.js 20'
inputs:
versionSpec: '20.x'
- task: NpmAuthenticate@0
displayName: 'Authenticate npm → Azure Artifacts'
inputs:
workingFile: .npmrc
- script: |
corepack enable && corepack prepare pnpm@9 --activate
pnpm install --frozen-lockfile || pnpm install
Expand All @@ -111,6 +115,11 @@ stages:
displayName: 'Use Python 3.12'
inputs:
versionSpec: '3.12'
- task: PipAuthenticate@1
displayName: 'Authenticate pip → Azure Artifacts'
inputs:
artifactsFeeds: 'agentbase/python'
onlyAddExtraIndex: false
- script: |
pip install -r packages/ai-service/requirements.txt
pip install pip-audit pytest
Expand Down
12 changes: 11 additions & 1 deletion azure-pipelines/templates/deploy-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,34 @@ stages:
echo "##vso[task.setvariable variable=AI_URL]$(out aiUrl)"

# 2 · Build & push the three images server-side in ACR (no agent Docker).
# AZURE_ARTIFACTS_TOKEN (System.AccessToken) is passed as a build arg so
# each Dockerfile can authenticate to the Azure Artifacts npm/PyPI feeds
# during the package install step inside the build.
- task: AzureCLI@2
displayName: '2 · Build & push images (az acr build)'
env:
AZURE_ARTIFACTS_TOKEN: $(System.AccessToken)
inputs:
azureSubscription: ${{ parameters.serviceConnection }}
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
set -euo pipefail
# Construct authenticated PyPI URL from the same token (basic-auth format)
ARTIFACTS_PIP_URL="https://build:${AZURE_ARTIFACTS_TOKEN}@pkgs.dev.azure.com/agentaflow/agentbase/_packaging/python/pypi/simple/"
az acr build --registry "$(ACR_NAME)" \
--build-arg AZURE_ARTIFACTS_TOKEN="$AZURE_ARTIFACTS_TOKEN" \
--image agentbase-core:$(imageTag) --image agentbase-core:latest \
--file packages/core/Dockerfile .
az acr build --registry "$(ACR_NAME)" \
--build-arg AZURE_ARTIFACTS_PIP_URL="$ARTIFACTS_PIP_URL" \
--image agentbase-ai-service:$(imageTag) --image agentbase-ai-service:latest \
--file packages/ai-service/Dockerfile .
az acr build --registry "$(ACR_NAME)" \
--image agentbase-frontend:$(imageTag) --image agentbase-frontend:latest \
--build-arg AZURE_ARTIFACTS_TOKEN="$AZURE_ARTIFACTS_TOKEN" \
--build-arg NEXT_PUBLIC_API_URL="$(CORE_URL)/api" \
--build-arg NEXT_PUBLIC_AI_URL="$(AI_URL)/api" \
--image agentbase-frontend:$(imageTag) --image agentbase-frontend:latest \
--file packages/frontend/Dockerfile .

# 3 · Seed Key Vault. Secret values are mapped through env: (required for
Expand Down
15 changes: 10 additions & 5 deletions packages/ai-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# ---- Build Stage ----
FROM python:3.12-slim AS builder
FROM mcr.microsoft.com/cbl-mariner/base/python:3.12 AS builder
WORKDIR /app

COPY packages/ai-service/requirements.txt .
RUN pip install --no-cache-dir --target=/deps -r requirements.txt

# Inject Azure Artifacts PyPI URL; falls back to public PyPI for local builds without the arg
ARG AZURE_ARTIFACTS_PIP_URL
RUN pip install --no-cache-dir \
--index-url "${AZURE_ARTIFACTS_PIP_URL:-https://pypi.org/simple/}" \
--target=/deps -r requirements.txt

# ---- Production Stage ----
FROM python:3.12-slim AS production
FROM mcr.microsoft.com/cbl-mariner/base/python:3.12 AS production
WORKDIR /app

RUN addgroup --system agentbase && adduser --system --group agentbase
RUN apt-get update && apt-get install -y --no-install-recommends wget && rm -rf /var/lib/apt/lists/*
RUN groupadd -r agentbase && useradd -r -g agentbase -s /sbin/nologin -M agentbase
RUN tdnf install -y wget

COPY --from=builder /deps /usr/local/lib/python3.12/site-packages
COPY packages/ai-service/app ./app
Expand Down
20 changes: 12 additions & 8 deletions packages/core/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
# ---- Build Stage ----
FROM node:20-alpine AS builder
FROM mcr.microsoft.com/cbl-mariner/base/nodejs:20 AS builder
WORKDIR /app

# Install pnpm
RUN corepack enable && corepack prepare pnpm@9 --activate

# Copy workspace config
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml* ./
# Copy workspace config and registry settings
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml* .npmrc ./
COPY packages/core/package.json packages/core/
COPY packages/shared/package.json packages/shared/

# Install dependencies
# Inject Azure Artifacts auth token; strip it after install so the layer has no creds
ARG AZURE_ARTIFACTS_TOKEN
RUN if [ -n "${AZURE_ARTIFACTS_TOKEN}" ]; then \
echo "//pkgs.dev.azure.com/agentaflow/agentbase/_packaging/python/npm/registry/:_authToken=${AZURE_ARTIFACTS_TOKEN}" >> .npmrc; \
fi
RUN pnpm install --frozen-lockfile 2>/dev/null || pnpm install
RUN sed -i '/_authToken/d' .npmrc

# Copy source
COPY packages/shared packages/shared
Expand All @@ -23,19 +28,19 @@ WORKDIR /app/packages/core
RUN npx nest build

# ---- Production Stage ----
FROM node:20-alpine AS production
FROM mcr.microsoft.com/cbl-mariner/base/nodejs:20 AS production
WORKDIR /app

RUN corepack enable && corepack prepare pnpm@9 --activate
RUN apk add --no-cache tini
RUN tdnf install -y wget

# Copy built app
COPY --from=builder /app/packages/core/dist ./dist
COPY --from=builder /app/packages/core/package.json ./
COPY --from=builder /app/node_modules ./node_modules

# Non-root user
RUN addgroup -g 1001 -S agentbase && adduser -S agentbase -u 1001
RUN groupadd -g 1001 agentbase && useradd -u 1001 -g agentbase -s /sbin/nologin -M agentbase
USER agentbase

ENV NODE_ENV=production
Expand All @@ -44,5 +49,4 @@ EXPOSE 3001
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
CMD wget -q --spider http://localhost:3001/api/health || exit 1

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "dist/main.js"]
18 changes: 12 additions & 6 deletions packages/frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
# ---- Build Stage ----
FROM node:20-alpine AS builder
FROM mcr.microsoft.com/cbl-mariner/base/nodejs:20 AS builder
WORKDIR /app

RUN corepack enable && corepack prepare pnpm@9 --activate

COPY package.json pnpm-workspace.yaml pnpm-lock.yaml* ./
# Copy workspace config and registry settings
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml* .npmrc ./
COPY packages/frontend/package.json packages/frontend/
COPY packages/shared/package.json packages/shared/

# Inject Azure Artifacts auth token; strip it after install so the layer has no creds
ARG AZURE_ARTIFACTS_TOKEN
RUN if [ -n "${AZURE_ARTIFACTS_TOKEN}" ]; then \
echo "//pkgs.dev.azure.com/agentaflow/agentbase/_packaging/python/npm/registry/:_authToken=${AZURE_ARTIFACTS_TOKEN}" >> .npmrc; \
fi
RUN pnpm install --frozen-lockfile 2>/dev/null || pnpm install
RUN sed -i '/_authToken/d' .npmrc

COPY packages/shared packages/shared
COPY packages/frontend packages/frontend
Expand All @@ -23,16 +30,16 @@ ENV NEXT_PUBLIC_AI_URL=$NEXT_PUBLIC_AI_URL
RUN npx next build

# ---- Production Stage ----
FROM node:20-alpine AS production
FROM mcr.microsoft.com/cbl-mariner/base/nodejs:20 AS production
WORKDIR /app

RUN apk add --no-cache tini
RUN tdnf install -y wget

COPY --from=builder /app/packages/frontend/.next/standalone ./
COPY --from=builder /app/packages/frontend/.next/static ./.next/static
COPY --from=builder /app/packages/frontend/public ./public

RUN addgroup -g 1001 -S agentbase && adduser -S agentbase -u 1001
RUN groupadd -g 1001 agentbase && useradd -u 1001 -g agentbase -s /sbin/nologin -M agentbase
USER agentbase

ENV NODE_ENV=production
Expand All @@ -41,5 +48,4 @@ EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
CMD wget -q --spider http://localhost:3000/ || exit 1

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "server.js"]
Loading