Skip to content

Instantly share code, notes, and snippets.

@markotom
Last active March 5, 2016 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markotom/f0c76970da0c5bd1ecc3 to your computer and use it in GitHub Desktop.
Save markotom/f0c76970da0c5bd1ecc3 to your computer and use it in GitHub Desktop.

Deploying applications using Docker and AWS Elastic Beanstalk

Hay dos maneras de crear contenedores de Docker en AWS EB. La primera responde a un single container que consiste en crear un solo contenedor para una instancia. La segunda son multiple containers que normalmente son utilizados para ser vinculados entre ellos; así podemos tener, por ejemplo, una aplicación de Nodejs en un contenedor y MongoDB en otro contenedor. En nuestro caso, nos basta un contenedor por instancia, pues siempre es una buena práctica tener las base de datos separadas en diferentes instancias.

Esta guía es para hacer deployment en single containers.

Dockerfile

Crea un archivo Dockerfile en el repositorio del proyecto con la configuración del contenedor. En su lugar también es posible crear un archivo Dockeraws.run.json para la configuración de contenedores. Este es un ejemplo básico de una aplicación de Node:

FROM node:5.7.0

# Install PM2
RUN npm install -g pm2

# Workdir directory
ENV APP_ROOT /usr/src/app

# Set Workdir
RUN mkdir -p $APP_ROOT
WORKDIR $APP_ROOT

# Install dependencies
COPY package.json $APP_ROOT
RUN npm install
COPY . $APP_ROOT

# Expose port
EXPOSE 1337

# Start server
CMD pm2 start app.js \
    -i 0 \
    --name MyApp \
    --no-daemon

AWS EB se encargará de construir el contenedor y configurar nginx para hacer un proxy al puerto declarado en el Dockerfile.

Nota: Es importante declarar directamente la exposición del puerto (sin referencia a una variable de entorno), porque AWS EB lo reproduce en la configuración de nginx de la instancia.

Application

Es necesario primero crear la configuración global de nuestra aplicación, en donde podemos definir las ramas de Git que serán usadas para desplegar la aplicación, esto es muy útil cuando se quiere crear un ambiente de QA.

Basta con crear la configuración desde la línea de comandos corriendo eb init, esto creará un archivo por defecto en .elasticbeanstalk/config.yml con la configuración. Pero, también se puede crear manualmente el archivo y poner lo siguiente:

branch-defaults:
  kamaji-rest:
    environment: kamaji-staging
global:
  application_name: "Kamaji API"
  default_ec2_keyname: 4yopping-general
  default_platform: Docker 1.9.1
  default_region: us-east-1
  profile: null
  sc: git

Environment

AWS EB necesita crear un environment previamente para hacer deployment de la aplicación. Utilizando la línea de comandos se puede hacer sin necesidad de una configuración previa, pero AWS EB creará la aplicación con la configuración que tiene por defecto. Esto no es útil si queremos personalizar nuestra VPC con diferentes subnets con NATs, un AMI y un tipo de instancia en particular, certificados para el ELB, etcétera.

Primero, crearemos este archivo de configuración en .elasticbeanstalk/saved_configs/staging.cfg.yml, con nuestros valores personalizados:

AWSConfigurationTemplateVersion: 1.1.0.0
EnvironmentConfigurationMetadata:
  Description: Configuration of kamaji-staging environment
SolutionStack: 64bit Amazon Linux 2015.09 v2.0.8 running Docker 1.9.1
OptionSettings:
  aws:elasticbeanstalk:command:
    BatchSize: 30
    BatchSizeType: Percentage
  aws:elb:policies:
    ConnectionDrainingEnabled: true
    ConnectionDrainingTimeout: 20
    ConnectionSettingIdleTimeout: 60
  aws:elb:loadbalancer:
    CrossZone: true
  aws:elasticbeanstalk:application:environment:
    NODE_ENV: production
  aws:elasticbeanstalk:environment:
    ServiceRole: aws-elasticbeanstalk-service-role
  aws:elasticbeanstalk:healthreporting:system:
    AWSEBHealthdGroupId: 88a215ee-4f87-4d42-9dca-df115ba7b9d4
    SystemType: enhanced
  aws:autoscaling:launchconfiguration:
    EC2KeyName: 4yopping-general
    IamInstanceProfile: aws-elasticbeanstalk-ec2-role
    ImageId: ami-10fdc17a
    InstanceType: t2.micro
    MonitoringInterval: 5 minute
    SSHSourceRestriction: tcp,22,22,0.0.0.0/0
  aws:autoscaling:updatepolicy:rollingupdate:
    MaxBatchSize: 1
    MinInstancesInService: 1
    RollingUpdateEnabled: true
    RollingUpdateType: Health
    Timeout: PT30M
  aws:ec2:vpc:
    VPCId: vpc-f36d4f97
    AssociatePublicIpAddress: true
    ELBScheme: public
    ELBSubnets: subnet-3c9bf301
    Subnets: subnet-ee98f0d3
  AWSEBCloudwatchAlarmHigh.aws:autoscaling:trigger:
    UpperThreshold: 6000000
  AWSEBCloudwatchAlarmLow.aws:autoscaling:trigger:
    BreachDuration: 5
    EvaluationPeriods: 1
    LowerThreshold: 2000000
    MeasureName: NetworkOut
    Period: 5
    Statistic: Average
    Unit: Bytes
  aws:autoscaling:asg:
    Availability Zones: Any
    Cooldown: 360
    MaxSize: 4
    MinSize: 1
  aws:elasticbeanstalk:hostmanager:
    LogPublicationControl: false
  aws:elb:healthcheck:
    HealthyThreshold: 3
    Interval: 10
    Target: TCP:80
    Timeout: 5
    UnhealthyThreshold: 5
  aws:elb:listener:80:
    InstancePort: 80
    InstanceProtocol: HTTP
    ListenerEnabled: true
    ListenerProtocol: HTTP
EnvironmentTier:
  Type: Standard
  Name: WebServer

Si quieres tener más información sobre las opciones que pueden configurarse, puedes ver esta documentación de AWS namespaces:

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html

De esta manera podemos crear el environment y hacer deployment con la configuración personalizada:

$ eb create --cfg staging

Así, en una futura ocasión, cuando el environment ya esté creado, podemos hacer deployment con lo siguiente:

$ eb deploy kamaji-staging

Nota: Es importante hacer commit en el controlador de versiones para hacer deploy de los últimos cambios. Pero también es posible usar el argumento --stage para definir un commit específico desde donde AWS EB debe hacer deploy.

Referencias

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/vpc.html

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