Skip to content

Deploy Your Website with GitHub Actions Self-Hosted Runner

4 min read

GitHub Actions

If you run a website on your home server and want to deploy it automatically every time you push code to GitHub, you might think you need to open ports on your router or set up complicated webhook services. But there’s a better way that doesn’t require opening any ports at all: a GitHub Actions self-hosted runner.

I had the same problem. My website runs on a mini PC at home, and I wanted automatic deployments without exposing my home network. The solution was simpler than I expected.

What is a GitHub Actions Self-Hosted Runner?

GitHub Actions is a CI/CD platform that runs automated tasks when you push code to your repository. Normally, these tasks run on GitHub’s own servers in the cloud. But sometimes you want to run them on your own machine, especially if you’re deploying to a home server.

A self-hosted runner is a small program that you install on your own computer. It connects to GitHub and asks “do you have any work for me?” every few seconds. When you push code to your repository, GitHub tells the runner to execute your workflow. The important part is that the runner connects to GitHub, not the other way around. This means you don’t need to open any ports in your router or configure complex firewall rules.

Think of it like checking your email. Your computer reaches out to the email server to see if there are new messages. The email server doesn’t need to know your home address or knock on your door.

Example Setup

Let’s say you have a simple website with an index.html file. You want it to run in a nginx Docker container, and you want it to update automatically when you push changes.

First, create a simple docker-compose.yml file in your project:

version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./public:/usr/share/nginx/html

This will serve your website files from a public folder. Put your index.html and other files there.

Installing the Self-Hosted Runner

Go to your GitHub repository settings and click on “Actions” then “Runners”. Click “New self-hosted runner” and GitHub will show you the exact commands to run. It looks something like this:

# Create a folder for the runner
mkdir actions-runner && cd actions-runner

# Download the runner (check GitHub for the latest version)
curl -o actions-runner-linux-x64-2.321.0.tar.gz -L \
  https://github.com/actions/runner/releases/download/v2.321.0/actions-runner-linux-x64-2.321.0.tar.gz

# Extract it
tar xzf ./actions-runner-linux-x64-2.321.0.tar.gz

# Configure with your repository (GitHub will give you a token)
./config.sh --url https://github.com/yourusername/yourrepo --token YOUR_TOKEN

After configuration, install it as a service so it runs automatically:

sudo ./svc.sh install
sudo ./svc.sh start

Creating the GitHub Actions Workflow

Now create a file in your repository at .github/workflows/deploy.yml:

name: Deploy Website

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: self-hosted
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Deploy to server
        run: |
          rm -rf /opt/website/public/*
          cp -r * /opt/website/public/
          cd /opt/website && docker compose restart web

The key line is runs-on: self-hosted. This tells GitHub to use your runner instead of their cloud servers. The workflow checks out your code and copies it to your nginx folder, then restarts the container.

Testing It

Make a change to your index.html, commit it and push to main:

git add index.html
git commit -m "Update homepage"
git push

Go to the “Actions” tab in your GitHub repository and you’ll see your workflow running. A few seconds later, your website will be updated.

Summary

A self-hosted runner gives you the convenience of automatic deployments without the security concerns of opening ports. It’s perfect for home servers, development machines, or any situation where you want to deploy code to a private network. The runner connects to GitHub, does the work, and reports back. Simple and effective.

← Back to blog