AWS ECS Fargate Proxy
The MonetizationOS Node.js proxy ships as a standard container, so it serves your site from an Amazon ECS Fargate service behind an Application Load Balancer in your own AWS account. Build the container in the Node.js Proxy guide, then deploy it with the steps below.
What is ECS Fargate?
AWS Fargate runs containers on Amazon ECS with no servers to manage: you register a task definition, and AWS provisions, places, and restarts the tasks.
The proxy sits between your visitors and your origin server:
Installation and configuration
Prerequisites
- The
mos-node-proxyservice andDockerfilefrom the Containerize step of the Node.js Proxy guide - A hostname that resolves straight to your origin server and isn't the hostname you publish to visitors, for example
origin.example.comfor a site served atnews.example.com. Step 6 moves the published hostname to the load balancer, so the proxy fetches this separate one - An AWS account with a VPC and permissions for ECR, ECS, Secrets Manager, and Elastic Load Balancing
- An ECS task execution role granting ECR pull, CloudWatch Logs, and Secrets Manager read. Note its ARN for the task definition
- The AWS CLI, authenticated with
aws configure - Docker running locally
1. Push the image to Amazon ECR
From the mos-node-proxy directory, create a repository and push the image:
aws ecr create-repository --repository-name mos-node-proxy
aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com
docker build --platform linux/arm64 -t mos-node-proxy .
docker tag mos-node-proxy:latest <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/mos-node-proxy:latest
docker push <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/mos-node-proxy:latestRebuild with --platform so the image architecture matches the one the task runs on.
linux/arm64 pairs with the ARM64 runtime platform set in the next step.
To run on x86 instead, build --platform linux/amd64 and leave the runtimePlatform block out of that step, because Fargate defaults to X86_64.
The push output ends with the image digest, confirming the image is in ECR.
2. Store the secret key in Secrets Manager
Keep the MonetizationOS secret key out of the task definition:
aws secretsmanager create-secret --name mos/proxy/secret-key --secret-string "<YOUR_SECRET_KEY>"The command returns the secret's ARN. Save it for the task definition.
3. Register the task definition
Create task-definition.json with the container, its environment variables, and the secret.
Use the execution role ARN from the prerequisites for <ECS_EXECUTION_ROLE_ARN>, and the secret ARN from the previous step for <SECRET_ARN>.
{
"family": "mos-node-proxy",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"runtimePlatform": { "cpuArchitecture": "ARM64", "operatingSystemFamily": "LINUX" },
"cpu": "256",
"memory": "512",
"executionRoleArn": "<ECS_EXECUTION_ROLE_ARN>",
"containerDefinitions": [
{
"name": "proxy",
"image": "<ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/mos-node-proxy:latest",
"essential": true,
"portMappings": [{ "containerPort": 3000, "protocol": "tcp" }],
"environment": [
{ "name": "ORIGIN_URL", "value": "https://origin.example.com" },
{ "name": "SURFACE_SLUG", "value": "web" },
{ "name": "AUTHENTICATED_USER_JWT_COOKIE_NAME", "value": "__session" },
{ "name": "ANONYMOUS_SESSION_COOKIE_NAME", "value": "anon-session-id" }
],
"secrets": [
{ "name": "MONETIZATION_OS_SECRET_KEY", "valueFrom": "<SECRET_ARN>" }
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/mos-node-proxy",
"awslogs-region": "<REGION>",
"awslogs-stream-prefix": "proxy"
}
}
}
]
}The environment variables are the ones defined in the Node.js Proxy guide.
aws ecs register-task-definition --cli-input-json file://task-definition.jsonThe response includes a taskDefinitionArn ending in the revision number, :1 for the first registration of this family.
4. Create the cluster
aws ecs create-cluster --cluster-name mos-proxy5. Create the service and load balancer
The console wizard creates the load balancer and target group alongside the service, so use it for this step. Open the mos-proxy cluster and create a service:
- Launch type: Fargate
- Task definition:
mos-node-proxy, latest revision - Desired tasks: 2
- Networking: your VPC and public subnets, with Public IP enabled
- Load balancing: create a new Application Load Balancer named
mos-proxy-alb, listener on port 80, and a new target groupmos-proxy-tgwith health check path/healthz
When the deployment reaches a steady state, the service's Tasks tab shows 2 running tasks passing health checks.
Request a page through the load balancer, using the DNS name from the load balancer's detail page:
curl -i http://<ALB_DNS_NAME>/The response is your origin's HTML, with a Set-Cookie header carrying the anonymous session identifier.
6. Point your domain at the load balancer
Create a Route 53 alias record, or a CNAME at your DNS provider, from the hostname you publish to visitors to the load balancer's DNS name.
Leave the origin hostname in ORIGIN_URL pointing at your origin server: if both hostnames resolve to the load balancer, each origin fetch returns to the proxy and the request loops.
To serve HTTPS, attach an AWS Certificate Manager certificate to a 443 listener on the load balancer.
Browsing your domain now serves your site through the proxy, with monetization decisions applied to its HTML responses.
For canonical setup details and updates, see the project README.
Next steps
- Build or update the container in the Node.js Proxy guide
- Learn the broader concept and architecture in Proxies
- Explore the request pipeline in the Proxy API reference