automatic-deploy is an npm-installable CLI tool (command name: mydeploy) that takes a web project, auto-generates a production Dockerfile using Google Gemini AI, and then deploys the containerised app to AWS ECS (Fargate) — all in one or two commands.
It is published at npm as automatic-deploy (v1.0.4) and authored by Arnav Kumar & Yash Agarwal.
flowchart LR
subgraph CLI["bin/cli.js"]
A["mydeploy init"]
B["mydeploy config"]
C["mydeploy deploy"]
end
subgraph AI["src/ai/"]
D["detectFramework()"]
E["generateDockerfile() via Gemini"]
F["fallbackTemplate() via EJS"]
end
subgraph AWS["src/aws/"]
G["createResources()"]
H["pushToECR()"]
I["deployToECS()"]
end
subgraph Utils["src/utils/"]
J["Logger (ora/chalk)"]
K["buildDockerImage()"]
L["writeEnvKey()"]
end
A --> D --> E --> F
C --> K --> G --> H --> I
B --> L
AI --> J
AWS --> J
Purpose: Analyze a project, detect its framework, and generate a production-ready Dockerfile.
Flow (init.js → analyzeProject.js):
-
Framework detection — Scans the target directory for telltale files:
File Found Framework Detected package.jsonwithexpressdependencynode-expressrequirements.txtcontainingdjangopython-djangogo.modgopom.xmljava-springboot -
AI-powered Dockerfile generation — If a Gemini API key is configured:
- Reads the project's manifest file (
package.json,requirements.txt,go.mod, orpom.xml) - Sends it to Gemini 2.0 Flash with a prompt asking for a production-ready Dockerfile
- Strips any markdown fences from the response and writes the Dockerfile
- Reads the project's manifest file (
-
Template fallback — If AI fails or is disabled (
--no-ai), it uses pre-built EJS templates from src/templates/:- Dockerfile-node-express.ejs — Multi-stage Node 18 Alpine build
- Dockerfile-python-django.ejs — Python 3.11 slim + Gunicorn
- Dockerfile-go.ejs — Multi-stage Go 1.22 Alpine build
- Dockerfile-java-springboot.ejs — Eclipse Temurin 21 + Maven
Tip
Use --force to overwrite an existing Dockerfile. Use --no-ai to skip Gemini entirely and use templates.
Purpose: Manage API keys and credentials via a .env file.
Flow (config.js → env.js):
| Action | Example | What It Does |
|---|---|---|
set |
mydeploy config set GEMINI_API_KEY abc123 |
Writes key=value into .env |
get |
mydeploy config get AWS_REGION |
Reads from process.env (loaded by dotenv at startup) |
setConfig()converts the key to uppercase, then callswriteEnvKey()which parses the existing.env, upserts the key, and rewrites the file.- Sensitive values (containing "key", "secret", "token", "password") are masked in console output (e.g.,
abcd****xyz1). - There's also a
~/.mydeploy/config.jsonsystem for persistent config (used byremoveConfig,listConfig,initConfig), though the primaryset/getpath uses.env.
Purpose: Build the Docker image, provision all required AWS infrastructure, push to ECR, and deploy to ECS Fargate.
Flow (deploy.js → docker.js → createResources.js → deployToECS.js):
This is the most complex command. It runs a 4-step pipeline:
docker.js — Runs docker build -t <image-name> . using execa. Requires a Dockerfile to exist (run init first).
createResources.js — Idempotently provisions everything needed:
flowchart TD
A["STS: Get Account ID"] --> B["ECR: Create/find repository"]
A --> C["ECS: Create/find cluster (Fargate)"]
A --> D["IAM: Create ecsTaskExecutionRole"]
A --> E["IAM: Create ecsTaskRole"]
A --> F["EC2: Find default VPC + subnets"]
F --> G["EC2: Create security group (ports 80, 443, 3000)"]
B & C & D & E & G --> H["ECS: Register task definition"]
H --> I["ECS: Create/find service (desiredCount=1)"]
Key details:
- Uses AWS SDK v3 (
@aws-sdk/client-ecs,client-ecr,client-iam,client-ec2,client-sts) - Every resource uses an ensure pattern — check if it exists first, create only if missing
- Task definition defaults: 256 CPU / 512 MB memory, port 3000, with CloudWatch Logs configured
- Security group opens ports 80, 443, and 3000 to
0.0.0.0/0
deployToECS.js → pushToECR():
- Gets ECR authorization token
- Runs
docker loginto the ECR endpoint - Tags and pushes the local image as
<repo-uri>:latest
deployToECS.js → deployToECS():
- Fetches the current task definition from the running service
- Registers a new revision with the updated image URI
- Calls
UpdateServiceCommandwithforceNewDeployment: true - Polls
DescribeServicesCommandevery 15 seconds (up to 10 minutes) untilrunningCount === desiredCount - Throws on failure events (e.g., "was stopped", "failed", "unable to place")
automated-deploy/
├── bin/
│ └── cli.js # Entry point, Commander.js setup, preflight checks
├── src/
│ ├── ai/
│ │ └── analyzeProject.js # Framework detection + Gemini Dockerfile generation
│ ├── aws/
│ │ ├── createResources.js # Idempotent AWS infra provisioning (ECR, ECS, IAM, VPC, SG)
│ │ └── deployToECS.js # ECR push + ECS task update + stability polling
│ ├── commands/
│ │ ├── init.js # Thin wrapper → analyzeProject()
│ │ ├── deploy.js # Orchestrates the 4-step deploy pipeline
│ │ └── config.js # Config get/set/remove/list + .env management
│ ├── templates/
│ │ ├── Dockerfile-node-express.ejs # Fallback Dockerfile for Node/Express
│ │ ├── Dockerfile-python-django.ejs# Fallback Dockerfile for Django
│ │ ├── Dockerfile-go.ejs # Fallback Dockerfile for Go
│ │ └── Dockerfile-java-springboot.ejs # Fallback Dockerfile for Spring Boot
│ └── utils/
│ ├── logger.js # Rich logging (chalk + ora spinners + tables)
│ ├── docker.js # Docker image build via execa
│ └── env.js # .env file read/write utility
├── package.json
├── Readme.md
└── .gitignore
| Package | Purpose |
|---|---|
commander |
CLI framework (commands, options, arguments) |
@google/generative-ai |
Google Gemini API for AI Dockerfile generation |
@aws-sdk/client-* |
AWS SDK v3 (ECS, ECR, IAM, EC2, STS, CloudWatch Logs) |
execa |
Subprocess execution (docker build/push/login) |
ejs |
Template rendering for fallback Dockerfiles |
inquirer |
Interactive CLI prompts (installed but not heavily used yet) |
ora |
Terminal spinners for long-running operations |
chalk |
Coloured terminal output |
figlet |
ASCII art text (installed, not currently used in code) |
dotenv |
.env file loading |
fs-extra |
Enhanced filesystem operations |
| Flag | Effect |
|---|---|
-v, --verbose |
Shows debug output, docker build logs, full stack traces |
--dry-run |
Prints what would happen without executing anything |
--profile <name> |
Sets AWS_PROFILE for the session |
--region <region> |
Sets AWS_DEFAULT_REGION for the session |
# 1. Install globally
npm install -g automatic-deploy
# 2. Configure credentials
mydeploy config set GEMINI_API_KEY your-gemini-key
mydeploy config set AWS_ACCESS_KEY_ID your-aws-key
mydeploy config set AWS_SECRET_ACCESS_KEY your-aws-secret
# 3. Analyze project & generate Dockerfile
mydeploy init ./my-express-app
# 4. Deploy to AWS ECS
mydeploy deploy ./my-express-app --region us-east-1Important
The deploy command requires Docker to be installed and running locally, plus valid AWS credentials with permissions for ECS, ECR, IAM, EC2, STS, and CloudWatch Logs.