Automate Build & Deploy for React production build with gitlab-ci to Linux base server (AWS)
Photo by Pankaj Patel on Unsplash
Right now, as everyone wants to automate everything, this post will show you how you can automate the react build and deployment. I am using create-react-app
getting started with react and assuming you have a similar setup.
Setup .gitlab-yml
file for Gitlab Auto deploy
Deploy React Build with gitlab-ci
image: node:10
cache:
paths:
— node_modules/
This line defines the node version that should be used by the docker instance of shared gitlab-runner and the path defines to cache the node_modules
dir.
before_script:
- apt-get update -qq && apt install -y openssh-client openssh-server
- mkdir -p ~/.ssh- echo -e "$SSH_PRIVATE_KEY" > ~/deploy.pem
- chmod 400 ~/deploy.pem
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
The code in before_script
runs before the actual execution. This is to install and setup pre-requisites for deployment like openssh. Also, as I am using AWS EC2 instance to host the project, I have a .pem file to logging in to server via ssh, which is stored in gitlab variables as SSH_PRIVATE_KEY
and accessed by $SSH_PRIVATE_KEY
in yaml file. So, I’m adding the public-key to a file and updating permission of the file as per AWS guidelines.
deploy_production:
only:
refs:
- master
stage: deploy
environment:
name: production
script:
- npm install
- REACT_APP_SERVER=production CI=true npm run build
- scp -i ~/deploy.pem -r build/* $USER_NAME@$SERVER_IP:/var/www/html/provider
deploy_production
& deploy_staging
blocks are almost similar except deploy_production
have all the setup for production build and master branch of react whereas deploy_staging
have setup for staging build and staging branch. You can define any other branch you want in refs
Here's the whole .gitlab-ci.yml file:
image: node:10
cache:
paths:
- node_modules/
before_script:
- apt-get update -qq && apt install -y openssh-client openssh-server
- mkdir -p ~/.ssh
- echo -e "$SSH_PRIVATE_KEY" > ~/deploy.pem
- chmod 400 ~/deploy.pem
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
deploy_production:
only:
refs:
- master
stage: deploy
environment:
name: production
script:
- npm install
- REACT_APP_SERVER=production CI=true npm run build
- scp -i ~/deploy.pem -r build/* $USER_NAME@$SERVER_IP:/var/www/html/provider
deploy_staging:
only:
refs:
- staging
stage: deploy
environment:
name: staging
script:
- npm install
- REACT_APP_SERVER=staging CI=false npm run build
- scp -i ~/deploy.pem -r build/* $USER_NAME@$SERVER_IP:/var/www/html/staging-provider
Gitlab ci/cd has 3 stages: test, build & deploy, I have merged the build and deploy part in the deploy stage, but you can implement it separately.
The script block runs the essential script to make the project live. Here, for production, I set the environment variable CI
to true
that’ll consider any warning pops-up while building as error, so make sure there is no warning (or error of course) else you can set that to false as I did for staging.
At last, you need to define the dir path where you want to upload/copy the build
We are using scp command to sync the build folder to our server. Basically, it uploads the build folder to our server.
You can easily set up the variables mentioned in code (i.e. SSH_PRIVATE_KEY, USER_NAME, SERVER_IP) from your project’s CI/CD settings. Visit this link for reference.
Note: While setting up environment variables, if you want to use it for protected branches only (i.e master/production) remember to select that option.
After setting up the variables, just push or merge to the branch you’ve specified in yaml file and check the CI/CD Pipeline. It will assign the job to the shared gitlab-runner (Also, you can set up your own gitlab-runner on your server and you can use your own docker image too) and execute these commands.
Another thing is, if you're using Github Actions, the yaml file will mostly remain the same, you just need to update its location from root of your project to .github directory.
So, that's it, your react app is deployed to aws ec2 server. Reach out to me in case you catch any issue while setting up.
PS: This kind of setup can be achieved for a basic node and express.js app too, you just need to update some commands to run it. I'm planning to publish one more blog regarding this using docker.