vscode
のremote-container
でelectron
のGUIアプリを作る環境を整える。
remote-container
はdevcontainer
とも呼ぶ。(勝手に呼んでいる)
結論から言うと次の2点で実用には遠いと感じた。
- 日本語が文字化けする。
- Electronアプリから他のアプリを起動できない。
1つ目は解決できるかもしれないが、2つ目は許容できない問題だ。 Electronアプリからブラウザを起動するのはよくあることなので、これができないと、かなり使いづらくなってしまう。もしかしたら解決できるのかもしれないが、再び問題にぶち当たりそうで探したくない。
環境構築については、一応まとめておこうと思ってここに残すことにした。
まずはコンテナの作成
すでに、Electronアプリがある前提で進める。なくても、構築後にチュートリアルアプリでもclone/pullしてくれば問題ないと思う。
remote-container
は準備が必要だったと思うので、準備する。ms-vscode-remote.remote-containers
のエクステンションをローカルのvscodeに入れておけば、vscodeを起動した時に、ウィンドウの左下に新しいアイコンが表示されているのが確認できると思う。
アプリがあるディレクトリでcode .
してvscodeを起動して、左下のアイコンを押して、Open folder in container
をクリックすれば、指定したフォルダをDockerコンテナで開ける。
今回はElectronアプリなので、Node.js 12
のイメージをコンテナに利用した。
またこの時、自動的に.devcontainer
フォルダが作成され、中に2つのファイルが作成される。devcontainer.json
とDockerfile
の2つ。
remote-container
の設定はこの2つのファイルをいじればいい。
コンテナの設定
まずは、Dockerfile
から。以下のような設定をする。
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
# To fully customize the contents of this image, use the following Dockerfile instead:
# https://github.com/microsoft/vscode-dev-containers/tree/v0.112.0/containers/javascript-node-12/.devcontainer/Dockerfile
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-12
# ** [Optional] Uncomment this section to install additional packages. **
#
ENV DEBIAN_FRONTEND=noninteractive
# Electronが使うパッケージなどをセットアップ
RUN apt-get update \
&& apt-get -y install --no-install-recommends libgtkextra-dev libgconf2-dev libnss3 libasound2 libxtst-dev libxss1 libgtk-3-0 \
#
# Clean up
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
# ENV DEBIAN_FRONTEND=dialog
# not to use shared memory
ENV QT_X11_NO_MITSHM=1
# settings to use Japanese
RUN apt-get update \
&& apt-get install -y locales
RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LC_CTYPE ja_JP.UTF-8
RUN localedef -f UTF-8 -i ja_JP ja_JP.utf8
# DISPLAYの設定を忘れずに
ENV DISPLAY=host.docker.internal:0
ほぼこちらを参考にした: 【Mac】dockerコンテナ上でGUI有りのElectron開発環境を作成する - Qiita
日本語の設定をしてもElectronアプリ中の日本語は文字化けしてしまっていた。
次に、devcontainer.json
の方。
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.112.0/containers/javascript-node-12
{
"name": "Node.js 12",
"dockerFile": "Dockerfile",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"dbaeumer.vscode-eslint",
"spadin.remote-x11" // 役に立つのかわよくわからない
],
// Xサーバ(ホスト側)のソケットをDockerコンテナ側にマウントする。
"mounts": [
"source=/tmp/.X11-unix/,target=/tmp/.X11-unix/,type=bind,consistency=cached"
],
// --privilegedがないとエラーが出る。
"runArgs": [
"--privileged"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install",
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "node" // rootだと`--no-sandbox`オプションが必要と言われる。
}
注意すべきは、mounts
とrunArgs
とremote-user
だろう。基本的にはdocker run
などで指定するものと同じ。行頭のformat details
を見ればよくわかる。
mounts
はホスト側のXサーバのドメインソケットを確認して、それをコンテナにマウントすればいい。
runArgs
はまさにdocker run
で指定するオプションと同じ。--privileged
は特権を持たせる。これを付与しないと、
The setuid sandbox is not running as root. Common causes:
* An unprivileged process using ptrace on it, like a debugger.
* A parent process set prctl(PR_SET_NO_NEW_PRIVS, ...)
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
このようなエラーが表示される。
remoteUser
は上のコメントにもあるように、rootでElectronアプリを実行すると、--no-sandbox
オプション無しのルート実行はサポートしていない。のようなメッセージが表示されてしまうため。
次にすることは、コンテナ側のproj_root/node_modules/electron/dist/chrome-sandbox
に権限の設定を行うこと、(もしかすると、不要かもしれない)
このファイルは、root所有で4755権限じゃないといけないよ、的なエラーが出た気がする。なので、
chown root node_modules/electron/dist/chrome-sandbox
chmod 4755 node_modules/electron/dist/chrome-sandbox
をリモートコンテナのシェルで行う。
上のようなコンテナ設定が済んだら、ホスト側、つまりXサーバ側での設定を行う。(別に逆順でもいい)
Xサーバ(ホスト側)の設定
自環境はmacos
なので、XサーバとしてはXQuartz
を使用した。imgをダウンロードしたり、homebrew caskでインストールできたりする。
インストールして、ログインアウトすれば、DISPLAY
環境変数が勝手に設定される。
次にxhost
コマンドでクライアント(コンテナ)のアクセスコントロールを設定する。
ソケットを渡しているので、実質自分(ホスト)となる。なので、
$ xhost +127.0.0.1
$ xhost # これで確認可能
を行なっておけばいい。
起動確認
Xウィンドウシステムの確認だけなら、vscodeのターミナル(リモートコンテナのシェル)で。
$ apt update && apt install -y x11-apps
...
$ xcalc
などで、確認できる。
Electronアプリの確認は、普通に、yarn start
などで起動すればいい。
エラーが発生する場合は、エラーメッセージをそのまま(ある程度短くして)検索エンジンに投げればいい。(丸投げ)
あとがき
ローカル環境を汚さないというメリットがあるが、GUIアプリのためにここまでするのはちょっと面倒。外部ブラウザとの連携も面倒というか起動しないので、この点は全く頼りにできない。
日本語問題はなんとかできるのかもしれないが、上の問題のせいで解決する気も無くしてしまった。
また気が向いたときにでも解決に取り組んでみようかと思う。
以上です。