SSD Nodes Learn Hosting plans →
Mwongozo Matt ConnorNa Matt Connor · Imeboreshwa 2026-11-06

Jinsi ya Kusanidi GitHub Actions Runner kwenye VPS

Sajili runner kwenye Ubuntu 24.04 kwa user maalum, checksum na config.sh, iendeshe kama systemd service, na elewa hatari ya fork pull requests.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Kazi ya GitHub Actions runner inayojipangisha

GitHub Actions runner inayojipangisha ni programu unayosakinisha kwenye VPS yako mwenyewe. Huomba kazi kutoka GitHub na kuziendesha kwenye maunzi yako. Unaisajili kwa repository moja, unaisakinisha kama systemd service, na huanza tena baada ya kila reboot. GitHub hupanga kazi. Seva yako hufanya kazi hiyo.

CI (continuous integration) kwenye mashine unayomiliki ina manufaa kwa sababu mbili. Dakika za build hazihesabiwi tena kwa matumizi, na kazi inaweza kufikia rasilimali zinazopatikana kwenye mashine yako pekee, kama build cache iliyo tayari au private network. Gharama yake ni usalama. Runner hutekeleza chochote kilichoelezwa kwenye workflow file, kwa kutumia user uliyompa. Kwa hiyo, workflow file ni remote code execution kwa muundo wake. Kwenye private repository, kila mtu anayeruhusiwa kuendesha workflows lazima aaminiwe, wakiwemo watu wanaoweza kuwasilisha fork pull requests zinazoendeshwa kwenye runner. Kwenye public repository, hii ni hatari halisi. Sehemu kuhusu fork pull requests inaeleza utaratibu huo.

Kila kitu hapa chini kinatumia Ubuntu 24.04 na runner version 2.338.0, ambayo ilikuwa release ya sasa tarehe 12 October 2026. Release ya hivi karibuni ya GitHub ni 2.338.2 kufikia 4 November 2026. Hata hivyo, commands na checksum zilizo hapa zimefungwa kwenye 2.338.0.

Unachohitaji kabla ya kuanza

Anza na VPS yenye akaunti ya kawaida ya admin na sudo, hali unayofikia katika dakika kumi za kwanza kwenye VPS mpya. Huhitaji kufungua port yoyote ya kuingia (inbound). Runner hufungua muunganisho wa kutoka (outbound) wa HTTPS (hypertext transfer protocol secure) kuelekea GitHub na kuudumisha ukiwa wazi wakati ikisubiri kazi, kwa hivyo GitHub haiunganishi kamwe na seva yako. Firewall yako inaweza kubaki imefungwa kwa ulimwengu na kazi bado zitafika.

Pia unahitaji haki za admin kwenye repository, kwa sababu token ya usajili huonyeshwa kwenye mipangilio ya repository.

Unda mtumiaji maalum kwa ajili ya runner

Usiwahi kuendesha runner kama root au kama mtumiaji wako wa admin. Kila kazi hurithi haki za mtumiaji wa runner, kwa hivyo workflow inayotumia sudo hufanikiwa ikiwa mtumiaji wa runner anaweza kutumia sudo. Unda mtumiaji mmoja asiye na upendeleo ambaye hamiliki chochote isipokuwa saraka yake ya nyumbani (home directory). Akaunti za watumiaji zenye upendeleo mdogo kwenye VPS inaelezea muundo wa jumla. Hapa kuna muundo maalum.

sudo useradd -m -s /bin/bash gharunner
sudo passwd -l gharunner
sudo chmod 750 /home/gharunner
sudo install -d -m 700 -o gharunner -g gharunner /home/gharunner/actions-runner

passwd -l hufunga nenosiri, ili hakuna mtu anayeweza kuingia kama gharunner kwa kutumia nenosiri. Mode 700 kwenye saraka ya runner ni muhimu kwa sababu runner huhifadhi vitambulisho vyake hapo katika mfumo wa maandishi wazi (cleartext), na checkout inaweza kuwa na source ya siri.

Kagua sifa zote mbili kabla ya kuendelea:

sudo passwd -S gharunner
sudo -l -U gharunner

