How to Deploy to Remote Server Using SSH and GitHub Actions?

One way to deploy changes to your web server via GitHub actions is to follow these steps:

  1. Create SSH Public/Private Keys;
  2. Clone the Repository on Server;
  3. Allow Passwordless Access to GitHub Actions;
  4. Add Private Key to Repository Secrets;
  5. Add GitHub Workflow for Deployment.

#Creating SSH Public/Private Keys

On your server, generate public/private SSH keys by using the following command:

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

This will generate a public/private key combination using the RSA algorithm. However, you're free to choose any other algorithm for the keys.

It's important to note that this command generates keys in the ~/.ssh/ directory by default. However, you can choose to provide a custom filename and location for the keys if desired.

#Cloning the Repository on Server

To be able to clone your repository on your server, for example, using an SSH URL (such as git@github.com:username/repo.git) you must add the public SSH key (that you generated in the first step) for authentication.

For example, you can use the following cat command to display the public key and copy it manually (including the new line at the end):

cat ~/.ssh/id_rsa.pub

Once you have copied the public key, do the following:

  1. Navigate to "deploy keys" in your GitHub repository settings (Settings > Deploy keys);
  2. Click on the "Add deploy key" button;
  3. Name the new key however you want in the text field labeled "Title";
  4. Paste the public key you copied in the textarea labeled "Key";
  5. Leave the "Allow write access" checkbox unchecked (as the server only requires pull access);
  6. Click the "Add key" button to add the deploy key to your repository with readonly access.

After adding the public key to your repository, you should be able to clone it via SSH on your server. To do so, navigate to the folder on your server where you wish to clone your git repository, and run the following git clone command:

git clone git@github.com:username/repo.git

For example, if your username is "designcise" and repository name is "web", then you would run the following command:

git clone git@github.com:designcise/web.git

#Allowing Passwordless Access to GitHub Actions

Use the following command to add the public key you generated into the authorized keys file (to enable passwordless SSH access for GitHub Actions):

cat ~/.ssh/id_rsa.pub | ssh username@host 'cat >> ~/.ssh/authorized_keys'

Here, replace the "username@host" with your username and server host. For example, if your username is "designcise" and host IP is "123.456.0.789", then you would run the following command:

cat ~/.ssh/id_rsa.pub | ssh designcise@123.456.0.789 'cat >> ~/.ssh/authorized_keys'

After you run this command, you will be prompted to enter the password for the username you entered. Upon entering it correctly, the public key will be stored in the authorized_keys file for the corresponding user on the server. This will allow access to the server using public key authentication from a remote system (such as GitHub).

Remember to set appropriate permissions on the ~/.ssh directory and the ~/.ssh/authorized_keys file (typically, 700 for .ssh and 600 for authorized_keys).

To confirm that the passwordless SSH access has been set up correctly, you can run the following command from your server:

ssh -vT designcise@123.456.0.789

This should create a new SSH session and log you into your server without prompting for password.

#Adding Private Key to Repository Secrets

From the keys you generated in the first step, copy the private key, and add it to repository secrets.

For example, you can use the following cat command on the server to display the private key and copy it manually (including the new line at the end):

cat ~/.ssh/id_rsa

Once you have copied the private key, do the following:

  1. Navigate to "secrets" in your GitHub repository settings (Settings > Secrets and variables > Actions);
  2. Click on the "New repository secret" button;
  3. Name the new key "SSH_DEPLOY_KEY" in the text field labeled "Name";
  4. Paste the private key you copied in the textarea labeled "Secret";
  5. Click the "Add secret" button to add the secret to your repository.

#Adding GitHub Workflow for Deployment

Create the following folder/file structure in your project directory:

.github/
..└── workflows/
....└── deploy.yml

Edit the deploy.yml file, and create your deployment workflow, for example, using the following GitHub Action code:

name: Deployment Workflow
on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Set up SSH key
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_DEPLOY_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
      - name: Deploy to server
        run: |
          echo "Starting deployment..."
          ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no username@host "cd /home/designcise && git pull origin main && <your-other-commands>"
          echo "Deployment completed."

Here, replace username@host with your host username and IP, for example, same as from the step where you added the public key to server authorized keys. In the double quotes at the end you can run any command you wish on your server, concatenating several commands using &&.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.