Dockerfiles & the Container Contract
Setup generates a framework-specific Alpine multi-stage Dockerfile engineered for zero Critical/High CVEs. Your app only needs to honor a small runtime contract — plus a few per-framework prerequisites printed as warnings (src/utils/warnings.js) at the end of setup.
The container contract
Section titled “The container contract”Every generated image assumes three things. Violating any of them is the most common cause of failing ALB health checks after an otherwise successful apply:
- Listen on
$PORT. The container must serve traffic on the port baked in as{{PORT}}(default per framework — see Supported Frameworks). - Bind
0.0.0.0, notlocalhost. Localhost-bound apps are unreachable inside ECS networking and Docker. - Answer the health check with
200 OK. The ALB polls your health-check path (default/); anything else marks the task unhealthy and the pipeline’s new deployment never stabilizes.
Per-framework prerequisites
Section titled “Per-framework prerequisites”| Framework | What setup warns you about |
|---|---|
| NestJS | Bind 0.0.0.0 in src/main.ts: await app.listen(process.env.PORT ?? 3000, '0.0.0.0') |
| Next.js | Set output: 'standalone' in your Next config and create a health-check route (copy-paste code is in the generated README’s “Critical Application Prerequisites”) |
| Node.js / Express | A start script in package.json (e.g. "start": "node index.js") and 0.0.0.0 binding |
| Python (FastAPI) | Web framework in requirements.txt, 0.0.0.0 binding, and a health-check route returning 200 OK |
| Rails | Your default Dockerfile is backed up to Dockerfile.bak and replaced with the Alpine build; if you use SQLite locally but provisioned RDS, add the pg gem |
| Static sites | Output folder defaults to /app/dist — if your framework emits build/ or out/, update the COPY command; ensure a build script exists (e.g. vite build) |
Warnings are skipped with --preconfigured and for static projects whose build directory was auto-detected.
What command runs your app
Section titled “What command runs your app”The container’s start command is resolved in this order:
Procfileweb:command, if aProcfileexists (aworker:process additionally generatesworker.tf, i.e. a second ECS service that doubles Fargate cost).- Otherwise the
commandof thedocker-compose.ymlweb service, if one exists. - Otherwise the default
CMDin the generatedDockerfile.
Keeping images lean
Section titled “Keeping images lean”Setup writes a .dockerignore excluding .git/, terraform/, state files, and .env, and appends Terraform entries to an existing .gitignore. Never commit .env — runtime secrets come from AWS Secrets Manager (see Secrets Management).
See also
Section titled “See also”- CI/CD Pipeline & First Deploy for how the image is built and rolled out.
- diagnose for reading ECS failure output when the contract is broken.