Skip to content

Instantly share code, notes, and snippets.

@jonjozwiak
Created September 13, 2024 20:46
Show Gist options
  • Save jonjozwiak/eb12123d1fdbc85a18ac5085b0e0cabd to your computer and use it in GitHub Desktop.
Save jonjozwiak/eb12123d1fdbc85a18ac5085b0e0cabd to your computer and use it in GitHub Desktop.
RHEL 8 Actions Runner with Podman

RHEL 8 Actions Runner with Podman

With the move to RHEL 8 Red Hat has removed Docker in place of Podman. Docker have changed docker-ce to experimental on RHEL. These steps enable using Podman tools with Actions since Actions cannot speak with Podman natively.

Podman comes with a couple issues when it comes to Actions that we need to workaround:

  • Actions relies on the docker socket
  • Podman does not create missing directories on container create. Docker does...

Below are the steps to setup Podman on RHEL 8 with an Actions runner. This assumes you already have a base RHEL 8 OS installed and connected to subsciption manager so you have access to repositories. Note this is not meant to be a definitive guide to all ways you can create a runner. This guide is using an organization-level runner and manually setting it up.

Steps to Setup

Initial Podman Install:

# Run these as root
sudo su - 
yum -y update
yum -y module install container-tools

# Install Podman-docker - This provides an alias for docker commands and socket so Podman can be compatible
yum -y install podman-docker
systemctl enable --now podman.socket

# Validate access to podman (only as root)
curl --unix-socket /run/podman/podman.sock -H 'content-type: application/json' http://localhost/_ping

# Quiet the podman emulation comments
touch /etc/containers/nodocker

# Add some software you'll probably want on your runner (optional)
yum -y install git jq hostname procps findutils which openssl

Verify Podman is functional by launching a container. Exit once verified:

docker run -it fedora bash
ls
exit

Create an organization-level runner. I created this in my demo org: jonjozwiak-demo-org

  • Go to your organization: https://github.com/jonjozwiak-demo-org
  • Click on the Settings Tab
  • Under Actions click on Runner groups
    • Create a new runner group. I called mine jozwiak-org-rhel-runners
  • Under Actions click on Runners
  • Click to add a new runner and select Self-Hosted runner
    • Click Linux and it will give you instructions to install including the registration token

On your runner, setup the runner app:

# Setup a directory owned by your runner user.  In my case I'm using cloud-user for my cloud VM image
sudo mkdir actions-runner
sudo chown cloud-user:cloud-user /actions-runner

# Download the latest runner package (this was 2.319.1 at time of writing) and extract
cd /actions-runner
curl -o actions-runner-linux-x64-2.319.1.tar.gz -L https://github.com/actions/runner/releases/download/v2.319.1/actions-runner-linux-x64-2.319.1.tar.gz
tar xzf ./actions-runner-linux-x64-2.319.1.tar.gz

# Install Dependencies
sudo ./bin/installdependencies.sh

# Create the runner and start the configuration experience (yes, you could put this all on command line)
# Update for your org and registration token
./config.sh --url https://github.com/jonjozwiak-demo-org --token ABCA........X5A
   # Enter your runner group: jozwiak-org-rhel-runners
   # Name of this runner: rhel8-runner
   # Accept default labels (self-hosted, Linux, X64)
   # Accept default work folder (_work)

Create a hook to execute prior to a job running. This is needed because Podman won't pre-create directories for volume mounts like Docker does.

mkdir /actions-runner/hooks

Create a file called /actions-runner/hooks/podman-hooks.sh as follows. Note to update RUNNER_DIR if you have this different in your environment:

#!/bin/bash

# Set runner install directory
RUNNER_DIR="/actions-runner"

# List of directories to check/create
directories=(
    "$RUNNER_DIR/_work"
    "$RUNNER_DIR/externals"
    "$RUNNER_DIR/_work/_temp"
    "$RUNNER_DIR/_work/_actions"
    "$RUNNER_DIR/_work/_tool"
    "$RUNNER_DIR/_work/_github_home"
    "$RUNNER_DIR/_work/_github_workflow"
)

# Loop through the list and create directories if they don't exist
for dir in "${directories[@]}"; do
    if [ ! -d "$dir" ]; then
        mkdir -p "$dir"
        echo "Created directory: $dir"
    else
        echo "Directory already exists: $dir"
    fi
done

Make certain the hook script is executable:

chmod 755 /actions-runner/hooks/podman-hooks.sh

Now update /actions-runner/.env to call the hook script when the job is started:

LANG=en_US.UTF-8
# Added pre-script
ACTIONS_RUNNER_HOOK_JOB_STARTED=/actions-runner/hooks/podman-hooks.sh

SELinux Interlude. I'm setting it to permissive because I haven't spent the time figuring out the right contexts. This might be addressed here: actions/runner#410, but I've not tested...

sudo sed -i 's/enforcing/permissive/g' /etc/selinux/config
sudo setenforce 0

Now setup the systemd unit files and start the runner - I'm running as root... Maybe better as a user...

sudo ./svc.sh install root

# Start the runner - replace jonjozwiak-demo-org.rhel8-runner with your org.runner-name
systemctl start actions.runner.jonjozwiak-demo-org.rhel8-runner
systemctl status actions.runner.jonjozwiak-demo-org.rhel8-runner

Now you should be able to run a simple test to confirm it can launch a container. Here's an example of the action I created to test:

name: Hello World
on:
  #push:
  #  branches: [ main ]
  workflow_dispatch:
  
jobs:
  hello-world:
    runs-on: 
      group: jozwiak-org-rhel-runners
    container:
      image: fedora:latest
    steps:
      - name: Hello World
        run: echo "Hello World"

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment