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:
The production environment will have the tag "latest" and the staging environment will have the tag "dev"
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:
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...
Hi , Did you use something to classify files( based on some rules already configured ) with syfmony without using elasticsearch
ReplyDeletefor the rules i want to do something like "if file contain java then place it in folder java" i think i will use expression langage
Do you have any suggestions ?
Today there are millions of websites on the internet. Also daily a number of websites are entering to the World Wide Web. All websites differ with each other in many ways, but despite of all things one thing is common in them, and that is they all use windows hosting. Windows hosting is one of the most important considerations in the process of hosting a website. https://onohosting.com/
ReplyDeleteWow! Such an amazing and helpful post this is. I really really love it. It's so good and so awesome. I am just amazed. I hope that you continue to do your work like this in the future also Mason Jacob
ReplyDeleteThis is such a great resource that you are providing and you give it away for free. I love seeing blog that understand the value of providing a quality resource for free. https://repelis24.website
ReplyDeleteThat appears to be excellent however i am still not too sure that I like it. At any rate will look far more into it and decide personally! https://9xflix.today
ReplyDelete