Deploy Your Website with GitHub Actions Self-Hosted Runner

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.