Docker Desktop for Windows で wine 使って Windows GUI を動かす #2

# これは何？

[Docker Desktop for Windows で Windows GUI コンテナを動かす](https://qiita.com/2fbCvmiYKX/items/4820da4ec5c2d87581e4) の続きです。

# 結論

次の組み合わせ

- [WineHQ](https://www.winehq.org/) をコンテナで動かす
- [X410](https://token2shell.com/x410/) をホストOS(windows) で動かす

# Dockerfile

使った Dockerfile です.
32bit アプリを動かすつもりなら, コメントアウトしている `ENV WINEARCH=win32` を有効にし, win32 環境を構築した方が良い

```Dockerfile:Dockerfile
FROM ubuntu:18.04

# @see https://qiita.com/fkshom/items/53de3a9b9278cd524099
RUN sed -i.bak -e "s%http://[^ ]\+%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g" /etc/apt/sources.list

RUN set -eux; \
	dpkg --add-architecture i386 \
	&& apt-get update \
	&& apt-get install -y --no-install-recommends \
		software-properties-common \
		apt-transport-https \
		gpg-agent \
		curl \
	&& curl -L -O https://dl.winehq.org/wine-builds/winehq.key \
	&& apt-key add winehq.key \
	&& apt-add-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ bionic main' \
	&& rm winehq.key \
	&& apt-get update \
	&& apt-get install -y --install-recommends \
		winehq-stable \
	&& apt-get install -y --no-install-recommends \
		winetricks \
	&& apt-get remove --purge -y \
		software-properties-common \
	&& apt-get autoremove -y \
	&& apt-get clean \
	&& rm -rf /var/lib/apt/lists/*

COPY local.conf /etc/fonts/local.conf

# for 32bit environment only
#ENV WINEARCH=win32

RUN set -eux; \
	apt-get update \
	&& apt-get install -y --no-install-recommends \
		xvfb \
	&& mkdir -p /root/.cache/wine \
	&& cd /root/.cache/wine \
	&& curl -L -O http://dl.winehq.org/wine/wine-gecko/2.47/wine_gecko-2.47-x86_64.msi \
	&& curl -L -O http://dl.winehq.org/wine/wine-gecko/2.47/wine_gecko-2.47-x86.msi \
	&& curl -L -O http://dl.winehq.org/wine/wine-mono/4.7.5/wine-mono-4.7.5.msi \
	&& winetricks nocrashdialog win10 \
	&& xvfb-run wineboot -u \
	&& apt-get remove --purge -y \
		xvfb \
	&& apt-get autoremove -y \
	&& apt-get clean \
	&& rm -rf /var/lib/apt/lists/* /root/.cache/wine/wine*.msi

```

local.conf は、 [Connect to the container and create a '/etc/fonts/local.conf' file](https://token2shell.com/howto/x410/launching-gui-apps-from-token2shell-docker-console/#sharing-windows-fonts) そのままです。 VcXsrv でも使えると思います。

```xml:local.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
    <dir>/mnt/winfonts</dir>
</fontconfig>
```

wineboot は DISPLAY 環境変数が未設定だと途中で abort します. なので、 xvfb を使います.
また, 単に xvfb-run に GUI を捨てると wine-mono と wine_gecko の download を促す dialog が表示されてしまいます.
この問題を回避するため, あらかじめ wine-mono と wine_gecko の .msi を `.cache/wine` に配置しています. ここに .msi ファイルがあると, wineboot がキャッシュから mono と gecko を install してくれます. 

現状の Dockerfile だと, winehq-stable のバージョンが変わったら, wget の download 先を書き換える必要があり, 面倒...

# コンテナの起動

docker image を `wine:latest` で作成したとします.

## X410 の場合

```:launch.cmd
setlocal
cd %~dp0
docker run -it --rm -v C:/Windows/Fonts:/mnt/winfonts:ro -v "%CD%:/root/workspace" -w /root/workspace -e DISPLAY=docker.for.win.localhost:0.0 wine %*
```

## VcXsrv の場合

試していませんが、多分これでOKと思います
下記のバッチファイルから起動すると, VcXsrv の `xhost +` と docker run の DISPLAY を設定しに行きます.

```:launch.cmd
setlocal
cd %~dp0
set ARGS=%*
set DISPLAY=127.0.0.1:0.0
"%PROGRAMFILES%\VcXsrv\xhost" +

CHCP 437
for /f "tokens=3 usebackq" %%i in (`netsh interface ipv4 show address "vEthernet (Default Switch)"^|find "IP Address:"`)  do @set "IP=%%i"
docker run -it --rm -v C:/Windows/Fonts:/mnt/winfonts:ro -v "%CD%:/root/workspace" -e DISPLAY=%IP%:0.0 wine %ARGS%
```

Dockerfile で ENTRYPOINT を wine にしていないので bash が走るのがイマイチなので適当に直してください。

# 参考にしたところ

[apt-getの利用リポジトリを日本サーバーに変更する](https://qiita.com/fkshom/items/53de3a9b9278cd524099)
[Installing WineHQ packages](https://wiki.winehq.org/Ubuntu)
[X410](https://token2shell.com/howto/x410/)
[Launching Linux GUI apps from the Docker Console in Token2Shell (Store App)](https://token2shell.com/howto/x410/launching-gui-apps-from-token2shell-docker-console/)
[How to change the codepage for DOS batch files to ANSI](https://www.ibm.com/support/pages/%C2%A0how-change-codepage-dos-batch-files-ansi)