GitHub Actions Runner
Overview
GitHub Actions Runner is the official self-hosted runner agent from GitHub. It runs your GitHub Actions workflows on machines you control instead of on GitHub-hosted runners. Use it when a job must reach a private network, use hardware or software that GitHub does not offer, run inside your own compliance boundary, or run longer or more often than hosted minutes allow.
This guide covers the deployment and configuration of GitHub Actions Runner on Ubuntu 24.04 on Azure, using the SecureAnyCloud Azure Marketplace image. The image installs runner 2.335.1 from the official GitHub release, verified against a pinned SHA256 checksum. The runner's own installdependencies.sh resolves its .NET dependencies.
The runner runs under a dedicated non-root service account, ghrunner, which has no password and no sudo rights. A runner executes whatever code your workflows contain, so it should never hold administrative privilege.
A self-hosted runner opens an outbound long-poll connection to GitHub and waits to be handed a job. It never listens for inbound CI traffic, so this image opens no inbound port other than SSH for your own management.
No credentials by design, and why the runner does not start on its own. A runner is useless until it is registered to a repository, organisation or enterprise. Registration requires a short-lived registration token that is specific to your account. An image that shipped a token, or the long-lived credentials that the token is exchanged for, would let anyone who launches that image join your continuous integration and execute against your repositories.
This image therefore ships with no token, no credentials and no registration state whatsoever. The github-actions-runner service is installed but deliberately left disabled, and it is gated so that it cannot start until you have registered. You register the runner once, with a token you generate yourself, and then enable the service.
What you get:
- GitHub Actions Runner 2.335.1 from the official GitHub release, SHA256 verified, installed at
/opt/actions-runner - A dedicated non-root service account,
ghrunner, with no password, no sudo rights, and membership of thedockergroup so that container jobs work - A systemd unit,
github-actions-runner.service, installed and ready to enable, and gated so that it cannot start before registration - A preinstalled CI toolchain, listed in full below, with nothing installed speculatively
- A per-VM runner name generated on first boot, so that several of these images can join one organisation without colliding, recorded in
/root/github-actions-runner-credentials.txt(root only) - A built-in self-test (
/opt/actions-runner/runner-selftest.sh) that verifies the runner, its dependencies and its service state, and that no credential artifact exists anywhere on the image - 24/7 SecureAnyCloud support
What is preinstalled
Everything below is present so that a typical workflow does not have to install it on every job run. This list is exhaustive. The image does not carry anything else on top of Ubuntu 24.04 LTS.
Package Why it is here
git Every workflow that uses actions/checkout needs it
docker.io Container jobs and service containers; ghrunner is in the docker group
build-essential, make, pkg-config Compiling C and C++ projects and native extensions
python3, python3-pip, python3-venv Python jobs and tooling
jq Parsing JSON in workflow steps
unzip, zip Artifact and cache handling
rsync Deployment and file sync steps
curl, wget, tar, gzip Fetching and unpacking in workflow steps
gnupg, openssl Signing and checksum verification steps
Node.js is not listed separately because the runner ships its own bundled Node runtimes, which is what JavaScript actions execute against.
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
- A subscription to the GitHub Actions Runner listing on Azure Marketplace
- A network security group (NSG) rule that allows TCP 22 for administration. No inbound CI port is required, because the runner connects outbound to GitHub
- Admin rights on the GitHub repository, organisation or enterprise that you want to register the runner to, so that you can generate a registration token
- Outbound HTTPS (TCP 443) egress to
github.comand its Actions endpoints
Recommended virtual machine size: Standard_D4s_v5 (4 vCPU, 16 GB RAM). A runner that does real work, such as compiling code, running test suites and building container images, is much more demanding than an idle appliance. Burstable B-series credits are the wrong shape for sustained build load. Scale up or out from there according to your job mix.
Deploy from the Azure Portal
Search the Azure Marketplace for GitHub Actions Runner, select the SecureAnyCloud publisher, and select Create.
Configure the network security group to allow TCP 22 for administration. You do not need to open any other inbound port.
Deploy from the Azure CLI
Create the VM with the Azure CLI:
RG="ci-runners"; LOCATION="eastus"; VM_NAME="ghrunner1" IMAGE_URN="sac1647283583153:github-actions-runner-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:github-actions-runner-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_D4s_v5 \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1001First boot - read your per-VM runner identity
On first boot, the image generates a unique runner name for this VM and resolves the VM's reachable address. It records the runner version and the registration instructions, and writes them to a root-only file. This completes within seconds.
SSH in as azureuser and read the file:
sudo cat /root/github-actions-runner-credentials.txtThe file records runner.name (the per-VM name to register with), runner.work_dir, runner.service_user, runner.version and runner.registered=false. It contains no token and no secret. The only credential in this product's life cycle is the one that GitHub issues to you at registration.
Confirm the runner is installed and correctly idle
The runner binary reports its real version. The service is installed but not enabled and not running, which is the correct state for an unregistered runner and not a fault.
sudo -u ghrunner /opt/actions-runner/bin/Runner.Listener --version systemctl is-enabled github-actions-runner.service systemctl is-active github-actions-runner.service systemctl is-active github-actions-runner-firstboot.serviceThe is-enabled command returns disabled and is-active returns inactive. This is by design. The runner has nothing to do until you register it, and the unit is gated on the registration state file so that it cannot start early.
Confirm the preinstalled toolchain
Every tool listed in the table above is present and on the path:
git --version docker --version python3 --version jq --version gcc --version | sed -n '1p' rsync --version | sed -n '1p'Verify the image carries no credentials
The image ships a self-test that checks the most important property of this product: that it contains no runner credential of any kind. The self-test checks that:
- The runner executes and reports its real version.
- The runner's dependencies resolve.
- The service is installed and correctly disabled.
- The runner refuses to start unregistered.
- No credential artifact exists. It checks the exact files that registration would create, and it sweeps the whole filesystem for credential-shaped files and GitHub token-shaped strings.
The self-test also runs a negative control. It plants a decoy credential file and a decoy token in a temporary directory, and requires both sweeps to detect them before it trusts the real sweeps. Without this control, a sweep that silently matched nothing would pass for the wrong reason.
Run the self-test:
sudo /opt/actions-runner/runner-selftest.shThe self-test prints RUNNER_SELFTEST_OK when every check passes.
You can confirm the same by hand. None of the files that registration would create exist yet:
sudo ls -a /opt/actions-runner | grep -E '^\.(runner|credentials|env|path)' || echo "no registration artifacts present"
sudo ls /etc/systemd/system/actions.runner.*.service 2>/dev/null || echo "no generated runner units present"Register the runner to your repository or organisation
This is the one step that only you can do, because the token belongs to your account.
Generate a registration token in GitHub:
- For a repository: go to your repository, then select Settings > Actions > Runners > New self hosted runner, and choose Linux / x64. The token appears in the configure command on that page.
- For an organisation: go to your organisation, then select Settings > Actions > Runners > New self hosted runner.
The token is short-lived. It expires within the hour and is single-use for registration. You do not need to keep it afterwards.
Then run the configure command on the VM as the ghrunner service account. Substitute your URL, your token and the per-VM runner name from Step 3:
sudo -u ghrunner /opt/actions-runner/config.sh \
--url https://github.com/<your-org>/<your-repo> \
--token <your-token> \
--name <RUNNER_NAME> \
--work <RUNNER_WORK_DIR> \
--labels self-hosted,linux,x64,azure \
--unattended sudo systemctl enable --now github-actions-runner.serviceRun the command as the <RUNNER_SERVICE_USER> account, never as root. The runner refuses to configure under sudo without an explicit override, and that refusal is deliberate.
After registration, config.sh writes the registration state file, which satisfies the service's start gate, and systemctl enable --now starts the runner. Your runner then appears under Settings > Actions > Runners in GitHub with an Idle status. It picks up any workflow job that targets it.
Send a job to your runner
Target the runner from a workflow with runs-on. The self-hosted label is applied automatically. The extra labels that you passed during registration let you route jobs more precisely.
name: build-on-self-hosted on: [push, workflow_dispatch] jobs: build: runs-on: [self-hosted, linux, x64] steps: - uses: actions/checkout@v4 - name: Show the runner environment run: | hostname git --version docker --versionPush that workflow, or trigger it from the Actions tab, and watch the job run on your VM. On the VM, you can follow the runner's own logs:
sudo systemctl status github-actions-runner.service --no-pager || true
sudo journalctl -u github-actions-runner.service -n 50 --no-pagerThe systemctl status command exits with a non-zero status while the unit is stopped, which is why the || true is there. It is not an error.
Operating the runner
Scaling out. Launch more of these images and register each one. Each VM generates its own unique runner name on first boot, so the runners never collide inside a single organisation. Group them with runner groups and route work with labels.
Untrusted code. A self-hosted runner executes whatever a workflow contains. GitHub's own guidance is to avoid self-hosted runners on public repositories, where anyone can open a pull request that runs code on your machine. Keep these runners on private repositories, or isolate them thoroughly.
Ephemeral runners. For stronger isolation between jobs, register with --ephemeral so that the runner accepts exactly one job and then deregisters. Pair this with launching a fresh VM per job.
Upgrades. By default, the runner updates itself when GitHub releases a new version, so a registered runner stays current on its own. To pin a version instead, register with --disableupdate and manage upgrades yourself.
Deregistering. To remove a runner cleanly, stop the service and remove the registration with a fresh removal token from the same GitHub settings page.
sudo systemctl disable --now github-actions-runner.service
sudo -u ghrunner /opt/actions-runner/config.sh remove --token <your-token>Troubleshooting
The service will not start. If systemctl start github-actions-runner appears to do nothing and the unit stays inactive, the runner is not registered yet. The unit is gated on /opt/actions-runner/.runner, which config.sh creates. Complete Step 7 first. Run systemctl status github-actions-runner to check, because it reports a skipped start condition.
config.sh refuses to run. Run it as the service account with sudo -u ghrunner, not as root. The runner deliberately refuses to configure as root.
The runner does not appear in GitHub. Registration tokens expire within the hour. Generate a fresh token and retry. Confirm that the VM has outbound HTTPS egress to github.com.
Container jobs fail. Confirm that docker.service is active and that the runner account is in the docker group, using id ghrunner. Group membership applies to the service on start, so restart the runner service after any change.
Check what the image contains. Run sudo /opt/actions-runner/runner-selftest.sh at any time to repeat every image-level check, including the credential sweeps.
Support
SecureAnyCloud provides 24/7 technical support for this GitHub Actions Runner image. Our engineers help with registration, runner groups and labels, scaling to a fleet, workflow and caching design, container and service container jobs, hardening the execution environment for untrusted code, network and firewall rules, and runner version upgrades. Critical issues receive a one-hour average response time. Contact sales@secureanycloud.com.
All product and company names are trademarks or registered trademarks of their respective holders. Use of these names does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch GitHub Actions Runner 2.335.1 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
GitHub Actions Runner is the official self-hosted runner agent for GitHub Actions. This image installs the same actions/runner agent that GitHub publishes, from the pinned, checksum-verified upstream release.
A self-hosted runner executes your GitHub Actions workflows on machines you control rather than on GitHub-hosted runners. Use it when a job must reach a private network, use hardware or software that the hosted runners do not offer, run inside your own compliance boundary, or run longer or more often than your hosted minutes allow.
The runner opens an outbound long-poll connection to GitHub and waits to be handed a job. It never listens for inbound CI traffic, so this image opens no inbound port other than SSH for your own management. There is nothing to publish to the internet and nothing to put behind a load balancer.
What you get:
- The runner installed at
/opt/actions-runner - A dedicated non-root system account,
ghrunner, with no password and no sudo rights - A systemd unit,
github-actions-runner.service, installed and ready but deliberately left disabled - A unique runner name generated on first boot for each instance
- 24/7 SecureAnyCloud support
This image ships with no credentials, on purpose
This image contains no GitHub token and no runner registration of any kind. This is a deliberate security decision, not an omission.
A runner registration token is short-lived and specific to your repository or organisation. The long-lived runner credentials that the token is exchanged for let the holder pick up your jobs. An image that shipped either would let anyone who launched it join your continuous integration and execute against your repositories. The image therefore ships the runner software only, and you perform the registration once, with a token you generate yourself.
Because there is nothing to run until you register, the runner service is left disabled and is additionally gated. Its unit carries ConditionPathExists=/opt/actions-runner/.runner, the state file that registration creates. Until you register, even an accidental systemctl start is a harmless no-op rather than a crash loop.
On first boot, the instance generates a unique runner name for itself, so several instances launched from this image can join the same organisation without colliding. It writes that identity, plus the exact registration commands, to /root/github-actions-runner-credentials.txt with mode 0600 so that only root can read it.
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An SSH key pair in the Region you intend to launch in
- A GitHub account with permission to add a self-hosted runner to the repository, organisation or enterprise you intend to serve. Adding a runner to a repository requires admin on that repository. Adding one to an organisation requires organisation owner
Launching the instance
You can launch from the AWS Marketplace console or from the AWS CLI.
To launch from the console, subscribe to the product and choose Launch through EC2. Pick your instance type and key pair, and select a security group that allows inbound TCP 22 from your own management address only. No other inbound port is required.
To launch from the CLI, substitute the AMI ID shown on the product page, your key name, your subnet and your security group:
aws ec2 run-instances \
--image-id ami-EXAMPLE0000000000 \
--instance-type m5.large \
--key-name your-key-name \
--security-group-ids sg-EXAMPLE00000000 \
--subnet-id subnet-EXAMPLE00000 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=actions-runner}]'Choosing an instance type
The listing recommends m5.large (2 vCPU, 8 GiB), which is a sensible general-purpose starting size and is available in every commercial region.
Size the instance to your workload, not to the idle runner. An idle runner uses almost no CPU, but a runner that does real work compiles code, runs test suites and builds container images. If your builds are heavy, move up to m5.xlarge or m5.2xlarge. Alternatively, run several smaller runners in parallel and let GitHub distribute jobs across them.
Give / enough room for your build working set. The runner's _work directory holds a full checkout plus build artefacts for every job.
Connecting to your instance
Connect over SSH on port 22 with the key pair that you selected at launch. The login user depends on the operating system variant that you launched:
OS variant SSH login user
Ubuntu 24.04 LTS ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>After you connect, read the per-instance runner identity and the registration instructions written for this instance:
sudo cat /root/github-actions-runner-credentials.txtThe file is written on first boot with mode 0600 root:root. It contains no secret, because this image has no secret to hold. It records this instance's generated runner name, the work directory, the service account, the runner version and the reachable address, and it records runner.registered=false.
To confirm that the identity was written and that only root can read the file, run the following command. It does not print the file:
echo "identity keys written by first boot:"
sudo grep -E '^runner\.(name|work_dir|service_user|version|registered)=' /root/github-actions-runner-credentials.txt
PERMS=$(sudo stat -c '%a %U:%G' /root/github-actions-runner-credentials.txt)
echo "permissions: ${PERMS}" if [ "${PERMS}" = "600 root:root" ]; then
echo "OK: instructions file is root only" else
echo "UNEXPECTED permissions: ${PERMS}" exit 1 fiWhat is preinstalled
Every package below is present because a real workflow needs it. Each one is listed here because a build image that quietly accumulates packages is a liability rather than a convenience.
Component Why it is here
actions/runner 2.335.1 The official self-hosted runner agent, installed at /opt/actions-runner from the pinned, checksum-verified upstream release
git Every workflow starts with actions/checkout
docker.io Container jobs and service containers, the single most common self-hosted runner requirement. The ghrunner account is in the docker group
build-essential, make, pkg-config Compiled projects
python3, python3-pip, python3-venv Python tooling and virtual environments
jq JSON handling in workflow steps
rsync, zip, unzip, tar, gzip Artefact packing and transfer
curl, wget, ca-certificates, gnupg, openssl Fetching and verifying dependencies
iproute2 Network diagnostics
Docker is installed from the Ubuntu archive rather than from Docker's own repository. It therefore stays inside the distribution's security update stream, which is the stream that this image is patched against and that the AWS Marketplace CVE scan measures.
Verifying the image
These checks are read-only and safe to run at any time.
Confirm the runner agent is installed and reports its real version:
sudo -u ghrunner /opt/actions-runner/bin/Runner.Listener --versionConfirm that the first-boot unit ran and Docker is up:
FB=$(systemctl is-enabled github-actions-runner-firstboot.service 2>/dev/null || true)
DK=$(systemctl is-active docker.service 2>/dev/null || true)
echo "firstboot unit: ${FB}"
echo "docker.service: ${DK}" if [ "${FB}" = "enabled" ] && [ "${DK}" = "active" ]; then
echo "OK: first boot initialisation is enabled and Docker is running" else
echo "UNEXPECTED: firstboot=${FB} docker=${DK}" exit 1 fiConfirm the runner service ships installed but disabled, which is the correct state before you register:
STATE=$(systemctl is-enabled github-actions-runner.service 2>/dev/null || true)
ACTIVE=$(systemctl is-active github-actions-runner.service 2>/dev/null || true)
echo "github-actions-runner.service is-enabled: ${STATE}"
echo "github-actions-runner.service is-active: ${ACTIVE}" if [ "${STATE}" = "disabled" ] && [ "${ACTIVE}" != "active" ]; then
echo "OK: the runner is installed and waiting for you to register it" else
echo "UNEXPECTED state: enabled=${STATE} active=${ACTIVE}" exit 1 fiThe built-in self-test
The image ships a self-test that checks, on your own instance, everything that can be verified about a runner that is deliberately not yet registered. It confirms that:
- The agent executes and reports its real version.
- Every native dependency resolves.
- The service is installed and correctly disabled.
- The runner refuses to start while unregistered.
- No credential artefact of any kind is present.
The self-test includes a negative control, so a sweep that silently matched nothing cannot pass by accident.
sudo -u ghrunner /opt/actions-runner/bin/Runner.Listener --version >/dev/null 2>&1 || true
sudo bash /opt/actions-runner/runner-selftest.shThe first run on a freshly launched instance takes a couple of minutes. This is expected and is not a fault. An EBS volume created from a snapshot loads its blocks from Amazon S3 on first access, so the runner's .NET libraries are read from S3 the first time rather than from local storage. Subsequent runs complete in a few seconds.
The command above touches the runner binary first, so that the wait happens at an obvious point rather than in the middle of the self-test.
Run the self-test again after you register. It then correctly reports the runner as configured, and the credential sweep checks that your credentials are where they belong and nowhere else.
Registering your runner
Registration is the one step that you perform yourself, and it takes about a minute.
Run the commands in this section on your instance with your token. They are intentionally not executable checks, because a registration token is specific to your account and expires within the hour.
Step 1 - Generate a registration token
In GitHub, go to the repository, organisation or enterprise that you want the runner to serve:
- Repository runner: repository > Settings > Actions > Runners > New self hosted runner
- Organisation runner: organisation > Settings > Actions > Runners > New self hosted runner
Choose Linux and x64. GitHub shows a configuration command that contains a registration token. You need only the URL and the token from that command. The runner software is already installed on this image, so skip GitHub's download steps.
The registration token is short-lived and expires within about an hour. Generate it when you are ready to use it.
Step 2 - Register
First, read your instance's generated runner name from the instructions file:
sudo grep '^runner.name=' /root/github-actions-runner-credentials.txtThen run the configuration command as the ghrunner service account, substituting your URL, your token and that runner name:
sudo -u ghrunner /opt/actions-runner/config.sh \
--url https://github.com/YOUR-ORG/YOUR-REPO \
--token YOUR-REGISTRATION-TOKEN \
--name YOUR-RUNNER-NAME \
--work /opt/actions-runner/_work \
--labels self-hosted,linux,x64,docker \
--unattendedFor an organisation-wide runner, use the organisation URL instead:
--url https://github.com/YOUR-ORGconfig.sh exchanges your short-lived registration token for long-lived runner credentials and writes them into /opt/actions-runner. Those files are the runner's identity. Treat them as secrets, and never bake them into an image of your own.
Step 3 - Start the runner
Enable and start the service:
sudo systemctl enable --now github-actions-runner.service
sudo systemctl status github-actions-runner.serviceThe unit's ConditionPathExists gate is satisfied as soon as registration has written the state file, so the service now starts normally. Within a few seconds, your runner appears as Idle under Settings > Actions > Runners in GitHub and starts accepting jobs.
Running your first workflow
Add a workflow to your repository at .github/workflows/selfhosted.yml:
name: Self hosted smoke test on: [push, workflow_dispatch] jobs: build: runs-on: self-hosted steps: - uses: actions/checkout@v4 - name: Show the runner environment run: | echo "Running on $(hostname)" git --version docker --version python3 --versionPush the file, or trigger it from the Actions tab. Your runner picks up the job instead of a GitHub-hosted runner.
To target a specific runner rather than any self-hosted one, use the labels that you set at registration:
runs-on: [self-hosted, linux, x64, docker]Runner groups, labels and fleets
Labels are how workflows select a runner. Set them at registration with --labels, or edit them later in the GitHub UI under the runner's settings. Give runners labels that describe real capabilities, for example docker, gpu or build-large, so that runs-on expresses a requirement rather than a hostname.
Runner groups let organisations control which repositories may use which runners. Create groups under Settings > Actions > Runner groups, then pass --runnergroup YOUR-GROUP at registration.
To build a fleet, launch several instances from this image. Each instance generates its own unique runner name at first boot, so they can all register into the same organisation without colliding. GitHub distributes queued jobs across whichever runners are idle.
Security model
A self-hosted runner executes whatever code your workflows contain. Treat it accordingly.
- The runner does not run as root. It runs as
ghrunner, a dedicated system account with no password, no sudo rights and no sudoers entry. The agent itself refuses to run as root. - No inbound ports. The runner connects outbound to GitHub, so the security group needs only your own SSH access. Do not open other ports for the runner, because it does not need them.
- Do not use a self-hosted runner on a public repository. This is GitHub's own guidance, and it matters. Anyone who can open a pull request against a public repository can propose workflow changes. On a self-hosted runner, that means proposing code that runs on your instance and inside your network. Keep self-hosted runners to private repositories, or gate workflow runs on approval.
- Jobs share the instance. By default, consecutive jobs run on the same machine with the same working directory tree. If your workflows handle secrets or untrusted code, isolate them. Run job steps inside containers, or treat runners as disposable and replace the instance between sensitive jobs.
- The
ghrunneraccount is in thedockergroup. This membership is required for container jobs, and it is effectively root-equivalent on the instance. It is the standard trade-off for a runner that supports Docker, and it is another reason to keep the instance's network exposure minimal. - Your registration credentials live only on your instance.
config.shcreates them at registration, and they are not present in the image. If you create your own AMI from a registered runner, remove the registration first. Otherwise, you clone your CI identity onto every instance launched from the AMI.
Upgrading the runner
GitHub releases runner updates regularly, and the service refuses a runner that is too far behind. When the runner is registered and running as a service, it updates itself in place by default, so ordinary version drift is handled for you.
To check the version that is currently installed, run:
sudo -u ghrunner /opt/actions-runner/bin/Runner.Listener --versionTo pin or control updates, pass --disableupdate at registration and manage upgrades yourself.
Removing a runner
To retire a runner cleanly, remove its registration from GitHub before you terminate the instance, so that it does not linger as an offline runner in your settings. Generate a removal token the same way you generated the registration token, then run:
sudo systemctl disable --now github-actions-runner.service
sudo -u ghrunner /opt/actions-runner/config.sh remove --token YOUR-REMOVAL-TOKENYou can also remove an offline runner directly in the GitHub UI under Settings > Actions > Runners.
Backup and maintenance
There is very little state to back up. The runner keeps no database. Its state is the registration files in /opt/actions-runner and the transient _work directory. You can safely lose the _work directory, because every job checks out again what it needs.
Pay attention to the following:
- Patch the instance. The image ships fully patched at build time. Apply operating system updates on your own schedule after that.
- Watch disk usage. The
_workdirectory accumulates checkouts and build artefacts, and Docker accumulates images and layers. If builds start failing for lack of space, prune Docker and clear old job directories. - Monitor runner health from Settings > Actions > Runners in GitHub, which shows each runner as Idle, Active or Offline.
To see how much space the runner working area uses, run:
sudo du -sh /opt/actions-runner/_work 2>/dev/null || echo "work directory is empty"Support
SecureAnyCloud provides 24/7 technical support for this image by email at sales@secureanycloud.com and through live chat.
We can help with deployment and first boot, registering the runner to a repository, organisation or enterprise, runner groups and labels, scaling to a fleet, configuring the systemd service, container and service container jobs with Docker, workflow and caching design, hardening the execution environment for untrusted code, network and security group rules, monitoring runner health, and runner version upgrades.
Trademarks
GitHub and GitHub Actions are trademarks of GitHub, Inc. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by GitHub, Inc. or Microsoft. The runner agent distributed in this image is the unmodified official release, published by GitHub under the MIT Licence. A copy of that licence ships at /opt/actions-runner/LICENSE. All other product and company names are trademarks or registered trademarks of their respective holders.
Deploy on AWS
Launch GitHub Actions Runner on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com