728x90 AdSpace

Wednesday, December 18, 2019

Deploy Symfony 5 on AWS Elastic Beanstalk with CI/CD, The right way of deploying Apps!

I always thought that deploying an app on the server is quite easy! I mean sure you will have some errors, you may spend few hours trying to make things work on the server, you may even do different steps from setting up the server, setting up the database, make code changes, etc and as much as I always enjoyed doing that, we have to admit that this is only valid for small projects.

Companies or even small startups are always making changes and adding new features, so it's not smart to waste time each time they want to deploy something new. You may have heard about CI before, maybe CI/CD, so let's see today how we can make things more professional.

In this blog I will deploy a Symfony 5 project, same steps should be valid for any other framework, we just have to create our docker container file and make some changes like port mapping...

In a more professional context, we should have 2 environments to deploy our app, an environment for production which have the stable version of the code (it's mostly the master branch) and an other environment called staging we use it to try the different features (different branches before merging them with the master branch).

Here is the link to the GitHub repository:  https://github.com/HosniMansour/Deploy-Symfony5-ECR-Elasticbeanstalk-CI.git.

I will create a new empty Symfony project, so if you already have a project add the following files to your exciting project (create a new project if you don't have a project), if you are using a different framework just make changes in your Dockerfile.

Let's start by adding the following folders and files:


.composer.sh is just a simple script to install composer 

.env.prod and .env.stg have the environment variables configuration for the Symfony project, inside .env.prod we will find the DATABASE_URL for the production environment and inside .env.stg will find the DATABASE_URL for the staging environment.

.deploy folder have the configuration for the production and staging environment, in each folder we will find the Dockerfile to build our image and Dockerrun.aws.json the configuration for Elastic Beanstalk.

The only difference between Dockerfile.prod and Dockerfile.stg is this:

COPY {./.env.prod | ./.env.stg} ./.env

We will get the right .env file inside our container and the rest is just installing and setting PHP, apache2 , composer...

We can build our container in local using the following command: 

docker build -t tmp:stg -f ./.deploy/stage/Dockerfile.stg .
docker run -p 80:80 tmp:stg

And for Prod:

docker build -t tmp:prod -f ./.deploy/prod/Dockerfile.prod .
docker run -p 80:80 tmp:prod

Let's go to Buddy.works, create a new project and add our GitGub repository:



We will create 2 pipelines one for production and the other one for staging. I won't go through all the steps but the idea is to build our docker image, push it inside AWS ECR and finally pull the image with Elastic Beanstalk: 

1/ Build & Push Docker Image to a registry



The difference between the production pipline and the staging pipline is that in the staging will load the Dockerfile: .deploy/stage/Dockerfile.stg as for the production pipline we will load .deploy/prod/Dockerfile.prod

For Tags the production pipline should have the word latest as tag and the staging pipline should the word dev

You must also give buddy.works access to register the docker image with AWS ECR, create a new IAM user and give it access to AmazonEC2ContainerRegistryFullAccess, then add it to buddy.works

We can also register the docker image with docker hub....

But if you used AWS ECR, you should see this in AWS ECR after running the pipline:



2/ Pull the image with Elastic Beanstalk:

If our docker image is registered, we can move to this step, we need to create an Elastic Beanstalk new app that has 2 environments (staging and production) the platform should be Multi-container Docker:



Now let's edit Dockerrun.aws.json and put the image link over there from AWS ECR:

{
  "AWSEBDockerrunVersion": 2,
  "volumes": [],
  "containerDefinitions": [
    {
      "name": "app",
      "image": "123456789.dkr.ecr.eu-central-1.amazonaws.com/hosni/symfony4:{latest|dev}",
      "environment": [],
      "essential": true,
      "memory": 256,
      "mountPoints": [],
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80
        }
      ]
    }
  ]
}

The production environment will have the tag "latest" and the staging environment will have the tag "dev"


Again buddy.works should have access to AWSElasticBeanstalkFullAccess.

There are a lot of extra steps I didn't mention in the middle like creating Elastic Beanstalk environments, create key pair, connect buddy.works to AWS... but that's not the point of this post, writing every thing in details will take time but basically that's it! 

From now on, if we want to deploy a new version, we will just click a button! we can also trigger the pipline to run when we push our code to GitHub... 

0 comments:

Post a Comment

Item Reviewed: Deploy Symfony 5 on AWS Elastic Beanstalk with CI/CD, The right way of deploying Apps! Rating: 5 Reviewed By: Hosni
Scroll to Top