GitHub Actions deploy to VPS: 2026 Best Step-by-Step

Master GitHub Actions deploy to VPS with our 2026 step-by-step CI/CD guide. Automate server setup. Start now!

Automated software deployment with glowing data streams into a futuristic server rack

If you build websites or apps, you know the pain of moving files by hand every time you change something. A GitHub Actions deploy to VPS workflow fixes this. It moves your code to your server the moment you push it. This guide shows you how to set it up step by step. It is written for beginners, so no big words or hard steps. By the end, you will have a working pipeline that saves you hours every week.

What You’ll Build: GitHub Actions Deploy to VPS Overview

Before we start, let’s see what we are building. A GitHub Actions deploy to VPS setup is a set of rules that tells GitHub to send your code to your server. It runs on every push, or on every merge to the main branch. You write the rules once, and they work forever.

Why Automate VPS Deployment with GitHub Actions

Manual deploys are slow and risky. You might forget a file, or break something on the server. A GitHub Actions deploy to VPS flow does three big things for you:

  • It saves time. You push code, and the server updates on its own.
  • It cuts mistakes. The same steps run every time, with no human error.
  • It keeps a log. You can see what was deployed, when, and by whom.

For small teams or solo devs, this is a huge win. You spend less time on ops and more time on building.

Deployment Architecture Overview

The setup has three parts. First, your code lives on GitHub. Second, GitHub Actions runs a workflow file when you push. Third, the workflow uses SSH to copy files to your VPS and restart your app. Think of it like a mail robot that takes your new code from GitHub to your server.

Prerequisites for GitHub Actions Deploy to VPS

Before you start, make sure you have a few things ready. This part is short, but do not skip it. Missing one item will block you later.

Required Tools and Accounts

  • A GitHub account (free plan works fine).
  • A VPS from any provider (DigitalOcean, Hetzner, Linode, AWS Lightsail, etc.).
  • A basic terminal on your computer (Terminal on Mac, PowerShell or CMD on Windows).
  • A project with a Git repo already on GitHub.

VPS Server Setup Requirements

Your VPS should run a Linux system like Ubuntu 22.04 or 24.04. It needs SSH access turned on. You should be able to log in as root or a sudo user. Make sure port 22 (or a custom SSH port) is open in your firewall.

GitHub Repository Preparation

Your repo should have a working app. It can be Node.js, PHP, Python, or even plain HTML. The workflow we build will copy files from the repo to a folder on your VPS. That folder is where your app runs from.

Step 1: Generate SSH Keys for GitHub Actions Deploy to VPS

SSH keys are like a special key and lock. The key stays with GitHub, and the lock sits on your VPS. When GitHub wants to send files, it shows the key, and the VPS opens the door.

Create an ED25519 SSH Key Pair

Open your terminal and run this command:

ssh-keygen -t ed25519 -C “github-actions-deploy” -f ~/.ssh/github_actions_deploy

Press Enter when it asks for a passphrase. Leave it empty. This makes a pair of files: a private key (github_actions_deploy) and a public key (github_actions_deploy.pub). The private key is secret. The public key goes on your VPS.

Add the Public Key to Your VPS

Copy the public key to your VPS with this command:

ssh-copy-id -i ~/.ssh/github_actions_deploy.pub your_user@your_vps_ip

Type your VPS password once. After that, you can log in without a password. Test it by running ssh your_user@your_vps_ip. It should log you in right away.

Create a Dedicated Deploy User (Recommended)

For safety, make a new user on the VPS just for deploys. Run these on your VPS:

  • sudo adduser deployer
  • sudo usermod -aG sudo deployer
  • sudo mkdir /home/deployer/.ssh
  • sudo cp ~/.ssh/authorized_keys /home/deployer/.ssh/
  • sudo chown -R deployer:deployer /home/deployer/.ssh

Now GitHub Actions will log in as deployer, not root. This is much safer.

Step 2: Configure GitHub Secrets for VPS Deployment

Secrets are safe boxes inside your GitHub repo. Only the workflow can open them. You will put your SSH key and server info in these boxes.

Store the SSH Private Key in GitHub Secrets

Open your terminal and print the private key:

cat ~/.ssh/github_actions_deploy

