Sumzap Engineering Blog

サムザップのエンジニアブログです。Unity, PHP, AWS/GCPなどの技術情報や会社のエンジニア文化などを日々発信していきます。

サムザップのエンジニアブログです。
技術情報や会社のエンジニア文化などを日々発信していきます。

Sumzap Engineering Blog

Dockerを用いたUnityビルド環境の構築

f:id:sumzap_engineer_blog:20200302191745p:plain

はじめに

はじめまして。サムザップで新規プロジェクトチームに所属しています三上です。

新規プロジェクトではCI環境構築も担当しており、今回はUnityビルド環境の構築についてお話ししようと思います。
結論から言うと、私のプロジェクトではオンプレミスのサーバーを用意して、JenkinsのマスターとスレーブのコンテナをDocker上で動かして、Dockerが動くホスト側でUnityプロジェクトをビルドしています。

構築方法の検討

Unityビルド環境の構築にあたり、下記の3つの構築方法の選択肢と、それぞれのメリデメを考えました。

構築方法 メリット デメリット
オンプレミス x Jenkinsをサーバーに直接導入 ・Jenkinsの初期構築工数が少ない ・Jenkins増設時の工数が多くなる
・ホストのビルド環境構築の工数が多い
オンプレミス x JenkinsをDockerコンテナ化 ・Jenkinsコンテナ化により、Jenkins増設時の工数が少なくなる
・同一ホストに複数のJenkinsコンテナを構築できる(今回の構成では,同一ホストにマスター・スレーブのコンテナを動かします)
・コンテナの構成情報はDockerfileで確認できる
・Jenkinsの初期構築工数が多い
・ホストのUnityビルド環境構築の工数が多い
Unity Cloud Build ・ビルドサーバーの構築、管理の工数が不要
・複数のUnityバージョンでのビルドが容易
・利用事例が多くない
・あくまで機能はUnity側のビルドに限られる
・ビルド時間のチューニングがしづらい

これらの構築方法を項目ごとに比較すると、下記の表のようになります。

項目 パイプライン機能 初期構築工数 増設構築工数 ビルド環境の保守性 費用
オンプレミス x Jenkinsをサーバーに直接導入 あり 初期コスト(+増設コスト)
オンプレミス x JenkinsをDockerコンテナ化 あり 初期コスト(+増設コスト)
Unity Cloud Build なし(Unity側のビルドのみ) なし なし サブスクリプション

パイプライン機能については、Unity Cloud BuildはUnityビルド機能のみなので、独自のAssetBundleビルド機能を導入したり、他のサービスと連携するには、上位のCIが必要になります。
Dockerを用いる場合は,初期構築工数はJenkinsを直接導入する場合に比べて多くなりますが、コンテナ化することで増設時にホストにJenkinsを構築する工数は少なくできます。
Unityビルド環境の保守性については、Unity Cloud Buildはビルド時間が長いという話と、事例が少ないので、運用中のトラブルシューティングに懸念がありました。
費用については、オンプレミスの場合は基本的にハードウェアの費用のみで、Unity Cloud Buildはサブスクリプションで費用が発生します。

私のプロジェクトでは、

  • Unityビルド環境の保守性
  • 増設コストの軽減

を優先に考え、「オンプレミス x JenkinsをDockerコンテナ化」を選択しました。

構築したUnityビルド環境

システム構成

構築したシステムの構成は下記のようになっています。
ホスト内に、コンテナ化したJenkinsサーバーをマスター・スレーブ構成で構築しています。
Unityのビルドはホスト側で実行するように構築し、スレーブからホストに処理を実行させており、成果物はApp Centerにアップロードし、Slackに通知を送っています。

f:id:sumzap_engineer_blog:20200225220335p:plain
Unityビルド環境のシステム構成

増設時のシステムの構成は、下記のようになる想定です。

f:id:sumzap_engineer_blog:20200225221611p:plain
Unityビルド環境のシステム構成(増設時)

コンテナ⇄ホストの連携

マスターおよびスレーブのDockerfileは下記のようになっています。

# master
FROM jenkins/jenkins:latest

# install required tools
USER root
RUN apt-get update && apt-get install -y \
openssh-client

# install jenkins plugins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt

# drop back to the regular jenkins user - good practice
USER jenkins
# slave
FROM jenkins/jenkins:latest

# install required tools
USER root

RUN apt-get update && apt-get install -y \
openssh-server

RUN mkdir -p /var/run/sshd

# install jenkins plugins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt

# jenkins workspace
RUN mkdir -p /jenkins/ws

# set sshd config
RUN echo "ClientAliveInterval 60" >> /etc/ssh/sshd_config
RUN echo "ClientAliveCountMax 10" >> /etc/ssh/sshd_config
CMD /usr/sbin/sshd -D && tail -f /dev/null

sshd_configに応答確認の設定を入れているのは、Unityのビルド中に接続がクローズされてしまうことが多かったためです。
また、スレーブからホストへの接続は下記のようにして、Pipelineからシェルを実行しています。

ssh ${hostUserName}@host.docker.internal ***.sh

host.docker.internalはDockerコンテナが起動しているホスト名です。

まとめ

新規プロジェクトで構築したUnityビルド環境のシステムについてお話ししました。
今回はUnity Cloud Buildを利用しませんでしたが、今後事例が溜まってきたら、利用を検討したいと思っています。
その際には、Jenkinsサーバーもクラウドで構築して、初期コスト&運用コストを減らすのが良いでしょう。
ビルド用のCI環境があるかないかで、プロジェクトの開発速度はかなり違ってきます。
Jenkinsをコンテナ化しておけば、CI構築も楽になりますし、jenkins_homeをコンテナの共有ボリュームに設定してgit管理すれば、まるまる同じ内容のJenkinsサーバーを複製することも容易です。
プロジェクトの初期からCIを導入しておくことで、チームのパフォーマンスの向上に貢献することができるでしょう。

参考文献

超便利! Unity Cloud Build の使い方