Skip to main content
This guide will help you deploy Carrier quickly in your local development environment or production Kubernetes cluster.

Local Development with Docker Compose

1

Create a Docker Compose file

Create a docker-compose.yml file with Carrier configured to forward SQS messages to your worker application.
docker-compose.yml
services:
  sqs:
    image: roribio/alpine-sqs
  carrier:
    image: amplifysecurity/carrier
    restart: unless-stopped
    volumes:
      - ${HOME}/.aws/credentials:/.aws/credentials
    links:
      - sqs:sqs
      - worker:worker
    environment:
      CARRIER_WEBHOOK_ENDPOINT: http://worker:9000/webhook
      CARRIER_SQS_ENDPOINT: http://sqs:9324
      CARRIER_SQS_QUEUE_NAME: default
  worker:
    build: .
This example requires AWS credentials to be mounted even for local SQS, otherwise the AWS SDK will panic. The credentials don’t need to be valid for local testing.
2

Configure your worker

Ensure your worker application:
  • Listens on port 9000 (or adjust CARRIER_WEBHOOK_ENDPOINT)
  • Has a webhook endpoint at /webhook that accepts POST requests
  • Returns appropriate HTTP status codes (200 for success, 429 for backoff)
3

Start the stack

docker-compose up
Carrier will start receiving messages from the local SQS queue and forwarding them to your worker.
4

Verify it's working

Send a test message to your SQS queue and watch the logs:
docker-compose logs -f carrier
You should see Carrier receiving and transmitting messages to your webhook endpoint.

Kubernetes Deployment

1

Prepare your service account

Create a Kubernetes ServiceAccount and map it to an IAM role with SQS permissions:
  • sqs:ReceiveMessage
  • sqs:DeleteMessage
  • sqs:GetQueueUrl
  • sqs:ChangeMessageVisibility (required for dynamic timeouts)
2

Create the deployment manifest

Create a deployment with Carrier as a sidecar container:
carrier-deployment.yml
---
# SQS event worker pattern deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: carrier-demo
  namespace: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: carrier-demo
  template:
    metadata:
      labels:
        app: carrier-demo
    spec:
      serviceAccountName: carrier-demo
      containers:
        - name: carrier
          image: amplifysecurity/carrier
          securityContext:
            runAsUser: 1000
            allowPrivilegeEscalation: false
            runAsNonRoot: true
          env:
            - name: CARRIER_WEBHOOK_ENDPOINT
              value: http://localhost:9000/webhook
            - name: CARRIER_SQS_ENDPOINT
              value: https://sqs.us-west-2.amazonaws.com
            - name: CARRIER_SQS_QUEUE_NAME
              value: carrier-demo
        - name: worker
          image: ${registry}/${container}:${tag}
This assumes the ServiceAccount carrier-demo is mapped to an IAM role with appropriate SQS permissions via IRSA (IAM Roles for Service Accounts).
3

Deploy to your cluster

kubectl apply -f carrier-deployment.yml
4

Verify the deployment

Check that both containers are running:
kubectl get pods -n demo -l app=carrier-demo
kubectl logs -n demo -l app=carrier-demo -c carrier
You should see Carrier connecting to SQS and processing messages.

Essential Configuration

Required Environment Variables

CARRIER_SQS_ENDPOINT
string
required
The AWS SQS service endpoint. Use regional endpoints like https://sqs.us-west-2.amazonaws.com or the local endpoint for testing.
CARRIER_SQS_QUEUE_NAME
string
required
The name of your SQS queue (not the full ARN, just the name).
CARRIER_WEBHOOK_ENDPOINT
string
default:"http://localhost:9000"
Full URL where webhooks should be sent. In Kubernetes, use http://localhost:<port>/<path> for sidecar containers.
CARRIER_WEBHOOK_HEALTH_CHECK_ENDPOINT
string
Health check endpoint for your webhook service. Highly recommended to prevent message failures during startup.
env:
  - name: CARRIER_WEBHOOK_HEALTH_CHECK_ENDPOINT
    value: http://localhost:9000/health
CARRIER_SQS_BATCH_SIZE
integer
default:"1"
Number of messages to receive per SQS request. Increase for higher throughput.
CARRIER_SQS_RECEIVER_WORKERS
integer
default:"1"
Number of concurrent workers transmitting webhooks per receiver. Set this equal to batch size for parallel processing.

Performance Tuning

For high-throughput scenarios, configure concurrency settings:
env:
  # Receive 10 messages per batch
  - name: CARRIER_SQS_BATCH_SIZE
    value: "10"
  # Process all 10 messages in parallel
  - name: CARRIER_SQS_RECEIVER_WORKERS
    value: "10"
  # Run 3 concurrent receivers
  - name: CARRIER_SQS_RECEIVERS
    value: "3"
This configuration processes up to 30 messages concurrently (3 receivers × 10 workers).
Monitor your worker application’s resource usage when increasing concurrency. Ensure it can handle the increased load.

Enable Health Checks

Health checks prevent message processing failures during application startup:
env:
  - name: CARRIER_WEBHOOK_HEALTH_CHECK_ENDPOINT
    value: http://localhost:9000/health
  - name: CARRIER_WEBHOOK_OFFLINE_THRESHOLD_COUNT
    value: "5"
  - name: CARRIER_WEBHOOK_HEALTH_CHECK_INTERVAL
    value: "60s"
Carrier will:
  1. Wait for the health endpoint to return 200 before processing messages
  2. Check health every 60 seconds
  3. Exit after 5 consecutive failed health checks (triggering Kubernetes restart)

Next Steps

Configuration Reference

Explore all available environment variables and settings

Dynamic Visibility Timeouts

Learn how to implement distributed backoff strategies

Health Monitoring

Configure advanced health check scenarios

Deployment Best Practices

Production deployment patterns and recommendations

Build docs developers (and LLMs) love