Docker API over HTTP on Mac OS X with Docker for Mac Beta

By | May 21, 2016

Docker for Mac Beta is very nice – more integrated with OS X and significantly faster. The only issue I have encountered so far is the Docker API not being available over HTTP.
The problem can be overcome using socat and launchd; socat is used to expose a HTTP endpoint on which the Docker API is available and launchd to automatically start the socat forwarder each time OS X is started. The socat workaround has been suggested by several persons – thanks! My own laziness drove me to create the launch daemon job.

Install Socat

The most convenient way to install socat is using Homebrew:

  • If you haven’t installed Homebrew, do it using the following command in a terminal window:
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • Install socat:
    brew install socat

If you now try the socat command without any parameters in the terminal, you should see output similar to this:

2016/05/21 11:43:41 socat[2598] E exactly 2 addresses required (there are 0); use option "-h" for help

Create a Launch Daemon

Some research told me that creating a launch daemon is the appropriate way to run a script or program at startup. Further details are available here.
After some tinkering, I came up with the following launchd job configuration:

<?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>Label</key>
        <string>se.ivankrizsan.socat_launcher</string>
        <key>Disabled</key>
        <false/>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/socat</string>
            <string>-d</string>
            <string>TCP-LISTEN:2376,range=127.0.0.1/32,reuseaddr,fork</string>
            <string>UNIX:/var/run/docker.sock</string>
        </array>
        <key>StandardErrorPath</key>
    	<string>/Library/Logs/socat_docker.log</string>
    	<key>StandardOutPath</key>
    	<string>/Library/Logs/socat_docker.log</string>
        <key>StartInterval</key>
       <integer>30</integer>
    </dict>
</plist>

Note that:

  • The value of the “Label” key must be unique among your launchd jobs.
  • The launchd job can be disabled by setting the key “Disabled” value to true.
  • The launchd job will be run at startup (RunAtLoad) and restarted if the process is terminated (KeepAlive).
  • The program to execute is the first value in array of the “ProgramArguments” key.
  • The arguments to socat needs to have one <string> elements each in the program arguments array.
  • The Docker API HTTP endpoint will be made available on port 2376.
    In addition, the Docker API HTTP endpoint will only be available from localhost (range=127.0.0.1/32).
    If you want to open the Docker API HTTP endpoint to access from any IP, modify row 17 of the launchd job configuration to look like this:

    <string>TCP-LISTEN:2376,reuseaddr,fork</string>
  • Log from socat will be written to the file /Library/Logs/socat_docker.log
  • Socat will be restarted with a 30 second interval if needed (StartInterval).

To activate the launchd job configuration:

  • Save the above launchd job configuration to a file with the postfix “.plist” (without quotes).
    My file is named “se.ivankrizsan.socat_launcher.plist”.
  • Copy the file you just saved to /Library/LaunchDaemons on your OS X boot disk.
  • Open a terminal window.
  • Go to the launch daemons directory:
    cd /Library/LaunchDaemons
  • Set the owner and group of the new launchd job configuration file:
    sudo chown root:wheel se.ivankrizsan.socat_launcher.plist
  • Load the launchd job configuration.
    This can be accomplished either by rebooting OS X or by the following command in the terminal:

    sudo launchctl load se.ivankrizsan.socat_launcher.plist
  • Open the Console application and examine the system log for entries related to socat and the socat_docker.log log file.
  • Start the Docker (for Mac Beta) application.
  • Open the link http://127.0.0.1:2376/version in a browser.
    You should see output similar to this:

    {"Version":"1.11.1","ApiVersion":"1.23","GitCommit":"8b63c77","GoVersion":"go1.5.4","Os":"linux","Arch":"amd64","KernelVersion":"4.4.9-moby","BuildTime":"2016-05-10T10:39:20.341523579+00:00"}

If there are problems regarding the permissions of the launchd job configuration file, use Disk Utility to repair permissions as a last resort.

Happy coding!

7 thoughts on “Docker API over HTTP on Mac OS X with Docker for Mac Beta

  1. Dirk Loeckx

    Excellent, exactly what I needed! Many many thanks!
    Maybe one small typo: you mention ‘The launchd job can be disabled by setting the key “Disabled” value to false.’. I guess this should be ‘to true’ instead of ‘to false’?

    Reply
  2. Kyle

    Awesome work. One note, you’re missing the closing angle bracket in the closing plist tag.
    Should be
    Otherwise, works excellently! Thanks!

    Reply
  3. Steve Johnson

    Isn’t the command line that follows the step description “Set the owner and group of the new launchd job configuration file:” wrong? Shouldn’t it be something like “sudo chown root:wheel se.ivankrizsan.socat_launcher.plist”?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *