How to Set Up GitHub CI/CD on Your Local Ubuntu Server Using a Self-Hosted Runner

How to Set Up GitHub CI/CD on Your Local Ubuntu Server Using a Self-Hosted Runner

Let’s say I want to setup GitHub CI/CD action to my local ubuntu server. How can I do that?


In this blog article, I’ll walk you through setting up GitHub Actions to deploy to your own Ubuntu server without relying on SSH commands. Instead, we'll install and configure a GitHub self-hosted runner, allowing a seamless, automated deployment pipeline.

Let's dive in!

Why Use a Self-Hosted Runner?

Using a self-hosted runner offers several advantages:

  • More Control: You can fully configure the environment according to your needs (e.g., installing custom software, optimizing hardware).
  • Cost Savings: No need to pay for additional cloud runners if you already have your own server.
  • Faster Deployment: Since your runner is local, deployments are quicker, with minimal network latency.
  • Customization: You can run Docker, specialized build tools, or custom scripts that might not work in GitHub's default environments.

Step 1: Create the GitHub Workflow File

Before setting up the runner on your server, we need to prepare the GitHub Actions workflow that will use the self-hosted runner.

Create a file called deploy.yml inside the .github/workflows directory of your repository:

name: cicd-python-app

on:
  push:
    branches: ["main"]
jobs:
  build:
    runs-on: self-hosted

    steps:
      - name: "checkout code"
        uses: actions/checkout@v3

      - name: "deploy to local server"
        run: |
          # Define the project directory
          PROJECT_DIR="your-project-name"

          # Define the runner project directory
          RUNNER_PROJECT_DIR="$HOME/actions-runner/_work/your-repo-name/$PROJECT_DIR"

          # back to home directory
          cd $HOME/

          # Check if the project directory exists. If not, copy the project directory from the runner
          if [ ! -d "$PROJECT_DIR" ]; then         
            cp -rf $RUNNER_PROJECT_DIR $PROJECT_DIR

          else

            # !!!WARNING: Do not run this command if you have .env or secret files NOT stored in GitHub!
            rm -rf "$PROJECT_DIR"(WARNING@!)

            # Overwrite the project directory with the one from the runner
            cp -rf "$RUNNER_PROJECT_DIR" "$PROJECT_DIR"
          fi

          # Move into the project directory
          cd "$PROJECT_DIR"

          # Stop and remove all containers
          docker-compose down

          # Clean up old Docker images, volumes, networks
          docker system prune --all --volumes --force

          # Build and run the new Docker containers
          docker-compose up -d --build
Note:
- Replace "your-project-name" and "your-repo-name" with your actual project and GitHub repository names.
- If you have sensitive files (e.g., .env files) that are not stored in GitHub, make sure to back them up before overwriting directories!

Step 2: Set Up the Self-Hosted Runner on Ubuntu Server

Now let's install the GitHub Actions runner software on your local Ubuntu server.

a. In your local server, create a directory called action-runners and navigate into it:

mkdir actions-runner && cd actions-runner

b. Next, download the latest version of the runner package:

curl -o actions-runner-linux-x64-2.323.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.323.0/actions-runner-linux-x64-2.323.0.tar.gz

c. Then extract the downloaded package with the command:

tar xzf ./actions-runner-linux-x64-2.323.0.tar.gz

Now you have the runner binaries extracted in the actions-runner folder.


Step 3: Configure the Runner with GitHub

Back in your GitHub repository:

a. Go to Settings > Actions > Runners > Click New self-hosted runner:

b. Select Linux as the runner image.

c. Follow the displayed instructions. You’ll see a command listed similar to:

./config.sh --url https://github.com/<your account name>/your repository --token XXXXXXXXXXXXXXXXXXXXXXXXXXX

Run that command inside your server's actions-runner directory to link your runner to GitHub.

d. You’ll be prompted to:

  • Choose the runner group (press Enter for Default).
  • Name your runner (e.g., my-runner).
  • Optionally add labels (you can skip this by pressing Enter).

Once successful, you’ll see a message indicating that your runner has been configured.

13 9

Step 4: Run the Runner

To start the runner manually, use:

./run.sh

If successful, you'll see output shows Connected to GitHub:

But this does not run in the background, If you close the terminal or hit Ctrl+C, the runner will stop.


Step 5: Set Up the Runner as a Background Service

To keep the runner alive even after rebooting or logging out, we should install it as a service.

a. First, stop the manual runner by pressing Ctrl+C. Then, install the runner service:

sudo ./svc.sh install

b. Start the service with the command:

sudo ./svc.sh start

c. You can also check the status of the runner:

sudo ./svc.sh status

Awesome — your runner is now set up to keep running in the background and will restart automatically if your server ever reboots!
Now, every time you push changes to your main branch, your app will be built and deployed straight to your self-hosted server, no extra work needed from you. 🎉

If you found this guide helpful, consider supporting me!

Read more