Deploy and Scale your PHP App with AWS ElasticBeanstalk and Docker- PHPTour Luxembourg 2015

Post on 18-Jul-2015

642 views 8 download

transcript

Deploy and Scale your PHP App usingDocker containers and AWS Beanstalk

Walter Dal Mut

@walterdalmut - github.com/wdalmut

I'm co-founder of @CorleyCloudapplication development

infrastructure and application migration on cloud

I'm also a co-founder of @UpClooU.K. based startup: powering related content across the web

walter.dalmut@gmail.com

First of all we have to agree onwhat scaling is for this talk

scalability is not high availabilityScalability is the ability of a system to handle a growing amount of work in capable manner or the ability to be

enlarged to accomodate that growth (from wikipedia)

Adapting Infrastructures

From single instances point of view

It is also meaning that with fixed hardware

we have to provide the highest computing capacity

Money wasters?

With Cloud Providers

About ElasticBeanstalkLoad Balanced web applications

Single instance web applications

Queue daemons (SQS)

Load balanced web applications

Autoscalable infrastructures

thresholds are used tocreate and remove instances

with (auto)scalable infrastructuresHow to manage application upgradesHow to monitor serversHow to handle servers configurationsHow to handle instances logs...

ElasticBeanstalk help us with this things

Application Deploy

Mainly Beanstalk takes a ZIP artifact (the PHP application)

and unpack it into the environmentUses YML definitions in order to setup the environment

The deploy cycle take care of:1. Packages2. Users & Groups3. Files4. Commands

before the application and web server are set up5. Services6. Container_commands

just before the application version is deployed

Configure PHP detailsfiles:  "/etc/php.d/my­timezone.ini" :    mode: "000644"    owner: root    group: root    content: |      date.timezone = Europe/Rome

You can also use beanstalk options

extract your application logscommands:    21_application_logs:        command: echo "/var/app/current/app/logs/*.log" > app.conf        cwd: /opt/elasticbeanstalk/tasks/bundlelogs.d    22_application_logs:        command: echo "/var/app/current/app/logs/*.log" > app.conf        cwd: /opt/elasticbeanstalk/tasks/systemtaillogs.d    23_application_logs:        command: echo "/var/app/current/app/logs/*.log" > app.conf        cwd: /opt/elasticbeanstalk/tasks/taillogs.d    24_application_logs:        command: echo "/var/app/current/app/logs/*.log" > app.conf        cwd: /opt/elasticbeanstalk/tasks/publishlogs.d

And check them directly from the web console

Beanstalk works with differentapplication containers

PHP, Node.js, Tomcat, Python, Ruby

and...

Docker & Multicontainer DockerMulticontainer Docker is connected to ElasticContainer Service

Why docker is interesting forElasticBeanstalk?

When there is a default PHP container withdifferent available versions: 5.3, 5.4, 5.5, 5.6

Instances are Amazon LinuxDifficult to configure a different distro: ubuntu, debian ...

Even packages: supervisors, agents etc.

Difficult to replicate the env locally (dev).

Default PHP container configuration

{{ Apache - MOD_PHP }}

The application path changeafter the deploy cycle

/var/app/ondeck -> /var/app/current

Symfony2 cache warmup problems...

With Docker we can create a morededicated setup

{{ Nginx - PHP-FPM }}

The docker environment is more stableand testable than the default one

Thanks to the docker isolation nature

File are uncompressed into: /var/app/current

Prepare a web serverFROM ubuntu:14.04

RUN apt­get update && apt­get install ­y php5 apache2 libapache2­mod­php5 \    php5­apcu php5­curl php5­mongo php5­xsl && rm ­rf /var/lib/apt/lists/*

RUN a2enmod rewrite deflate expires headers

EXPOSE 80

CMD ["/usr/sbin/apache2ctl", "­D", "FOREGROUND"]

prepare your Dockerfile

You can build the container during thedeploy cycle

Just let the `Dockerfile` in the root folder of your project

docker build -t wdalmut/webserver .docker push

Docker containers are engaged with:https://registry.hub.docker.com/

+ automated builds! (keep container up to date automatically)

Already provisioned containers

You can use itfor your development

docker pull wdalmut/webserver

docker run   -p 8080:80   -v ̀pwd̀:/var/www/html   -d wdalmut/webserver

Use Vagrant docker provisioner for your dev environments

Same environment in ElasticBeanstalkDockerrun.aws.json

{  "AWSEBDockerrunVersion": "1",  "Image": {    "Name": "wdalmut/webserver",    "Update": "true"  },  "Ports": [    {      "ContainerPort": "80"    }  ],  "Volumes": [    {      "HostDirectory": "/var/app/current",      "ContainerDirectory": "/var/www/html"    }  ],  "Logging": "/var/log/app"}

Beanstalk proxieswith nginx

your first exposed port80 -> EXPOSE *****[, ******]

Ok, we have the infrastructure

And about the application setup?

App tuning with environment variables

<?php $env = getenv("SYMFONY__ENV");

download config files from S3Resources:    AWSEBAutoScalingGroup:        Type: "AWS::AutoScaling::AutoScalingGroup"        Metadata:            AWS::CloudFormation::Authentication:                S3AccessCred:                    type: "S3"                    roleName: "aws­elasticbeanstalk­ec2­role"                    buckets: "myapp­deploy"

files:    "/root/parameters.yml":        mode: "000400"        owner: root        group: root        source: https://s3­eu­west­1.amazonaws.com/myapp­deploy/parameters.yml

container_commands:     01_copy_configuration:         command: cp /root/parameters.yml app/config/parameters.yml

remember that EC2 IAM roles should be configured correctly

EC2 Role configuration{    "Version": "2012­10­17",    "Statement": [        {            "Sid": "Stmt1305192283000",            "Effect": "Allow",            "Action": [                "s3:*"            ],            "Resource": [                "arn:aws:s3:::app­deploy/",                "arn:aws:s3:::app­deploy/*"            ]        }    ]}

Could be more detailed and restricted than this example

You cannot use PHP from the host (it is in the docker container)...

You have to pass commands via docker containers

docker run   --rm -i -t   -v /var/app/current:/var/www/html   wdalmut/webserver   app/console ca:cl -e=prod

Thanks for listening