passwd -S huchapisha mstari unaoanza na gharunner L, ambapo L inamaanisha nenosiri limefungwa. sudo -l -U gharunner inapaswa kujibu na is not allowed to run sudo. Ikiwa inachapisha orodha ya amri zinazoruhusiwa badala yake, akaunti hiyo iko kwenye kundi la sudo na kutengwa (isolation) uliyojenga hivi punde kumepotea.

Pakua runner na uhakiki tarball

Fanya kazi kama mtumiaji wa runner kuanzia hapa.

sudo -iu gharunner
cd ~/actions-runner
RUNNER_VERSION=2.338.0
curl -fL -o actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz \
  "https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz"

Tekeleza uname -m kwanza ikiwa huna uhakika na usanifu (architecture) wa mfumo wako. x86_64 hutumia faili ya linux-x64 hapo juu. aarch64 hutumia actions-runner-linux-arm64-${RUNNER_VERSION}.tar.gz.

Sasa hakiki ulichopakua. SHA256 (secure hash algorithm, 256 bit) hapa chini ni kwa ajili ya tarball ya 2.338.0 x64. GitHub huchapisha thamani ya toleo la sasa kwenye ukurasa wa releases na kwenye skrini ya New self-hosted runner. Thamani hii hubadilika kila toleo jipya linapotoka, kwa hivyo nakili kutoka hapo unaposakinisha toleo tofauti.

echo "af4b794c1bc41d73d40535e3fe092a39f9679cd8d965954c2aca25a05ca41d32  actions-runner-linux-x64-2.338.0.tar.gz" | sha256sum -c

Upakuaji uliofanikiwa huchapisha mstari mmoja:

actions-runner-linux-x64-2.338.0.tar.gz: OK

Faili iliyokatika au iliyobadilishwa huchapisha hitilafu na onyo:

actions-runner-linux-x64-2.338.0.tar.gz: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

Usiruke hatua hii ya uhakiki na kuacha tar igundue tatizo baadaye. Kumbukumbu (archive) iliyoandikwa nusu itashindwa kwa gzip: stdin: unexpected end of file na tar: Unexpected EOF in archive, ambayo hukuambia kuwa faili imeharibika lakini haikwambii kama ilikatwa katikati au ilibadilishwa.

tar xzf ./actions-runner-linux-x64-2.338.0.tar.gz
ls

Yaliyomo kwenye tarball na yale yasiyokuwemo

Baada ya kutoa faili, saraka hiyo ina config.sh, run.sh, env.sh, safe_sleep.sh, bin/ na externals/. bin/ ina binaries za runner na bin/installdependencies.sh. externals/ ina Node runtime iliyounganishwa ambayo hatua za JavaScript hutekelezwa juu yake.

Hakuna svc.sh bado. Nyaraka za GitHub zinaielezea kama hati "inayoundwa baada ya kuongeza runner kwa mafanikio", kwa sababu imeandikwa kutoka kwenye kiolezo chenye jina la hazina yako na jina la runner yakiwa yameingizwa kwenye jina la huduma. Kwa hivyo sudo ./svc.sh install kabla ya ./config.sh inashindwa na kutoa sudo: ./svc.sh: command not found. Sajili kwanza, kisha usakinishe huduma.

Sakinisha utegemezi wa runner

runner ni programu ya .NET, kwa hiyo inahitaji maktaba kadhaa zinazoshirikiwa. Toka kwenye shell ya mtumiaji wa runner, kisha zisakinishe kwa sudo, kwa sababu script huandika kwenye hifadhidata ya vifurushi vya mfumo.

exit
cd /home/gharunner/actions-runner
sudo ./bin/installdependencies.sh

Kwenye Ubuntu 24.04, hiyo husakinisha libkrb5-3, zlib1g, liblttng-ust1t64, libssl3t64 na libicu74. Script hujaribu majina kadhaa ya matoleo kwa kila maktaba na hutumia lile ambalo toleo lako la mfumo linasambaza. Ndiyo sababu script hiyo hiyo hufanya kazi kwenye Ubuntu za zamani na Debian.

Ikiwa maktaba iliyokaguliwa kwa ldd haipo, ./config.sh husitisha kabla ya kuanzisha runner:

