Skip to content

Instantly share code, notes, and snippets.

Last active January 18, 2023 00:16
What would you like to do?
Build a Docker image, push it to AWS EC2 Container Registry, then deploy it to AWS Elastic Beanstalk
# usage: ./ staging f0478bd7c2f584b41a49405c91a439ce9d944657
# license: public domain
aws configure set default.region us-east-1
# Authenticate against our Docker registry
eval $(aws ecr get-login)
# Build and push the image
docker build -t $NAME:$VERSION .
docker push $$NAME:$VERSION
# Replace the <AWS_ACCOUNT_ID> with the real ID
# Replace the <NAME> with the real name
sed -i='' "s/<NAME>/$NAME/"
# Replace the <TAG> with the real version number
sed -i='' "s/<TAG>/$VERSION/"
# Zip up the Dockerrun file (feel free to zip up an .ebextensions directory with it)
zip -r $ZIP
aws s3 cp $ZIP s3://$EB_BUCKET/$ZIP
# Create a new application version with the zipped up Dockerrun file
aws elasticbeanstalk create-application-version --application-name $NAME-application \
--version-label $VERSION --source-bundle S3Bucket=$EB_BUCKET,S3Key=$ZIP
# Update the environment to use the new application version
aws elasticbeanstalk update-environment --environment-name $NAME \
--version-label $VERSION
"AWSEBDockerrunVersion": "1",
"Image": {
"Update": "true"
"Ports": [
"ContainerPort": "443"
Copy link

philipithomas commented May 12, 2016

Looks like our Staffjoy deploy code. I suggest polling to see if the deploy succeeded. I copied and sanitized some code to do this from our deploys below that should match your variables (I haven't tested the modifications though). It looks for the deployed tag to match the anticipated one, it looks for EB to return to a "Ready" state (where another deploy can be initiated), and it times out if these conditions are not met (returning exit code 1).

deploystart=$(date +%s)
timeout=3000 # Seconds to wait before error. If it's taking awhile - your boxes probably are too small.
threshhold=$((deploystart + timeout))
while true; do
    # Check for timeout
    timenow=$(date +%s)
    if [[ "$timenow" > "$threshhold" ]]; then
        echo "Timeout - $timeout seconds elapsed"
        exit 1

    # See what's deployed
    current_version=`aws elasticbeanstalk describe-environments --application-name "$NAME-application" --environment-name "$NAME" --query "Environments[*].VersionLabel" --output text`

    status=`aws elasticbeanstalk describe-environments --application-name "$NAME-application" --environment-name "$NAME" --query "Environments[*].Status" --output text`

    if [ "$current_version" != "$VERSION" ]; then
        echo "Tag not updated (currently $version). Waiting."
        sleep 10
    if [ "$status" != "Ready" ]; then
        echo "System not Ready -it's $status. Waiting."
        sleep 10

Copy link

I'm new to Docker and came across this gist today while researching deployment strategies with Docker and Elastic Beanstalk. How does your application get built into the image? Are you pulling it from the repo as you build it? This is one thing I'm not super clear on.

Copy link

yefim commented Oct 4, 2016

@theseanstewart great question! I build the docker image with docker build -t $NAME:$VERSION . then push the built (and tagged) image to the Amazon EC2 Container Registry with docker push $$NAME:$VERSION.

The way the Elastic Beanstalk application environment knows how to deploy itself is the file. In that file I specify the docker image to use and create a new application version with that points to the newly built, tagged, and pushed docker image URL. Does that make sense?

Copy link

revl-ca commented Oct 18, 2016

Is it possible to accomplish this with the awsebcli?

Copy link

mskutin commented Dec 13, 2016
missing trailing slash
sed -i='' "s/<NAME>/$NAME"
sed -i='' "s/<NAME>/$NAME/"

Copy link

@yefim any chance you can explicitly specify a license for this? I am assuming its public domain, but its always nice to be explicit.

Copy link

ghost commented Dec 29, 2016

This is really helpful. Thank you!

Copy link

rootux commented Feb 17, 2017

Would like to add a comment for new comers that you need to create a EC2 container first here that will be the $NAME param -

Copy link

instead of this

aws s3 cp $ZIP s3://$EB_BUCKET/$ZIP

# Create a new application version with the zipped up Dockerrun file
aws elasticbeanstalk create-application-version --application-name $NAME-application \
    --version-label $VERSION --source-bundle S3Bucket=$EB_BUCKET,S3Key=$ZIP

# Update the environment to use the new application version
aws elasticbeanstalk update-environment --environment-name $NAME \
      --version-label $VERSION

you can use awsebcli

eb deploy ${EB_ENV_NAME}

Copy link

Super helpful, thanks!

I adapted it so that it can be downloaded and executed with curl / eval as a single self-contained script with project specific env vars pulled out:

Copy link

Alexhha commented Apr 11, 2017

Note: script won't work for the first time. aws elasticbeanstalk update-environment command will work only for existing environment

# Replace the <NAME> with the real name
sed -i='' "s/<NAME>/$NAME"

should contain trailing slash at the end

sed -i "s/<NAME>/$NAME/"

Copy link

wprater commented Jun 16, 2017

should probably be user to add node_modules to a .dockerignore file as well

Copy link

simonguldstrand commented Jun 30, 2017

@Alexhha, would you just add the aws ecs register-task-definition to be able to use this script without existing env?

Copy link

@stephen-swensen unbelievable lifesaver. I spent 2 hours reading AWS docs and with your scripts completed the same in < 10 minutes.

Seriously, code shouts, documentation whispers.

Copy link

How elastic beanstalk knows the credentials of ECS registry?

Copy link

If you are using docker-compose instead of docker build

instead of

docker build -t $NAME:$VERSION .

put this

docker-compose -f docker-compose.yml build

and add the image: key to your docker-compose.yml file

version: '3.3'
     image: $IMAGE_NAME


Copy link

Hello All,

I'm doing different.
I'm using AWSEBCLI to deploy the application with the structure bellow:

  • .
  • .elasticbeanstalk/config.yml
  • (Dockerfile and all files of application)

So in config.yml is necessary put the keys bellow:


The archive will be like this:

    environment: myEnv
  application_name: myApp
  default_ec2_keyname: myKey
  default_platform: arn:aws:elasticbeanstalk:sa-east-1::platform/Docker running on
    64bit Amazon Linux/2.8.4
  default_region: sa-east-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: null
  sc: git
  workspace_type: Application

then is just execute the command 'eb deploy' in main directory os your app.

Copy link

@javahometech when using elastic beanstalk ,and ecr, you set up an iam role. So then when the following was run:

eval $(aws ecr get-login)

aws ecr get-login prints out a docker login command with a temporary credential. That output then gets executed with the eval statement and that's how auth is handled.

Copy link

ivarprudnikov commented Nov 25, 2018

sed command contains minor "error":
sed -i='' "s/<AWS_ACCOUNT_ID>/$AWS_ACCOUNT_ID/" will make a backup file called which is not what would be expected. Assume because -i was used the expectation is that file will be modified in place.

-i='' needs to be replaced with either --in-place='' or with -i '' or with a sensible backup extension -i.bak
First 2 options will not work on all systems and I found the last one -i.bak a bit more reliable when running sed on OSX and on Linux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment