-
Notifications
You must be signed in to change notification settings - Fork 20
fix: enable container deployment for Python Agent Framework sample #218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: enable container deployment for Python Agent Framework sample #218
Conversation
Problem: The Python Agent Framework sample bound to 'localhost' which prevented the agent from receiving external traffic when running in containers. Health checks failed and Bot Framework messages couldn't reach the agent. Solution: - Changed network binding from 'localhost' to '0.0.0.0' in host_agent_server.py - Added Dockerfile for containerized deployments - Added .dockerignore to exclude dev files from container builds - Added comprehensive Container Deployment section to README explaining: - Why container deployment is recommended for production - Azure integration benefits (Container Apps, AKS, ACR) - Network binding requirements for containerized agents - Build and deployment instructions for Docker and Azure Container Apps This fix was discovered while deploying to Azure Container Apps for a shared demo tenant. The agent worked locally but failed all health checks when containerized due to the localhost binding limitation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Enables container-friendly deployment for the Python Agent Framework sample by adjusting the server bind address and adding Docker tooling + documentation to support running in Docker/Azure container environments.
Changes:
- Bind the aiohttp server to
0.0.0.0instead oflocalhostso the agent is reachable outside containers. - Add a Dockerfile and
.dockerignorefor building/running the sample in containers. - Extend the sample README with container deployment guidance (Docker + Azure Container Apps).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| python/agent-framework/sample-agent/host_agent_server.py | Updates server bind address and startup log output for container networking. |
| python/agent-framework/sample-agent/README.md | Adds container deployment documentation and example commands. |
| python/agent-framework/sample-agent/Dockerfile | Introduces a container build/run path with an HTTP healthcheck. |
| python/agent-framework/sample-agent/.dockerignore | Reduces Docker build context by excluding common local/dev files. |
| # Install Python dependencies from pyproject.toml | ||
| RUN pip install --no-cache-dir --root-user-action=ignore . | ||
|
|
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR description mentions “Non-root user considerations”, but this Dockerfile runs everything as root (and suppresses root warnings via --root-user-action=ignore). If the intent is a production-ready container, consider adding a non-root user and switching to it before running the app (and installing deps accordingly).
| # Copy application code | ||
| COPY . . | ||
|
|
||
| # Install Python dependencies from pyproject.toml | ||
| RUN pip install --no-cache-dir --root-user-action=ignore . | ||
|
|
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For faster/cleaner image builds, consider copying only pyproject.toml (and any lock file) first, installing dependencies, then copying the rest of the source. The current “COPY . .” before dependency installation makes Docker layer caching ineffective and will reinstall deps on any source change.
| # Copy application code | |
| COPY . . | |
| # Install Python dependencies from pyproject.toml | |
| RUN pip install --no-cache-dir --root-user-action=ignore . | |
| # Copy dependency metadata first for better caching | |
| COPY pyproject.toml . | |
| # Install Python dependencies from pyproject.toml | |
| RUN pip install --no-cache-dir --root-user-action=ignore . | |
| # Copy application code | |
| COPY . . |
| ```bash | ||
| docker build -t python-agent . | ||
| docker run -p 3978:3978 \ | ||
| -e AZURE_OPENAI_ENDPOINT=https://your-endpoint.openai.azure.com/ \ | ||
| -e AZURE_OPENAI_API_KEY=your-key \ | ||
| -e AZURE_OPENAI_DEPLOYMENT=gpt-4o \ | ||
| python-agent |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Docker build/run snippet assumes the current working directory is the sample-agent folder. If a reader runs this from the repo root, it will either fail or pick up the wrong context. Consider clarifying the working directory (cd into python/agent-framework/sample-agent) or using an explicit -f path + build context in the command.
| # Build and push to Azure Container Registry | ||
| az acr build --registry <your-acr> --image python-agent:latest . | ||
|
|
||
| # Create Container App | ||
| az containerapp create \ | ||
| --name python-agent \ | ||
| --resource-group <your-rg> \ | ||
| --environment <your-env> \ | ||
| --image <your-acr>.azurecr.io/python-agent:latest \ | ||
| --target-port 3978 \ | ||
| --ingress external |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Azure Container Apps example doesn’t show how to provide required runtime configuration (e.g., AZURE_OPENAI_ENDPOINT/API_KEY/DEPLOYMENT, and any bot/auth settings) to the container app. Without setting these env vars/secrets, the deployed container likely won’t start successfully. Consider adding an example using --env-vars / secrets, and noting prerequisites like Azure CLI login and an ACR pull identity if needed.
| # Build and push to Azure Container Registry | |
| az acr build --registry <your-acr> --image python-agent:latest . | |
| # Create Container App | |
| az containerapp create \ | |
| --name python-agent \ | |
| --resource-group <your-rg> \ | |
| --environment <your-env> \ | |
| --image <your-acr>.azurecr.io/python-agent:latest \ | |
| --target-port 3978 \ | |
| --ingress external | |
| # Make sure you are logged in and using the correct subscription | |
| az login | |
| az account set --subscription <your-subscription-id> | |
| # Build and push to Azure Container Registry | |
| az acr build --registry <your-acr> --image python-agent:latest . | |
| # Create Container App (ensure this environment can pull from your ACR) | |
| az containerapp create \ | |
| --name python-agent \ | |
| --resource-group <your-rg> \ | |
| --environment <your-env> \ | |
| --image <your-acr>.azurecr.io/python-agent:latest \ | |
| --target-port 3978 \ | |
| --ingress external \ | |
| --env-vars \ | |
| AZURE_OPENAI_ENDPOINT=https://your-endpoint.openai.azure.com/ \ | |
| AZURE_OPENAI_API_KEY=your-key \ | |
| AZURE_OPENAI_DEPLOYMENT=gpt-4o |
| # Python | ||
| __pycache__/ | ||
| *.py[cod] | ||
| .venv/ | ||
| venv/ | ||
|
|
||
| # IDE | ||
| .vscode/ | ||
| .idea/ | ||
|
|
||
| # Local files | ||
| .env | ||
| .env.local | ||
| *.log | ||
|
|
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding common Python build artifacts to .dockerignore (e.g., .pytest_cache/, .mypy_cache/, .ruff_cache/, build/, dist/, *.egg-info/). Excluding these helps avoid accidentally copying local build outputs into the image and improves build performance.
| print(f"📚 Endpoint: http://localhost:{port}/api/messages") | ||
| print(f"❤️ Health: http://localhost:{port}/api/health\n") |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The server now binds to 0.0.0.0, but the printed Endpoint/Health URLs still use http://localhost. In container/remote scenarios this is misleading (localhost from a different machine won’t reach the container). Consider printing 0.0.0.0 or deriving a display host (e.g., from an env var) to keep the startup output consistent with the actual binding.
| print(f"📚 Endpoint: http://localhost:{port}/api/messages") | |
| print(f"❤️ Health: http://localhost:{port}/api/health\n") | |
| print(f"📚 Endpoint: http://0.0.0.0:{port}/api/messages") | |
| print(f"❤️ Health: http://0.0.0.0:{port}/api/health\n") |
| try: | ||
| run_app(app, host="localhost", port=port, handle_signals=True) | ||
| run_app(app, host="0.0.0.0", port=port, handle_signals=True) |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file’s header doesn’t follow the repo’s standard Microsoft MIT header format (it’s currently a single-line “Copyright (c) Microsoft. All rights reserved.”). Since this file is being modified, please update the header to the standard two-line “Copyright (c) Microsoft Corporation.” / “Licensed under the MIT License.” at the top of the file.
| # Health check | ||
| HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ | ||
| CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:3978/api/health')" || exit 1 |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HEALTHCHECK hard-codes port 3978 and doesn’t set a request timeout. This can fail if the app is configured to use a different PORT, or if the server ever selects a different port (host_agent_server.py can increment the port if the desired one is in use). Consider reading PORT from the environment in the healthcheck command and passing an explicit timeout to avoid hangs.
- Dockerfile: Add non-root user for security, fix layer caching order, use curl with PORT env var for healthcheck - host_agent_server.py: Update copyright header to standard format, fix print statements to show 0.0.0.0 binding - .dockerignore: Add Python build artifacts (.pytest_cache, .mypy_cache, .ruff_cache, build/, dist/, *.egg-info) - README.md: Add cd instructions, Azure CLI login steps, and env vars for Container Apps deployment with secret reference example Related to microsoft#187
Pull Request: Enable Container Deployment for Python Agent Framework Sample
Summary
This PR fixes a critical networking issue that prevents the Python Agent Framework sample from running in containerized environments and adds comprehensive container deployment documentation and tooling.
Problem Statement
The Issue
When deploying the Python Agent Framework sample to containerized environments (Docker, Azure Container Apps, Kubernetes), the agent fails to receive any external traffic. The server starts successfully, but:
Root Cause
The
host_agent_server.pywas binding the HTTP server tolocalhost:In container networking,
localhost(127.0.0.1) refers only to the loopback interface inside the container. This means:Impact
Anyone deploying this sample to a containerized environment will encounter this issue, including:
This is a blocking issue for production deployments.
Solution
Code Change
Changed the network binding from
localhostto0.0.0.0:Binding to
0.0.0.0instructs the server to accept connections on all available network interfaces, including:This is the standard practice for containerized applications and is safe because:
Additional Files
Dockerfile.dockerignoreREADME.md(updated)Why Container Deployment?
Production Readiness
Container deployment is the recommended approach for production Agent 365 workloads because it provides:
1. Environment Consistency
2. Operational Excellence
3. Scalability
4. Deployment Velocity
Azure Integration
Container deployment unlocks the full Azure ecosystem:
Cost Efficiency
Files Changed
1.
host_agent_server.pyChange:
localhost→0.0.0.0in two locations2.
Dockerfile(New)Production-ready Dockerfile with:
3.
.dockerignore(New)Excludes from container builds:
__pycache__/,*.pyc).venv/,venv/).vscode/,.idea/).env)4.
README.md(Updated)Added comprehensive "Container Deployment" section covering:
Testing
Local Validation
Test Results
Discovery Context
This issue was discovered while deploying the Python Agent Framework sample to Azure Container Apps for a shared demo tenant.
Symptoms observed:
Debugging steps:
curl localhost:3978/api/healthTime to resolution: ~2 hours (would have been immediate with proper documentation)
Related Resources
Checklist