Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Deploying Meteor to AWS Elastic Beanstalk as a Docker image from Github via CircleCI
{
"https://index.docker.io/v1/": {
"auth": "<base64 encoded Docker username:password>",
"email": "<Docker Account Email>"
}
}
files:
"/etc/nginx/conf.d/websocketupgrade.conf":
mode: "000755"
owner: root
group: root
content: |
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
machine:
node:
version: 0.10.35
services:
- docker
dependencies:
override:
- sudo pip install awscli
- if [ ! -f $HOME/.meteor/meteor ]; then curl https://install.meteor.com | sh; fi
- sudo ln -s $HOME/.meteor/meteor /usr/bin/meteor
- docker info
- docker build -t hellotech/prototype:$CIRCLE_SHA1 .
cache_directories:
- ../.meteor
test:
post:
- docker run -d -e ROOT_URL=http://localhost -e MONGO_URL=<Mongo URL - e.g., mongodb://compose.io/blah> -p 8080:80 your/repo:$CIRCLE_SHA1; sleep 15
- curl -v http://localhost:8080
deployment:
elastickbeanstalk:
branch: <repo branch>
commands:
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
- ./deploy.sh $CIRCLE_SHA1
#! /bin/bash
# Make sure this file is permissioned 00755
SHA1=$1
# Deploy image to Docker Hub
docker push your/repo:$SHA1
# Create new Elastic Beanstalk version
EB_BUCKET=<some-bucket>
DOCKERRUN_FILE=$SHA1-Dockerrun.aws.json
sed "s/<TAG>/$SHA1/" < Dockerrun.aws.json.template > $DOCKERRUN_FILE
aws s3 cp $DOCKERRUN_FILE s3://$EB_BUCKET/$DOCKERRUN_FILE
aws s3 cp ~/.dockercfg s3://$EB_BUCKET/dockercfg --region=us-east-1
if ! [ -n "$(aws elasticbeanstalk describe-environments --region=us-east-1 | grep '<app env - e.g., repo-env>')" ]; then
aws elasticbeanstalk create-application --application-name <app name - e.g., repo> --description "<my app>"
aws elasticbeanstalk create-environment --application-name <app name - e.g., repo> --environment-name <app env - e.g., repo-env> --region=us-east-1 --solution-stack-name "64bit Amazon Linux 2014.09 v1.2.0 running Docker 1.3.3"
sleep 60
fi
aws elasticbeanstalk create-application-version --application-name <app name - e.g., repo> \
--version-label $SHA1 --source-bundle S3Bucket=$EB_BUCKET,S3Key=$DOCKERRUN_FILE --region=us-east-1 \
--auto-create-application
# Update Elastic Beanstalk environment to the new version
aws elasticbeanstalk update-environment --environment-name <app env - e.g., repo-env> --version-label $SHA1 --region=us-east-1
FROM meteorhacks/meteord
MAINTAINER <YOU>
ENV MONGO_URL <Mongo URL - e.g., mongodb://compose.io/blah>
ENV ROOT_URL <App URL - e.g., http://gobbletygook.elasticbeanstalk.com>
{
"AWSEBDockerrunVersion": "1",
"Authentication": {
"Bucket": "<some-bucket>",
"Key": "dockercfg"
},
"Image": {
"Name": "your/repo:<TAG>",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "80"
}
]
}
First off, most of this is cribbed from various other sources (AWS docs, CircleCI docs, Meteorhacks, Stackoverflow, etc.). I just cobbled it together for my own needs.
FWIW - I'm deploying from a private Github repo and posting my Docker images to a private Docker Hub.
The files all live at the root of the project excpet for 01_files.config which should be placed in a directory called .ebextensions.
In CircleCI setup a new project. Be sure to set your AWS credentials in the options. Additionally, in the Environment Variables enter values for DOCKER_EMAIL, DOCKER_USER and DOCKER_PASS.
I tried getting the AWS EBS environment to setup auto-magically but kept running into issues. I'm sure if I spent the time and added some conditionals it would work, but I was in a hurry. In the end I manually did that part with the awscli tool (one time task):
aws elasticbeanstalk create-environment --application-name <app name - e.g., repo> --environment-name <app env - e.g., repo-env> --region=us-east-1 --solution-stack-name "64bit Amazon Linux 2014.09 v1.2.0 running Docker 1.3.3"
** Fixed to check for the environment first and create if not already there **
Also, I got tired of messing around with IAM profiles and whatnot to get the permissions right on the dockercfg file stored in S3. To create the file you need your Docker username and password. Then:
$ echo "username:password" | base64
dXNlcm5hbWU6cGFzc3dvcmQK
Replace the trailing K with an = in the .dockercfg file which you upload to S3. The template is just there to show you the format. Keep your actual .dockercfg safe in your home dir if anywhere.
I'll eventually get around to fixing the IAM profile stuff appropriately too. Again, was in a hurry.
** As expected, once I fixed my IAM policies the .dockercfg file is being uploaded and copied appropriately. **
Also on the AWS side, I have an aws-elasticbeanstalk-ec2-role role that I've associated with my resources. But since everyone will have different setups and requirements for the security part, I'll leave it as an exercise for the reader.
If you need websockets to function properly, you'll need to change the Load Balancer configuration in AWS to be of type TCP instead of HTTP. This means that you can't also use Sticky Sessions. For my use case that's not an issue. Since, I'm only launching a single instance. If this were a production environment, then you'd have to either live without websockets or do something else. Maybe turn off he load balancer and use Meteorhack Cluster?
I think that's about it. Now, anytime I commit CircleCI fires up, creates a new Docker image and then deploys it to AWS EBS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment