Skip to content

Commit d11970a

Browse files
feat: refactor mcp server Dockerfile to compatible with uv sync and added bicep code for container app
1 parent 6e8fce5 commit d11970a

File tree

2 files changed

+122
-16
lines changed

2 files changed

+122
-16
lines changed

infra/main.bicep

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,101 @@ module containerApp 'br/public:avm/res/app/container-app:0.14.2' = if (container
10461046
}
10471047
}
10481048

1049+
var containerAppMcpResourceName = 'ca-mcp-${solutionPrefix}'
1050+
module containerAppMcp 'br/public:avm/res/app/container-app:0.18.1' = if (containerAppEnabled) {
1051+
name: take('avm.res.app.container-app.${containerAppMcpResourceName}', 64)
1052+
params: {
1053+
name: containerAppMcpResourceName
1054+
tags: containerAppConfiguration.?tags ?? tags
1055+
location: containerAppConfiguration.?location ?? solutionLocation
1056+
enableTelemetry: enableTelemetry
1057+
environmentResourceId: containerAppConfiguration.?environmentResourceId ?? containerAppEnvironment.outputs.resourceId
1058+
managedIdentities: {
1059+
systemAssigned: true
1060+
userAssignedResourceIds: [userAssignedIdentity!.outputs.resourceId]
1061+
}
1062+
ingressTargetPort: containerAppConfiguration.?ingressTargetPort ?? 8000
1063+
ingressExternal: true
1064+
activeRevisionsMode: 'Single'
1065+
corsPolicy: {
1066+
allowedOrigins: [
1067+
]
1068+
}
1069+
// WAF aligned configuration for Scalability
1070+
scaleSettings: {
1071+
maxReplicas: containerAppConfiguration.?maxReplicas ?? 1
1072+
minReplicas: containerAppConfiguration.?minReplicas ?? 1
1073+
rules: [
1074+
{
1075+
name: 'http-scaler'
1076+
http: {
1077+
metadata: {
1078+
concurrentRequests: containerAppConfiguration.?concurrentRequests ?? '100'
1079+
}
1080+
}
1081+
}
1082+
]
1083+
}
1084+
containers: [
1085+
{
1086+
name: 'mcp'
1087+
image: 'macaer.azurecr.io/macaebackend:macaev3' //'${containerAppConfiguration.?containerImageRegistryDomain ?? 'biabcontainerreg.azurecr.io'}/${containerAppConfiguration.?containerImageName ?? 'macaebackend'}:${containerAppConfiguration.?containerImageTag ?? 'latest'}'
1088+
resources: {
1089+
//TODO: Make cpu and memory parameterized
1090+
cpu: containerAppConfiguration.?containerCpu ?? '2.0'
1091+
memory: containerAppConfiguration.?containerMemory ?? '4.0Gi'
1092+
}
1093+
env: [
1094+
{
1095+
name: 'MCP_HOST'
1096+
value: '0.0.0.0'
1097+
}
1098+
{
1099+
name: 'MCP_PORT'
1100+
value: '9000'
1101+
}
1102+
{
1103+
name: 'MCP_DEBUG'
1104+
value: 'false'
1105+
}
1106+
{
1107+
name: 'MCP_SERVER_NAME'
1108+
value: 'MACAE MCP Server'
1109+
}
1110+
{
1111+
name: 'MCP_ENABLE_AUTH'
1112+
value: 'true'
1113+
}
1114+
{
1115+
name: 'AZURE_TENANT_ID'
1116+
value: tenant().tenantId
1117+
}
1118+
{
1119+
name: 'AZURE_CLIENT_ID'
1120+
value: userAssignedIdentity!.outputs.clientId
1121+
}
1122+
{
1123+
name: 'AZURE_JWKS_URI'
1124+
value: 'https://login.microsoftonline.com/${tenant().tenantId}/discovery/v2.0/keys'
1125+
}
1126+
{
1127+
name: 'AZURE_ISSUER'
1128+
value: 'https://sts.windows.net/${tenant().tenantId}/'
1129+
}
1130+
{
1131+
name: 'AZURE_AUDIENCE'
1132+
value: 'api://${userAssignedIdentity!.outputs.clientId}'
1133+
}
1134+
{
1135+
name: 'DATASET_PATH'
1136+
value: './datasets'
1137+
}
1138+
]
1139+
}
1140+
]
1141+
}
1142+
}
1143+
10491144
var webServerFarmEnabled = webServerFarmConfiguration.?enabled ?? true
10501145
var webServerFarmResourceName = webServerFarmConfiguration.?name ?? 'asp-${solutionPrefix}'
10511146

src/mcp_server/Dockerfile

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1-
FROM python:3.11-slim
2-
3-
# Set working directory
1+
FROM mcr.microsoft.com/devcontainers/python:3.11-bullseye AS base
42
WORKDIR /app
53

6-
# Install system dependencies
7-
RUN apt-get update && apt-get install -y \
8-
gcc \
9-
&& rm -rf /var/lib/apt/lists/*
4+
FROM base AS builder
5+
6+
# Copy uv binaries from astral-sh image
7+
COPY --from=ghcr.io/astral-sh/uv:0.6.3 /uv /uvx /bin/
8+
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
9+
10+
# Copy lock and project files first for caching
11+
COPY uv.lock pyproject.toml /app/
12+
13+
# Install dependencies (frozen, no dev) using uv
14+
RUN --mount=type=cache,target=/root/.cache/uv \
15+
uv sync --frozen --no-install-project --no-dev
1016

11-
# Copy requirements first for better caching
12-
COPY requirements.txt .
17+
# Copy application code and install project dependencies
18+
COPY . /app
19+
RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev
20+
21+
# Final stage
22+
FROM base
23+
24+
WORKDIR /app
25+
COPY --from=builder /app /app
26+
COPY --from=builder /bin/uv /bin/uv
1327

14-
# Install Python dependencies
15-
RUN pip install --no-cache-dir -r requirements.txt
16-
####
17-
# Copy the application
18-
COPY . .
28+
# Set PATH to use venv created by uv
29+
ENV PATH="/app/.venv/bin:$PATH"
1930

2031
# Create non-root user
2132
RUN useradd --create-home --shell /bin/bash app && chown -R app:app /app
@@ -28,5 +39,5 @@ EXPOSE 9000
2839
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
2940
CMD curl -f http://localhost:9000/health || exit 1
3041

31-
# Default command
32-
CMD ["python", "mcp_server.py"]
42+
# Run your main script
43+
CMD ["uv", "run", "python", "mcp_server.py"]

0 commit comments

Comments
 (0)