@toolboxcollective/ecs-express
v1.0.0
Published
Zero-config CLI to deploy containerised apps to AWS ECS Fargate — the spiritual successor to AWS Copilot.
Downloads
108
Readme
ecs-express ⚡

Zero-config ECS Fargate deployments. The spiritual successor to AWS Copilot.
npx @toolboxcollective/ecs-express init
npx @toolboxcollective/ecs-express deployThat's it. Your app is live on AWS — ECR, Fargate, ALB, auto-scaling, CloudWatch logs, Secrets Manager — all wired up with sensible defaults.
Why ecs-express?
AWS Copilot is being phased out. The alternatives (raw CDK, Terraform, ECS console) are powerful but require deep AWS knowledge just to deploy a container. ecs-express fills that gap: it gives you production-grade infrastructure with the simplicity of a git push workflow.
| | ecs-express | Raw CDK | Copilot | |---|---|---|---| | Time to first deploy | ~5 min | hours | ~10 min | | Auto-scaling | ✅ built-in | manual | ✅ | | Secrets Manager | ✅ built-in | manual | partial | | Multi-env (dev/prod) | ✅ built-in | manual | ✅ | | Still maintained (2026) | ✅ | ✅ | ❌ | | Escape hatch to raw CDK | ✅ | n/a | ❌ |
Prerequisites
- Node.js ≥ 18
- Docker (running locally)
- AWS CLI configured (
aws configure) - AWS credentials with permissions to create ECS, ECR, VPC, IAM, ALB resources
Installation
npm / npx (no install needed):
npx @toolboxcollective/ecs-express initGlobal install:
npm install -g @toolboxcollective/ecs-expressHomebrew:
brew tap ToolboxCollective/ecs-express
brew install ecs-expressQuick start
# 1. In your project root (Dockerfile required for deploy)
npx @toolboxcollective/ecs-express init
# 2. Answer a few questions — app name, port, CPU, memory, region
# ecs-express.yml is written, CDK bootstraps, infra deploys (~4 min)
# 3. Ship it (requires a Dockerfile in your project root)
npx @toolboxcollective/ecs-express deploy
# Your app is live. Get the URL:
npx @toolboxcollective/ecs-express statusCommands
ecs-express init
Scaffolds ecs-express.yml, bootstraps CDK, and provisions all AWS infrastructure.
Options:
-n, --name <name> App name (default: current directory name)
-e, --env <env> Environment name (default: dev)
-p, --port <port> Container port (default: 3000)What gets created in AWS:
- ECR repository with image scanning + lifecycle policy (keep last 20)
- VPC with public + private subnets across 2 AZs (3 for prod)
- NAT Gateway (1 for dev, 2 for prod)
- ECS Fargate cluster with Container Insights
- Application Load Balancer (public, port 80)
- ECS Service with circuit breaker + auto-rollback
- Auto-scaling (CPU + memory targets; request-count for prod)
- CloudWatch log group with retention policy
- IAM roles (least privilege)
- Secrets Manager secret placeholder
Generated files:
ecs-express.yml- Your configuration file (commit this)cloudformation-template.json- Full CloudFormation template for transparency.ecs-express-outputs.json- Stack outputs (ALB URL, ECR URI, etc.)
The init command will show you a preview of resources before deploying and ask for confirmation.
ecs-express deploy
Builds your Docker image, pushes it to ECR, and updates the ECS service.
Options:
-e, --env <env> Target environment (default: dev)
--no-build Skip docker build, push existing local image
--tag <tag> Image tag (default: current git SHA)
--no-wait Don't wait for deployment to stabilize (faster)# Deploy to dev
ecs-express deploy
# Deploy to production
ecs-express deploy --env prod
# Deploy a specific tag without rebuilding
ecs-express deploy --no-build --tag v1.2.3
# Deploy without waiting for stabilization (faster, for CI/CD)
ecs-express deploy --no-waitecs-express status
Shows running tasks, ALB URL, deployment history, and task health.
ecs-express status
ecs-express status --env prodExample output:
📊 my-app / dev
Status ACTIVE
Running 2 / 2 tasks
Pending 0
URL http://my-app-dev-123456.us-east-1.elb.amazonaws.com
Cluster my-app-dev
Service my-app-dev
Running tasks:
a1b2c3d4e5f6 started 2026-03-20 10:42:01 health HEALTHY
b2c3d4e5f6a1 started 2026-03-20 10:42:05 health HEALTHYecs-express logs
Tail CloudWatch logs for your service.
# Print last 50 lines
ecs-express logs
# Follow / stream live
ecs-express logs --follow
# Last 200 lines from prod
ecs-express logs --env prod --lines 200ecs-express env
Manage environment variables via AWS Secrets Manager. Secrets are injected into your container at runtime — never baked into the image.
# Set secrets
ecs-express env set DATABASE_URL=postgres://... JWT_SECRET=abc123
# Set secrets from a .env file
ecs-express env set --file .env
# List all keys (values are never shown)
ecs-express env list
# Remove a key
ecs-express env unset OLD_KEY
# Target a specific environment
ecs-express env set API_KEY=xyz --env prodHow it works: All key/value pairs are stored as a single JSON object in Secrets Manager at
ecs-express/<app>/<env>/secrets. The ECS task definition pulls this secret and injects it as_APP_SECRETS_JSON. Your application must parse this JSON at startup to expose individual secrets as environment variables.📖 See docs/SECRETS.md for complete implementation examples in Node.js, Python, Go, and more.
ecs-express destroy
Tears down all AWS resources for an environment. ECR images are retained by default.
ecs-express destroy --env dev
ecs-express destroy --env prod --force # skip confirmationConfiguration: ecs-express.yml
Generated by init, committed to your repo.
app:
name: my-app
port: 3000
dockerfile: Dockerfile
aws:
region: us-east-1
environments:
dev:
cpu: 256 # 0.25 vCPU
memory: 512 # MiB
desiredCount: 1
port: 3000
healthCheckPath: /health
scaling:
minTasks: 1
maxTasks: 5
targetCpuPercent: 70
targetMemoryPercent: 70
envVars:
NODE_ENV: development
prod:
cpu: 512
memory: 1024
desiredCount: 2
port: 3000
healthCheckPath: /health
scaling:
minTasks: 2
maxTasks: 50
targetCpuPercent: 60
targetMemoryPercent: 60
envVars:
NODE_ENV: productionCPU / Memory combinations (Fargate)
| CPU | Valid memory values | |-----|---| | 256 (0.25 vCPU) | 512 MiB, 1 GB, 2 GB | | 512 (0.5 vCPU) | 1 GB – 4 GB (in 1 GB increments) | | 1024 (1 vCPU) | 2 GB – 8 GB (in 1 GB increments) | | 2048 (2 vCPU) | 4 GB – 16 GB (in 1 GB increments) | | 4096 (4 vCPU) | 8 GB – 30 GB (in 1 GB increments) | | 8192 (8 vCPU) | 16 GB – 60 GB (in 4 GB increments) | | 16384 (16 vCPU) | 32 GB – 120 GB (in 8 GB increments) |
Source: AWS Fargate task CPU and memory
CI/CD integration
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
aws-region: us-east-1
- run: npm install -g @toolboxcollective/ecs-express
- name: Deploy to production
run: ecs-express deploy --env prodGitLab CI
deploy:
stage: deploy
image: node:20-alpine
script:
- apk add --no-cache docker aws-cli
- npm install -g @toolboxcollective/ecs-express
- ecs-express deploy --env prod
only:
- mainEscape hatch: raw CDK
ecs-express is thin wrapper around CDK. If you outgrow it, eject to raw CDK at any time:
# The CloudFormation template is already generated during init
cat cloudformation-template.json
# Or regenerate it manually
cd node_modules/ecs-express/cdk
ECS_EXPRESS_APP=my-app ECS_EXPRESS_ENV=prod \
ECS_EXPRESS_CONFIG=/path/to/ecs-express.yml \
npx cdk synth
# Copy the CDK stack to your own repo and take full ownership
cp node_modules/ecs-express/cdk/lib/ecs-express-stack.ts ./infra/Your existing CloudFormation stacks remain — nothing breaks.
Architecture
Developer machine
└─ ecs-express CLI
├─ init → CDK synth + deploy → CloudFormation
├─ deploy → docker build/push → ECR → ECS force-deploy
├─ status → ECS / CF describe APIs
├─ logs → CloudWatch Logs filter
└─ env → Secrets Manager get/put
AWS account
└─ VPC (public + private subnets)
├─ Application Load Balancer (public)
└─ ECS Fargate cluster
└─ Service (circuit breaker, auto-rollback)
├─ Task → pulls image from ECR
├─ Secrets → injected from Secrets Manager
├─ Logs → CloudWatch Log Group
└─ Auto-scaling (CPU + Memory + Requests)Roadmap
- [x] v0.1 — init, deploy, status, logs, env, destroy
- [ ] v0.2 — Custom image support (
--imageflag for init and deploy) - [ ] v0.3 — HTTPS / ACM certificate auto-provisioning
- [ ] v0.4 —
ecs-express exec(shell into running task) - [ ] v0.5 — Scheduled tasks / cron jobs
- [ ] v0.6 — RDS / ElastiCache add-ons
- [ ] v1.0 — Stable API + plugin system
Contributing
PRs welcome. See CONTRIBUTING.md.
git clone https://github.com/ToolboxCollective/ecs-express
cd ecs-express
npm install
npm run dev -- init # runs the CLI from sourceLicense
MIT © ToolboxCollective
