MacでDockerが遅いとお嘆きの人たちへ

MacでDocker Desktopを使用して日々作業をする場合に
どうしても、Mac上で直接操作するのよりもDockerで操作する時に遅くなってしまいます。
DockerからMacのファイルシステムにアクセスする時に特に遅くなってしまいます。
(今回の記事の対象者として「macでDockerを使ってコードを書いたりしている人」と仮定してます。)
そこで、MacでDockerを早くする方法、
それはずばり、Docker Desktopを使わない
という事になります。
え!?どーいうこと?
となりそうですが、それをこれから詳しく解説していきます。

必要な物

  • VirtualBox
  • Vagrant
  • Visual Studio Code
  • Visual Studio Code – Remote Developmentプラグイン

不要になる物

  • Docker Desktop for mac

今回必要なツール、それぞれの簡単な解説

VirtualBox

macの中で、別の環境(Windowsとかubuntuとか)を稼働させることが出来る仮想環境を作るアプリケーションです。

Vagrant

Vagrantなどの仮想環境アプリケーションを使い、コマンドラインで仮想環境自体の操作が出来るツールです。

Visual Studio Code

コードエディタ

ということで、まずはVirtualBoxとVagrantとVisual Studio Codeを入れていきます。

それぞれの公式へのリンク

Vgrant公式

https://www.vagrantup.com/
こちらからVagrantをダウンロードします。

VirtualBox公式

https://www.virtualbox.org/
こちらからVirtualBoxをダウンロードします。

Visual Studio Code公式

https://azure.microsoft.com/ja-jp/products/visual-studio-code/
こちらからVisual Studio Codeをダウンロードします。

手順

VirtualBoxとVagrantはdmg形式でダウンロードなので、開いて中にあるインストーラを使ってインストール完了させます。
Visual Studio CodeはZIPなので、解凍してアプリケーションフォルダに    Visual Studio Codeを移動します。

これで準備は整いました。
ターミナルを開いて
vagrantと入力してみましょう。

$ vagrant
Usage: vagrant [options]  []

    -v, --version                    Print the version and exit.
    -h, --help                       Print this help.

Common commands:
     box             manages boxes: installation, removal, etc.
     cloud           manages everything related to Vagrant Cloud
     destroy         stops and deletes all traces of the vagrant machine
     global-status   outputs status Vagrant environments for this user
     halt            stops the vagrant machine
     help            shows the help for a subcommand
     init            initializes a new Vagrant environment by creating a Vagrantfile
     login           
     package         packages a running vagrant environment into a box
     plugin          manages plugins: install, uninstall, update, etc.
     port            displays information about guest port mappings
     powershell      connects to machine via powershell remoting
     provision       provisions the vagrant machine
     push            deploys code in this environment to a configured destination
     rdp             connects to machine via RDP
     reload          restarts vagrant machine, loads new Vagrantfile configuration
     resume          resume a suspended vagrant machine
     snapshot        manages snapshots: saving, restoring, etc.
     ssh             connects to machine via SSH
     ssh-config      outputs OpenSSH valid configuration to connect to the machine
     status          outputs status of the vagrant machine
     suspend         suspends the machine
     up              starts and provisions the vagrant environment
     upload          upload to machine via communicator
     validate        validates the Vagrantfile
     version         prints current and latest Vagrant version
     winrm           executes commands on a machine via WinRM
     winrm-config    outputs WinRM configuration to connect to the machine

For help on any individual command run `vagrant COMMAND -h`

Additional subcommands are available, but are either more advanced
or not commonly used. To see all subcommands, run the command
`vagrant list-commands`.

という感じに出ると思います。

Vagrantの仕組みとしては
Vagrantfileという設定ファイルを元にして
そこに設定してあるOSのイメージをVagrantのサイトからダウンロードして来て
そのイメージを元に環境を起動する。
という動きをします。
その元になるイメージというのは
Vagrantではboxと呼ばれています。

どのようなイメージがあるのかというのは
Vagrantの公式にもリンクがありますが
https://app.vagrantup.com/boxes/search
で探すことが出来ます。

今回はDockerを使いたいので
手堅く??ubuntu/focal64を探します。
ubuntuのv20.04ですね。
/の前がオーナーその後がイメージ名で、オーナーが良く分からない人の場合は使用は慎重に。。。
とい言う事でubuntu公式のイメージを選びます。

How to use this box with Vagrant
のところでNewを選ぶとコマンドが出ます。

早速実行します。
vagrant init ubuntu/focal64
vagrant up

