はじめに
「GitHub Actionsって、CIでテストを回したりビルドしたりするやつでしょ?」
そう思っていたのですが、あるリポジトリを見つけて衝撃を受けました。GitHub Actionsのランナー上に、まるごとGNOMEデスクトップ環境を起動して、ブラウザからリモート操作できてしまうというものです。
今回はこのワークフローの中身を実際に読み解きながら、「そもそもどういう仕組みで動いているのか」「本当に動かせるのか」を検証してみました。
使ったのはこちらのリポジトリです。
リポジトリの説明には「⚠️This project is intended for testing and verification purposes only.⚠️(このプロジェクトは検証・テスト目的のみを想定しています)」という注意書きがあります。ネタとして面白い反面、扱いには注意が必要な内容なので、その点も含めて紹介します。
検証対象のワークフロー
対象は .github/workflows/ubuntu-gnome.yml です。全体はこんな構成になっています。
name: Ubuntu GNOME
on:
workflow_dispatch:
jobs:
ubuntu-gnome:
runs-on: ubuntu-latest
steps:
- name: Install GNOME
run: |
set -euo pipefail
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
dbus-x11 \
fonts-noto-cjk \
gnome-shell \
gnome-terminal \
libpulse0 \
libva-drm2 \
libva-wayland2 \
libva-x11-2 \
pulseaudio \
pulseaudio-utils \
xvfb
- name: Install Selkies
run: |
set -euo pipefail
git clone https://github.com/selkies-project/selkies.git "$RUNNER_TEMP/selkies"
cd "$RUNNER_TEMP/selkies"
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install \
https://github.com/selkies-project/pixelflux/releases/download/f8cda2e/pixelflux-2.1.0-cp312-cp312-manylinux_2_28_x86_64.whl \
https://github.com/selkies-project/pcmflux/releases/download/a489f79/pcmflux-2.1.0-cp312-cp312-manylinux_2_28_x86_64.whl
./scripts/ci/build-web.sh
.venv/bin/python -m pip install -e .
- name: Start GNOME, Selkies
run: |
set -euo pipefail
cd "$RUNNER_TEMP/selkies"
Xvfb :99 -screen 0 1920x1080x24 > "$RUNNER_TEMP/xvfb.log" 2>&1 &
pulseaudio --start --exit-idle-time=-1
nohup env DISPLAY=:99 \
XDG_CURRENT_DESKTOP=GNOME \
XDG_SESSION_DESKTOP=gnome \
XDG_SESSION_TYPE=x11 \
dbus-run-session -- gnome-shell --x11 > "$RUNNER_TEMP/gnome-shell.log" 2>&1 &
nohup env DISPLAY=:99 \
XDG_CURRENT_DESKTOP=GNOME \
XDG_SESSION_DESKTOP=gnome \
XDG_SESSION_TYPE=x11 \
dbus-run-session -- "$PWD/.venv/bin/selkies" \
--enable-basic-auth=false > "$RUNNER_TEMP/selkies.log" 2>&1 &
sudo sed -i 's/^Prompt=.*$/Prompt=never/' /etc/update-manager/release-upgrades
gsettings set org.gnome.desktop.background picture-uri 'file:///usr/share/backgrounds/ubuntu-wallpaper-d.png'
gsettings set org.gnome.desktop.background picture-uri-dark 'file:///usr/share/backgrounds/ubuntu-wallpaper-d.png'
gsettings set org.gnome.desktop.lockdown disable-lock-screen true
gsettings set org.gnome.desktop.screensaver lock-enabled false
gsettings set org.gnome.desktop.screensaver idle-activation-enabled false
gsettings set org.gnome.desktop.session idle-delay 0
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing'
- name: Desktop URL https://<random-subdomain>.trycloudflare.com / Stop with curl x or x/ in Address Bar
run: |
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb >/dev/null 2>&1
echo "<?php passthru('pkill cloudflared');" > index.php
sudo nohup php -S 0.0.0.0:80 2>/dev/null &
cloudflared tunnel --url http://localhost:8080
やっていることは大きく4ステップです。
-
GNOMEのインストール —
gnome-shellとgnome-terminal、音声まわりのライブラリなどをaptで入れる - Selkiesのインストール — WebRTCベースでデスクトップ画面をブラウザにストリーミングするOSSプロジェクト。クラウドゲーミングやリモートデスクトップの分野で使われている技術です
-
仮想ディスプレイ上でGNOMEとSelkiesを起動 —
Xvfb(X Virtual Framebuffer)でヘッドレスな仮想ディスプレイを作り、その上でgnome-shellをX11モードで起動。同じディスプレイをSelkiesがキャプチャしてブラウザへ配信する -
cloudflaredの一時トンネルで外部公開 —
cloudflare tunnel --urlを認証なしで実行すると、https://<ランダムな文字列>.trycloudflare.comというURLが自動発行され、GitHub Actionsのランナー内で起動しているサービスにインターネット経由でアクセスできるようになる
つまり「CIランナーの中に一時的なデスクトップ環境を作り、それをQuick Tunnelで外の世界に橋渡しする」というのがこのワークフローの正体です。GitHub ActionsのUbuntuランナーはDockerコンテナではなくフルのVMなので、GUIアプリを含めてかなり自由度高くソフトウェアをインストールできる、という前提を逆手に取ったアイデアだと言えます。
実際に試す手順
自分の環境で検証したい場合は、次の流れになります。
- リポジトリを自分のGitHubアカウントにフォークする
- フォーク先の Actions タブを開き、ワークフローの実行を有効化する
- 「Ubuntu GNOME」ワークフローを選択し、
workflow_dispatchから Run workflow を押す - 実行中のジョブのログを開き、最後のステップ(
cloudflared tunnel)の出力を確認する - ログに表示される
https://xxxxxxxx.trycloudflare.comのURLをブラウザで開く - Selkiesの画面が表示されたら、その中でGNOMEデスクトップが操作できる
ログに出るURLはジョブが起動するたびに変わるランダムなサブドメインです。ジョブが終了(あるいはタイムアウト)するとトンネルごと消えるため、常時使えるサーバーにはなりません。
触ってみて気づいたポイント
- ブラウザ越しの操作なのでレイテンシはそれなりにあります。快適な操作感というより「ちゃんとGUIが動いている」ことを確認する用途向けです
- GitHub Actionsのジョブには最大実行時間の制限があるため、デスクトップを使えるのはその時間内だけです。長時間の作業用途には向きません
- ジョブが終わればランナーごと破棄されるので、保存したファイルや設定はすべて消えます。あくまで使い捨ての検証環境です
注意しておきたいこと
面白い検証ではあるものの、実運用や常用を考える前に押さえておきたい点がいくつかあります。
-
認証なしで公開される:
--enable-basic-auth=falseの指定により、Selkiesのデスクトップ画面は認証なしでインターネットに公開されます。URLの推測しにくさだけが頼りの状態なので、機密情報を扱う用途には不向きです。停止したい場合はワークフロー内のコメントにもある通り、アドレスバーでxやx/にアクセスすることでcloudflaredのプロセスを止める仕組みが用意されています - GitHub Actionsは本来CI/CD用のサービス: 常時起動のデスクトップ環境やホスティング用途として使い続けることは、GitHubの利用規約・Acceptable Use Policiesの想定外になる可能性があります。あくまで一時的な検証・学習目的にとどめるのが安全です
- フォーク元のREADMEにも明記されている通り「testing and verification purposes only」: 本格的なリモートデスクトップ環境が欲しい場合は、素直にクラウドのVMサービスなどを使うのが筋です
まとめ
GitHub ActionsのUbuntuランナーはただのCI実行環境ではなく、実質フルスペックのLinux VMです。そこにGNOMEとSelkies、cloudflaredのQuick Tunnelを組み合わせることで、「CI環境の中に一時的なリモートデスクトップを作る」という、なかなかパンチの効いた使い方が実現できることが分かりました。
実用性よりも「そんなことまでできるのか」という発見が面白いタイプのハックです。試す際は、この記事で紹介した注意点(認証なし公開・利用規約・データの揮発性)を踏まえた上で、自己責任かつ検証目的の範囲で楽しんでみてください。
