Last active
March 24, 2026 16:00
-
-
Save beautyfree/5eb5c60c5da307612fe0d5fbc332b6c6 to your computer and use it in GitHub Desktop.
Proxmox LXC Create Github Actions Runner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # This script automates the creation and registration of a Github self-hosted runner within a Proxmox LXC (Linux Container). | |
| # The runner is based on Ubuntu 23.04. Before running the script, ensure you have your GITHUB_TOKEN | |
| # and the OWNERREPO (github owner/repository) available. | |
| # Creates and sets up a self-hosted GitHub Actions runner in an LXC container on Proxmox: | |
| # Create a new LXC container based on ubuntu 23.04 | |
| # Installs apt-get dependencies (git, curl) | |
| # Installs docker | |
| # Installs Github actions (needs GITHUB_TOKEN and OWNERREPO) and sets up service | |
| # NOTE: Since the new container has docker support, it cannot be run unpriviledged. This approach is more insecure than using a full-blown VM, at the benefit of being much faster most times. That being said, make sure you only use this self-hosted runner in contexts that you can control at all times (e.g. careful using with public repositories). | |
| # Instructions | |
| # # Download the script | |
| # curl -O https://gist.githubusercontent.com/beautyfree/5eb5c60c5da307612fe0d5fbc332b6c6/raw/lxc_create_github_actions_runner.sh | |
| # # Inspect script, customize variables | |
| # # Run the script | |
| # bash lxc_create_github_actions_runner.sh | |
| # Warning: make sure you read and understand the code you are running before executing it on your machine. | |
| set -e | |
| # Variables | |
| GITHUB_RUNNER_URL="https://github.com/actions/runner/releases/download/v2.333.0/actions-runner-linux-x64-2.333.0.tar.gz" | |
| TEMPL_URL="http://download.proxmox.com/images/system/ubuntu-22.04-standard_22.04-1_amd64.tar.zst" | |
| PCTSIZE="20G" | |
| PCT_ARCH="amd64" | |
| PCT_CORES="4" | |
| PCT_MEMORY="4096" | |
| PCT_SWAP="4096" | |
| PCT_STORAGE="local-lvm" | |
| DEFAULT_IP_ADDR="192.168.0.123/24" | |
| DEFAULT_GATEWAY="192.168.0.1" | |
| # Ask for GitHub token and owner/repo if they're not set | |
| if [ -z "$GITHUB_TOKEN" ]; then | |
| read -r -p "Enter github token: " GITHUB_TOKEN | |
| echo | |
| fi | |
| if [ -z "$OWNERREPO" ]; then | |
| read -r -p "Enter github owner/repo: " OWNERREPO | |
| echo | |
| fi | |
| # log function prints text in yellow | |
| log() { | |
| local text="$1" | |
| echo -e "\033[33m$text\033[0m" | |
| } | |
| # Prompt for network details | |
| # --- Auto-detect network from vmbr0 --- | |
| HOST_IP_CIDR=$(ip -o -f inet addr show vmbr0 | awk '{print $4}') | |
| HOST_IP=$(echo "$HOST_IP_CIDR" | cut -d/ -f1) | |
| CIDR=$(echo "$HOST_IP_CIDR" | cut -d/ -f2) | |
| # Guess gateway (usually .1) | |
| GATEWAY_GUESS=$(ip route | awk '/default/ {print $3}' | head -n1) | |
| # Generate container IP (same subnet, random last octet) | |
| BASE_NET=$(echo "$HOST_IP" | awk -F. '{print $1"."$2"."$3}') | |
| RANDOM_OCTET=$(( (RANDOM % 200) + 50 )) | |
| DEFAULT_IP_ADDR="$BASE_NET.$RANDOM_OCTET/$CIDR" | |
| DEFAULT_GATEWAY="${GATEWAY_GUESS:-$BASE_NET.1}" | |
| echo | |
| echo "Detected network:" | |
| echo " Host IP: $HOST_IP" | |
| echo " Suggested CT IP: $DEFAULT_IP_ADDR" | |
| echo " Suggested GW: $DEFAULT_GATEWAY" | |
| echo | |
| # Prompt user with defaults | |
| read -r -e -p "Container Address IP (CIDR format) [$DEFAULT_IP_ADDR]: " input_ip_addr | |
| IP_ADDR=${input_ip_addr:-$DEFAULT_IP_ADDR} | |
| read -r -e -p "Container Gateway IP [$DEFAULT_GATEWAY]: " input_gateway | |
| GATEWAY=${input_gateway:-$DEFAULT_GATEWAY} | |
| # Get filename from the URLs | |
| TEMPL_FILE=$(basename $TEMPL_URL) | |
| GITHUB_RUNNER_FILE=$(basename $GITHUB_RUNNER_URL) | |
| # Get the next available ID from Proxmox | |
| PCTID=$(pvesh get /cluster/nextid) | |
| # Download Ubuntu template | |
| log "-- Downloading $TEMPL_FILE template..." | |
| curl -q -C - -o "$TEMPL_FILE" $TEMPL_URL | |
| # Create LXC container | |
| log "-- Creating LXC container with ID:$PCTID" | |
| pct create "$PCTID" "$TEMPL_FILE" \ | |
| -arch $PCT_ARCH \ | |
| -ostype ubuntu \ | |
| -hostname github-runner-proxmox-$(openssl rand -hex 3) \ | |
| -cores $PCT_CORES \ | |
| -memory $PCT_MEMORY \ | |
| -swap $PCT_SWAP \ | |
| -storage $PCT_STORAGE \ | |
| -features nesting=1,keyctl=1 \ | |
| -net0 name=eth0,bridge=vmbr0,gw="$GATEWAY",ip="$IP_ADDR",type=veth | |
| # Resize the container | |
| log "-- Resizing container to $PCTSIZE" | |
| pct resize "$PCTID" rootfs $PCTSIZE | |
| # Start the container & run updates inside it | |
| log "-- Starting container" | |
| pct start "$PCTID" | |
| sleep 10 | |
| log "-- Running updates" | |
| pct exec "$PCTID" -- bash -c "apt update -y && apt install -y git curl zip && passwd -d root" | |
| # Install Docker inside the container | |
| log "-- Installing docker" | |
| pct exec "$PCTID" -- bash -c "curl -qfsSL https://get.docker.com | sh" | |
| # Get runner installation token | |
| log "-- Getting runner installation token" | |
| RES=$(curl -s -L -X POST \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| https://api.github.com/repos/$OWNERREPO/actions/runners/registration-token) | |
| RUNNER_TOKEN=$(echo $RES | grep -o '"token": "[^"]*' | grep -o '[^"]*$') | |
| if [ -z "$RUNNER_TOKEN" ]; then | |
| echo "ERROR: Failed to get GitHub runner token. Check GITHUB_TOKEN and OWNERREPO." | |
| echo "Response was: $RES" | |
| exit 1 | |
| fi | |
| # Install and start the runner | |
| log "-- Installing runner" | |
| pct exec "$PCTID" -- bash -c "mkdir actions-runner && cd actions-runner &&\ | |
| curl -o $GITHUB_RUNNER_FILE -L $GITHUB_RUNNER_URL &&\ | |
| tar xzf $GITHUB_RUNNER_FILE &&\ | |
| RUNNER_ALLOW_RUNASROOT=1 ./config.sh --unattended --url https://github.com/$OWNERREPO --token $RUNNER_TOKEN &&\ | |
| ./svc.sh install root &&\ | |
| ./svc.sh start" | |
| # Delete the downloaded Ubuntu template | |
| rm "$TEMPL_FILE" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Instructions
Download the script
Inspect script, customize variables
Run the script
Warning: make sure you read and understand the code you are running before executing it on your machine.