Skip to content

Instantly share code, notes, and snippets.

@s-lyn
Last active December 22, 2021 09:51
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save s-lyn/81767ed6c67138eaba681d7739a9db61 to your computer and use it in GitHub Desktop.
Save s-lyn/81767ed6c67138eaba681d7739a9db61 to your computer and use it in GitHub Desktop.
Deploy react app with gitlab.com and RSYNC

Deploy react app with gitlab.com and RSYNC

This is tutorial is about simple client-server file updating. This is not blue-green deploy!

Protocol: RSYNC through SSH. Tested on target server: Ubuntu 16.04 x64. (suitable for Ubuntu 14.x).

Configure target server

1. Create new sudo-user

Login with SSH user "root " and run:

adduser ubuntu
usermod -aG sudo ubuntu
su ubuntu

2. Add SSH keys for current server

Now we should add SSH keys to access current server without password.

Generate new keys:

Run next command again, but set file path to /home/ubuntu/access:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

This command will generate private (/home/ubuntu/access) and public (/home/ubuntu/access.pub) key. Move new generated key to authorized_keys:

cat /home/ubuntu/access.pub >> ~/.ssh/authorized_keys

You must copy and save private key on your computer. To print this key on screen use:

cat ~/access

Or add your existing SSH key:

Add your key for access (replace ...HER_YOUR_PUBLIC_KEY... with your public key):

echo 'ssh-rsa ...HER_YOUR_PUBLIC_KEY...' >> ~/.ssh/authorized_keys

3. Create .htpasswd file

USERNAME=admin
PASSWORD=admin
sudo printf "$USERNAME:$(openssl passwd -crypt $PASSWORD)\n" >> ~/.htpasswd

4. Install nginx

sudo apt-get install nginx -y
sudo rm /etc/nginx/sites-enabled/default

Open nginx config:

sudo nano /etc/nginx/sites-available/app

and replace it with:

server {
  listen 80;
  server_name app;
  root /home/ubuntu/app;
  location / {
    auth_basic           "closed site";
    auth_basic_user_file /home/ubuntu/.htpasswd;
    try_files $uri /index.html;
  }
}

Then run:

sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
sudo systemctl restart nginx
# Note: for Ubuntu 14.x run instead: sudo service nginx restart

5. Test server

mkdir ~/app
echo 'test' > ~/app/index.html

Open http://your.ip.adress/, you should see test string.

Configure deployment with Gitlab CI

6. Add secret variables in gitlab:

Go to gitlab.com -> Your project -> "Settings" -> "CI/CD" -> "Secret variables". Add some variables:

Variable Description
TARGET_SERVER_USER_HOST Target server host like ubuntu@127.0.0.1 or ubuntu@your.host.com
TARGET_SERVER_SECRET_KEY_BASE64 Base64 encoded private RSA key to login target server. Make it protected
TARGET_SERVER_PATH Targer server path, like '~/app'

7. Create file .gitlab-ci.yml in root directory of project:

stages:
  - build
  - deploy

build_react:
  image: node:alpine
  stage: build

  script:
    - echo "====== Install dependencied ======"
    - npm i
    - echo "====== Build react APP ======"
    - npm run build

  artifacts:
    name: panel-build
    paths:
      - build

deploy_react:
  image: alpine
  stage: deploy
  script:
    - echo "====== Deploy to production server ======"
    - apk update && apk upgrade
    - apk add openssh bash rsync
    - echo "====== Add target servers secret key ======"
    - mkdir ~/.ssh
    - echo $TARGET_SERVER_SECRET_KEY_BASE64 | base64 -d > ~/.ssh/id_rsa
    - chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
    - echo "====== Test ssh connection ======"
    - ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T "$TARGET_SERVER_USER_HOST"
    - echo "====== Install rsync on remote server ======"
    - ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null  "$TARGET_SERVER_USER_HOST" 'sudo apt-get install rsync -y'
    - echo "====== Sync local and remote directory ======"
    # Ending "/" in string "./build/" is important!
    - rsync -azPq -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --delete ./build/ "$TARGET_SERVER_USER_HOST:$TARGET_SERVER_PATH"
  only:
  - master

If all is okay, your project will be automatically deployed every push and merge to master branch.

@eikeland
Copy link

Hi, thanks for your awesome and detailed setup. Much appreciated.
But the shell sh don't support long variables and cuts the base64 encoded key in half,
So change shell to bash after you have installed it:

    - apk add openssh bash rsync
    - bash
    - echo "====== Add target servers secret key ======"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment