EC2・Cloud9のUbuntuにDesktop (GUI) 環境を構築してVNCで接続する

# 本記事について

## 背景

**Androidタブレット上にLinux開発環境が欲しい。GUIも欲しい!!**

- 最近、11インチAndroidタブレットを買いました。喫茶店などで軽くコードを書いたりLinuxのお勉強をするだけならブラウザからアクセス出来るCloud9やGoogle Colabが使えます。が、GUIが絡むとやはり専用の環境が必要になってきます
- 以下のことを実現したいと思いました
    - Linuxマシンにアクセスしてターミナル操作、コーディングが出来る (リモートデスクトップ越しだとタイピングにストレスがあるので、エディタ類は独立したものが欲しい)
        - これはCloud9で実現
    - GUI操作が出来る
        - あまり複雑な操作はしない
        - 画面出力結果の確認やボタンをポチポチすることが出来ればよい
    - Androidからアクセスが出来る
        - ターミナルやsshは使わない
        - ブラウザやGoogle Playからインストールできるアプリだけで実現したい
- ↓の写真は、Androidタブレット (Xiaomi Pad 6) 上でChromeからCloud9に接続してコーディングやターミナル操作をしつつ、裏で表示しているRealVNCでGUI出力結果を確認しています

![PXL_20231123_122431941.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/371f6e36-23b4-f801-e71e-29aa5d87a4dd.jpeg)

## 本記事で説明することと他記事との差分

- Amazon EC2 インスタンスにGUIをインストールします
  - [公式](https://repost.aws/ja/knowledge-center/ec2-linux-2-install-gui)からも方法は公開されていますが、ここではいくつか異なる方法をとります
- Ubuntu 22.04を対象にxubuntu環境をインストールします
- VNCアクセスのためにポートを開放して、認証にはVNC用パスワードを使います
    - 公式だとSSHトンネルを使用しています
    - 本記事ではAndroidから簡単にアクセスすることを目的としているためです
- Cloud9用EC2にも適用してみます

## 注意

- ここで紹介する方法はセキュリティ的に堅牢ではないので注意してください
- パスワードが漏れたら第三者がログインできてしまいます
- 気になる場合は公式の手順と同様にSSHトンネルを使った方が多少は安全です
  - それでもキーが漏れてしまったら第三者がログインできてしまいますが

# 既存のEC2インスタンスにデスクトップ環境+VNCを構築する

## 前提

- Ubuntu 22.04のEC2インスタンスが既に存在する
    - sshターミナルやセッションマネージャーから何らかの操作ができる
    - インターネットに接続されておりパブリックIPv4アドレスを持つ (固定である必要はない)

## セキュリティグループの設定

- VNC用ポートのアクセスを受け付けるようにセキュリティグループの設定を変更する
- 対象とするEC2インスタンスに割り当てられているセキュリティグループを開く
- インバウンドルール -> インバウンドのルールを編集 -> ルールを追加、から以下を追加する
  - ポート範囲 = `5901`
      - (known portは使わない方が多少は安全かも)
  - ソース = `0.0.0.0/0`
      - (IP指定できるならした方が良い)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/e13db3f2-4ada-ce7b-427f-9683e67ec8b0.png)

## EC2の設定

- 下記コマンドでデスクトップ環境とVNCソフトのインストールと設定を行う
- VNC起動時の設定で `:1` としているため、ディスプレイ番号 = 1となる。またポート番号は5901 = 5900 + 1となる

```sh
# パスワード設定
sudo passwd ubuntu
## ubuntuユーザー用パスワードを入力する
sudo su -
passwd
## root用パスワードを入力する
## ctrl-dで戻る

# デスクトップ環境のインストール
sudo apt update
sudo apt install -y xubuntu-desktop
## lightdmを選ぶ

# VNCインストール
sudo apt install -y tigervnc-standalone-server
sudo apt install -y tigervnc-xorg-extension

# VNC設定
vncpasswd
## VNC用のパスワードを入力する
## Would you like to enter a view-only password (y/n)? n

echo "dbus-launch --exit-with-session xfce4-session" > ~/.vnc/xstartup
chmod 755 ~/.vnc/xstartup

# VNC起動
vncserver :1 -localhost no

# VNC関連コマンド (メモ)
vncserver :1 -localhost no -xstartup /usr/bin/xterm
vncserver :1 -localhost no -xstartup xfce4-session
vncserver --list
vncserver --kill :1
```

