├── assets
└── djocker.png
├── Formula
├── docker-machine-pf.rb
├── docker-machine-nfs-generic.rb
└── docker-virtualbox.rb
├── bin
├── docker
├── docker-compose
└── docker-machine-init
└── README.md
/assets/djocker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sergeycherepanov/homebrew-docker-virtualbox/HEAD/assets/djocker.png
--------------------------------------------------------------------------------
/Formula/docker-machine-pf.rb:
--------------------------------------------------------------------------------
1 | require 'formula'
2 |
3 | class DockerMachinePf < Formula
4 | url 'https://github.com/johanhaleby/docker-machine-port-forwarder/archive/d58e7b8f267b6d9e4156f0c5939c01a84afb52ec.tar.gz'
5 | homepage 'https://github.com/johanhaleby/docker-machine-port-forwarder'
6 | sha256 '0acd6f61c71b4f719613c92e2b5df5231ec5d76816ef4e321c2b7c2150d1fcdf'
7 | version "0.0.1"
8 | revision 2
9 |
10 | def install
11 | bin.install "pf"
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/Formula/docker-machine-nfs-generic.rb:
--------------------------------------------------------------------------------
1 | class DockerMachineNfsGeneric < Formula
2 | desc "Activates NFS on docker-machine (with generic driver support)"
3 | homepage "https://github.com/sergeycherepanov/docker-machine-nfs"
4 | url "https://github.com/sergeycherepanov/docker-machine-nfs/archive/0.5.4.2.tar.gz"
5 | sha256 "5067da89d8ba1205883cfa0087106cbbe5bc4140ee4b9f45ed1a7b772363417b"
6 | license "MIT"
7 | version "0.5.4"
8 | revision 2
9 |
10 | def install
11 | bin.install "docker-machine-nfs.sh" => "docker-machine-nfs-generic"
12 | end
13 |
14 | test do
15 | system "#{bin}/docker-machine-nfs-generic"
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/bin/docker:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | #set -x
4 | LIMIT=90
5 | if [[ -f /tmp/docker-virtualbox.starting ]]; then
6 | >&2 echo -e "\033[93mWaiting while Docker starting..."
7 | >&2 echo -e "\033[0m"
8 | i=0
9 | while [[ -f /tmp/docker-virtualbox.starting ]]; do
10 | if [[ "$i" -gt "$LIMIT" ]]; then
11 | >&2 echo -e "Default \e[91mThe timeout reached, please verify the vm log for errors: /tmp/docker-virtualbox.log\e[39m"
12 | fi
13 | i=$(($i+1))
14 | sleep 1;
15 | done
16 | fi
17 |
18 | [[ -f /tmp/docker-virtualbox.env && -f /tmp/docker-virtualbox-machine.env ]] || {
19 | echo -e "\033[91m"
20 | echo -e "\033[91mLooks like docker-virtualbox doesn't work"
21 | echo -e ""
22 | echo -e "\033[0mYou have to start it by following command:"
23 | echo -e ""
24 | echo -e "\033[96mbrew services start docker-virtualbox "
25 | echo -e "\033[0m"
26 | exit 1
27 | }
28 |
29 | source /tmp/docker-virtualbox.env
30 |
31 | [[ -z "${DOCKER_HOST}" ]] && {
32 | source /tmp/docker-virtualbox-machine.env
33 | }
34 |
35 | exec ${DOCKER_CLI_BIN_PATH} "$@"
36 |
--------------------------------------------------------------------------------
/bin/docker-compose:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | #set -x
4 | LIMIT=90
5 | if [[ -f /tmp/docker-virtualbox.starting ]]; then
6 | >&2 echo -e "\033[93mWaiting while Docker starting..."
7 | >&2 echo -e "\033[0m"
8 | i=0
9 | while [[ -f /tmp/docker-virtualbox.starting ]]; do
10 | if [[ "$i" -gt "$LIMIT" ]]; then
11 | >&2 echo -e "Default \e[91mThe timeout reached, please verify the vm log for errors: /tmp/docker-virtualbox.log\e[39m"
12 | fi
13 | i=$(($i+1))
14 | sleep 1;
15 | done
16 | fi
17 |
18 | [[ -f /tmp/docker-virtualbox.env && -f /tmp/docker-virtualbox-machine.env ]] || {
19 | echo -e "\033[91m"
20 | echo -e "\033[91mLooks like docker-virtualbox doesn't work"
21 | echo -e ""
22 | echo -e "\033[0mYou have to start it by following command:"
23 | echo -e ""
24 | echo -e "\033[96mbrew services start docker-virtualbox "
25 | echo -e "\033[0m"
26 | exit 1
27 | }
28 |
29 | source /tmp/docker-virtualbox.env
30 |
31 | [[ -z "${DOCKER_HOST}" ]] && {
32 | source /tmp/docker-virtualbox-machine.env
33 | }
34 |
35 | exec ${DOCKER_COMPOSE_BIN_PATH} "$@"
36 |
--------------------------------------------------------------------------------
/Formula/docker-virtualbox.rb:
--------------------------------------------------------------------------------
1 | require 'formula'
2 |
3 | class DockerVirtualbox < Formula
4 | url "https://github.com/sergeycherepanov/homebrew-docker-virtualbox.git", :using => :git
5 | version "0.0.7"
6 | revision 1
7 |
8 | depends_on 'coreutils'
9 | depends_on 'curl'
10 | depends_on 'jq'
11 | depends_on 'terminal-notifier'
12 | depends_on 'docker'
13 | depends_on 'docker-compose'
14 | depends_on 'docker-credential-helper'
15 | depends_on 'docker-machine'
16 | depends_on 'docker-machine-nfs-generic'
17 |
18 | keg_only "this package may conflict with official docker client"
19 |
20 | resource "gobetween" do
21 | url "https://github.com/yyyar/gobetween/releases/download/0.8.0/gobetween_0.8.0_darwin_amd64.zip"
22 | sha256 "15efec9cef9dc01c4e195042df62def95f189090e470678d5b6f024afa71e1b0"
23 | end
24 |
25 | def install
26 | resource("gobetween").stage do
27 | bin.install "gobetween"
28 | end
29 | (buildpath/"gobetween.toml").write <<~EOS
30 | [api]
31 | enabled = true
32 | bind = "127.0.0.1:8181"
33 | EOS
34 | (etc/"docker-virtualbox").mkpath
35 | etc.install "gobetween.toml" => 'docker-virtualbox/gobetween.toml'
36 |
37 | bin.install "bin/docker"
38 | bin.install "bin/docker-compose"
39 | bin.install "bin/docker-machine-init"
40 | prefix.install "assets/djocker.png"
41 | end
42 |
43 | def caveats
44 | s = <<~EOS
45 | Docker Virtualbox was installed
46 |
47 | Please don't forget to configure your PATH variable
48 | EOS
49 | s
50 | end
51 |
52 | def plist; <<~EOS
53 |
54 |
55 |
56 |
57 | KeepAlive
58 |
59 | Label
60 | #{plist_name}
61 | ProgramArguments
62 |
63 | #{opt_bin}/docker-machine-init
64 |
65 | RunAtLoad
66 |
67 | WorkingDirectory
68 | /tmp
69 |
70 |
71 | EOS
72 | end
73 | end
74 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Homebrew Docker Virtualbox (But not VirtualBox only)
2 | This formula resolves the Docker issue on AMD based MacOS (Ryzentosh). Also can be used on any Mac.
3 |
4 | *PLEASE READ FIRST THE NOTICE: https://gist.github.com/slykar/e92732be9bf81a71e08068245656d70e?permalink_comment_id=4105556#gistcomment-4105556*
5 |
6 | ## Installation
7 |
8 | ### Install Virtualbox from Oracle website
9 | https://www.virtualbox.org/wiki/Downloads.
10 | > Please don't forget to remove all previous installations.
11 | > This step required only if you want to use VirtualBox driver, otherwise see below how to start with another driver.
12 |
13 | ### Virtualbox 6.1.28+ Note
14 | Due the changes of virtualbox networking, you need to allow docker-machine host in order to use 192.168.99.0/8 network. [More Details](https://www.virtualbox.org/manual/ch06.html#network_hostonly)
15 |
16 | Add this line into
17 | `/etc/vbox/networks.conf`
18 | ```bash
19 | * 192.168.99.0/8
20 | ```
21 |
22 | ### Install the docker-virtualbox via Homebrew
23 | ```bash
24 | brew tap serhiicherepanov/docker-virtualbox
25 | brew install docker-virtualbox
26 | ```
27 |
28 | ### Configure the docker-virtualbox requirements
29 | > WARNING: Only this commands requires root permissions, all next should be run under your user
30 |
31 | Ensure the NFS exports file exists
32 | ```bash
33 | sudo touch /etc/exports
34 | ```
35 |
36 | Allow the staff group to configure NFS shares and run the balancer without a password prompt
37 | ```bash
38 | sudo tee /etc/sudoers.d/docker-machine-nfs < Reboot your system to be sure that sudoers applied
48 |
49 | ### Configure the environment
50 |
51 | If you didn't install Docker for Mac you can link binaries instead of PATH update
52 | ```
53 | brew link --force --overwrite docker-virtualbox
54 | ```
55 |
56 | Otherwise configure the PATH variable
57 | ```bash
58 | # For the bash
59 | echo "export PATH=\"$(brew --prefix docker-virtualbox)/bin:\$PATH\"" >> ~/.bash_profile
60 | # For the zsh
61 | echo "export PATH=\"$(brew --prefix docker-virtualbox)/bin:\$PATH\"" >> ~/.zshrc
62 | ```
63 |
64 | Reload the shell
65 | ```
66 | exec $SHELL
67 | ```
68 |
69 | ### Initialize the docker machine
70 | In the first run according to the permissions policy you need to run it manually and approve permissions.
71 |
72 | ```bash
73 | docker-machine-init initialize
74 | ```
75 | > This is will download, create and configure the VirtualBox-based machine if the machine was not configured before. If the machine was created manually this will only set up NFS mount.
76 |
77 |
78 | ### Start the docker-virtualbox service
79 | When initialization will be finished you are ready to enable the service
80 | > The log file will be always available in `/tmp/docker-virtualbox.log`.
81 | ```bash
82 | brew services start docker-virtualbox
83 | ```
84 |
85 | ### Verify installation
86 |
87 | Test the Docker by running Nginx
88 | ```bash
89 | docker run -d -p 8989:80 nginx
90 | curl -v localhost:8989
91 | ```
92 |
93 | ## Additional information
94 |
95 | If you don't want to use the VirtualBox as docker-machine driver you need to create a machine manually before initialization by similar command:
96 | ```bash
97 | docker-machine create --driver generic --generic-ip-address=192.168.24.108 --generic-ssh-user=developer --generic-ssh-key=$HOME/.ssh/id_rsa docker
98 | ```
99 | > Please note the docker-machine-nfs plugin supports only Debian based Linux as the target system. For more information read the [documentation](https://github.com/sergeycherepanov/docker-machine-nfs/blob/master/README.md)
100 |
101 | Read the log when the docker doesn't work properly
102 | ```bash
103 | tail -n 1000 -f /tmp/docker-virtualbox.log
104 | ```
105 |
106 | SSH connection to the docker-machine
107 | ```bash
108 | docker-machine ssh docker
109 | ```
110 |
111 | To stop the service just run
112 | ```bash
113 | brew services stop docker-virtualbox
114 | ```
115 |
116 | To setup environment for 3rd party tools ([`ctop`](https://github.com/bcicen/ctop) as example)
117 | ```
118 | source /tmp/docker-virtualbox.env
119 | source /tmp/docker-virtualbox-machine.env
120 | ```
121 |
122 | ## Known issues
123 | 1. The system won't sleep when the NFS server runs
124 | 2. The port forwarding doesn't work for UDP proto (improvement needed)
125 |
--------------------------------------------------------------------------------
/bin/docker-machine-init:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | [[ $1 == "debug" ]] && {
4 | set -x
5 | }
6 | if [[ $(id -u ${USER}) -eq 0 ]]; then
7 | echo "Please don't run this script under the root user!"
8 | exit 1
9 | fi
10 | LOGDIR="/tmp";
11 |
12 | [[ $1 != "initialize" ]] && [[ $1 != "debug" ]] && {
13 | exec > ${LOGDIR}/docker-virtualbox.log
14 | exec 2>&1
15 | }
16 |
17 | START_TIME=$(date +%s)
18 |
19 | if [[ -n "${BREW_BIN}" ]]; then
20 | BREW_BIN=$BREW_BIN
21 | elif [[ "Darwin" == "$(uname)" ]]; then
22 | BREW_BIN=/usr/local/bin
23 | else
24 | BREW_BIN=/home/linuxbrew/.linuxbrew/bin
25 | fi
26 |
27 | PATH="${PATH}:${BREW_BIN}"
28 | GOBETWEEN_BIN=$(brew --prefix)/opt/docker-virtualbox/bin/gobetween
29 | TERMINAL_NOTIFIER_BIN="$(brew --prefix terminal-notifier)/bin/terminal-notifier -appIcon $(brew --prefix docker-virtualbox)/djocker.png"
30 | JQ_BIN="$(brew --prefix jq)/bin/jq"
31 | DOCKER_MACHINE_BIN=$(brew --prefix docker-machine)/bin/docker-machine
32 | DOCKER_MACHINE_NFS_BIN=$(brew --prefix docker-machine-nfs-generic)/bin/docker-machine-nfs-generic
33 |
34 | DOCKER_MACHINE_DRIVER=${DOCKER_DRIVER-virtualbox}
35 | DOCKER_MACHINE_MACHINE_NAME=${DOCKER_MACHINE_NAME-docker}
36 |
37 | function stop()
38 | {
39 | [[ -f /tmp/docker-virtualbox.env ]] && rm /tmp/docker-virtualbox.env
40 | [[ -f /tmp/docker-virtualbox-machine.env ]] && rm /tmp/docker-virtualbox-machine.env
41 | echo "===> Stopping docker machine: ${DOCKER_MACHINE_MACHINE_NAME}"
42 | ${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Stopping virtual machine: '${DOCKER_MACHINE_MACHINE_NAME}'"
43 | ${DOCKER_MACHINE_BIN} stop ${DOCKER_MACHINE_MACHINE_NAME}
44 | exit 0
45 | }
46 |
47 | trap stop SIGKILL
48 | trap stop SIGTERM
49 | trap stop SIGINT
50 |
51 |
52 | ${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Initialize..."
53 | sleep 1
54 |
55 | if [[ -z ${DOCKER_MACHINE_DISK_SIZE} ]]; then
56 | DOCKER_MACHINE_DISK_SIZE="16000"
57 | if [[ $($(brew --prefix coreutils)/libexec/gnubin/df --block-size=1073741824 | grep '\/$' | awk '{print $2}') -gt 200 ]]; then
58 | DOCKER_MACHINE_DISK_SIZE="32000"
59 | fi
60 | fi
61 |
62 | if [[ -z ${DOCKER_MACHINE_CPU_COUNT} ]]; then
63 | if [[ "Darwin" == "$(uname)" ]]; then
64 | DOCKER_MACHINE_CPU_COUNT=$(sysctl -n hw.ncpu | awk 'function ceil(x, y){y=int(x); return(x>y?y+1:y)} { print ceil($1*0.25) }')
65 | else
66 | DOCKER_MACHINE_CPU_COUNT=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}' | awk 'function ceil(x, y){y=int(x); return(x>y?y+1:y)} { print ceil($1*0.25) }')
67 | fi
68 | fi
69 |
70 | if [[ -z ${DOCKER_MACHINE_MEMORY_COUNT} ]]; then
71 | if [[ "Darwin" == "$(uname)" ]]; then
72 | DOCKER_MACHINE_MEMORY_COUNT=$(sysctl -n hw.memsize | awk '{ mem=($1 * 0.25 / 1024 / 1024 ); print int(mem > 4096 ? 4096 : mem) }')
73 | else
74 | DOCKER_MACHINE_MEMORY_COUNT=$(free -b | grep Mem | awk '{ mem=($2 * 0.25 / 1024 / 1024 ); print int(mem > 4096 ? 4096 : mem) }')
75 | fi
76 | fi
77 |
78 | [[ "Running" == $(${DOCKER_MACHINE_BIN} status ${DOCKER_MACHINE_MACHINE_NAME}) ]] && {
79 | touch /tmp/docker-virtualbox.starting
80 | echo "===> Virtual machine '${DOCKER_MACHINE_MACHINE_NAME}' already started"
81 | ${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Virtual machine '${DOCKER_MACHINE_MACHINE_NAME}' started"
82 | } || {
83 | touch /tmp/docker-virtualbox.starting
84 | [[ "Stopped" == $(${DOCKER_MACHINE_BIN} status ${DOCKER_MACHINE_MACHINE_NAME}) ]] && {
85 | ${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Starting virtual machine: ${DOCKER_MACHINE_MACHINE_NAME}"
86 | echo "===> Starting docker machine: ${DOCKER_MACHINE_MACHINE_NAME}"
87 | ${DOCKER_MACHINE_BIN} start ${DOCKER_MACHINE_MACHINE_NAME}
88 | } || {
89 | echo "===> Creating docker machine: ${DOCKER_MACHINE_MACHINE_NAME}"
90 | ${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Creating virtual machine: ${DOCKER_MACHINE_MACHINE_NAME}"
91 | ${DOCKER_MACHINE_BIN} create --driver ${DOCKER_MACHINE_DRIVER} \
92 | --virtualbox-cpu-count ${DOCKER_MACHINE_CPU_COUNT} \
93 | --virtualbox-memory ${DOCKER_MACHINE_MEMORY_COUNT} \
94 | --virtualbox-disk-size ${DOCKER_MACHINE_DISK_SIZE} \
95 | ${DOCKER_MACHINE_MACHINE_NAME}
96 | }
97 |
98 | # Extra vm options
99 | ${DOCKER_MACHINE_BIN} ssh ${DOCKER_MACHINE_MACHINE_NAME} sudo sysctl -w vm.max_map_count=262144
100 | }
101 |
102 | ${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Configuring NFS mount for: '${DOCKER_MACHINE_MACHINE_NAME}'"
103 |
104 | ${DOCKER_MACHINE_NFS_BIN} ${DOCKER_MACHINE_MACHINE_NAME}
105 |
106 | [[ $1 == "initialize" ]] && {
107 | echo ""
108 | echo -e "\033[91m>>>>> \033[92m *** CONGRATULATION *** DOCKER READY TO USE *** \033[91m<<<<<"
109 | echo -e "\033[0m"
110 | echo "Please start the service by following command:"
111 | echo -e "\033[0m"
112 | echo -e "\033[0m"
113 | echo -e " \033[96mbrew services start docker-virtualbox"
114 | echo -e "\033[0m"
115 | exit 0
116 | }
117 |
118 | echo "===> Starting Gobetween..."
119 | [[ -f /tmp/docker-virtualbox-gobetween.pid ]] && ps -p $(cat /tmp/docker-virtualbox-gobetween.pid) > /dev/null && {
120 | echo "---> Gobetween already started, disabling outdated port forwarding..."
121 | servers=$(curl --silent http://127.0.0.1:8181/servers | ${JQ_BIN} -r '. | keys | .[]')
122 | for server in $servers; do
123 | echo "Disabling port forwarding for: ${server}"
124 | curl --silent -X DELETE http://127.0.0.1:8181/servers/${server}
125 | done
126 | } || {
127 | sudo ${GOBETWEEN_BIN} -c $(brew --prefix)/etc/docker-virtualbox/gobetween.toml > ${LOGDIR}/docker-virtualbox-gobetween.log 2>&1 &
128 | echo $! > /tmp/docker-virtualbox-gobetween.pid
129 | echo "---> Gobetween started"
130 | }
131 |
132 | # setup env
133 | echo "export DOCKER_CLI_BIN_PATH=\"$(brew --prefix docker)/bin/docker\"" > /tmp/docker-virtualbox.env
134 | echo "export DOCKER_COMPOSE_BIN_PATH=\"$(brew --prefix docker-compose)/bin/docker-compose\"" >> /tmp/docker-virtualbox.env
135 | echo "export DOCKER_MACHINE_IP=\"$(${DOCKER_MACHINE_BIN} ip ${DOCKER_MACHINE_MACHINE_NAME})\"" >> /tmp/docker-virtualbox.env
136 | ${DOCKER_MACHINE_BIN} env ${DOCKER_MACHINE_MACHINE_NAME} --shell bash >> /tmp/docker-virtualbox-machine.env
137 | ${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Virtual machine '${DOCKER_MACHINE_MACHINE_NAME}' ready for work"
138 |
139 |
140 | source /tmp/docker-virtualbox.env
141 | source /tmp/docker-virtualbox-machine.env
142 |
143 | echo ""
144 | echo "===> Configuring port forwarding for alrady running containers..."
145 | while read -r subjectid
146 | do
147 | ports="$(${DOCKER_CLI_BIN_PATH} inspect -f '{{range $p, $conf := .NetworkSettings.Ports }} {{ if $conf}} {{$conf}} {{end}} {{end}}' "${subjectid}" | sed -nE 's:\[\{[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}[^0-9]*([0-9]{1,})\}\]:\1:pg' | xargs echo -n)"
148 | [[ -z ${ports} ]] || {
149 | for port in $ports; do
150 | echo ""
151 | echo "Enabling port forwarding: ${port} -> ${DOCKER_MACHINE_IP}:${port}"
152 | >&2 curl --silent -X POST --data "@-" http://127.0.0.1:8181/servers/${subjectid_short}_${port} < Listen for events..."
175 | [[ -f /tmp/docker-virtualbox.starting ]] && rm /tmp/docker-virtualbox.starting
176 | while read -r event;
177 | do
178 | subject=$(echo $event | awk '{ print $2 }')
179 | action=$(echo $event | awk '{ print $3 }')
180 | subjectid=$(echo $event | awk '{ print $4 }')
181 | subjectid_short=$(echo $subjectid | cut -c -8)
182 | if [[ "container" == ${subject} ]]; then
183 | case $action in
184 | "start")
185 | ports="$(${DOCKER_CLI_BIN_PATH} inspect -f '{{range $p, $conf := .NetworkSettings.Ports }} {{ if $conf}} {{$conf}} {{end}} {{end}}' "${subjectid}" | sed -nE 's:\[\{[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}[^0-9]*([0-9]{1,})\}\]:\1:pg' | xargs echo -n)"
186 | [[ -z ${ports} ]] || {
187 | for port in $ports; do
188 | echo ""
189 | echo "Enabling port forwarding: ${port} -> ${DOCKER_MACHINE_IP}:${port}"
190 | >&2 curl --silent -X POST --data "@-" http://127.0.0.1:8181/servers/${subjectid_short}_${port} < service terminated"
229 |
--------------------------------------------------------------------------------