macOSで起動時にDockerデーモンを立ち上げる

Docker for Mac (Docker.app) を使えばHyperKitによるMacネイティブな仮想化の恩恵を受けられる。
開発用としてGUIログインする場合にはこれで十分。 f:id:S64:20170609013514p:plain


が、macOS Serverとして利用する場合はGUIログインしたくない。
現時点 (2017-06-09 01:36, Docker.app stable 17.03.1-ce-mac12) ではDocker.appはGUIログイン時にしか自動起動できず、またdocker, docker-composeなどの関連コマンドもDocker.appが自動的に配置するため、ブートタイムにこれを利用するのは難しい。

一応psすると/Applications/Docker.app/Contents/MacOS/com.docker.hyperkitあたりが実体のように見えるが、それなりに複雑なパラメータが渡されているため安易に直叩きするのは危険。


仕方ないので、Docker Toolboxに同梱されているdocker-machineを使う。すなわち、VirtualBox上のdockerマシンを見ることにする。

  • Docker Toolbox
  • VirtualBox
  • Oracle VM VirtualBox Extension Pack

をインストール。

docker-machineは各実行ユーザの~/.docker/machine配下で管理するようなので、デーモン用のユーザを作成。 今回は_myawesomeuser、ホームディレクトリを/Users/_myawesomeuserとした。(Macにおいてデーモン等のシステムユーザは先頭がアンダースコア)

システムユーザなのでログインさせないようにしておく。

sudo dscl . create /Users/_myawesomeuser IsHidden 1

以下のようにしてデーモン用ユーザになり、仮想マシンを作成。

sudo su -l _myawesomeuser
docker-machine create myawesomemachine
exit # 元のユーザに戻る

/Library/LaunchDaemons配下に、以下のような起動スクリプトを作成。

<!-- /Library/LaunchDaemons/your.awesome.domain.myawesomemachine.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
      
        <key>EnvironmentVariables</key>
        <dict>
            <key>PATH</key>
            <string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
        </dict>
        
        <key>Label</key>
        <string>your.awesome.domain.myawesomemachine</string>
        
        <key>UserName</key>
        <string>_myawesomeuser</string>
        
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/docker-machine</string>
            <string>start</string>
            <string>myawesomemachine</string>
        </array>
        
        <key>RunAtLoad</key>
        <true/>
        
    </dict>
</plist>

以下のようにして起動に組み入れる。

sudo launchctl load /Library/LaunchDaemons/your.awesome.domain.myawesomemachine.plist

注意点として、Docker.appの場合と違いポートがexposeされる先がVirtualBoxの仮想マシンになる。以下のようにして仮想マシンのIPを取得し叩く必要がある。

sudo -u clean -- bash -l -c 'docker-machine ip myawesomemachine'

よってリバースプロキシなんかを挟む場合には一筋縄では行かない。これはまたこんど記事を書く。