Dependencies is missing for Dotnet Core 6.0
Execute sudo ./bin/installdependencies.sh to install any missing Dotnet Core 6.0 dependencies.

libicu ikiwa haipo, hutoa ushauri huo huo chini ya mstari wa kwanza tofauti, Libicu's dependencies is missing for Dotnet Core 6.0. Yote mawili hutoka sehemu moja: config.sh hukagua maktaba zilizojumuishwa kwa kutumia ldd, na libicu kwa kutumia ldconfig, kabla ya kuanza. Kwa hiyo, kiunganishi kisichotatuliwa husitisha script badala ya kusababisha crash isiyoeleweka baadaye. Ukaguzi huu haujumuishi kila kifurushi ambacho installer huorodhesha. liblttng-ust1t64 ikiwa haipo, hauanzishi ukaguzi huo: .NET hupakia ufuatiliaji wa LTTng kwa hiari na huendelea wakati utegemezi wake wa ufuatiliaji haupatikani.

Jisajili kama runner kwenye hazina yako

Pata token kutoka kwenye hazina (repository). Fungua Settings, kisha Actions, kisha Runners, kisha New self-hosted runner. Ukurasa huo utaonyesha token ya usajili. Token hiyo huisha muda wake saa moja baada ya kutengenezwa, kwa hivyo itengeneze wakati uko tayari kuibandika.

Jisajili ukiwa kama mtumiaji wa runner. config.sh inakataa kuendeshwa chini ya sudo.

sudo -iu gharunner
cd ~/actions-runner
./config.sh --url https://github.com/YOUR-USER/YOUR-REPO \
  --token PASTE_REGISTRATION_TOKEN_HERE \
  --name vps-runner-1 \
  --labels vps \
  --work _work \
  --unattended \
  --replace

Kazi za flag hizo ni kama ifuatavyo. --name ndilo jina ambalo runner atatumia kuonekana kwenye hazina, kwa hivyo chagua jina ambalo utalikumbuka hata baada ya miezi sita. --labels huongeza lebo zako mwenyewe; runner tayari anazo lebo za self-hosted, Linux na X64 bila kuombwa. --work hutaja saraka (directory) ambapo faili zilizopakuliwa (checkouts) huwekwa, ndani ya saraka ya runner. --unattended hujibu maombi ya maingiliano (interactive prompts) kwa kutumia chaguo-msingi, jambo ambalo ni muhimu wakati amri hiyo inapoendeshwa ndani ya hati (script). --replace huchukua nafasi ya usajili uliopo wenye jina lilelile badala ya kufeli, jambo ambalo ni muhimu unapojenga upya seva.

Usajili uliofanikiwa huishia na mistari hii:

√ Runner successfully added
√ Runner connection is good
√ Settings Saved.

Usajili sasa unapatikana ndani ya saraka ya runner kama .runner, .credentials na .credentials_rsaparams. Faili mbili za mwisho humtambulisha runner huyu kwa GitHub, kwa hivyo mtu yeyote anayeweza kuzisoma anaweza kujifanya kuwa yeye. Hiyo ndiyo sababu saraka hiyo ina mode 700 na mtumiaji hana ruhusa ya sudo.

Sakinisha runner kama huduma ya systemd

./run.sh katika terminal inafaa kwa jaribio moja, lakini inakufa pale unapofunga session yako ya SSH. Sakinisha huduma hii ili runner ianze kuwaka wakati wa boot. systemd services and timers on a VPS inaelezea faili za unit zenyewe. Hapa svc.sh inakuandikia moja.

exit
cd /home/gharunner/actions-runner
sudo ./svc.sh install gharunner
sudo ./svc.sh start
sudo ./svc.sh status

svc.sh inahitaji root kwa sababu inaandika unit ndani ya /etc/systemd/system na kuiwezesha. Hoja inayofuata install ni mtumiaji ambaye huduma hiyo itatumia kufanya kazi. Pitisha gharunner kwa uwazi. Bila hoja yoyote, script inarudi kwenye $SUDO_USER, ambayo ni akaunti yako ya admin, na kisha kila kazi itafanyika kama mtumiaji anayeweza kutumia sudo.

Unit hiyo hupewa jina kulingana na repository na runner, kwa muundo wa actions.runner.YOUR-USER-YOUR-REPO.vps-runner-1.service. Huna haja ya kuandika jina hilo:

