ローカル Docker 環境 で runs-on: self-hosted

runs-onself-hostedを選択すると、自身のマシンでワークフローを実行させれます。その為には先に自身のマシンで環境構築が必要です。
マシンには自分のマシン環境そのままを使っても良いですが、ここではあまり環境を汚したくない為 Docker 上で起動した Ubuntu の上で環境構築します。

とりあえず構築前に以下で Ubuntu を建てます。

docker run -itd \
  --name self-hosted-runner \
  --env WORKING_DIR=/home/runner/actions-runner
  ubuntu

次で ID が表示されれば建てれてます。

docker ps --filter name=self-hosted-runner --quiet

依存インストール

Docker の Ubuntu は最小環境らしくcurlが無いのでインストールします。

docker exec -it self-hosted-runner \
  sh -c 'apt update && apt install curl --yes'

ユーザーを作る

マシンはいつワークフローが実行されても大丈夫なように、(GitHub 提供の).shを実行して待機状態にしておく必要がありますが、この.shはスーパーユーザー権限だと実行できません。

そのため以下でユーザーrunnerを作り、このユーザーでその.shを実行させます。

docker exec -it self-hosted-runner \
  sh -c 'useradd runner -m && echo runner:secret | chpasswd'

最初のユーザーなので恐らく UID が1000runnerが作られたはずです。その為今後は、

docker exec --user 1000 -it self-hosted-runner sh -c '...'

として実行した...runnerユーザーによって行われるコマンドになります。

依存ファイルのインストール

これは適当なリポジトリの

  1. Settings
  2. Actions
  3. Add runner

で開くダイアログに載っているコマンドを叩くだけです。

docker exec --user 1000 -it self-hosted-runner sh -c '
  mkdir -p $WORKING_DIR && \
  cd $WORKING_DIR && \
  curl -O -L https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-x64-2.164.0.tar.gz && \
  tar xzf ./actions-runner-linux-x64-2.164.0.tar.gz
'

そしてダイアログに示されてる次の./config.shから始まるコマンドを実行すると以下のメッセージが出ます。

Libicu's dependencies is missing for Dotnet Core 3.0
Execute ./bin/installdependencies.sh to install any missing Dotnet Core 3.0 dependencies.

また「欲しいツールが入ってないので、./bin/installdependencies.shを実行してインストールしてね」という感じのことを言ってるので./bin/installdependencies.shスーパーユーザーで叩きます。

docker exec -it self-hosted-runner \
  sh -c 'cd $WORKING_DIR && ./bin/installdependencies.sh'

再度runnerユーザーで./config.sh ...を叩きます。これもコピペで良いです。注意点として、一定時間が経過するとトークンが期限切れになるようなので、その場合は再度ダイアログを開き直して再生成してください。

docker exec --user runner -it self-hosted-runner \
  sh -c 'cd $WORKING_DIR && ./config.sh --url https://github.com/<owner>/<repo> --token <token>'

いくつか聞かれるものがありますが、それもデフォルト値が入ってるので変えたいものがあれば変えます。試しに以下のようにしてみました。

# self-hosted runner の名前
Enter the name of runner: [press Enter for 06332a3d575d] my-runner
# ...
#
# ワークフローを実行する際にいるフォルダ名
Enter name of work folder: [press Enter for _work]
# ...

うまくいくと Settings → Actions の Self-hosted runners へこのように runner が追加されます。

待ち受け状態にする

最後のコマンドを実行します。このコマンドで GitHub runner として接続され、ctrl-cを叩くまで実行されます。また、マシンの通信などが切れた場合は終了せず、自動で再接続を試みてくれるようです。

docker exec --user runner -it self-hosted-runner \
  sh -c 'cd $WORKING_DIR && ./run.sh'

すると先程はオフラインだった runner がアイドル状態になります。

最後にこの状態でgit pushなどを行った時に実行状態のターミナル画面にワークフローのログが現れればうまくいってます。こま### Docker 化

以下のようなDockerfileで Image 化すればdocker run -it --rm <image-name>だけで簡単にアイドル状態にできます。

FROM ubuntu:bionic

RUN apt update && apt install language-pack-ja sudo curl --yes

ENV TZ Asia/Tokyo
ENV LANG ja_JP.UTF-8

RUN useradd runner -m && \
  echo runner:secret | chpasswd && \
  usermod -aG sudo runner

USER runner
WORKDIR /home/runner

RUN mkdir actions-runner && cd actions-runner
RUN curl -O -L https://github.com/actions/runner/releases/download/v2.164.0/actions-runner-linux-x64-2.164.0.tar.gz
RUN tar xzf ./actions-runner-linux-x64-2.164.0.tar.gz

USER root

RUN ./bin/installdependencies.sh

USER runner

RUN ./config.sh --url https://github.com/nju33/github-actions-self-hosted-runner --token ADZKC3TA36BF3Y6VR7K7CPC6FZGMY

CMD [ "./run.sh" ]