Fresh out the bat after finally completing your new react project, you must be feeling pumped and ready to unleash your web app for the world to admire huh? That's fine, I guess. It's only the right thing to do.
So you went against what everyone was saying about going serverless or you just really want to get all your projects on your digitalocean droplet or for whatever reason you didn't use any of Github Pages, Netlify, Gitlab Pages, Heroku and the rest. You took the bold step of wanting to manage everything on your server. Stupid! You are going to get introduced to a new world of pain so get ready!
Your requirements:
- Digitalocean droplet with Ubuntu server ~16.4
- Docker - How To Install and Use Docker on Ubuntu: Follow steps 1 and 2 to install Docker on the server
- Gitlab Repository
- Familiarity with SSH
- Connection to server via SSH, if not create one with sshkeygen
- Admin access to gitlab repository
- Your react project already in that repository
Adding gitlab CI to your repo
Gitlab CI looks for a .gitlab-ci.yml
in the repository you want the CI/CD to run. So at the root of your project folder, create a .gitlab-ci.yml
and add the folllowing content to it for react. For other formats, you can look up the references documentation here Gitlab Reference Documentation.
You'll need to create variables, In your gitlab repository, go to Settings > CI/CD > Variables
and then click the expand button by the side, it should look something like the picture below:
Add the following variables
$SSH_PRIVATE_KEY
- The value is your SSH private key generated from your digitalocean server (e.g. content of ~/.ssh/id_rsa)$SSH_USERNAME
- The username of the ssh used to login to your server (e.g. root)$SSH_IP
- The IP address of your server (e.g. 192.292.28.132 or example.com){path-to-project}
- The path to your project on your server
The project on your server must have been initially cloned from your repository / linked via git remote add … and in sync.
For React, the code below should go into your .gitlab-ci.yml
:
image: node:latest stages: - build - deploy cache: paths: - node_modules/ install_dependencies: stage: build script: - npm install artifacts: paths: - node_modules/ before_script: - apt-get update -qq - apt-get install -qq git # Setup SSH deploy keys - 'which ssh-agent || ( apt-get install -qq openssh-client )' - eval $(ssh-agent -s) - ssh-add <(echo "$SSH_PRIVATE_KEY") - mkdir -p ~/.ssh - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' deploy_staging: stage: deploy type: deploy environment: name: staging url: theknowledgeapp.com script: - ssh {$SSH_USERNAME}@{$SSH_IP} "cd /var/www/{path-to-project} && git checkout master && git pull origin master && npm run build && exit" only: - master
Now when you make any commit and push to your repos master
's branch Gitlab would attempt to trigger continuous integration for your project.
You will be taken to the pipeline overview page, where you can see that the CI run is marked as pending and labeled as “stuck”:
If you click the pending status to get more info you would get:
If you click the install_dependencies
job, you would see more specific details of what might be delaying the CI. You would be greeted with a warning notification at the top indicating that the pipeline is stuck because of a lack of runners. Before we create a runner, we need to setup the GItlab runner service on our digitalocean server, so log in to your server to download the latest version of the gitlab runner service with the command:
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh -o /tmp/gl-runner.deb.sh
You can check the similarity of the contents of the script just downloaded to the one here -> Gitlab Runner. The location for the script just downloaded could be found here:
$ less /tmp/gl-runner.deb.shAfterwards, you can go ahead and run the installer with the command:
$ sudo bash /tmp/gl-runner.deb.shAnd then start the runner with this command:
$ sudo apt-get install gitlab-runner
Enable Gitlab Runners
In your gitlab's repository, go to Settings > CI/CD > Runners
and expand, you should see Shared Runners
.
Disable it
for this project by clicking the disable button. At the left-hand side you should see a title that reads Set up a specific Runner manually
.
Copy the token
under it, head back to your digitalocean server and type the following command:
$ sudo gitlab-runner register
You will be asked some configuration questions for the runner such as:
- Please enter the gitlab-ci coordinator URL: Enter your repository host name, in our case,
https://gitlab.com
- Please enter the gitlab-ci token for this runner: The
token
you just copied from the runners page - Please enter the gitlab-ci description for this runner: The name you want to give to this runner
- Please enter the gitlab-ci tags for this runner (comma separated): You can leave this blank
- Please enter the executor: Type in
docker
- Please enter the default Docker image (e.g. ruby:2.1): Type in
alpine:latest
.
To check and see if your intallation went succesfully, run:
$ sudo gitlab-runner listYou should see an output similar to
Listing configured runners ConfigFile=/etc/gitlab-runner/config.toml example-runner Executor=docker Token=e746250e282d197baa83c67eda2c0b URL=https://example.com
Test CI
In your web browser, you can view the running CI in your gitlab repository, by trying to add a new commit or going to CI/CD > Pipeline
and viewing all your pipelines. If it is still running you might see something like,
When the CI has run and is successful, it should show this,
You can click on the first check icon or the install_dependncies
job to view the details of the runner
You would notice there is no longer a notice of no runners being available and your CI/CD has built successfully.
TIP:
In your Virtualhost
file in your site-available, put the site root at `/var/www/{path-to-project}/build because the react production build would be kept in the build folder of the project's directory.
Go to the domain of your site and you should see your new commit take effect. Yayy!!! 🎉