systemctl list-units 'actions.runner.*'
sudo journalctl -u 'actions.runner.*' -n 20 --no-pager

Runner iliyo katika hali nzuri hutoa log ya √ Connected to GitHub na kisha mstari unaoishia na Listening for Jobs, na ukurasa wa Runners wa repository hiyo huionyesha kama Idle. Runner inayoonekana kama Offline aidha haifanyi kazi au haiwezi kufikia GitHub kupitia port 443.

Tuma kazi kwa runner

runs-on huchagua runner kwa kutumia label. Omba self-hosted pamoja na label yako mwenyewe, ili kazi isiwekwe kwenye runner ambayo hukukusudia.

name: build
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: [self-hosted, linux, vps]
    steps:
      - uses: actions/checkout@v5
      - run: uname -a

Ikiwa kazi inasubiri kwenye Waiting for a runner to pick up this job, hakikisha kwamba runner inayolingana iko mtandaoni na haina kazi. Kila label katika runs-on lazima iwepo kwenye runner. Kwa hiyo, neno moja la ziada huacha kazi ikiwa kwenye foleni hadi runner inayolingana ipatikane au kazi ishindwe baada ya 24 hours. Linganisha orodha hiyo na labels zinazoonyeshwa kando ya runner katika mipangilio ya repository.

Kwa nini self-hosted runners na public repositories haviendani

Hii ndiyo sehemu ambayo watu wengi hupuuza. Mwongozo wa GitHub uko wazi: self-hosted runners “zinapaswa karibu kamwe kutotumiwa kwa public repositories”, na “hazina dhamana ya kuendeshwa kwenye virtual machines safi za muda mfupi, na zinaweza kuathiriwa kwa kudumu na code isiyoaminika iliyo kwenye workflow”.

Utaratibu wake ni rahisi. Pull request kutoka fork huleta nakala yake yenyewe ya workflow file. Ikiwa public repository yako inaendesha pull request workflows kwenye runner yako, mtu yeyote anayeweza kufanya fork ya repository anaweza kupendekeza workflow inayoendesha commands zake kwenye VPS yako. Hawahitaji write access, kwa sababu kitu wanachopendekeza ndicho kinachoendeshwa.

Mipangilio ya approval hupunguza hatari hii bila kuiondoa. Sera chaguomsingi ya public repository humtaka maintainer kuidhinisha workflow ya fork ya mchangiaji wa kwanza. GitHub humhesabu mtu kuwa wa mara ya kwanza hadi commit au pull request yake yoyote iwe imeunganishwa kwenye repository. Baada ya hapo, pull requests zake zinazofuata huendeshwa bila ombi la idhini, na GitHub yenyewe inaonya kwamba fix ndogo iliyounganishwa inatosha kufikia hali hiyo. Kwa hiyo, kizuizi hicho ni mtu kusoma diff, na payload iliyofichwa ndani ya viwango vitatu vya build script inaweza kupuuzwa kwa urahisi.

Fork pull request haipokei secrets zako, na GITHUB_TOKEN yake ni read only. Hilo hupunguza madhara ndani ya GitHub. Halifanyi chochote kwa server yako. Mshambuliaji ana shell kama gharunner, kwa hiyo anaweza kusoma kila file ambalo user huyo anaweza kusoma, kufikia chochote ambacho VPS inaweza kufikia kwenye private network yake, na kuacha kitu kwenye ~/.bashrc au user systemd unit inayoendeshwa wakati wa job inayofuata.

Kusajili kwa kutumia --ephemeral hufanya runner ikubali job moja kisha ijiondoe kwenye usajili; hakufuti workspace ya job hiyo. Husaidia tu ikiwa kuna kitu kinachounda upya machine au container kwa kila job, kwa sababu backdoor iliyoandikwa kwenye home directory ya runner user hubaki baada ya usajili mpya.

Sheria zinazofuata ni fupi. Tumia self-hosted runners kwa private repositories. Ikiwa ni lazima uunganishe moja na public repository, usiendeshe fork pull requests juu yake, usiache kitu kingine kwenye server hiyo, na ichukulie machine hiyo kuwa ya kutupwa.

