React Project Continuous Deployment with GitLab and AWS
1. Introduction
In this article, I will explain how we can automate the deployment of a React project hosted in Gitlab using Amazon services
1.1 Prerequisites
- NodeJS
- Gitlab account
- AWS account
2. Create a React project
Make sure that you have NodeJS installed on your local machine and you have access to npm. Open your terminal and type npm -version.
To create a new React project type the following command in your terminal:
>npx create-react-app react-app.
Add the following Dockerfile in the root directory of the project.
FROM node:alpine as builder
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY ./ ./
RUN npm run buildFROM nginx
EXPOSE 80
COPY --from=builder /app/build /usr/share/nginx/html
3. Push the Project to Gitlab
- Login or create a new account in Gitlab.
- Create a new repository named react-app.
- Follow the procedure on how to link the remote repository to our local project.
- Commit all the files.
- Push the changes.
4. Create Amazon ECR
- Login to your AWS account.
- Click the Services menu and search “ECR”.
- In the dropdown select Elastic Container Registry.
- On the Amazon ECR page, click Create Repository.
- Enter the repository name “react-app”.
- Click Create Repository.
- Copy the Repository URI. We will use this when we create an ECS task definition.
5. Create Amazon ECS
- Login to your AWS account.
- Click the Services menu and search “ECS”.
- In the dropdown select Elastic Container Service.
- On the left side click Amazon ECS / Task Definitions.
- Click Create new Task Definition.
- Select EC2 and click Next.
- Set the following values:
- In the Task Definition Name enter “DeployContainer”. No Space.
- Task memory (MiB)=128
- Task CPU (unit)=1 vCPU
- Click the Add Container button.
- In the Container name enter “ReactAppContainer”. No Space.
- In the Image, input enter the ECR URI.
- Under Port mappings set
- Host port=80, which will let us access the react application in port 80
- Container port=80, nginx port
- Click Add.
- Click Create.
- On the left side, click Amazon ECS / Clusters.
- Click Create Cluster.
- Select EC2 Linux + Networking.
- Click Next Step.
- Set the following fields
- Cluster name=”ReactCluster”.
- EC2 instance type*=t2.micro (very important)
- Under the Networking section, select a VPC if you already have one, otherwise, let it create for you.
- Select the Subnets if you already have them.
- Select a Security Group that allows public access or in our case expose port 80 to the world.
- Click Create.
- Click View Cluster.
- Under the Services tab, click Create.
- Set the following fields
- Launch type=EC2
- Task Definition=DeployContainer
- Service name=ReactService
- Number of tasks=1
- Minimum healthy percent=0
- Maximum percent=100
- Click Next Step.
- Click Next Step, as we don’t need a load balancer for this demo.
- Click Next Step.
- Click Create Service.
- Click View Service.
6. Create AWS Access Key
- Login to your AWS account.
- Click the Services menu and search for “IAM”, click it.
- On the left side, click Users.
- Click Add user.
- Enter a username and select Programmatic user.
- Click Next:Permissions.
- Click Attach Existing Policies directly.
- Check “AdministratorAccess”. This is for testing purposes only.
- Click Next: Tags.
- Click Next: Review.
- Click Create user
- Download the CSV that contains the Access Key ID and Access Key. We will use it later when setting up the Github action.
7. Adding and Configuring Gitlab Deployment Script
Before we add action, we need to set the AWS secret keys first.
- Open your project in GitLab.
- Click the Settings / CI/DI menu on the left panel.
- Expand the Variables section.
- Add the following variables:
- AWS_DEFAULT_REGION
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
8. Commit, Build, and Deploy
Create a GitLab configuration in our project named: .gitlab-ci.yml with the following content:
image: maven:3.6.3-openjdk-11variables:
MAVEN_OPTS: >-
-Dmaven.repo.local=.m2/repository
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN
-Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true
MAVEN_CLI_OPTS: >-
--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true
-DdeployAtEnd=true
CI_AWS_ECS_CLUSTER: ReactCluster
CI_AWS_ECS_SERVICE: ReactService
CI_AWS_REGISTRY_IMG: 981794644853.dkr.ecr.us-east-2.amazonaws.com/react-appbefore_script:
- >-
echo " ------------------------------- Global > Before Script
------------------------- ------"
- echo $CI_COMMIT_BRANCHstages:
- compile
- build
- deploykaniko-build-docker:
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
stage: build
variables:
REGISTRY: $CI_AWS_REGISTRY_IMG
before_script:
- ls -la
only:
- master
script:
# see https://github.com/GoogleContainerTools/kaniko/issues/1227
- mkdir -p /kaniko/.docker
- echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json
- /kaniko/executor --cache=true --context $CI_PROJECT_DIR --dockerfile ${CI_PROJECT_DIR}/Dockerfile --destination $REGISTRY:$CI_COMMIT_SHORT_SHA --destination $REGISTRY:latestdeploy:
image: python:3.8
stage: deploy
only:
- master
before_script:
- pip install ecs-deploy
needs:
- kaniko-build-docker
script:
- ecs deploy $CI_AWS_ECS_CLUSTER $CI_AWS_ECS_SERVICE -t $CI_COMMIT_SHORT_SHA --timeout 600
- Fire up your Visual Studio Code.
- Open the react-app folder.
- Modify the App.js file and add a Hello Amazon line.
- Commit and push the change.
- Access the URL using the EC2 URL of the container.
9. References
- https://www.czetsuyatech.com/2020/09/continuous-integration-continuous-deployment.html
- https://czetsuya-tech.blogspot.com/2020/08/react-project-continuous-deployment-with-github-and-aws.html.html
- https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
Originally published with video at https://www.czetsuyatech.com/2020/09/react-project-continuous-deployment-with-gitlab-and-aws.html.html.