initでVagrantfileを作成して、upで起動ですね。
(vagrant upをするとイメージのダウンロードから始まるので最初はちょっと遅いですが、一度イメージをダウンロードすると再利用するので早いです。)

vagrant upすると
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'ubuntu/focal64' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'ubuntu/focal64'
    default: URL: https://vagrantcloud.com/ubuntu/focal64
==> default: Adding box 'ubuntu/focal64' (v20201007.0.0) for provider: virtualbox
    default: Downloading: https://vagrantcloud.com/ubuntu/boxes/focal64/versions/20201007.0.0/providers/virtualbox.box
    default: Download redirected to host: cloud-images.ubuntu.com
==> default: Successfully added box 'ubuntu/focal64' (v20201007.0.0) for 'virtualbox'!
==> default: Importing base box 'ubuntu/focal64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'ubuntu/focal64' version '20201007.0.0' is up to date...
==> default: Setting the name of the VM: vagrant_default_1602137641580_23902
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection reset. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: 
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default: 
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default: 
    default: Guest Additions Version: 6.1.10
    default: VirtualBox Version: 6.0
==> default: Mounting shared folders...
    default: /vagrant => /Users/gen/vagrant

という感じにログが表示されると思います。

正常に起動したあとは
sshしてみます。
そのまま

vagrant ssh

で入る事が可能です。

vagrant sshで入る事は出来ますが、Visual Studio Codeからsshをしてリモートするので、mac上の自分のユーザのパブリックキーをvagrant上のubuntuに設定します。

ssh vagrant@localhost -p 2222

で入る事出来るようになります。

続いて、Docker環境を作って行きます。

Docker公式
https://www.docker.com/
こちらから

ダウンロードボタンが展開出来るので

そこから
View Linux Engine
という所をクリックします。

リストが表示されるので
Docker Engine – Ubuntu (Community)
というのを探します。

開いた先でさらに
Docker Engine – Ubuntu (Community)
の項目を探します。

ここにあるdocs.docker.comのURLをクリックします。
こちらにインストール方法が書いてありますね。

必要なコマンドを上から実行していきましょう。

Uninstall old versions
は、まだ入れてないので飛ばします。

Install using the repository
ここのコマンドから実行していきます。

ここはそのままx86_64 / amd64でokです。

To install a specific version of Docker Engine, list the available versions in the repo, then select and install:

の項目は実行しなくて大丈夫です。

Verify that Docker Engine is installed correctly by running the hello-world image.
の項目を実行してエラーが無ければDockerのインストールが完了しました。

ここから下は実行しなくて大丈夫です。

まだdockerコマンドがsudo付きじゃ無いと動かないので
Next stepsの項目にある
Post-installation steps for Linux
を開きます。

Manage Docker as a non-root user
という項目があるので、ここの手順を実行します。

続いて
docker-composeコマンドツールをインストールしていきます。

先ほどの画面の左側に
Docker Composeの項目があるので
その中のInstall Composeを開きます。

Install Compose
の項目の手順を実行していきます。

選ぶのはLinuxタブ

Install pre-release builds
この項目から下は実行しなくて良いです。

これでVirtualBoxのubuntu内にDockerを動かす環境が整いました。

続いて
Visual Studio Codeの設定をしていきます。

Visual Studio Codeにプラグインで
Remote Developmentと言うのを探してインストールしておきます。

インストールが完了すると
左のアイコンの所に

というのが出てきます。
これをクリック。

REMOTE EXPLORERのSSH Targetsを選択し、歯車マークを選択します。

Settingsを選択

.ssh/configのパスを設定します。
続いて、.ssh/config のファイルを編集します。

Host vagrant_ubuntu
  HostName 127.0.0.1
  Port 2222
  User vagrant

を追加します。

SSH TARGETSの中から
vagrant_ubuntuを選択して、プロジェクトを開始するディレクトリを選択します。

これでvagrantで起動したubuntu(以降、vagrant_ubuntuと呼びます)にVisual Studio Codeで接続して、編集できるようになりました。

vagrant_ubuntuには、sshは2222で接続出来るのですが、webの80や443や3000はポートがmacからはこのままでは繋がらないので、繋ぐようにしていきます。

いくつか方法があるのですが
その一つ
SSHでトンネルを繋ぐ方法を紹介します。

ssh -N -L3000:localhost:3000 -p2222 vagrant_ubuntu

と実行すると、vagrant_ubuntu内のポート3000番がlocalhostの3000番として接続出来るようになります。

もう一つは、vagrantの設定をイジってlocalhostに繋がるように設定しますが詳しい設定方法は別の機会に。