-
-
Save yefim/93fb5aa3291b3843353794127804976f to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# usage: ./deploy.sh staging f0478bd7c2f584b41a49405c91a439ce9d944657 | |
# license: public domain | |
BRANCH=$1 | |
SHA1=$2 | |
AWS_ACCOUNT_ID=12345678900 | |
NAME=name-of-service-to-deploy | |
EB_BUCKET=aws-s3-bucket-to-hold-application-versions | |
VERSION=$BRANCH-$SHA1 | |
ZIP=$VERSION.zip | |
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 tag $NAME:$VERSION $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/$NAME:$VERSION | |
docker push $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/$NAME:$VERSION | |
# Replace the <AWS_ACCOUNT_ID> with the real ID | |
sed -i='' "s/<AWS_ACCOUNT_ID>/$AWS_ACCOUNT_ID/" Dockerrun.aws.json | |
# Replace the <NAME> with the real name | |
sed -i='' "s/<NAME>/$NAME/" Dockerrun.aws.json | |
# Replace the <TAG> with the real version number | |
sed -i='' "s/<TAG>/$VERSION/" Dockerrun.aws.json | |
# Zip up the Dockerrun file (feel free to zip up an .ebextensions directory with it) | |
zip -r $ZIP Dockerrun.aws.json | |
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": { | |
"Name": "<AWS_ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/<NAME>:<TAG>", | |
"Update": "true" | |
}, | |
"Ports": [ | |
{ | |
"ContainerPort": "443" | |
} | |
] | |
} |
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.
@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 $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/$NAME:$VERSION
.
The way the Elastic Beanstalk application environment knows how to deploy itself is the Dockerrun.aws.json
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?
Is it possible to accomplish this with the awsebcli?
https://gist.github.com/yefim/93fb5aa3291b3843353794127804976f#file-deploy-sh-L28
missing trailing slash
from:
sed -i='' "s/<NAME>/$NAME" Dockerrun.aws.json
to:
sed -i='' "s/<NAME>/$NAME/" Dockerrun.aws.json
@yefim any chance you can explicitly specify a license for this? I am assuming its public domain, but its always nice to be explicit.
This is really helpful. Thank you!
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 - https://console.aws.amazon.com/ecs
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}
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: https://github.com/relayfoods/aws-docker-deploy
Note: deploy.sh 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" Dockerrun.aws.json
should contain trailing slash at the end
sed -i "s/<NAME>/$NAME/" Dockerrun.aws.json
should probably be user to add node_modules
to a .dockerignore
file as well
@Alexhha, would you just add the aws ecs register-task-definition
to be able to use this script without existing env?
@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.
How elastic beanstalk knows the credentials of ECS registry?
Thanks,
Hari
If you are using docker-compose
instead of docker build
In deploy.sh
instead of
docker build -t $NAME:$VERSION .
put this
export IMAGE_NAME=$NAME:$VERSION
docker-compose -f docker-compose.yml build
and add the image:
key to your docker-compose.yml
file
version: '3.3'
services:
service_name:
image: $IMAGE_NAME
Reference:
https://stackoverflow.com/questions/33816456/how-to-tag-docker-image-with-docker-compose
Hello All,
I'm doing different.
I'm using AWSEBCLI to deploy the application with the structure bellow:
- .
- .elasticbeanstalk/config.yml
- Dockerrun.aws.json
- (Dockerfile and all files of application)
So in config.yml is necessary put the keys bellow:
deploy:
artifact: Dockerrun.aws.json
The archive will be like this:
branch-defaults:
master:
environment: myEnv
deploy:
artifact: Dockerrun.aws.json
global:
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.
@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.
sed
command contains minor "error":
sed -i='' "s/<AWS_ACCOUNT_ID>/$AWS_ACCOUNT_ID/" Dockerrun.aws.json
will make a backup file called Dockerrun.aws.json=
which is not what would be expected. Assume because -i
was used the expectation is that file will be modified in place.
Documentation https://linux.die.net/man/1/sed
-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
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).