Deployment
This page summarizes common deployment patterns for ActingWeb apps.
Docker
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN pip install poetry && poetry config virtualenvs.create false \
&& poetry install --only main --no-root
COPY . .
CMD ["python", "app.py"]
Expose the port your Flask/FastAPI app listens on (e.g., 5000).
Pass configuration via environment (e.g., APP_HOST_FQDN, LOG_LEVEL).
AWS Lambda (Serverless)
# handler.py
import serverless_wsgi
from flask import Flask
from actingweb.interface import ActingWebApp
flask_app = Flask(__name__)
aw_app = (
ActingWebApp(...)
.with_web_ui()
.with_sync_callbacks() # IMPORTANT for Lambda!
)
aw_app.integrate_flask(flask_app)
def handler(event, context):
return serverless_wsgi.handle_request(flask_app, event, context)
Important: Enable Synchronous Callbacks
In Lambda/serverless environments, async fire-and-forget callbacks may be lost when the function freezes after returning a response. Use with_sync_callbacks() to ensure all subscription callbacks (both diff and resync) complete before the handler returns:
aw_app = ActingWebApp(...).with_sync_callbacks(enable=True)
This makes callbacks use blocking HTTP requests instead of async tasks, guaranteeing delivery at the cost of slightly longer response times.
Why this is needed:
Lambda freezes execution after returning a response
Async fire-and-forget callbacks are terminated before completion
Sync callbacks block until delivery is confirmed
Both diff callbacks and resync callbacks respect this configuration
Local Development:
Do NOT use with_sync_callbacks() in local/container deployments:
Default async behavior prevents blocking and self-deadlock
Async mode allows both actors on the same server to communicate without blocking
Callbacks complete in the background after the response is returned
Note
ActingWeb automatically detects Lambda environments (via AWS_LAMBDA_FUNCTION_NAME or AWS_EXECUTION_ENV environment variables) and logs a warning if sync callbacks are not enabled. This helps catch misconfigurations during development and deployment.
Serverless config example:
service: actingweb-app
provider:
name: aws
runtime: python3.11
region: us-east-1
functions:
app:
handler: handler.handler
events:
- http:
path: /{proxy+}
method: ANY
- http:
path: /
method: ANY
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: actingweb-app
spec:
replicas: 2
selector:
matchLabels:
app: actingweb-app
template:
metadata:
labels:
app: actingweb-app
spec:
containers:
- name: actingweb
image: your-registry/actingweb:latest
ports:
- containerPort: 5000
Notes
Ensure AWS IAM policies allow DynamoDB operations your app requires.
For base paths (reverse proxies, API gateways), templates should use
actor_rootandactor_www; see WWW Handler and Templates.See Routing Overview for generated routes and structure.
Health Checks
Simple Flask health endpoint:
@app.route("/health") def health(): return {"status": "ok"}, 200
Simple FastAPI health endpoint:
@api.get("/health") def health(): return {"status": "ok"}
Base Path (Reverse Proxy) Examples
FastAPI (root_path)
# Deploying under /mcp-server
api = FastAPI(root_path="/mcp-server")
aw.integrate_fastapi(api, templates_dir="templates")
Nginx
server {
listen 443 ssl;
server_name your.domain;
location /mcp-server/ {
proxy_pass http://127.0.0.1:5000/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /mcp-server;
}
}
Notes on Base Paths
When running under a base path, ensure links in templates use
actor_rootandactor_www(not relative URLs).For FastAPI, prefer
root_pathso OpenAPI and routes align with the proxy path.For Flask, when using WSGI behind a proxy that sets
X-Forwarded-Prefix/SCRIPT_NAME, make sure the WSGI server/middleware honors it (e.g.,werkzeug.middleware.proxy_fix.ProxyFixif needed).