Apple siliconのMacで仮想マシンを作る(Docker Desktop代替)

はじめまして！
[株式会社Relic](https://relic.co.jp/)の[Nishimura](https://dev.relic.co.jp/members/a2cnsmr/)です。

自分がWeb業界に入った当時は自分のPCでコーディングし、動作確認するためにはファイルをFTPソフトでサーバーへ送信していましたが、今やPCでも仮想マシンによるサーバーが構築できるようになりました。

Macでも仮想化アプリはいくつかありますが、今回は「UTM」というアプリを使って仮想環境を構築し、Docker Desktop for Macの代替えになるよう仕立てたいと思います。


# Docker Desktop の手軽さには勝てない
いきなりの敗北宣言になってしまいますが、手軽さでいえば Docker Desktopは優秀です。
特にMacは、アプリのアイコンをApplicationフォルダへドラッグ＆ドロップするとインストールが完了します。

しかし、その手軽さを捨ててでも仮想マシン（以下、VM）を利用するメリットがあります。

1. Linuxを知る
1. ネットワークを知る

これですね。
例えるなら、手軽に買えるコンビニ弁当も美味しいですが、素材選びや調理方法など知識や経験が豊富なプロの料理人が作ったものは格別に美味しいものです。
プログラミング言語の知識だけでなく、OSやネットワークの知識を身につけることで、よりプロフェッショナル性が高まると信じております。

:::note warn
お断りをいれておくと、Docker Desktop ほどの利便性はありません。
Docker Desktop 使わないのなら、Mac に 直接 Docker いれたほうがいいんじゃない？ って思います。
:::

# 流れ

1. ホストマシン(Mac)の整備(HomeBrew、UTM)。
1. Ubuntu ServerのISOイメージファイルを使用してUbuntuをインストール。
1. Docker/docker compose のインストール。ホストとの連携。
1. Portainer のインストール。

# 手順

ちょうどM2 Pro の MBP を購入したので、その時のキッティング記録として作成したものを[GitHub](https://github.com/a2cnsmr/kitting)にて公開しております。

# 補足
## 1. ホストマシン(Mac)の整備(HomeBrew、UTM)

ネットワーク機器にも「UTM」というものがありますが、別ものです。
UTMは[こちら](https://docs.getutm.app/installation/macos/)からダウンロードできますので、`GitHub版`(Download from GitHubボタン)をダウンロードしてください。
App Store版もあり、2023年６月現在で9.99ドル（約1,400円）のようです。今でも素晴らしい製品ですが、さらに育ってほしいので、課金しても良さそうですね。

また、HomeBrewを[公式](https://brew.sh/index_ja)に沿ってインストールしてください。

#### 1-1. localhost:ポート番号でアクセスさせるためのポイント

普通にVMによる環境をこしらえると、`192.168.xx.xx`のようなプライベートIPアドレスが振られます。
Docker Desktopのように`localhost:ポート番号`でWebアプリケーションにアクセスさせるには、UTMのネットワークインターフェースを「仮想VLAN」にする必要があります。

仮想VLANにすると`10.xx.xx.xx`のようなプライベートIPアドレスが振られますので、ホストからVMへのSSHも可能です。

#### 1-2. 共有フォルダ

UTMはQEMUを使用しているので、[VirtFS](https://docs.getutm.app/guest-support/linux/#virtfs)でホスト・ゲスト間でフォルダを共有できます。
ホスト側のフォルダに置いたdockerプロジェクトをゲスト側からコンテナ起動すると、どうもモッサリ感が否めません。

※[VirtioFS](https://docs.getutm.app/guest-support/linux/#macos-virtiofs)が使用できるようです。~~が、これはApplまだ試せていません。~~
- 名前は似てますが、VirtFSとVirtioFSは別物です。
- VM作成時に「Apple仮想化」(Apple Virtualization)を選択した際に利用できます。
- ただし「Apple仮想化」を選択すると仮想VLANが選択できず、ポートフォワードもできないので`localhost:ポート番号`のようなURLでローカル開発ができません。

##### 1-2-2. Laravel sail を使用する場合　

1. VirtFSでホストの特定フォルダを共有化する。
1. ゲスト側でフォルダの所有者を変更する。`sudo chown -R フォルダパス`
1. ゲスト側で Laravel sail のアプリケーション作成コマンドを実行する。
    - `curl -s "https://laravel.build/example-app" | bash`

##### 1-2-3. 共有フォルダに既存Gitリポジトリがある場合

共有フォルダ内にGitリポジトリがある場合、そこには `.git` フォルダがあるはずです。
その状態で上記の chown コマンドで所有者を一括変更しようとすると、`Permission denied`になります。
これはどうにかして .git フォルダを除外したほうがいいと思います。


## 2. Ubuntu Server

Ubuntu は[こちら](https://ubuntu.com/download/server)からサーバー版のISOファイルをダウンロードしてください。
デスクトップ環境は不要です。
後からどうしてもデスクトップ環境が欲しくなった場合はコマンドからインストールできるので、問題ありません。


## 3. Docker/docker compose

今回の目的はホストマシン(Mac)からゲストマシン(VM)内のDockerを動かすので、ホストマシンに `docker-cli`をインストールする必要があります。
※まちがってdocker.app(=Docker Desktop)をインストールしないようにしてください。

また、ホストからゲスト内のDockerは2375ポートを介して操作しますので、ウイルス対策ソフト等によるファイアウォールが設定されている場合は、疎通ができるよう設定してください。


## 4. Portainerのインストール

すべてDockerコマンドで操作するのは骨が折れるので、やはりGUIが欲しいところです。
Webで動く[Portainer CE](https://docs.portainer.io/start/install-ce/server/docker/linux)というツールをインストールします。


# まとめ

いかがだったでしょうか？
Docker Desktopの手軽さは最高ですが、それだけが唯一の手段ではありません。
別のアプローチを模索してみるのも、知識の幅が広がって良いのではないでしょうか。


# お知らせ

株式会社Relicでは、エンジニア・デザイナーを積極的に採用中です。
またRelicには地方拠点がありますので、U・Iターンも大歓迎です！🙌
少しでもご興味がある方は、Relic採用サイトからエントリーください！

[株式会社Relic　採用サイト](https://relic.co.jp/recruit?utm_source=qiita&utm_medium=article&utm_campaign=qiita_article)

## 地方拠点：和歌山イノベーションラボとは

私が勤務している株式会社Relic 和歌山イノベーションラボは、JR和歌山駅から徒歩２分というベストロケーションにオフィスを構え、挑戦者と共に勇気と情熱を持ってイノベーションを創造し、和歌山から日本経済を活性化することをミッションに活動しております。 
私達の拠点紹介ページがありますので、ご欄いただけますと幸いです。 

🏢[和歌山イノベーションラボ](https://relic.co.jp/company/branch_office/wakayama_innovationlabo/?utm_source=qiita&utm_medium=article&utm_campaign=qiita_article)