Slide 1

Slide 1 text

Deploy a Symfony application on AWS Beanstalk with Docker SymfonyCon Lisbon 2018

Slide 2

Slide 2 text

Hello, I'm Romaric. I work at netinfluence @ Lausanne, Switzerland.

Slide 3

Slide 3 text

What's our goal? We want a setup one-man* can manage We want high availability As a bonus, we would like to have auto-scalability *It also means documented, to account for "bus factor".

Slide 4

Slide 4 text

Why Docker? Avoid snowflake servers Documentation as code More robust: easier to rebuild, upgrade, rollback Easier to deploy a new server

Slide 5

Slide 5 text

Why AWS Elastic Beanstalk? We were already using some AWS services. Huge ecosystem Competitive prices 3 different solutions: ECS (advanced) Elastic Beanstalk Fargate (serverless)

Slide 6

Slide 6 text

How does it costs? It is free

Slide 7

Slide 7 text

How does it costs? It is free You pay for used ressources, typically EC2 instances and ELB load balancer ($20/month). Plus other services you may use outside of EB.

Slide 8

Slide 8 text

Getting started

Slide 9

Slide 9 text

Step 1: Prepare your application

Slide 10

Slide 10 text

Move all state (data) out of web servers Use an external file storage for uploaded files S3... Split the database from web servers AWS RDS for MySQL/PostgreSQL, set up your own DB EC2 instance... Store sessions in a shared storage DB (easy!), memcached or Redis (AWS ElastiCache)... Optional: send logs to an external service Sentry...

Slide 11

Slide 11 text

Pro tip: use AWS Route53 namesevers You don't have to register your domain name with AWS, but you should use Route53 as nameserver(s) (set up a hosted zone, a few $/month), so you can use an alias A record instead of copying the load balancer IP. It will also make getting SSL certificates easier, with AWS ACM (free).

Slide 12

Slide 12 text

Use environment variables for configuration Supported in Symfony 2 with Incenteev Parameter handler, Symfony3 (getenv), Symfony4 Also supported in php.ini For other scenarii, use envsubst

Slide 13

Slide 13 text

Step 2: Define architecture

Slide 14

Slide 14 text

Elastic Beanstalk concepts Platform: Docker (not PHP) 2 flavors: "single container" platform or "multicontainer" platform. Application: our project (with history of code versions...), we will have only one. Environment: an "instance" of our application, with some configuration and resources (EC2 instances...). It could be "staging" and "production".

Slide 15

Slide 15 text

Container(s) architecture From AWS EB multi-container documentation

Slide 16

Slide 16 text

Listing containers We need: 1..n container for nginx 1..n for PHP-FPM 1 running Cron jobs 1 for ephemeral tasks (like running DB migrations...) Some can auto-scale, some should not (ie., Cron). Solution: use 2 Beanstalk environments, myapp-web and myapp- worker

Slide 17

Slide 17 text

Step 3: make Docker images

Slide 18

Slide 18 text

Step 4: create the manifest file

Slide 19

Slide 19 text

Manifest file: Dockerrun.aws.json Everything is declared in a Dockerrun.aws.json file, in our project directory. We have 2 different files, one for myapp-web and one for myapp- worker. Full code on Gist here { "volumes": [ { "name": "sf-app", "host": { "sourcePath": "/var/app/current" } } ], "AWSEBDockerrunVersion": 2, "containerDefinitions": [ { "name": "php-web",

Slide 20

Slide 20 text

Step 5: deploying

Slide 21

Slide 21 text

Step 5.1: create the app on Elastic Beanstalk

Slide 22

Slide 22 text

Select multi-container, and sample application

Slide 23

Slide 23 text

Select "high availability", and then you can configure rolling updates

Slide 24

Slide 24 text

Step 5.2: deploy your code

Slide 25

Slide 25 text

Deploying... Install EB CLI. From our application folder, with the application installed* and everything committed to Git**, we can now run eb deploy [-- init]: *So you should composer install and generate assets before **If you are using Git and some files are not committed, by default EB will deploy committed changes only.

Slide 26

Slide 26 text

Done! romaric@netinfluence.ch