πŸ”„ Auto-Deploy Your Code to VPS Using GitHub Actions and SSH

πŸš€ In this guide, we’ll automate the deployment of your private GitHub repo to a Linux VPS using GitHub Actions and SSH. No more logging in manually to pull code!

This is Part 2 of our series. If you haven’t yet connected your VPS to GitHub using SSH deploy keys, read Part 1 here.


🧩 What You’ll Set Up

  • βœ… Automatically pull code when you push to the main branch
  • βœ… Restart your app or server after deployment (e.g., nginx)
  • βœ… Keep everything secure using SSH keys and GitHub secrets

πŸ” Step 1: Add the Public Key to Your VPS Deploy User

Switch to the deployer user on your server:

sudo su - deployer
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys

Paste the contents of your id_rsa_github.pub file.

Then set the correct permissions:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
exit  # return to root

πŸ”’ Step 2: Add the Private Key to GitHub Secrets

Back on your local system (or VPS), run:

cat ~/.ssh/id_rsa_github

Copy the entire content (including -----BEGIN OPENSSH PRIVATE KEY----- to the end).

Go to your GitHub repository:

Settings β†’ Secrets and variables β†’ Actions β†’ New repository secret

  • Name: PRODUCTION_SSH_KEY
  • Value: Paste the private key
  • Save

βš™οΈ Step 3: Create the GitHub Action Workflow

In your GitHub repo, create this file:

.github/workflows/deploy.yml

Paste the following content:

name: πŸš€ Deploy myapp static site to Server via SSH

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: βœ… Checkout Code
      uses: actions/checkout@v3

    - name: πŸ”„ Deploy via SSH
      uses: appleboy/ssh-action@master
      with:
        host: 209.38.120.52       # your server IP
        username: deployer
        key: ${{ secrets.PRODUCTION_SSH_KEY }}
        port: 22
        script: |
          cd /var/www/myapp
          git reset --hard
          git pull origin main
          sudo systemctl restart nginx

πŸ” Note: Replace the IP and path as per your setup.


πŸ§ͺ Optional: Test the SSH Connection First

Replace the script block temporarily for testing:

script: |
  echo "Connected to server successfully!"
  whoami
  hostname
  date

Once tested, replace it with your actual deployment script.


βœ… Step 4: Configure Your Server for Safe Automation

Run once under the deployer user:

git config --global --add safe.directory /var/www/myapp

Then, as root, allow passwordless access to restart nginx:

sudo visudo

Add this at the bottom:

deployer ALL=(ALL) NOPASSWD:ALL
deployer ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx, /bin/systemctl reload nginx

This ensures sudo systemctl restart nginx won’t ask for a password.


🧹 Step 5: Set Correct Ownership for Code Directory

Run this on your VPS:

sudo chown -R deployer:deployer /var/www/myapp

πŸš€ Final Step: Push Your Code

Now, just push code to the main branch:

git push origin main

GitHub Actions will:

  • Log into your VPS via SSH
  • Pull the latest code
  • Restart your service (e.g., nginx)

Fully automated and passwordless πŸ’‘


🧩 Coming from Part 1?

This is the second part of our deployment series:

Stay tuned for more advanced deployment workflows (CI/CD, staging environments, rollback strategies, and more)!