Docker jobs, na kundi ambalo kwa kweli ni root

Container jobs, service containers na hatua yoyote ya workflow inayotumia docker build inahitaji Docker daemon kwenye host ya runner. Sakinisha Docker kwa njia ya kawaida, kama ilivyoelezwa kwenye Docker na Docker Compose kwenye VPS, kisha ongeza mtumiaji wa runner kwenye kundi la docker.

Elewa athari kabla ya kufanya hivyo. Uanachama wa kundi la docker ni sawa na kuwa na root, kwa sababu container inaweza ku-mount / na kuendesha mchakato kama root ndani yake. Kwa hiyo, workflow inayoweza kuwasiliana na Docker socket inaweza kusoma na kuandika kila faili kwenye VPS, ikiwemo /etc/shadow. Kwenye repository ya faragha yenye wachangiaji wanaoaminika, hilo linaweza kuwa gharama inayokubalika. Kwingineko, huondoa maana ya kutumia mtumiaji asiye na privileges. Rootless Docker huweka builds za container ndani ya ruhusa za mtumiaji wa runner mwenyewe, ikiwa na vikwazo vya storage driver na networking; container capabilities hazitoi privileges juu ya host.

Masasisho na kuondoa runner kwa usafi

Self-hosted runner hujisasisha kwa chaguo-msingi. Hugundua release mpya, hubadilisha faili zake na kuwasha upya service, kwa hiyo kwa kawaida huhitaji kufanya chochote. Ili kuzima self-update, pitisha --disableupdate kwa ./config.sh unaposajili runner; kwa runner ambayo tayari imesajiliwa, hiyo inamaanisha kuisajili tena kwa flag hiyo. Hii haikuruhusu kubaki kwenye version moja milele. Documentation ya GitHub inaeleza wazi kwamba runner iliyosanidiwa kwa --disableupdate bado lazima isasishwe kwa mkono ndani ya siku 30 baada ya release mpya, la sivyo GitHub itaacha kuipangia jobs. Security update muhimu inaweza kusababisha jobs zisitungiwe foleni hadi usasishe, bila kusubiri muda huo wa mwisho.

Usasishaji wa mkono huhifadhi usajili, kwa sababu .runner na .credentials hazipo kwenye tarball. Simamisha service, pakua tarball mpya na uhakikishe checksum yake kama gharunner, extract juu ya directory hiyo hiyo kwa tar xzf, kisha uwashe service tena:

cd /home/gharunner/actions-runner
sudo ./svc.sh stop
sudo ./svc.sh start

Ili kuondoa runner, uninstall service kwanza, kisha iondoe kwenye usajili. Removal token inapatikana kwenye ukurasa huohuo wa Runners, chini ya kitufe cha Remove cha runner yenyewe.

cd /home/gharunner/actions-runner
sudo ./svc.sh stop
sudo ./svc.sh uninstall
sudo -iu gharunner
cd ~/actions-runner
./config.sh remove --token PASTE_REMOVAL_TOKEN_HERE

Kufuta directory bila kuiondoa runner kwenye usajili huiacha runner ikiwa imeorodheshwa kama Offline kwenye repository. Itaendelea kuonekana hadi admin abonyeze Force remove this runner, au hadi GitHub iondoe kiotomatiki baada ya siku 14 bila muunganisho.

Njia za kushindwa, pamoja na ujumbe utakaouona

Must not run with sudo. config.sh huchapisha ujumbe huu na kusimama inapoendeshwa kama root. Ukaguzi huu ni wa makusudi, kwa sababu faili zinazomilikiwa na root ndani ya _work huharibu kila kazi inayofuata inayotekelezwa kama mtumiaji wa huduma. Endesha ./config.sh kama gharunner. Kigezo cha RUNNER_ALLOW_RUNASROOT hupuuza ukaguzi huu, na kukitumia husogeza tu uharibifu huo mbele.

sudo: ./svc.sh: command not found. Upo kwenye saraka sahihi. svc.sh haipo bado, kwa sababu config.sh haijakamilisha usajili. Sajili runner, kisha usakinishe huduma.

