m1のMacでVagrantが動かないため、multipassで仮想環境を作りました。
現在multipassのインスタンス(ゲストOS)の中でdocker-composeを起動してRails開発してますが、今のところ特に不自由なく開発できています。
以下、Vagrantで行っていた操作や設定をmultipassでどのように実現するかという点に絞って構築手順を残したいと思います。
インストール
まずはbrewでmultipassをインストールします。
brew install --cask multipass
インスタンスの作成
次にインスタンスを新規作成します。vagrant up
に相当するコマンドです。
multipass launch --name myapp --mem 8G --disk 20G --cloud-init cloud-init.yml
--name
には起動するインスタンスに付ける名前を指定します。
--mem
と--disk
はインスタンスに割り当てるリソースの指定です。Vagrantではインスタンスに割り当てるリソースをVagrantfileに記述しましたが、multipassではlaunchコマンド実行時にオプションで指定します。
プロビジョニングはcloud-initというツールで行います。
cloud-init用の設定ファイルを作成して、--cloud-init
にそのファイルを指定します。
例えば、dockerとdocker-composeを使えるようにしたい場合は、cloud-init.ymlは以下のような内容になります。
#cloud-config
timezone: Asia/Tokyo
apt:
sources:
docker.list:
source: deb [arch=arm64 signed-by=$KEY_FILE] https://download.docker.com/linux/ubuntu $RELEASE stable
keyid: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
packages:
- make
- docker-ce
- docker-ce-cli
- docker-compose
system_info:
default_user:
groups: [docker]
データの同期
ホストOS(インスタンスの外)とインスタンスの間でデータを同期する場合、VagrantではVagrantfileにmountの設定を書いてました。
multipassの場合、launchした後に別途コマンドを実行する必要があります。
multipass mount . myapp:/mnt
これでカレントディレクトリがインスタンスの/mntにマウントされます。
Vagrantのようにlaunch時にマウントできたらよいのですが、調べた限り現時点ではできないようです。githubのissueにも上がってました。
インスタンスにSSH接続する
vagrant ssh
に相当するコマンドです。
multipass shell myapp
ホストOSからインスタンス内のサーバにアクセスする
VagrantではVagrantfileにconfig.vm.network "forwarded_port", guest: 3000, host: 3000
のような設定を書くことで、ホストOSのブラウザからインスタンス内のサーバにアクセスできました。
しかしmultipassにはホストOSとインスタンスをポートフォワーディングする機能がありません。
以下のように手動でsshポートフォワーディングします。
sudo ssh -i /var/root/Library/Application\ Support/multipassd/ssh-keys/id_rsa \
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
-L 3000:localhost:3000 \
ubuntu@$(multipass info myapp | grep IPv4 | awk '{print $2}')
これを実行した後に、ホストOSのブラウザからhttp://localhost:3000
にアクセスすると、インスタンス内で3000番ポートをlistenしてるサーバに繋がります。
-i /var/root/Library/Application\ Support/multipassd/ssh-keys/id_rsa
はmultipassをMacにインストールした時にここにkeyが保存されるのでそれを指定しています。
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
は未知のサーバにアクセスする時に出る警告等を無視するオプション。
-L 3000:localhost:3000
がポートフォワーディングの設定です。
「SSHポートフォワーディング」でググると情報が見つかります。
最後の$(multipass info myapp | grep IPv4 | awk '{print $2}')
ですが、これはインスタンスのIPを取得しています。
インスタンス起動時に毎回自動でIPが振られるので、multipass info
コマンドでIPを取得して接続先を決定しています。
最後に
今までずっとVagrantを使ってましたが、multipassはVagrantと操作感も似ていてシンプルですぐに馴染めました。
Vagrantから乗り換えるなら学習コストも低くてとてもおすすめです。
m1 Macに対応した仮想環境としては他にはUTMという選択肢もあります。
個人的にはGUI環境の操作が馴染めませんでしたが、multipassがubuntuの仮想環境しか作れないので、それ以外のOSが必要な場合はUTMが良さそうです。