[docker-machine-sakuracloud番外編]docker+wine+innosetupでのインストーラ作成

本記事は[Docker Advent Calendar 2015](http://qiita.com/advent-calendar/2015/docker) 11日目の記事です。

前日の[docker-machine-driver-xhyve](http://qiita.com/zchee/items/cb4bb68a0aab12dfa2c1)面白そうですね:+1:
自前のMac上でガンガンdocker動かせると嬉しいですね。今後の開発楽しみにしてます。

[docker-machine-driver-xhyve](http://qiita.com/zchee/items/cb4bb68a0aab12dfa2c1)ではローカルにdocker環境を作っていますが、
私のように貧弱な開発環境しか用意できない人には、
さくらのクラウド上でdockerできるようにするプラグイン[docker-machine-sakuracloud](https://github.com/yamamoto-febc/docker-machine-sakuracloud)もオススメです。

以下に紹介記事を書いてますので興味のある方はぜひどうぞ:smile:
[docker-machine + さくらのクラウドでお手軽リモートdockerするよ](http://qiita.com/yamamoto-febc/items/4aff7472fc1ea025db0a)

# はじめに

さて、今日は[docker-machine-sakuracloud](http://qiita.com/yamamoto-febc/items/4aff7472fc1ea025db0a)の開発時に参考にしたdockerの事例のうち、
広く使い回せそうなwine+innosetupでのインストーラ作成を
実際に環境構築してみながら紹介します。

 * wine      : Windows用のソフトをLinux上で動作させるためのソフト
 * innosetup : インストーラー作成ソフト

wine,innosetupについては詳細には触れませんので別途解説サイトなどをご覧ください。


# 概要

## 今回のゴール

 Dockerコンテナ上でwineを用いてinnosetupを実行し、
Windows用インストーラー(exe)を作成する。

## インストーラー作成までの流れ

1. innosetup用のセットアップスクリプト(.iss)の作成

1. Dockerfileの作成 (wine + innosetupを実行できるDockerイメージの準備)

1. dockerコンテナ起動 (インストーラーのビルド)

# 構築作業

それでは実際に構築作業を行っていきましょう。
今回は拙作の[docker-machine-sakuracloud](https://github.com/yamamoto-febc/docker-machine-sakuracloud)のインストーラー作成を行ってみます。

今回は配布するアプリとは別ディレクトリにインストーラー作成用のスクリプト類を作成していきます。
場合によっては配布するアプリ本体のリポジトリに含めてしまう方がいいかもしれません。

## 今回のファイル構成

```bash
[dir]
  ├── DockerMachineSakuracloud.iss  # 1. innosetup用セットアップスクリプト
  ├── Dockerfile                    # 2. Dockerfile
  ├── build.sh                      # 3. Docker起動用スクリプト
  └── dist/                          # 成果物格納用ディレクトリ
```

## 1. innosetup用のセットアップスクリプト(.iss)の作成

`DockerMachineSakuracloud.iss`ファイルを作成し、以下を記載します。
書いてある内容は適宜コメント入れてますのでなんとなく読み取れると思います。

```iss
;-----------------------------
;変数定義
;-----------------------------
#define MyParentAppName "Docker Toolbox"
#define MyAppName "Docker Machine Sakuracloud"
#define MyAppPublisher "yamamoto-febc"
#define MyAppURL "https://github.com/yamamoto-febc/docker-machine-sakuracloud"
#define MyAppContact "https://github.com/yamamoto-febc/docker-machine-sakuracloud"

;インストーラーで配布するexeの定義
#define dockerMachineSakuracloudDriver "docker-machine-driver-sakuracloud.exe"

;-----------------------------------------
; Setupセクション:インストーラーの動きを定義する
;-----------------------------------------
[Setup]
AppId={{FC4417F0-D7F3-48DB-BCE1-F5ED5BAFFD91}
AppCopyright={#MyAppPublisher}
AppContact={#MyAppContact}
AppComments={#MyAppURL}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}

; 64bit対応
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64

DefaultDirName={pf}\{#MyParentAppName}
UsePreviousAppDir=yes
CreateUninstallRegKey=no
UpdateUninstallLogAppName=no

; 出力されるインストーラー.exeの名称
OutputBaseFilename=DockerMachineSakuracloudSetup

;--------------------------------------
; Filesセクション:配布するファイルを定義する
;--------------------------------------
[Files]
Source: "{#dockerMachineSakuracloudDriver}"; DestDir: "{app}"; Flags: ignoreversion;
```


## 2. Dockerfileの作成

DockerfileでWineとinnosetupを実行可能なDockerイメージを作成します。
`Dockerfile`ファイルを作成し、以下内容を記載します。
こちらも適宜コメントを入れています。

```Dockerfile
FROM debian:jessie

ENV DEBIAN_FRONTEND noninteractive

#-------------------------------
# 依存パッケージのインストール
#-------------------------------
RUN dpkg --add-architecture i386
#contrib/non-freeリポジトリの有効化
RUN sed -i "s/main/main contrib non-free/" etc/apt/sources.list 
# wine,バイナリ取得用のcurl,ファイル展開用のunrarとunzipをインストールしておく
RUN apt-get update && apt-get install -yq wine curl unrar unzip

#-------------------------------
# innosetupのインストール
#-------------------------------
RUN mkdir innosetup && \
    cd innosetup && \
    curl -fsSL -o innounp043.rar "https://downloads.sourceforge.net/project/innounp/innounp/innounp%200.43/innounp043.rar?r=&ts=1439566551&use_mirror=skylineservers" && \
    unrar e innounp043.rar

RUN cd innosetup && \
    curl -fsSL -o is-unicode.exe http://www.jrsoftware.org/download.php/is-unicode.exe && \
    wine "./innounp.exe" -e "is-unicode.exe"

#-------------------------------
# 配布するバイナリの取得(githubから)
#-------------------------------
RUN mkdir /installer
WORKDIR /installer
RUN curl -fsSL -o docker-machine-sakuracloud.zip "https://github.com/yamamoto-febc/docker-machine-sakuracloud/releases/download/v0.0.6/docker-machine-driver-sakuracloud-windows-amd64.zip" && \
    unzip docker-machine-sakuracloud.zip && \
    rm docker-machine-sakuracloud.zip

#-------------------------------------
# セットアップスクリプトをコンテナ内へコピー
#-------------------------------------
COPY DockerMachineSakuracloud.iss /installer/

#-------------------------------------
# wineでinnosetup起動
#-------------------------------------
RUN rm -rf /tmp/.wine-0/
RUN wine ../innosetup/ISCC.exe DockerMachineSakuracloud.iss /DMyAppVersion=0.0.6
```

## 3. Dockerコンテナ起動

後はdockerコンテナを起動するだけです。
毎回コマンドを叩くのも面倒ですので以下のスクリプトを作成します。

build.sh

```bash
#!/bin/bash

# 成果物格納ディレクトリを削除
rm -rf dist/

# dockerイメージのビルド
docker build -t windows-installer -f Dockerfile .  

# コンテナ起動:wine + innosetupを実行
CONTAINER="$(docker run -d windows-installer)"

# 成果物格納用ディレクトリを作成
mkdir -p dist

# コンテナから成果物(exe)をコピー
docker cp "${CONTAINER}":/installer/Output/DockerMachineSakuracloudSetup.exe dist/

# コンテナを削除
docker rm "${CONTAINER}" 2>/dev/null || true
```

初回起動時はイメージのビルドに時間がかかるかと思いますが、
2回目以降はキャッシュされているため早いです。

では実行してみましょう。

```bash
$ chmod +x build.sh
$ build.sh
$ ls -al dist/ # .exeが作成されているはず
```

うまくいけばexeファイルが作成されているはずです。

## 終わりに

今回はWindowsへの配布用インストーラーを作成しました。
スクリプトの差し替え程度の作業で様々なプロダクトへ使いまわせると思います。
windows環境を用意しなくともdockerさえ動く環境ならOKというのは非常に楽ですね:+1:

私は普段開発するときは
   1. docker-machine-sakuracloudでさくらのクラウド上にサーバ作成
   2. dockerを使ってビルド
とやってます。 

数分しかサーバを利用しないためわずか数円で毎回クリーンなビルド環境が手に入りますよ〜。
([さくらのクラウド](http://cloud.sakura.ad.jp/)最安値は1時間7円!!)

このインストーラーにちょっとだけ手を入れたものが以下に置いてありますのでぜひご覧ください。
実際にdocker-machine-sakuracloudのインストーラー作成で利用しているものです。

 * [docker-machine-sakuracloud-installer](https://github.com/yamamoto-febc/docker-machine-sakuracloud-installer)


また、参考元であるDocker-toolboxではMac用にパッケージングするような処理も入ってますので
興味のある方は下記の参考サイトを覗いてみてください。

 * [docker-toolbox](https://github.com/docker/toolbox)

さすがにDocker公式プロダクト、各所でdockerが使われています。
勉強させてもらいつつ、~~パクらせてもらい~~参考にさせてもらいました。


以上です。