## 手元のクライアントPCから接続する

- EC2 インスタンスのパブリックIPv4アドレスを確認する
    - 例えば、`111.222.333.444` とする
- PC上で RealVNC Viewerなどを開き、新しい接続先に以下を設定する
    - `111.222.333.444::5901`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/6ca480e3-972d-67df-9676-ec6bad99d2d6.png)

# 新規のCloud9環境を作成し、デスクトップ環境+VNCを構築する

## Cloud9環境を作成する

- 設定
    - 環境タイプ = 新しいEC2インスタンス
    - インスタンスタイプ = any
        - 自分は少し重い処理をするのと、常時起動するわけではないので奮発してc5.xlargeにした
    - プラットフォーム = Ubuntu Server 22.04 LTS
    - ネットワーク設定 = AWS System Manager (SSM)
    - VPC設定 = デフォルト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/60ed12ec-b55c-8ee5-fa98-e2fc0d81eb83.png)

## Cloud9環境作成後の追加設定

### ボリュームサイズを増加

- 10 GiBのボリュームが作られるが足りないので64 GiB程度に増やす
    - 増やした後はインスタンスを再起動する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/230370ea-5527-01f7-344f-c824a8286d67.png)

### セキュリティグループの設定変更

- Cloud9用に作成されたEC2インスタンスに割り当てられているセキュリティグループを開く
- 上述の[セキュリティグループの設定変更](https://qiita.com/drafts/b7bdf1cfc0ba372bd695/edit#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%AE%E8%A8%AD%E5%AE%9A%E5%A4%89%E6%9B%B4) と同じ設定を行う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/438951cc-736f-c23d-5cd0-4269eebcf95e.png)

## EC2の設定

上述の[EC2の設定](https://qiita.com/article/b7bdf1cfc0ba372bd695/ec2%E3%81%AE%E8%A8%AD%E5%AE%9A)と同じ設定を行う

## 普段の操作

### VNCを起動するタイミング

セキュリティ的に不安なので、普段はCloud9上で作業を行い、必要なタイミングでのみVNCを起動する。不要になったらすぐに `vncserver --kill :1` する

### Cloud9コンソールからGUIアプリを起動する方法

- 事前にターミナル上で以下を打っておく
    - `export DISPLAY=:1`
    - (`~/.bashrc` に追記しておいてもいいかも)
- または、コマンドごとに指定する
    - `DISPLAY=:1 xeyes`
- もちろん、VNC (GUI) 上からターミナルを開いてコマンドを打ってもOK

### 作業風景

- 普段はChromeブラウザ上でCloud9でコードを書く
- 画面確認が必要になったら、VNCに切り替える
  - 下図はスマホのアプリ切り替え中の画面。Cloud9 (Chrome) でAutowareの設定と起動を行い、VNCで結果確認している
- または、ChromeブラウザとVNCアプリを2画面 or フローティングにする
    - 下図はタブレットの画面。VNCの上にChromeをフローティングで表示している
    - (AndroidのRealVNCアプリが2画面に対応していなかったのでフローティングで我慢)

![Screenshot_20231124-000439.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/3dd4ac7f-96e6-00f3-f741-555e63de4dfa.jpeg)

![Screenshot_2023-11-23-21-24-57-717_com.android.chrome.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214268/a18878a9-fa3e-eab7-67a2-cb8a6163d3cd.jpeg)

# その他

- 一度GUI操作が出来るようになったらChrome Remote Desktopをインストールして、VNC用ポートは閉じてしまうのも有りかもしれないです (未確認)
- 各種インストールと設定が完了した時点でAMIイメージを作成しておけば、環境を作り直す際に時間を節約できます
- 意図せずVNCを有効にしたくないので、本記事ではVNCサービス登録は行っていません。自動的にVNCを起動したい場合は[公式](https://repost.aws/ja/knowledge-center/ec2-linux-2-install-gui)を参考にしてください