Ubuntu 24.04-এ self-hosted GitHub Actions runner সেটআপ
Ubuntu 24.04 VPS-এ GitHub Actions runner সেটআপ করার নিয়ম জানুন। dedicated user তৈরি, checksum যাচাই, config.sh কনফিগারেশন এবং systemd service হিসেবে রান করার পূর্ণ গাইড।
একটি self-hosted GitHub Actions runner যা করে
একটি self-hosted GitHub Actions runner হলো এমন একটি প্রোগ্রাম যা আপনি আপনার নিজস্ব VPS-এ ইনস্টল করেন। এটি GitHub-এর কাছে কাজের (jobs) অনুরোধ পাঠায় এবং আপনার হার্ডওয়্যারে সেগুলো সম্পাদন করে। আপনি এটিকে একটি রিপোজিটরির সাথে রেজিস্টার করেন, systemd service হিসেবে ইনস্টল করেন এবং প্রতিটি reboot-এর পর এটি স্বয়ংক্রিয়ভাবে চালু হয়। GitHub কাজের সময়সূচী নির্ধারণ করে, আর আপনার সার্ভার সেই কাজ সম্পন্ন করে।
আপনার নিজস্ব মেশিনে CI (continuous integration) ব্যবহার করার দুটি সুবিধা রয়েছে। প্রথমত, build minutes-এর জন্য কোনো চার্জ কাটে না। দ্বিতীয়ত, একটি job এমন সব রিসোর্স অ্যাক্সেস করতে পারে যা শুধুমাত্র আপনার মেশিনে আছে, যেমন warm build cache বা কোনো private network। এর বিনিময়ে আপনাকে নিরাপত্তার বিষয়টি মাথায় রাখতে হবে। runner আপনার দেওয়া ব্যবহারকারীর অনুমতি নিয়ে workflow ফাইলে যা লেখা থাকে ঠিক তাই সম্পাদন করে, তাই workflow ফাইলটি মূলত ডিজাইন অনুযায়ীই remote code execution। একটি private রিপোজিটরিতে, যাদের workflow চালানোর অনুমতি আছে তাদের অবশ্যই বিশ্বস্ত হতে হবে; এর মধ্যে এমন ব্যক্তিরাও অন্তর্ভুক্ত যারা fork pull request জমা দিতে পারে যা runner-এ রান করবে। public রিপোজিটরির ক্ষেত্রে এটি একটি বড় ঝুঁকি, এবং fork pull request সংক্রান্ত সেকশনে এর কার্যপদ্ধতি ব্যাখ্যা করা হয়েছে।
নিচের সবকিছু Ubuntu 24.04 এবং runner version 2.338.0-এর জন্য প্রযোজ্য, যা 12 অক্টোবর 2026 তারিখ অনুযায়ী বর্তমান রিলিজ। 4 নভেম্বর 2026 তারিখ অনুযায়ী GitHub-এর সর্বশেষ রিলিজ হলো 2.338.2; তবে নিচের কমান্ড এবং checksum 2.338.0 ভার্সনের জন্যই নির্দিষ্ট রাখা হয়েছে।
শুরু করার আগে আপনার যা প্রয়োজন
একটি VPS থেকে শুরু করুন যেখানে একটি সাধারণ অ্যাডমিন অ্যাকাউন্ট এবং sudo সুবিধা রয়েছে, যা আপনি একটি নতুন VPS-এ প্রথম দশ মিনিট-এর মাধ্যমে অর্জন করেন। আপনাকে কোনো ইনবাউন্ড পোর্ট খোলার প্রয়োজন নেই। রানার GitHub-এর সাথে একটি আউটবাউন্ড HTTPS (hypertext transfer protocol secure) সংযোগ খোলে এবং কাজের অপেক্ষায় থাকার সময় তা খোলা রাখে, তাই GitHub কখনোই সরাসরি আপনার সার্ভারের সাথে সংযোগ স্থাপন করে না। আপনার ফায়ারওয়াল বাইরের জগতের জন্য বন্ধ থাকলেও কাজগুলো সার্ভারে পৌঁছাবে।
আপনার রিপোজিটরিতে অ্যাডমিন অধিকারও থাকা প্রয়োজন, কারণ রেজিস্ট্রেশন টোকেনটি রিপোজিটরির সেটিংসে প্রদর্শিত হয়।
রানারের জন্য একটি ডেডিকেটেড ইউজার তৈরি করুন
কখনও root হিসেবে বা আপনার নিজস্ব অ্যাডমিন ইউজার হিসেবে রানার চালাবেন না। প্রতিটি জব রানার ইউজারের অধিকার উত্তরাধিকারসূত্রে পায়, তাই যে ওয়ার্কফ্লো sudo কল করে তা সফল হবে যদি রানার ইউজার sudo ব্যবহার করতে পারে। এমন একজন আনপ্রিভিলেজড ইউজার তৈরি করুন যার নিজের হোম ডিরেক্টরি ছাড়া আর কিছুর মালিকানা নেই। VPS-এ ন্যূনতম প্রিভিলেজড ইউজার অ্যাকাউন্ট সাধারণ নিয়মটি কভার করে। এখানে নির্দিষ্ট নিয়মটি দেওয়া হলো।
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-runnerpasswd -l পাসওয়ার্ড লক করে দেয়, তাই কেউ পাসওয়ার্ড দিয়ে gharunner হিসেবে লগ ইন করতে পারবে না। রানার ডিরেক্টরিতে 700 মোড গুরুত্বপূর্ণ কারণ রানার সেখানে তার ক্রেডেনশিয়ালগুলো প্লেইনটেক্সটে সংরক্ষণ করে এবং চেকআউটে প্রাইভেট সোর্স থাকতে পারে।
সামনে এগিয়ে যাওয়ার আগে উভয় বৈশিষ্ট্য যাচাই করুন:
sudo passwd -S gharunner
sudo -l -U gharunnerpasswd -S একটি লাইন প্রিন্ট করে যা gharunner L দিয়ে শুরু হয়, যেখানে L মানে পাসওয়ার্ড লক করা আছে। sudo -l -U gharunner এর উত্তরে is not allowed to run sudo আসা উচিত। যদি এটি পরিবর্তে অনুমোদিত কমান্ডের একটি তালিকা প্রিন্ট করে, তবে অ্যাকাউন্টটি একটি sudo গ্রুপে আছে এবং আপনি যে আইসোলেশন তৈরি করেছেন তা নষ্ট হয়ে গেছে।
Runner ডাউনলোড করুন এবং tarball যাচাই করুন
এখন থেকে runner user হিসেবে কাজ করুন।
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"Architecture সম্পর্কে নিশ্চিত না হলে আগে uname -m চালান। x86_64 উপরের linux-x64 ফাইলটি নেয়। aarch64 নেয় actions-runner-linux-arm64-${RUNNER_VERSION}.tar.gz।
এখন ডাউনলোড করা ফাইলটি যাচাই করুন। নিচের SHA256 (secure hash algorithm, 256 bit) মানটি 2.338.0 x64 tarball-এর জন্য। GitHub release page এবং New self-hosted runner screen-এ বর্তমান release-এর মান দেখায়। প্রতিটি version-এ এটি পরিবর্তিত হয়। তাই অন্য version install করার সময় সেখান থেকে মানটি কপি করুন।
echo "af4b794c1bc41d73d40535e3fe092a39f9679cd8d965954c2aca25a05ca41d32 actions-runner-linux-x64-2.338.0.tar.gz" | sha256sum -cডাউনলোড সঠিক হলে একটি লাইন দেখাবে:
actions-runner-linux-x64-2.338.0.tar.gz: OKফাইল অসম্পূর্ণ বা পরিবর্তিত হলে ব্যর্থতার বার্তা এবং একটি সতর্কতা দেখাবে:
actions-runner-linux-x64-2.338.0.tar.gz: FAILED
sha256sum: WARNING: 1 computed checksum did NOT matchএই যাচাই বাদ দিয়ে সমস্যাটি tar-এর মাধ্যমে খুঁজে বের করার ওপর নির্ভর করবেন না। অর্ধেক লেখা archive gzip: stdin: unexpected end of file এবং tar: Unexpected EOF in archive-এ ব্যর্থ হয়। এতে বোঝা যায় যে ফাইলটি নষ্ট, কিন্তু এটি অসম্পূর্ণ ছিল নাকি প্রতিস্থাপিত হয়েছে তা বোঝা যায় না।
tar xzf ./actions-runner-linux-x64-2.338.0.tar.gz
lsটারবলটিতে কী থাকে এবং কী থাকে না
এক্সট্রাকশনের পর ডিরেক্টরিটিতে config.sh, run.sh, env.sh, safe_sleep.sh, bin/ এবং externals/ থাকে। bin/-এ রানার বাইনারি এবং bin/installdependencies.sh থাকে। externals/-এ বান্ডেল করা Node রানটাইম থাকে, যার ওপর JavaScript অ্যাকশনগুলো কার্যকর হয়।
এখনও কোনো svc.sh নেই। GitHub-এর ডকুমেন্টেশনে এটিকে সেই স্ক্রিপ্ট হিসেবে বর্ণনা করা হয়েছে "যা রানার সফলভাবে যোগ করার পর তৈরি হয়", কারণ এটি একটি টেমপ্লেট থেকে লেখা হয় যেখানে আপনার রিপোজিটরি এবং রানারের নাম সার্ভিস নামের সাথে যুক্ত থাকে। তাই ./config.sh-এর আগে sudo ./svc.sh install চালালে তা sudo: ./svc.sh: command not found ত্রুটির কারণে ব্যর্থ হয়। প্রথমে রেজিস্টার করুন, তারপর সার্ভিসটি ইনস্টল করুন।
রানার ডিপেন্ডেন্সি ইনস্টল করা
রানার একটি .NET অ্যাপ্লিকেশন, তাই এর জন্য কিছু শেয়ার্ড লাইব্রেরি প্রয়োজন। রানার ইউজারের শেল থেকে বেরিয়ে আসুন এবং sudo ব্যবহার করে এগুলো ইনস্টল করুন, কারণ স্ক্রিপ্টটি সিস্টেম প্যাকেজ ডেটাবেসে রাইট করে।
exit
cd /home/gharunner/actions-runner
sudo ./bin/installdependencies.shUbuntu 24.04-এ এটি libkrb5-3, zlib1g, liblttng-ust1t64, libssl3t64 এবং libicu74 প্যাকেজগুলো নিয়ে আসে। স্ক্রিপ্টটি প্রতিটি লাইব্রেরির জন্য বেশ কয়েকটি ভার্সন নাম পরীক্ষা করে এবং আপনার রিলিজে যে ভার্সনটি আছে সেটিই রাখে; এই কারণেই একই স্ক্রিপ্ট পুরনো Ubuntu এবং Debian-এ কাজ করে।
যদি ldd দিয়ে চেক করা কোনো লাইব্রেরি অনুপস্থিত থাকে, তবে রানার শুরু করার আগেই ./config.sh থেমে যায়:
Dependencies is missing for Dotnet Core 6.0
Execute sudo ./bin/installdependencies.sh to install any missing Dotnet Core 6.0 dependencies.একটি অনুপস্থিত libicu একই পরামর্শ দেয়, তবে প্রথম লাইনটি ভিন্ন হয়, যা হলো Libicu's dependencies is missing for Dotnet Core 6.0। উভয়ই একই জায়গা থেকে আসে: config.sh রানার শুরু হওয়ার আগে ldd দিয়ে বান্ডেল করা লাইব্রেরিগুলো এবং libicu দিয়ে ldconfig চেক করে। ফলে কোনো unresolved link থাকলে তা পরে বিভ্রান্তিকর ক্র্যাশ তৈরি না করে স্ক্রিপ্টটিকে শুরুতেই থামিয়ে দেয়। এই চেকগুলো ইনস্টলারের তালিকায় থাকা প্রতিটি প্যাকেজ কভার করে না। অনুপস্থিত liblttng-ust1t64 এই চেকগুলোকে ট্রিগার করে না: .NET ঐচ্ছিকভাবে LTTng ট্রেসিং লোড করে এবং ট্রেসিং ডিপেন্ডেন্সিগুলো পাওয়া না গেলেও কাজ চালিয়ে যায়।
রানারকে আপনার repository-র সঙ্গে নিবন্ধন করুন
repository থেকে একটি token নিন। Settings খুলুন, তারপর Actions, এরপর Runners এবং শেষে New self-hosted runner নির্বাচন করুন। পৃষ্ঠায় একটি registration token দেখা যাবে। এটি তৈরি হওয়ার এক ঘণ্টা পরে মেয়াদ শেষ হয়। তাই token paste করার জন্য প্রস্তুত হওয়ার পর এটি তৈরি করুন।
runner user হিসেবে নিবন্ধন করুন। config.sh 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এই flag-গুলো যা করে। --name নির্ধারণ করে repository-তে runner-টি কী নামে দেখা যাবে। তাই ছয় মাস পরেও চিনতে পারবেন এমন একটি নাম বেছে নিন। --labels আপনার নিজস্ব label যোগ করে। runner-এ কোনো অতিরিক্ত পদক্ষেপ ছাড়াই self-hosted, Linux এবং X64 আগে থেকেই থাকে। --work checkout-এর ফাইল কোথায় থাকবে তা নির্ধারণ করে; এটি runner directory-র ভেতরের একটি directory। --unattended interactive prompt-গুলোর default উত্তর গ্রহণ করে। command-টি script-এর মধ্যে থাকলে এটিই প্রয়োজন। --replace একই নামের বিদ্যমান registration-এর দায়িত্ব নেয়, তাই command ব্যর্থ হয় না। server পুনর্নির্মাণের সময় এটিই প্রয়োজন।
সফলভাবে চালালে শেষে এই লাইনগুলো দেখা যাবে:
√ Runner successfully added
√ Runner connection is good
√ Settings Saved.এখন registration-সংক্রান্ত তথ্য runner directory-তে .runner, .credentials এবং .credentials_rsaparams হিসেবে সংরক্ষিত থাকে। শেষের দুটি GitHub-এর কাছে এই runner-কে শনাক্ত করে। তাই এগুলো পড়তে পারে এমন যে কেউ runner-টির ছদ্মবেশ নিতে পারে। এই কারণেই directory-টির mode 700 এবং user-এর sudo সুবিধা নেই।
systemd সার্ভিস হিসেবে রানার ইনস্টল করা
টার্মিনালে ./run.sh চালানো একটি পরীক্ষার জন্য ঠিক আছে, কিন্তু আপনার SSH সেশন বন্ধ হয়ে গেলে এটিও বন্ধ হয়ে যায়। সার্ভিসটি ইনস্টল করুন যাতে সিস্টেম বুট হওয়ার সময় রানার স্বয়ংক্রিয়ভাবে চালু হয়। VPS-এ systemd সার্ভিস এবং টাইমার অংশে ইউনিট ফাইলগুলো সম্পর্কে ব্যাখ্যা করা হয়েছে। এখানে svc.sh আপনার জন্য একটি ইউনিট ফাইল তৈরি করে দেবে।
exit
cd /home/gharunner/actions-runner
sudo ./svc.sh install gharunner
sudo ./svc.sh start
sudo ./svc.sh statussvc.sh চালানোর জন্য root অনুমতির প্রয়োজন হয়, কারণ এটি /etc/systemd/system ডিরেক্টরিতে একটি ইউনিট ফাইল লেখে এবং সেটি সক্রিয় করে। install-এর পরের আর্গুমেন্টটি হলো সেই ইউজার, যার অধীনে সার্ভিসটি চলবে। স্পষ্টভাবে gharunner পাস করুন। কোনো আর্গুমেন্ট না দিলে স্ক্রিপ্টটি ডিফল্টভাবে $SUDO_USER ব্যবহার করে, যা আপনার অ্যাডমিন অ্যাকাউন্ট। সেক্ষেত্রে প্রতিটি জব এমন একজন ইউজারের অধীনে চলবে যার sudo ব্যবহারের ক্ষমতা আছে।
ইউনিটটির নামকরণ করা হয় রিপোজিটরি এবং রানারের নামানুসারে, যা actions.runner.YOUR-USER-YOUR-REPO.vps-runner-1.service ফরম্যাটে থাকে। আপনাকে এটি টাইপ করার প্রয়োজন নেই:
systemctl list-units 'actions.runner.*'
sudo journalctl -u 'actions.runner.*' -n 20 --no-pagerএকটি সচল রানার √ Connected to GitHub লগ করে এবং এরপর একটি লাইন দেখায় যা Listening for Jobs দিয়ে শেষ হয়। রিপোজিটরির Runners পেজে এটিকে Idle হিসেবে দেখা যাবে। যদি রানার Offline দেখায়, তবে বুঝতে হবে এটি চলছে না অথবা 443 পোর্টে GitHub-এর সাথে সংযোগ স্থাপন করতে পারছে না।
রানার-এ একটি জব পাঠান
runs-on লেবেল ব্যবহার করে রানার নির্বাচন করে। self-hosted এর সাথে আপনার নিজস্ব লেবেল যোগ করুন, যাতে জবটি আপনার উদ্দেশ্যহীন কোনো রানারে না যায়।
name: build
on:
push:
branches: [main]
jobs:
build:
runs-on: [self-hosted, linux, vps]
steps:
- uses: actions/checkout@v5
- run: uname -aযদি জবটি Waiting for a runner to pick up this job এ অপেক্ষা করে, তবে নিশ্চিত করুন যে একটি সামঞ্জস্যপূর্ণ রানার অনলাইন এবং idle অবস্থায় আছে। runs-on এ থাকা প্রতিটি লেবেল অবশ্যই রানারে থাকতে হবে; একটি অতিরিক্ত শব্দ থাকলেও জবটি কিউতে থাকবে যতক্ষণ না একটি সঠিক রানার পাওয়া যায় অথবা 24 ঘণ্টা পর জবটি ব্যর্থ হবে। রিপোজিটরি সেটিংস-এ রানারের পাশে প্রদর্শিত লেবেলগুলোর সাথে আপনার তালিকার তুলনা করুন।
কেন self-hosted runner এবং public repository একসাথে ব্যবহার করা উচিত নয়
এটি এমন একটি অংশ যা মানুষ এড়িয়ে যায়। GitHub-এর নির্দেশনা স্পষ্ট: self-hosted runner "should almost never be used for public repositories" (public repository-র জন্য প্রায় কখনোই ব্যবহার করা উচিত নয়), এবং এগুলোর "running in ephemeral clean virtual machines-এর কোনো নিশ্চয়তা নেই, এবং workflow-এ থাকা untrusted code-এর মাধ্যমে এগুলো স্থায়ীভাবে compromised হতে পারে"।
এর কার্যপদ্ধতি সহজ। একটি fork থেকে আসা pull request তার নিজস্ব workflow file-এর কপি নিয়ে আসে। যদি আপনার public repository আপনার runner-এ pull request workflow চালায়, তবে যে কেউ repository-টি fork করে এমন একটি workflow প্রস্তাব করতে পারে যা আপনার VPS-এ তাদের কমান্ড চালাবে। তাদের কোনো write access-এর প্রয়োজন নেই, কারণ তারা যা প্রস্তাব করছে সেটিই রান করছে।
Approval setting এই ঝুঁকি কিছুটা কমায় কিন্তু পুরোপুরি দূর করে না। একটি public repository-র জন্য ডিফল্ট পলিসি অনুযায়ী, একজন maintainer-কে প্রথমবার অবদান রাখা কোনো contributor-এর fork workflow অনুমোদন করতে হয়। GitHub কাউকে শুধুমাত্র ততক্ষণই first-time contributor হিসেবে গণ্য করে যতক্ষণ না তাদের কোনো commit বা pull request repository-তে merge করা হয়। এরপর, তাদের পরবর্তী pull requestগুলো কোনো সতর্কতা ছাড়াই রান করে, এবং GitHub নিজেই সতর্ক করে যে একটি সাধারণ merge করা fix-ই এর জন্য যথেষ্ট। তাই এই গেটটি মূলত একজন মানুষের diff পড়ার ওপর নির্ভরশীল, এবং build script-এর গভীরে লুকিয়ে রাখা কোনো payload সহজে চোখ এড়িয়ে যেতে পারে।
একটি fork pull request আপনার secrets পায় না এবং এর GITHUB_TOKEN থাকে read-only। এটি GitHub-এর ভেতরে ক্ষতির পরিমাণ সীমিত করে। কিন্তু এটি আপনার সার্ভারের জন্য কোনো সুরক্ষা দেয় না। আক্রমণকারীর কাছে gharunner হিসেবে একটি shell থাকে, তাই তারা সেই user-এর পড়া সম্ভব এমন প্রতিটি ফাইল পড়তে পারে, VPS-এর private network-এ থাকা যেকোনো কিছুতে পৌঁছাতে পারে, এবং ~/.bashrc বা এমন কোনো user systemd unit-এ কিছু রেখে দিতে পারে যা পরবর্তী job-এর সময় রান করবে।
--ephemeral দিয়ে register করলে runner একটি job গ্রহণ করে এবং তারপর deregister হয়ে যায়; এটি সেই job-এর workspace মুছে ফেলে না। এটি শুধুমাত্র তখনই সাহায্য করে যদি প্রতিটি job-এর জন্য মেশিন বা container নতুন করে তৈরি করা হয়, কারণ runner user-এর home directory-তে লেখা কোনো backdoor নতুন registration-এর পরেও টিকে থাকে।
নিচের নিয়মগুলো সংক্ষিপ্ত। self-hosted runner private repository-র জন্য ব্যবহার করুন। যদি আপনাকে কোনো public repository-র সাথে এটি যুক্ত করতেই হয়, তবে এতে fork pull request চালাবেন না, সেই সার্ভারে অন্য কিছু রাখবেন না এবং মেশিনটিকে disposable বা ফেলে দেওয়ার যোগ্য হিসেবে বিবেচনা করুন।
Docker jobs এবং যে গ্রুপটি মূলত root
Container jobs, service containers এবং docker build কল করে এমন যেকোনো workflow step-এর জন্য runner host-এ একটি Docker daemon প্রয়োজন। সাধারণ নিয়মে Docker ইনস্টল করুন, যা Docker and Docker Compose on a VPS-এ আলোচনা করা হয়েছে, এরপর runner user-কে docker গ্রুপে যুক্ত করুন।
এটি করার আগে এর ঝুঁকিগুলো বুঝে নিন। docker গ্রুপের সদস্যপদ থাকা মানে root হওয়ার সমান, কারণ একটি container /-কে bind mount করতে পারে এবং এর ভেতরে root হিসেবে চলতে পারে। সুতরাং, যে workflow Docker socket-এর সাথে যোগাযোগ করতে পারে, সেটি /etc/shadow সহ VPS-এর প্রতিটি ফাইল পড়তে ও লিখতে পারে। বিশ্বস্ত কন্ট্রিবিউটরদের নিয়ে গঠিত private repository-র ক্ষেত্রে এটি মেনে নেওয়া যেতে পারে। অন্য যেকোনো ক্ষেত্রে এটি unprivileged user ব্যবহারের মূল উদ্দেশ্যকেই নষ্ট করে দেয়। Rootless Docker কন্টেইনার বিল্ডগুলোকে runner user-এর নিজস্ব অধিকারের মধ্যে সীমাবদ্ধ রাখে, যার সাথে storage driver এবং networking-এর সীমাবদ্ধতা থাকে; container capabilities হোস্টের ওপর কোনো বিশেষ সুবিধা প্রদান করে না।
আপডেট এবং রানার সঠিকভাবে মুছে ফেলা
একটি self-hosted runner ডিফল্টভাবে নিজেই আপডেট হয়। এটি নতুন কোনো release শনাক্ত করলে নিজের ফাইলগুলো প্রতিস্থাপন করে এবং service রিস্টার্ট করে, তাই সাধারণত আপনাকে কিছুই করতে হয় না। self-update বন্ধ করতে, রানার রেজিস্টার করার সময় ./config.sh-এর সাথে --disableupdate ফ্ল্যাগটি ব্যবহার করুন; ইতিমধ্যে রেজিস্টার করা রানারের ক্ষেত্রে, এর অর্থ হলো ফ্ল্যাগটিসহ পুনরায় রেজিস্টার করা। এটি আপনাকে অনির্দিষ্টকালের জন্য একটি ভার্সনে আটকে থাকতে দেবে না। GitHub-এর ডকুমেন্টেশনে স্পষ্টভাবে বলা আছে যে, --disableupdate দিয়ে কনফিগার করা রানারকেও নতুন release আসার 30 দিনের মধ্যে হাতে আপডেট করতে হবে, অন্যথায় GitHub এতে কোনো job queuing করবে না। কোনো গুরুত্বপূর্ণ security update-এর ক্ষেত্রে সেই সময়সীমার অপেক্ষা না করেই job queuing বন্ধ হয়ে যেতে পারে।
ম্যানুয়াল আপডেটের ক্ষেত্রে রানারের রেজিস্ট্রেশন অক্ষুণ্ণ থাকে, কারণ .runner এবং .credentials ফাইলগুলো tarball-এর মধ্যে থাকে না। service বন্ধ করুন, নতুন tarball ডাউনলোড করুন এবং gharunner দিয়ে checksum যাচাই করুন, এরপর tar xzf ব্যবহার করে একই ডিরেক্টরিতে তা extract করুন এবং সবশেষে service পুনরায় চালু করুন:
cd /home/gharunner/actions-runner
sudo ./svc.sh stop
sudo ./svc.sh startরানার মুছে ফেলার জন্য, প্রথমে service আনইনস্টল করুন, তারপর deregister করুন। removal token-টি একই Runners পেজ থেকে, রানারের নিজস্ব Remove বাটন থেকে পাওয়া যাবে।
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_HEREderegister না করে ডিরেক্টরি মুছে ফেললে রানারটি রিপোজিটরিতে Offline হিসেবে থেকে যায়। যতক্ষণ না কোনো অ্যাডমিন Force remove this runner বাটনে ক্লিক করেন, অথবা সংযোগ বিচ্ছিন্ন হওয়ার 14 দিন পর GitHub স্বয়ংক্রিয়ভাবে এটি সরিয়ে না নেয়, ততক্ষণ এটি সেখানেই থাকবে।
ব্যর্থতার ধরন এবং যে বার্তাগুলো দেখবেন
Must not run with sudo। root হিসেবে চালালে config.sh এই বার্তা দেখিয়ে বন্ধ হয়ে যায়। এই পরীক্ষা ইচ্ছাকৃত, কারণ _work-এ root-এর মালিকানাধীন ফাইল তৈরি হলে service user হিসেবে চলা পরবর্তী সব job ব্যর্থ হয়। ./config.sh হিসেবে gharunner চালান। RUNNER_ALLOW_RUNASROOT variable এই পরীক্ষা এড়িয়ে যায়, কিন্তু এটি ব্যবহার করলে শুধু ব্যর্থতা পরে ঘটে।
sudo: ./svc.sh: command not found। আপনি সঠিক directory-তে আছেন। svc.sh এখনো নেই, কারণ config.sh এখনো registration সম্পন্ন করেনি। Runner register করুন, তারপর service install করুন।
Http response code: NotFound from 'POST https://api.github.com/actions/runner-registration'। সাধারণত token-টি বৈধ registration token নয়। এটি এক ঘণ্টা পর মেয়াদোত্তীর্ণ হয়ে থাকতে পারে, অথবা Runners page-এর registration token-এর বদলে personal access token paste করা হয়েছে। নতুন token তৈরি করে আবার paste করুন। এছাড়া --url-এ সম্পূর্ণ repository URL আছে কি না যাচাই করুন।
Dependencies is missing for Dotnet Core 6.0। root হিসেবে runner directory থেকে sudo ./bin/installdependencies.sh চালান, তারপর আবার register করুন।
Reboot-এর পরে Runner Offline। systemctl is-enabled 'actions.runner.*' চালান। কিছু তালিকাভুক্ত না হলে ./svc.sh install কখনো চালানো হয়নি। তাই runner শুধু আপনার terminal session-এর মধ্যেই ছিল। unit enabled থাকা সত্ত্বেও runner যদি Offline থাকে, journalctl -u 'actions.runner.*' পড়ুন এবং outbound HTTPS পরীক্ষা করুন।
ডিস্ক পূর্ণ হয়ে যায়। checkout, build cache এবং Docker image _work-এর অধীনে ও runner user-এর home directory-তে জমতে থাকে; এগুলো আপনার হয়ে কেউ পরিষ্কার করে না। du -sh /home/gharunner/actions-runner/_work monitor করুন এবং disk নিজে সমস্যা তৈরি করার আগেই scheduled clean-up যোগ করুন।
FAQ
কেন sudo ./svc.sh install command not found দেখায়?
কারণ svc.sh runner tarball-এ নেই। ./config.sh registration সম্পন্ন করলে runner directory-তে এটি তৈরি হয়। তখন repository এবং runner name ব্যবহার করে service name তৈরি করা হয়। প্রথমে runner user হিসেবে ./config.sh চালান। এরপর sudo ./svc.sh install gharunner script-টি খুঁজে পাবে এবং actions.runner.OWNER-REPO.RUNNER-NAME.service নামের একটি unit /etc/systemd/system-এ লিখবে।
self-hosted runner-এর জন্য কি firewall port খুলতে হবে?
না। runner GitHub-এর সঙ্গে outbound HTTPS connection খোলে এবং job-এর জন্য অপেক্ষা করার সময় সেটি চালু রাখে। তাই GitHub কখনও আপনার VPS-এ connection শুরু করে না। outbound 443 অনুমোদন করুন এবং inbound rule বন্ধ রাখুন। service চলমান থাকা অবস্থায় runner যদি Offline দেখায়, inbound rule নয়, outbound filtering এবং DNS পরীক্ষা করুন।
public repository-তে কি self-hosted runner ব্যবহার করা যায়?
যায়, তবে GitHub এটি না করার পরামর্শ দেয়। কোনো fork থেকে আসা pull request-এ সেই fork-এর নিজস্ব workflow file থাকে। তাই আপনার repository fork করতে পারে এমন যে কেউ আপনার মেশিনে চলবে এমন command প্রস্তাব করতে পারে। Default approval prompt শুধু সেই contributor-দের ক্ষেত্রে প্রযোজ্য, যাদের কোনো commit বা pull request আগে repository-তে merge হয়নি। public repository-তে runner যুক্ত করলে fork pull request workflow নিষ্ক্রিয় করুন, ওই server-এ অন্য কোনো কাজ রাখবেন না, এবং নির্দিষ্ট সময় পরপর মেশিনটি rebuild করুন।
Http response code: NotFound সহ registration কেন ব্যর্থ হয়?
credential ভুল হলে registration call NotFound উত্তর দেয়। URL ভুল হলেই শুধু এটি ঘটে না। তাই message-টি বিভ্রান্তিকর। Registration token দেখানোর এক ঘণ্টা পর expire হয়। এই call-এর জন্য personal access token গ্রহণ করা হয় না। আবার Settings, Actions, Runners, New self-hosted runner খুলুন, নতুন token copy করুন, এবং নিশ্চিত করুন যে --url value এমন একটি repository-র দিকে নির্দেশ করছে যেখানে আপনার admin rights আছে।