AWS quietly retired three Elastic Beanstalk platform branches on August 13, 2026: Node.js 20, Python 3.9, and Ruby 3.2, all running on Amazon Linux 2023. If you deployed an app on any of those stacks in the last year, your next platform update just became mandatory reading. Elastic Beanstalk remains one of the fastest ways to get a web app from a laptop to a load-balanced, auto-scaling AWS environment without hand-wiring EC2, an Application Load Balancer, Auto Scaling groups, and CloudWatch alarms yourself. This tutorial walks through a complete, current setup: installing the right CLI versions, deploying a real Node.js app on the Amazon Linux 2023 platform, attaching an RDS database, wiring up HTTPS, and automating deployments with GitHub Actions. Every version number and price below comes from AWS’s own documentation and pricing pages as of August 19, 2026.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
What Is AWS Elastic Beanstalk in 2026?
AWS Elastic Beanstalk is a platform-as-a-service layer that provisions and manages the AWS infrastructure your application actually runs on: EC2 instances, an Application Load Balancer, an Auto Scaling group, security groups, and optionally an RDS database. You upload a code bundle or a container image, and Elastic Beanstalk handles the provisioning, health monitoring, and rolling deployments. As of a March 11, 2026 platform update, that also includes deployment logs streamed live in the console and CLI as a rollout progresses, rather than only being available after the fact. Unlike a fully abstracted platform, Elastic Beanstalk still gives you SSH access to the underlying EC2 instances and full control over the VPC, which matters if you need to install system packages, tune kernel parameters, or debug a process that’s eating memory at 2 a.m.
There’s no separate charge for Elastic Beanstalk itself. AWS’s official pricing page states plainly that you pay only for the underlying resources — EC2 instances, S3 storage, RDS, and the load balancer — that your environment creates. That makes Elastic Beanstalk a genuinely free orchestration layer on top of billable compute.
Platform support in 2026 runs on two base images: Amazon Linux 2 and Amazon Linux 2023 (AL2023), covering Node.js, Python, Java (Corretto), .NET Core, PHP, Ruby, Go, and Docker stacks, according to AWS’s Linux platforms documentation. The older AL2 branch hasn’t been frozen in place, either: a March 11, 2026 AL2 platform update bumped the AMI to version 2.0.20260302, upgraded Go to 1.26.1 with security fixes, and moved Maven to 3.9.13 for the Corretto tooling, building on a November 20, 2025 AL2 update that had already pushed Go to 1.25.4, Tomcat 9 to 9.0.110, and the ECS Agent on the Docker branch to 1.100.1. AWS ships coordinated AL2023 platform updates on a similar roughly three-to-four-week cadence — a March 31, 2026 release refreshed multiple AL2023 runtimes, the July 29, 2026 release bumped Docker AL2023 to version 4.13.5 (Docker engine 25.0.16, Docker Compose 5.3.1), and by mid-August the current Docker AL2023 branch had moved to version 4.13.6. That cadence is worth knowing because Elastic Beanstalk platform branches don’t live forever. On August 13, 2026, AWS retired the Node.js 20, Python 3.9, and Ruby 3.2 AL2023 branches outright, per the official release notes. If your environment is still pinned to one of those, plan a platform upgrade now rather than after AWS stops patching it. Looking ahead, AWS’s published platform release schedule lists Python 3.15 and Node.js 26 arriving on Amazon Linux 2023 in November 2026, with .NET 11 following in December 2026.
Practically, that means the safe platform choice for a new deployment in August 2026 is Node.js 22 (not 20), Python 3.12 or 3.13 (not 3.9), and Ruby 3.3 (not 3.2). This tutorial uses the Node.js 22 AL2023 platform for its sample app.
Under the hood, every Elastic Beanstalk environment is really just a stack of ordinary AWS resources tagged and grouped so the console can manage them as one unit. When you run eb create, Elastic Beanstalk calls CloudFormation to provision a launch template, an Auto Scaling group, a security group, an S3 bucket for your application versions, and — if you request a load-balanced environment — an Application Load Balancer with a target group pointed at your instances. That matters for two reasons. First, nothing stops you from reaching into the AWS console and inspecting or even modifying those resources directly, though hand-editing them outside of Elastic Beanstalk’s own configuration tends to get overwritten on the next deploy. Second, it means the mental model for debugging a broken environment is the same as debugging any EC2/ALB/ASG stack: check the target group’s health check status first, then the instance’s system log, then your application’s own log output.
Elastic Beanstalk also supports two environment tiers that solve different problems. A web server tier — the one this tutorial uses — sits behind a load balancer and handles HTTP requests directly. A worker tier has no load balancer at all; instead, it polls an Amazon SQS queue and runs your code against each message, which is the right shape for anything that doesn’t need to respond to a browser in real time, like resizing uploaded images, sending transactional email, or generating PDF reports. Picking the wrong tier for the job is a common early mistake: teams sometimes bolt a queue-polling loop onto a web server tier instead of using the purpose-built worker tier, which wastes the ALB’s health-check cycle on a process that was never meant to answer HTTP requests.
AWS Elastic Beanstalk vs App Runner vs Fargate vs Amplify
Elastic Beanstalk isn’t AWS’s only “deploy my app” option, and picking the wrong one costs you either flexibility or hours of DevOps overhead. App Runner hides almost all infrastructure and scales on request concurrency, which is great for a stateless API but limiting if you need custom networking or SSH access. Fargate (via ECS) gives you full container orchestration control at the cost of writing task definitions, service definitions, and your own load balancer wiring. Amplify targets front-end and full-stack JavaScript apps with opinionated hosting, auth, and CI/CD baked in, but it’s a poor fit for a traditional server-rendered backend. Elastic Beanstalk sits in the middle: it manages the EC2/ALB/Auto Scaling layer for you but still exposes the instances if you need to get under the hood.
| Service | Deployment Artifact | Infrastructure Visible? | Scaling Model | Best For |
|---|---|---|---|---|
| Elastic Beanstalk | ZIP/JAR/WAR or Docker image | Yes (EC2, ALB, ASG, VPC) | Instance-based Auto Scaling | Traditional web apps/APIs needing infra control |
| AWS App Runner | Source repo or container image | No — fully hidden | Concurrency-based, scale to zero | Simple containerized services, minimal DevOps |
| AWS Fargate (ECS) | Docker image only | Partial (task defs, networking) | Service/task-based scaling | Microservices needing orchestration control |
| AWS Amplify | Git-connected front-end repo | No — fully hidden | Managed hosting/CDN | Front-end and full-stack JS apps |
If you’re weighing container-first alternatives more broadly, our Google Cloud Run setup guide and AWS Lambda tutorial cover the serverless end of the spectrum, where you don’t manage instances at all. Elastic Beanstalk is the right call when you want that infrastructure control back without building the ALB and Auto Scaling group by hand in Terraform or CloudFormation.
The decision usually comes down to one question: how much do you want to see? Teams running a monolithic Rails, Django, or Express app with a handful of background cron jobs tend to land on Elastic Beanstalk because the deployment artifact — a ZIP of your working directory — maps directly onto how they already think about releases. Teams building a fleet of small, independently deployable services usually end up on Fargate instead, because Elastic Beanstalk’s environment-per-app model gets unwieldy once you’re managing more than a handful of services. App Runner tends to win when the team is small, the workload is a single container, and nobody wants to think about VPC subnets at all. None of these are permanent choices — migrating from Elastic Beanstalk to Fargate later is a matter of containerizing your app and writing an ECS task definition, not a rewrite — so it’s fine to start on Elastic Beanstalk and move later if your architecture outgrows it.
Prerequisites: Accounts, Tools, and Versions You’ll Need
Before you start, get these in place. Version mismatches are the single most common source of “it works on my machine” failures with the EB CLI, so check each one with the listed command.
| Requirement | Minimum Version (Aug 2026) | Check Command |
|---|---|---|
| AWS account with billing enabled | N/A | N/A |
| AWS CLI | v2.36.x | aws --version |
| Python (for EB CLI) | 3.9+ (3.12 recommended) | python3 --version |
| EB CLI (awsebcli) | 3.21.0 or later | eb --version |
| Node.js (sample app) | 22 LTS | node --version |
| Git | 2.40+ | git --version |
You’ll also want a credit card on the AWS account (Elastic Beanstalk itself is free, but the EC2, ALB, and RDS resources it provisions are billable — more on exact costs later), and roughly 90 minutes for the full walkthrough including the CI/CD and HTTPS steps. One note on free tier: AWS’s own free-tier program is now scoped to accounts opened before July 15, 2025 — accounts created after that date don’t get the traditional 750 free EC2 hours per month, so budget for the t3.micro’s roughly $7.59/month even in a dev environment.
If you’re on macOS, install both CLIs through Homebrew rather than pip and the AWS installer separately — brew install awscli handles the AWS CLI cleanly, though the EB CLI still needs pip since Homebrew doesn’t maintain an official formula for it. Linux users on Ubuntu or Debian should confirm python3-pip is installed before the pip install awsebcli step, since a surprising number of fresh Ubuntu installations ship without pip preinstalled. Windows users are best served by PowerShell rather than the legacy Command Prompt, since the EB CLI’s interactive prompts render more reliably there. Whichever platform you’re on, run every version check command in the table above before moving to Step 1 — catching a stale AWS CLI now saves a confusing permissions error forty minutes into the walkthrough.
Step 1: Create an IAM User and Configure AWS Credentials
Never deploy with your AWS root account credentials. In the IAM console, create a new user named something like eb-deploy with programmatic access enabled. Attach the managed policies AWSElasticBeanstalkFullAccess and, if you’ll be pushing Docker images through it, AmazonEC2ContainerRegistryFullAccess. Generate an access key pair and store it somewhere other than a plaintext file in your repo.
aws configure --profile eb-deploy
# AWS Access Key ID [None]: AKIA...
# AWS Secret Access Key [None]: ****************
# Default region name [None]: us-east-1
# Default output format [None]: json
# Verify the identity that will be used for all EB commands
aws sts get-caller-identity --profile eb-deploy
If you manage multiple AWS accounts, keep this as a named profile rather than overwriting your default credentials — the EB CLI respects AWS_PROFILE and the --profile flag on every command.
Resist the temptation to attach AdministratorAccess to this user just to make errors go away faster. AWSElasticBeanstalkFullAccess already covers everything the EB CLI needs to create environments, deploy versions, and manage configuration; it just doesn’t extend to unrelated services like IAM user management or billing. If you later add features that touch other AWS services — an S3 bucket for uploads, an SQS queue for a worker tier — add those specific permissions to the same IAM user rather than reaching for a blanket admin policy. It’s a five-minute difference in setup time now against a much worse afternoon later if that access key ever leaks in a public repo or a misconfigured CI log.
Step 2: Install and Verify the AWS CLI and EB CLI
The EB CLI is a separate Python package from the AWS CLI, distributed on PyPI as awsebcli. Install it with pip, ideally inside a virtual environment so it doesn’t collide with other Python tooling on your machine.
# Install the AWS CLI v2 first if you haven't already (macOS example)
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
# Install the EB CLI via pip
pip install awsebcli --upgrade --user
# Confirm both are on PATH and current
aws --version
eb --version
# Expected output: EB CLI 3.21.0 (Python 3.12)
On Windows, use the official EB CLI setup scripts from AWS’s GitHub repo rather than a bare pip install — it handles the Python bootstrapping for you and avoids the PATH headaches that come from multiple Python installs on the same machine.
Step 3: Build a Sample Node.js Application
Create a project directory and a minimal Express app. Elastic Beanstalk’s Node.js platform expects your app to listen on the port defined by the PORT environment variable, which the platform’s nginx reverse proxy sets automatically.
mkdir eb-demo-app && cd eb-demo-app
npm init -y
npm install express
cat > server.js << 'EOF'
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;
app.get('/', (req, res) => {
res.json({
message: 'Hello from Elastic Beanstalk',
platform: 'Node.js 22 on Amazon Linux 2023',
timestamp: new Date().toISOString()
});
});
app.get('/health', (req, res) => res.status(200).send('OK'));
app.listen(port, () => console.log(`Server running on port ${port}`));
EOF
Add a start script to package.json — the platform runs npm start by default:
{
"name": "eb-demo-app",
"version": "1.0.0",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.19.2"
}
}
The /health route matters — you’ll point the load balancer’s health check at it in Step 8, and a missing or slow health endpoint is the number one cause of environments stuck in “Degraded” status.
This is a deliberately minimal sample so you can see every moving part of the deployment clearly, but the same pattern scales to a real application. A production Express app would add a router file per resource, a database connection pool initialized once at boot (not per-request), structured logging via something like pino so eb logs output is machine-parseable, and a graceful shutdown handler that listens for SIGTERM — Elastic Beanstalk sends that signal before terminating an instance during a deploy or scale-in event, and an app that doesn’t handle it can drop in-flight requests. None of that changes anything about the deployment steps below; it’s still the same ZIP, the same eb deploy, and the same health check contract.
Step 4: Initialize Your Application with eb init
From inside the project directory, run eb init. This creates a .elasticbeanstalk/config.yml file that stores your application name, region, and default platform — it doesn’t create any AWS resources yet.
eb init --profile eb-deploy
# Interactive prompts:
# Select a default region: 3) us-east-1
# Enter Application Name: eb-demo-app
# It appears you are using Node.js. Is this correct? Yes
# Select a platform branch: Node.js 22 running on 64bit Amazon Linux 2023
# Do you wish to continue with CodeCommit? No
# Do you want to set up SSH for your instances? Yes
# Select a keypair or create one
You can skip the prompts entirely with flags, which is what you’ll want in a CI pipeline: eb init eb-demo-app --platform "node.js-22" --region us-east-1.
Step 5: Configure the Environment with .ebextensions
The .ebextensions directory lets you declare environment configuration as YAML files checked into your repo, so environment settings travel with your code instead of living only in the console. Create .ebextensions/01-environment.config:
option_settings:
aws:elasticbeanstalk:application:environment:
NODE_ENV: production
aws:autoscaling:launchconfiguration:
InstanceType: t3.micro
aws:elasticbeanstalk:environment:proxy:
ProxyServer: nginx
aws:elasticbeanstalk:healthreporting:system:
SystemType: enhanced
Enhanced health reporting is worth turning on explicitly — it gives you causal detail (which instance, which process, which log line) instead of just a red/yellow/green dot, and it’s what powers the eb health command you’ll use in Step 11. AWS sharpened this further with a March 11, 2026 update to Elastic Beanstalk’s AI-driven environment analysis, which now surfaces clearer, more specific error messages in both the console and the EB CLI when something breaks.
Step 6: Deploy with eb create
This is the command that actually provisions infrastructure: an EC2 instance, a security group, an Application Load Balancer (if you request one), and an Auto Scaling group. It typically takes four to six minutes on a fresh environment.
eb create eb-demo-env \
--instance-type t3.micro \
--elb-type application \
--min-instances 1 \
--max-instances 4 \
--envvars NODE_ENV=production
# Watch the environment come up
eb status
eb open # opens the environment URL in your browser
Once the environment status reads “Ready” and health reads “Green,” hit the URL — you should see the JSON response from your server.js. For subsequent code changes, you don’t run eb create again; you use eb deploy, which zips your working directory and performs a rolling update against the existing environment.
Step 7: Attach an RDS Database and Set Environment Variables
For anything beyond a stateless demo, you’ll want a database. You can let Elastic Beanstalk provision RDS as part of the environment, but that ties the database’s lifecycle to the environment — terminate the environment, lose the database. The safer pattern for production is to create RDS separately and connect via environment variables.
# Create a standalone db.t3.micro Postgres instance (outside EB's lifecycle)
aws rds create-db-instance \
--db-instance-identifier eb-demo-db \
--db-instance-class db.t3.micro \
--engine postgres \
--master-username ebadmin \
--master-user-password 'ChangeThisPassword123!' \
--allocated-storage 20 \
--profile eb-deploy
# Point your app at it via EB environment variables
eb setenv DB_HOST=eb-demo-db.xxxxxxxx.us-east-1.rds.amazonaws.com \
DB_NAME=ebdemo DB_USER=ebadmin DB_PASSWORD='ChangeThisPassword123!'
Remember to open the RDS security group to inbound traffic from the Elastic Beanstalk EC2 security group specifically — not 0.0.0.0/0. Our Amazon RDS setup guide covers Multi-AZ, backup retention, and parameter group tuning in more depth if you’re taking this to production.
Passing database credentials as plain environment variables via eb setenv is fine for a tutorial but worth upgrading before real traffic hits it. Once you’re past the prototype stage, move the password into AWS Secrets Manager and read it at boot with the AWS SDK instead of baking it into the environment configuration — that way, rotating the password doesn’t require redeploying the whole application, and the secret never shows up in eb printenv output or in a teammate’s terminal history. It’s a fifteen-minute change: create the secret, grant the EB instance role secretsmanager:GetSecretValue on that specific secret’s ARN, and swap the environment-variable read in your app’s startup code for a Secrets Manager SDK call.
Step 8: Configure Auto Scaling, Load Balancer, and Health Checks
By default, the Application Load Balancer’s health check hits /. Point it at your dedicated health endpoint instead, so a slow homepage query doesn’t get your instance marked unhealthy and cycled out by Auto Scaling.
eb config
# In the editor that opens, under aws:elasticbeanstalk:environment:process:default —
# HealthCheckPath: /health
# Port: 8080
# Under aws:autoscaling:asg —
# MinSize: 2
# MaxSize: 6
# Under aws:autoscaling:trigger —
# MeasureName: CPUUtilization
# UpperThreshold: 70
# LowerThreshold: 25
Running a minimum of two instances instead of one means the ALB always has a healthy target during a deployment or an instance replacement, which is the difference between a rolling deploy your users never notice and a brief 502 spike.
Deployment policy matters just as much as scaling policy here. By default, Elastic Beanstalk uses a rolling deployment that updates instances in batches, but you can tighten that further with an immutable deployment, which launches an entirely new Auto Scaling group alongside the old one, waits for it to pass health checks, then swaps traffic over and terminates the old group. Immutable deployments take longer — often eight to ten minutes instead of three to four — but they guarantee that a bad deploy never touches more than zero production instances, since the new group only receives traffic once it’s fully healthy. Set it under eb config in the aws:elasticbeanstalk:command namespace with DeploymentPolicy: Immutable. For a low-traffic side project, rolling is fine; for anything customer-facing where a bad deploy means real revenue impact, the extra five minutes of deploy time is worth it.
Step 9: Set Up HTTPS with ACM and a Custom Domain
Request a free public certificate from AWS Certificate Manager for your domain, validate it via DNS, then attach it to the ALB’s HTTPS listener.
# Request the cert (must be in the same region as your EB environment for an ALB)
aws acm request-certificate \
--domain-name app.example.com \
--validation-method DNS \
--profile eb-deploy
# After DNS validation completes, add the HTTPS listener via eb config:
# aws:elbv2:listener:443 —
# Protocol: HTTPS
# SSLCertificateArns: arn:aws:acm:us-east-1:123456789012:certificate/xxxx
# Then point your domain at the environment's ALB with a CNAME or Route 53 alias record
While you’re in there, redirect port 80 to 443 by adding a second listener rule, or your app will silently accept unencrypted traffic on the default HTTP listener even after HTTPS is live.
Step 10: Automate Deployments with GitHub Actions CI/CD
Manual eb deploy runs don’t scale past a solo project. Wire deployments to your main branch with GitHub Actions using the community-maintained beanstalk-deploy action, which wraps the same S3-upload-and-version-create flow the EB CLI uses internally.
# .github/workflows/deploy.yml
name: Deploy to Elastic Beanstalk
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Zip application
run: zip -r deploy.zip . -x ".git/*" ".github/*"
- name: Deploy to EB
uses: einaregilsson/beanstalk-deploy@v22
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: eb-demo-app
environment_name: eb-demo-env
region: us-east-1
version_label: ${{ github.sha }}
deployment_package: deploy.zip
Use a scoped IAM user for the GitHub Actions secrets — not the same broad-access user from Step 1 — and store the version label as the Git SHA so every deployment maps back to an exact commit when you need to roll back.
Step 11: Monitor, Roll Back, and Clean Up Resources
Once your environment is live, three commands cover 90% of day-to-day operations. Use eb logs to pull instance logs without SSH, eb health to see per-instance status with enhanced reporting enabled, and eb deploy --version-label to roll back to any prior application version instantly.
# Pull recent logs from all instances
eb logs --all
# Check detailed per-instance health
eb health
# List previous application versions and roll back to a known-good one
eb appversion
eb deploy --version-label
# When you're done testing, terminate the environment to stop billing
eb terminate eb-demo-env
That last command matters more than it looks — an idle Elastic Beanstalk environment keeps billing for its EC2 instances, ALB, and any attached RDS instance around the clock, even with zero traffic. Terminating the environment doesn’t delete standalone RDS instances you created separately in Step 7, so drop those explicitly with aws rds delete-db-instance if you’re done with them.
Monthly Cost Breakdown: What You’ll Actually Pay
Elastic Beanstalk itself never appears as a line item on your bill — every dollar comes from the EC2, ELB, and RDS resources it creates. Here’s what three realistic setups cost in us-east-1, based on current on-demand pricing from AWS’s EC2 T3 instance pricing page and RDS pricing page.
| Setup | Components | Approx. Monthly Cost |
|---|---|---|
| Minimal dev (single instance) | 1× t3.micro ($0.0104/hr), no load balancer | ~$7.59 |
| Small production (2 instances + ALB) | 2× t3.small ($0.0208/hr each) + Application Load Balancer | ~$47–$55 |
| Production with database | 2× t3.small + ALB + 1× RDS db.t3.micro ($0.017/hr) | ~$60–$68 |
The ALB itself typically adds around $16–$20/month in base hourly charges plus a small per-LCU fee under real traffic — budget for it even in the “minimal” tier if you enable one. If you opened your AWS account after July 15, 2025, none of this is covered by the legacy 12-month free tier, so the t3.micro dev environment above is a real cost from day one, not a free trial.
Two levers cut these numbers meaningfully once you’re past the prototype stage. Reserved Instances or a Savings Plan on the EC2 layer typically knock 30-40% off the on-demand hourly rate if you can commit to steady baseline usage for a year, which is worth doing the moment your environment stops being a throwaway test. And if your workload is genuinely bursty — busy during business hours, idle overnight — a scheduled scaling action that drops MinSize to zero or one outside peak hours can cut the “small production” tier’s compute cost close to in half, since you’re not paying for idle t3.small capacity all night. Neither change requires touching your application code; both are configuration changes in eb config or the EC2 console.
Common Pitfalls When Deploying to Elastic Beanstalk
Most Elastic Beanstalk failures trace back to a handful of repeatable mistakes. Here are the ones that cost the most debugging time.
- Hardcoding the port instead of reading PORT. Elastic Beanstalk’s nginx proxy forwards traffic to your app on the port it assigns via the
PORTenvironment variable, not a fixed port you pick. Hardcode port 3000 and the proxy can’t reach your process at all. - Deploying with an oversized package. If
node_modules, build caches, or test fixtures end up in your deployment ZIP, uploads slow to a crawl and can hit the platform’s package size limits. Add a.ebignorefile mirroring your.gitignore. - Skipping the health check path. Leaving the default health check on
/when your homepage does a slow database query means transient DB latency gets read as instance failure, triggering unnecessary Auto Scaling replacements. - Using a deprecated platform branch. With Node.js 20, Python 3.9, and Ruby 3.2 AL2023 branches retired as of August 13, 2026, environments still pinned to them stop receiving security patches. Check your platform version with
eb platform showbefore you assume it’s current. - Storing secrets in .ebextensions files. Config files under
.ebextensionsget committed to Git. Database passwords and API keys belong ineb setenvor AWS Secrets Manager, never in a YAML file that lands in version control.
Troubleshooting: 8 Common Elastic Beanstalk Errors and Fixes
| Error | Typical Cause | Fix |
|---|---|---|
| Environment health: Severe (Red) | App crashes on startup or fails health checks consecutively | Run eb logs --all, check /var/log/eb-engine.log for the stack trace |
| “Failed to deploy application.” | A deployment hook or .ebextensions command failed mid-deploy | Check eb-engine.log for the exact failing command; validate hooks locally first |
| “ERROR: Failed to run npm install.” | Instance runs out of memory during install, or an unreachable private registry | Use a larger instance type temporarily, or commit a lockfile and prune devDependencies |
| “Unsuccessful command execution on instance id(s)” | A platform hook script exited non-zero | SSH into the instance and re-run the script manually to see the real error |
| 502 Bad Gateway from the ALB | App isn’t listening on the PORT env var, or crashed after boot | Confirm process.env.PORT is used, not a hardcoded port |
| “Incorrect application version found on all instances” | A deploy partially failed and instances are out of sync | Redeploy a known-good version label with eb deploy --version-label |
| eb init hangs or times out | Wrong region selected, or IAM user lacks Elastic Beanstalk permissions | Re-run with --region explicit and confirm the IAM policy includes AWSElasticBeanstalkFullAccess |
| RDS connection refused from the app | Security group doesn’t allow inbound traffic from the EB instance’s security group | Add an inbound rule on the RDS security group referencing the EB EC2 security group ID |
When none of the obvious fixes work, AWS’s own Elastic Beanstalk developer guide has a dedicated troubleshooting reference that walks through reading eb-engine.log, application logs, and nginx proxy logs in sequence — that log order (engine, then app, then proxy) is the fastest path to root cause almost every time.
Advanced Tips for Production Elastic Beanstalk Environments
Once the basic environment is stable, a few advanced patterns separate a toy deployment from a production one. Blue/green deployment via CNAME swap lets you stand up a second, fully separate environment, deploy and test the new version there, then swap the environment URLs so traffic cuts over instantly with an easy rollback path — run eb swap once both environments are healthy. For background job processing, a worker tier environment (rather than a web server tier) pulls messages from an SQS queue and processes them without an ALB in front, which is the right shape for anything asynchronous like email sending or report generation.
Platform hooks — scripts under .platform/hooks/predeploy, postdeploy, and similar directories — replace the older, more fragile container_commands syntax in .ebextensions and run at defined points in the deployment lifecycle on Amazon Linux 2023 platforms. Use them for database migrations or cache warming rather than jamming that logic into your app’s boot sequence. And if you’re running the Docker platform specifically, pin to a known-good AL2023 Docker branch (4.13.6 as of mid-August 2026) rather than “latest,” since AWS ships a new Docker AL2023 version roughly monthly and an untested jump can break a container that depends on a specific Docker Compose behavior. That caution is well-founded — AWS’s August 22, 2025 AL2 platform update alone touched eight different platforms in a single release, including Docker and PHP, so a Compose behavior that worked last month can quietly shift in the next batch.
Finally, treat your .elasticbeanstalk, .ebextensions, and .platform directories as part of your application’s source of truth, not console clicks you’ll remember to redo later. A surprising number of production incidents trace back to a configuration change made directly in the console — a health check timeout bumped up to stop alarms firing, a security group rule loosened to unblock a debugging session — that never made it back into version control. The next environment rebuild, or the next teammate running eb create from a clean checkout, silently loses that fix. Running eb config save periodically to pull the live configuration back into a saved config file in your repo closes that gap, and it’s worth doing right after any console-side emergency fix while the change is still fresh in your memory.
Frequently Asked Questions
Is AWS Elastic Beanstalk free to use?
Elastic Beanstalk itself has no service charge. You pay only for the AWS resources it provisions — EC2 instances, the load balancer, and any attached RDS database — at standard on-demand rates.
What’s the difference between eb create and eb deploy?
eb create provisions a brand-new environment with all its infrastructure and only needs to run once. eb deploy pushes updated code to an existing environment via a rolling deployment and is what you run on every subsequent release.
Can I run Docker containers on Elastic Beanstalk?
Yes. The Docker platform on Amazon Linux 2023 (currently version 4.13.6) runs a single container or a Docker Compose multi-container setup, giving you the same rolling-deployment and Auto Scaling behavior as the language-specific platforms.
Why did my Elastic Beanstalk platform branch stop receiving updates?
AWS retires platform branches on a rolling schedule. Node.js 20, Python 3.9, and Ruby 3.2 on Amazon Linux 2023 were retired on August 13, 2026. Check your current branch with eb platform show and migrate to a supported version — Node.js 22, Python 3.12/3.13, or Ruby 3.3 — before it’s fully deprecated.
Should I let Elastic Beanstalk manage my RDS database?
For quick prototypes, letting EB provision RDS inline is fine. For anything you plan to keep, create the RDS instance separately and connect via environment variables — that decouples the database’s lifecycle from the environment, so terminating or recreating the environment doesn’t risk deleting your data.
How is Elastic Beanstalk different from AWS App Runner?
App Runner hides the underlying infrastructure entirely and scales on request concurrency with effectively zero configuration. Elastic Beanstalk exposes the EC2 instances, load balancer, and Auto Scaling group directly, trading some simplicity for the ability to SSH in, install packages, and tune networking.
What EB CLI version should I be running?
AWS’s documentation as of mid-2026 shows EB CLI 3.21.0 running on Python 3.12 as a current, actively supported release. Run pip install awsebcli --upgrade --user periodically to stay current, since the CLI adds support for new platform branches over time.
Does terminating an environment delete my database?
Only if the RDS instance was created inline as part of that environment. A standalone RDS instance you created separately with aws rds create-db-instance persists after eb terminate and must be deleted independently to stop billing for it.
Related Coverage
- How to Set Up AWS Lambda: 12 Steps, 90 Min [2026]
- How to Set Up Amazon RDS: 12 Steps, 90 Min [2026]
- How to Set Up Google Cloud Run: 13 Steps, 80 Min [2026]
- How to Set Up Terraform on AWS: 13 Steps, 90 Min [2026]
- AWS vs Azure vs Google Cloud: 4x H100 GPU Price Gap [2026]
- AWS RDS vs Azure Database vs Google Cloud SQL: 25% Price Gap [2026]


