Continuous Deployment, The Easy Way
Tags: github, devops, tutorial, webdev
Published: 2020-08-23 08:01:12

Github Actions let you automate all your boring stuff. In this blog, You'll see How you can automate deployment on any Personal Server, Virtual Private Server(VPS) or Virtual Machine(VM). Every Major Cloud Service Provider provide auto-deployment which is only restricted to web hosting service. 

Most of you want to always want to automate deployment on your Personal Server and VPS/VM but afraid of the hectic process. Here is how you can easily do it. It is not restricted to JavaScript, Python, Ruby. You can automate the deployment of anything from ML Model to Game's new version.


## Let's Start :rocket:

+ We will use SSH for Automation. Make sure you have Port 22 open your Server. 

+ Let's create new SSH Key for Github Actions in server and 
copy it. 
``` bash 
# Save it with a recognizable name eg. github_actions 
# Do give it a strong passphrase
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# Add Key to Authorize Keys. So, We can connect to it. 
cat ~/.ssh/github_actions.pub >> ~/.ssh/authorized_keys

# Copy content of Public Key. 
clip < ~/.ssh/github_actions
```
+ Navigate to Secrets Option in your Github Repository Settings. 

+ Click on 'New Secret' to add new Secrets. 
  + `KEY` - the content of ssh private key. eg. raw content of ~/.ssh/github_actons. Copied in the Previous Step. 
  + `HOST` - ssh host
  + `PORT` - ssh port, default is 22
  + `USERNAME` - ssh username
  + `PASSWORD` - ssh password
  + `PASSPHRASE` - the passphrase is usually to encrypt the private key.

+ Go to the 'Actions' Tab in your repository and click on 'set up a workflow yourself'. 

+ Use & Personalize below given .yml file. 

``` yml
# Give the workflow a name. 
name: Continuous Deployment

# Trigger Workflow on master/production branch. 

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "deploy"
  deploy:
    name: Deploy
    # make sure to run this action in Linux env (say ubuntu)
    runs-on: ubuntu-latest
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    - name: executing remote ssh commands using password
      uses: appleboy/ssh-action@master
      # all environment variables needed to connect with Server is placed in with. 
      with:
        host: ${{ secrets.HOST }}
        key: ${{ secrets.KEY }}
        username: ${{ secrets.USERNAME }}
        password: ${{ secrets.PASSWORD }}
        port: ${{ secrets.PORT }}
        passphrase: ${{ secrets.PASSPHRASE }}
        # Here will go script required for auto-deployment.
        # eg. For Django server using Gunicorn. 
        # Website Server is stored in thewebsite folder
        script: |
        echo "Changing Directory to thewebsite"
        cd thewebsite/
        echo "Pulling From Github"
        git pull -q origin master
        echo "Git Pull Complete"
        echo "Restarting Service"
        sudo systemctl daemon-reload
        sudo systemctl restart gunicorn

```
This above will automatically deploy any change in Django. You can change the script according to the language and framework of your choice. 

You can also use a locally saved script by giving the path of the script instead of writing here.  eg. 
``` yml
script: /home/username/deploy.sh
```

## Conclusion :notebook:

You can automate anything with this workflow with a change in the master/production branch as a trigger.  

This workflow is designed using `appleboy/ssh-action`. You can read more about arguments and documentation [here](https://github.com/appleboy/ssh-action).