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.
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.
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
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.
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