Copy all the output. Then go to your GitHub repo, click Settings, then Secrets and variables, then Actions. Click New repository secret. Name it SSH_PRIVATE_KEY. Paste the key as the value. Click Add secret.

Add Server Host, Port, and Username Variables

Add three more secrets in the same place:

  • VPS_HOST: your server IP or domain (e.g., 123.45.67.89)
  • VPS_PORT: SSH port, usually 22
  • VPS_USER: the deploy user name (e.g., deployer)

Set Up Environment-Specific Secrets (Staging vs Production)

If you have a staging server and a production server, use GitHub Environments. Go to Settings, then Environments. Create two: staging and production. Add secrets to each one. In your workflow, you can pick which environment to use. This keeps your staging and production deploys apart.

Step 3: Write the GitHub Actions Workflow to Deploy to VPS

Now we write the rules file. This file tells GitHub what to do when you push code.

Create the deploy.yml Workflow File

In your repo, make a folder called .github/workflows. Inside it, make a file called deploy.yml. Paste this starter code:

name: Deploy to VPS

on:

push:

branches: [main]

jobs:

deploy:

runs-on: ubuntu-latest

steps:

– uses: actions/checkout@v4

Configure SSH Connection and File Transfer

Add a step to set up SSH and copy files. Use the popular appleboy/ssh-action or burnett01/rsync-deployments action. Here is a simple version with rsync:

– name: Deploy via rsync

uses: burnett01/rsync-deployments@7.0.0

with:

switches: -avzr –delete

path: ./

remote_path: /var/www/myapp/

remote_host: ${{ secrets.VPS_HOST }}

remote_user: ${{ secrets.VPS_USER }}

remote_port: ${{ secrets.VPS_PORT }}

remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

This step copies all files from your repo to /var/www/myapp/ on the VPS. The –delete flag removes old files that are no longer in the repo.

Add Post-Deployment Commands (Restart Services, Run Migrations)

After files are copied, you may need to restart your app or run database migrations. Add another step that uses appleboy/ssh-action:

– name: Run post-deploy commands

uses: appleboy/ssh-action@v1.0.3

with:

host: ${{ secrets.VPS_HOST }}

username: ${{ secrets.VPS_USER }}

key: ${{ secrets.SSH_PRIVATE_KEY }}

port: ${{ secrets.VPS_PORT }}

script: |

cd /var/www/myapp

npm install –production

pm2 restart myapp

Complete Workflow Example for Node.js Apps

Here is the full deploy.yml for a Node.js app using a GitHub Actions deploy to VPS flow:

name: Deploy to VPS

on:

push:

branches: [main]

jobs:

deploy:

runs-on: ubuntu-latest

steps:

– uses: actions/checkout@v4

– name: Deploy via rsync

uses: burnett01/rsync-deployments@7.0.0

with:

switches: -avzr –delete

path: ./

remote_path: /var/www/myapp/

remote_host: ${{ secrets.VPS_HOST }}

remote_user: ${{ secrets.VPS_USER }}

remote_port: ${{ secrets.VPS_PORT }}

remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

– name: Restart app

uses: appleboy/ssh-action@v1.0.3

with:

host: ${{ secrets.VPS_HOST }}

username: ${{ secrets.VPS_USER }}

key: ${{ secrets.SSH_PRIVATE_KEY }}

port: ${{ secrets.VPS_PORT }}

script: cd /var/www/myapp && npm install –production && pm2 restart myapp

GitHub Actions Deploy to VPS: Stack-Specific Variations

Different apps need slightly different steps. Here are quick tweaks for three common stacks.

Deploy a Docker Application to VPS

For Docker apps, you do not copy files. Instead, you build an image, push it to a registry, then pull it on the VPS. The post-deploy step runs docker compose pull and docker compose up -d. Make sure Docker and Docker Compose are installed on your VPS.

Deploy a Static Site to VPS

Static sites are the easiest. Just use rsync to copy the build folder to your web root, like /var/www/html. No restart is needed. Nginx or Apache will serve the new files right away.

Deploy a Laravel/PHP Application to VPS