Http response code: NotFound from 'POST https://api.github.com/actions/runner-registration'. Kwa kawaida token si token halali ya usajili. Aidha muda wake umekwisha, kwa kuwa hudumu kwa saa moja, au personal access token iliwekwa badala ya token ya usajili kutoka ukurasa wa Runners. Tengeneza token mpya na uiweke tena, kisha uhakikishe kuwa --url ni URL kamili ya hazina (repository).

Dependencies is missing for Dotnet Core 6.0. Endesha sudo ./bin/installdependencies.sh kutoka kwenye saraka ya runner kama root, kisha sajili tena.

Runner iko Offline baada ya reboot. Endesha systemctl is-enabled 'actions.runner.*'. Ikiwa hakuna kinachoonekana, ./svc.sh install haikuwahi kuendeshwa, kwa hivyo runner ilikuwepo tu ndani ya session yako ya terminal. Ikiwa unit imewezeshwa na runner bado iko Offline, soma journalctl -u 'actions.runner.*' na uangalie mawasiliano ya HTTPS ya kutoka nje.

Diski inajaa. Checkouts, akiba za build (build caches) na Docker images hujilimbikiza chini ya _work na kwenye home ya mtumiaji wa runner, na hakuna kinachozisafisha kwa ajili yako. Fuatilia du -sh /home/gharunner/actions-runner/_work na uongeze utaratibu wa kusafisha uliopangwa kabla ya diski kuamua kwa ajili yako.

FAQ

Kwa nini sudo ./svc.sh install inasema command not found?

Kwa sababu svc.sh haipo kwenye tarball ya runner. Inatengenezwa ndani ya saraka ya runner wakati ./config.sh inapomaliza kujiandikisha, ikitumia jina la hazina (repository) yako na jina la runner ili kuunda jina la huduma. Endesha ./config.sh kama mtumiaji wa runner kwanza. Baada ya hapo, sudo ./svc.sh install gharunner itapata hati hiyo na kuandika unit inayoitwa actions.runner.OWNER-REPO.RUNNER-NAME.service ndani ya /etc/systemd/system.

Je, ninahitaji kufungua port ya firewall kwa ajili ya self-hosted runner?

Hapana. Runner hufungua muunganisho wa HTTPS wa kutoka (outbound) kuelekea GitHub na kuushikilia ukiwa wazi wakati inasubiri kazi, kwa hivyo GitHub haiwahi kuanzisha muunganisho kuelekea VPS yako. Ruhusu trafiki ya kutoka kwenye port 443 na uache sheria zako za kuingia (inbound) zikiwa zimefungwa. Ikiwa runner inaonyesha Offline wakati huduma yake ikiwa inaendeshwa, angalia uchujaji wa trafiki ya kutoka na DNS badala ya sheria za kuingia.

Je, ninaweza kutumia self-hosted runner kwenye hazina ya umma (public repository)?

Unaweza, lakini GitHub inashauri kutofanya hivyo. Pull request kutoka kwa fork hubeba faili yake ya workflow, kwa hivyo mtu yeyote anayeweza kufanya fork ya hazina yako anaweza kupendekeza amri zinazoendeshwa kwenye mashine yako. Kidokezo cha idhini (approval prompt) chaguo-msingi hufunika tu wachangiaji ambao hawajawahi kuwa na commit au pull request iliyounganishwa kwenye hazina hiyo. Ikiwa utaunganisha runner kwenye hazina ya umma, zima workflows za fork pull request juu yake, usiweke kitu kingine chochote kwenye seva hiyo, na ujenge upya mashine hiyo kwa ratiba.

Kwa nini usajili unashindwa na Http response code: NotFound?

Wito wa usajili hujibu NotFound wakati kitambulisho (credential) si sahihi, si tu wakati URL si sahihi, jambo linalofanya ujumbe huo kupotosha. Tokeni za usajili huisha muda wake saa moja baada ya kuonyeshwa, na personal access token haikubaliwi kwa wito huu. Fungua Settings, Actions, Runners, New self-hosted runner tena, nakili tokeni mpya, na uthibitishe kuwa thamani ya --url inaelekeza kwenye hazina ambapo una haki za msimamizi (admin).

Je, makala hii ilikusaidia?

#github-actions#ci#self-hosted#runner#ubuntu-24-04