CentOS7にGUI環境が欲しい
こんにちは戸田です.アドカレということで駆り出されました.
SSHとユーザー,localeが辛うじて設定された程度の(ほぼ)ミニマルインストール状態のCentOS7に,ある程度GUI操作できる環境を構築した話.
といってもDesktop丸々使うと重いので,ウィンドウ単位でX転送できるようにする.
前提
- CentOS7(VPS)
- CPU Xeon E3-1270 v5
- RAM 500MB
- SSH除き外部ネットワークからのアクセス不可(重要)
- 手元クライアントはWin機
タスク
細々としたブツのインストールは省略.
* 手元環境の整備
* X転送設定
* 日本語入力に対応
シェルが欲しい
取り敢えずシェルが欲しい.
commandPromptやpowerShellでは話にならぬ.
UTF-8もってこい.
というわけで先輩や同期に教えてもらいながら2つほど導入.
これでだいぶ楽になりました.
Bash on Ubuntu on Windows
実際シェル.
UbuntuのシステムコールをWindowsのそれにリアルタイムで変換してくれるらしい.
仕組みについてはこちらのサイトで分かりやすく解説してくださってたのでペタリ.
Windows で Ubuntu バイナリ(bash)が動作することの概略
- 「プログラムと機能」->「Windowsの機能の有効かまたは無効化」から,「Windows subsystem for Linux(Beta)」をインストール
- PCを再起動
- 「設定」から開発者モードを有効化
参考:Bash on Ubuntu on Windowsをインストールしてみよう!
この時Win機にSSHサーバとしての機能もインストールされるので,ファイアウォールで弾いておくとよさげ.
wsl-terminal
端末エミュレータの一種で,「wsl」と名に持つようにwsl環境(windows subsystem for linux)に合わせて作られたものとのこと.
めっちゃ使いやすい(語彙力がない).
こっちはexeで配布してくれてるのでDLするだけでよい.
SSH接続簡易化
公開鍵認証
このCent,VPSの為基本的に接続はSSHで行っている.
デフォルトだとSSH接続時の認証はプレーンパスワード方式で行われているが,毎回パスワードの入力求められて面倒くさい.
というわけでRSA鍵を生成・登録して手間を減らす.
- クライアント側で
ssh-keygen -t rsa
* -t rsa
で鍵のタイプを設定.今回はRSAを選択.
2. 求められるままにkeyの名前とパスワードを設定
* パスワードは空でもよいらしい.ここでは名前をhoge
として説明する.
3. hogeをクライアントの~/.ssh
に配置
4. hoge.pubをサーバーの~/.ssh/authorization_key
に統合(追記)
5. 設定されてない場合,~/.ssh
のパーミッションを700,~/.ssh/authorization_keys
のパーミッションを600に設定
* 適切にパーミッション設定しないとそもそもロードしてくれない
ショートカット(ssh_config)
クライアントの~/.ssh/config
には,SSH先を設定してエイリアスを貼ることができる.
## サーバーがhoge.jpだった時の例
Host hoge
HostName hoge.jp #Host名
ForwardX11 yes #後述するXの転送を許可
User overslept-dev #サーバーにおけるユーザ名
こんな感じに~./ssh/config
を書いて,ssh hoge
するとssh overslept-dev@hoge.jp -X
してくれる.
便利.
X転送設定
「X Window System」(別名:「X」「X11」,以下「X」)の設定を行う.
XはUnix系OSでウィンドウシステムを提供するプロトコルで,GUI構築には専らこれが使われる.
CentOSのGUIインストール時に入ってる「GNOME Desktop」なんかもこれの上で動いてるらしい.
デスクトップ丸ごと欲しいなら「GNOME Desktop」入れてやればいいんだけど,それじゃ重い.
サーバー側
上述のとおり,「X Window System」が欲しい.
CentOS7のyumだと標準でこいつをそのまま持ってこれるらしい.なので持ってくる.
sudo yum -y groupinstall "X Window System"
sudo yum -y install vlgothic-*
* 場合によっては文字化けするので,日本語フォントも入れておく
参考:CentOS7 に後から GUI (X Window System) を追加する
クライアント側
Xはアプリケーションのウィンドウ(GUI)部分を「X Server」に転送するものである.
普通に(物理的に)端末にアクセスした場合のデスクトップがこれに当たる.
今回はサーバーで走っているアプリケーションのウィンドウをクライアントに転送したいので,クライアント側に「X Server」を立て,サーバー側のアプリケーションから転送させる.
ややこしい.
転送の際には,グローバルIPで「X Server」の所在地を指定してやることができる.
が,ssh
コマンドに-X
オプションをつけて実行することでSSHの経路を辿るように指定できるしこっちの方が楽.
- 「Xming」をDL,インストール
* 割と有名な,Win用のX Server.
2. インストールしたXmingを実行
* 一回実行すると裏でX Serverが起動状態になり,ウィンドウの転送を受け付けてくれる
3. export DISPLAY=localhost:0.0
して,$DISPLAY変数にXmingを指定しておく
* echo "export DISPLAY=localhost:0.0" >> ~/.bashrc
などして,起動時に毎回設定されるようにしておくと楽.
X転送したウィンドウの日本語入力を設定
上記の手順を順調にこなしてると,この時点でサーバーからGUIアプリケーションを起動できるようになってる.
でも日本語入力できない.
というわけで「Ibus」という入力フレームワークを導入する.
IMEの友達みたいなものと思っておけばよい.
sudo yum -y groupinstall "Input Method"
してibusを入れる.export GTK_TM_MODULE=ibus
export QT_TM_MODULE=ibus
export XMODIFIERS=@im=ibus
,ここまでやって各種環境変数が設定できるibus-daemon -drx
してibusを裏で起動
* -d
がバックグラウンド起動,-r
が多重起動防止,-x
が起動
6. ibus-setup
で設定画面が開くので,よしなに
X設定の時同様,2~5は~/.bashrc
に書きこんでおくと次回起動時に打ち込みなおす必要がなくて楽.
完成
終わり.
元々画像処理とか勉強するためにGUI環境入れたのに,PythonだけじゃなくDockerやらRubyやらつっこまれてすっかりCUIマシンと化している.
もはや何のためにGUI入れたのかわからなくなってきたが,Docker ContainerからX転送する可能性が浮上してきたのでまた日の目を見ることがあるかもしれない.
おまけ
Bash on Ubuntu on Windowsをアクティベートしたことで,Winの中で実行できるUbuntu環境が手に入った.
といってもWin上で動かす為のあれこれのせいで完全なものではなく,いろいろと動かないアプリケーションもある.
取り敢えず問題点として重大なのが,「X転送したアプリケーションで日本語入力できない」というものである(当社調べ).
Bash on Ubunu上ではibusが動かないのだ(Winで動かしてるから).
似た様な機能を提供しているfcitxも動かない.辛い.
調べたところ,「dbus」というプロセス間メッセージング用のソケットが上手く動いてないらしい.
そりゃダメだわ.
代替案
一応代替策として提案するのが,Winのアプリケーションで代用することである.
「cbwin」というアプリケーションをBashにインストールすることで提供される「wrun」「wstart」「wcmd」等のコマンドを使用すればexeも動く(何故かパス変換が通らない為,第一変数に:
.第二変数にWin式のパスで指定してやる必要がある).
なんかこう,身も蓋もない感じがする.
一応Ubuntuの本体は,C:\Users\\Appdata\Local\lxss
にある.
隠しフォルダになっていて「隠しファイルを表示」しても見えないが,アドレスを直打ちすると通る.
ただなんかWinとUbuntuで妙なパーミッションになってるのか変なところで弾かれる.
よくわからぬ.
最後に自前で使っているexe実行用シェルスクリプトをぺたり.
さっき書いた.
exe_path="\"C:\Program Files\Sublime Text 3\sublime_text.exe\""
usr_path='C:\Users\\AppData\Local\lxss\home\'
if [ ! $1 ]; then
file_path=""
else
file_path=$(cd $(dirname $1) && pwd)/$(basename $1)
if [ ! -f $file_path ]; then
`touch ${file_path}`
else
echo
fi
file_path=${file_path//\//\\}
file_path="${usr_path}${file_path##\\home\\}"
fi
/usr/local/bin/wrun : $exe_path $file_path &