For Laravel, copy the files, then run these commands on the VPS:

  • composer install –no-dev
  • php artisan migrate –force
  • php artisan config:cache
  • php artisan route:cache
  • chmod -R 775 storage bootstrap/cache

Put these in the post-deploy SSH step of your GitHub Actions deploy to VPS workflow.

Secure Your GitHub Actions Deploy to VPS Setup

Security matters. A weak setup can let bad actors into your server. Follow these three rules.

Implement Least-Privilege SSH Access

The deploy user should only be able to do what it needs. Do not give it full root. Lock its SSH key to only run certain commands by editing the authorized_keys file on the VPS. Add a command=”…” prefix to the key line.

Rotate SSH Keys Regularly

Every 90 days, make a new key pair. Add the new public key to the VPS, update the GitHub secret, then delete the old key. This limits the damage if a key is leaked.

Enable GitHub Secret Scanning and Alerts

Go to your repo Settings, then Code security and analysis. Turn on Secret scanning and Push protection. GitHub will block any push that has a secret in it. This stops you from leaking your SSH key by accident.

Troubleshooting GitHub Actions Deploy to VPS Failures

Things will break. That is normal. Here is how to fix the most common issues.

Fix SSH Connection and Permission Denied Errors

If you see “Permission denied (publickey)”, check these:

  • The private key in GitHub Secrets has no extra spaces or missing lines.
  • The public key is in /home/deployer/.ssh/authorized_keys on the VPS.
  • The .ssh folder is mode 700 and authorized_keys is mode 600.
  • The deploy user owns the .ssh folder.

Resolve Workflow Timeout and Build Failures

If the workflow times out, your VPS might be slow or the file set is too big. Add a timeout-minutes: 10 line to the job. If npm install fails on the VPS, check that Node.js is installed and in the PATH for the deploy user.

Debug Deployment Script Issues on the VPS

SSH into your VPS by hand and run the same commands the workflow runs. This shows you the real error. Add set -x at the top of your script block to print each command before it runs.

Advanced: Rollback, Monitoring, and Notifications for VPS Deployments

Once your GitHub Actions deploy to VPS flow works, you can add smart features on top.

Set Up Automatic Rollback on Failure

Keep a backup folder on the VPS. Before rsync runs, copy the current app to /var/www/myapp-backup. If the deploy step fails, add a rollback step that copies the backup back. This gets your site up in seconds.

Add Health Checks After Deployment

After the deploy, add a step that curls your site URL. If it does not return 200, fail the job. This catches broken deploys before users see them.

Send Slack or Discord Notifications on Deploy Status

Use the slackapi/slack-github-action or a Discord webhook step. Send a message on success or failure. Your team will know right away when a deploy happens.

FAQ: GitHub Actions Deploy to VPS

How Do I Deploy to Multiple VPS Servers with GitHub Actions?

Use a matrix strategy in your workflow. List each server as a matrix entry. GitHub will run the deploy job for each one in parallel. Give each server its own set of secrets, or use GitHub Environments.

Can I Use GitHub Actions to Deploy to a VPS Without SSH Keys?

Yes, but it is not advised. You can use a username and password with the appleboy/ssh-action. But passwords are weaker than keys. Always use SSH keys for a GitHub Actions deploy to VPS setup.

How Do I Handle Database Migrations When Deploying to VPS?

Put migration commands in the post-deploy SSH step. For Laravel, use php artisan migrate –force. For Node.js with Prisma, use npx prisma migrate deploy. Always back up your database before running migrations in production.

What Is the Best Deployment Strategy for a VPS?

For most small apps, a simple rsync plus service restart is enough. For bigger apps, use a blue-green setup with two folders and a symlink. Point the symlink to the new folder after the deploy. This gives you zero-downtime deploys.

Conclusion: Start Automating Your VPS Deployments with GitHub Actions Today

You now have everything you need to build a GitHub Actions deploy to VPS workflow. You learned how to make SSH keys, set up GitHub secrets, write the deploy.yml file, and handle different app stacks. You also know how to keep the setup safe and fix common errors.

Start small. Deploy a test project first. Once it works, move your real apps over. You will save time, cut mistakes, and sleep better at night. The next step is to add rollback, health checks, and notifications. Happy deploying!