Repository: sergeycherepanov/homebrew-docker-virtualbox
Branch: master
Commit: db2937470ebc
Files: 7
Total size: 17.3 KB
Directory structure:
gitextract_54isjdzp/
├── Formula/
│ ├── docker-machine-nfs-generic.rb
│ ├── docker-machine-pf.rb
│ └── docker-virtualbox.rb
├── README.md
└── bin/
├── docker
├── docker-compose
└── docker-machine-init
================================================
FILE CONTENTS
================================================
================================================
FILE: Formula/docker-machine-nfs-generic.rb
================================================
class DockerMachineNfsGeneric < Formula
desc "Activates NFS on docker-machine (with generic driver support)"
homepage "https://github.com/sergeycherepanov/docker-machine-nfs"
url "https://github.com/sergeycherepanov/docker-machine-nfs/archive/0.5.4.2.tar.gz"
sha256 "5067da89d8ba1205883cfa0087106cbbe5bc4140ee4b9f45ed1a7b772363417b"
license "MIT"
version "0.5.4"
revision 2
def install
bin.install "docker-machine-nfs.sh" => "docker-machine-nfs-generic"
end
test do
system "#{bin}/docker-machine-nfs-generic"
end
end
================================================
FILE: Formula/docker-machine-pf.rb
================================================
require 'formula'
class DockerMachinePf < Formula
url 'https://github.com/johanhaleby/docker-machine-port-forwarder/archive/d58e7b8f267b6d9e4156f0c5939c01a84afb52ec.tar.gz'
homepage 'https://github.com/johanhaleby/docker-machine-port-forwarder'
sha256 '0acd6f61c71b4f719613c92e2b5df5231ec5d76816ef4e321c2b7c2150d1fcdf'
version "0.0.1"
revision 2
def install
bin.install "pf"
end
end
================================================
FILE: Formula/docker-virtualbox.rb
================================================
require 'formula'
class DockerVirtualbox < Formula
url "https://github.com/sergeycherepanov/homebrew-docker-virtualbox.git", :using => :git
version "0.0.7"
revision 1
depends_on 'coreutils'
depends_on 'curl'
depends_on 'jq'
depends_on 'terminal-notifier'
depends_on 'docker'
depends_on 'docker-compose'
depends_on 'docker-credential-helper'
depends_on 'docker-machine'
depends_on 'docker-machine-nfs-generic'
keg_only "this package may conflict with official docker client"
resource "gobetween" do
url "https://github.com/yyyar/gobetween/releases/download/0.8.0/gobetween_0.8.0_darwin_amd64.zip"
sha256 "15efec9cef9dc01c4e195042df62def95f189090e470678d5b6f024afa71e1b0"
end
def install
resource("gobetween").stage do
bin.install "gobetween"
end
(buildpath/"gobetween.toml").write <<~EOS
[api]
enabled = true
bind = "127.0.0.1:8181"
EOS
(etc/"docker-virtualbox").mkpath
etc.install "gobetween.toml" => 'docker-virtualbox/gobetween.toml'
bin.install "bin/docker"
bin.install "bin/docker-compose"
bin.install "bin/docker-machine-init"
prefix.install "assets/djocker.png"
end
def caveats
s = <<~EOS
Docker Virtualbox was installed
Please don't forget to configure your PATH variable
EOS
s
end
def plist; <<~EOS
KeepAlive
Label
#{plist_name}
ProgramArguments
#{opt_bin}/docker-machine-init
RunAtLoad
WorkingDirectory
/tmp
EOS
end
end
================================================
FILE: README.md
================================================
# Homebrew Docker Virtualbox (Not Only for VirtualBox)
This Homebrew formula fixes Docker issues on AMD‑based macOS systems (Ryzentosh), and it also works on regular Macs using VirtualBox or other Docker Machine drivers.
**Before starting:** read this notice: [https://gist.github.com/slykar/e92732be9bf81a71e08068245656d70e?permalink_comment_id=4105556#gistcomment-4105556](https://gist.github.com/slykar/e92732be9bf81a71e08068245656d70e?permalink_comment_id=4105556#gistcomment-4105556)
---
## 1. Install VirtualBox (Optional)
Download VirtualBox: [https://www.virtualbox.org/wiki/Downloads](https://www.virtualbox.org/wiki/Downloads)
> Required only if you want to use the VirtualBox driver. Remove previous installations first.
---
## 2. VirtualBox 6.1.28+ Network Configuration
If you use VirtualBox, allow access to 192.168.99.0/8:
Edit:
```
sudo nano /etc/vbox/networks.conf
```
Add:
```
* 192.168.99.0/8
```
---
## 3. Install docker‑virtualbox via Homebrew
```
brew tap serhiicherepanov/docker-virtualbox
brew install docker-virtualbox
```
---
## 4. Configure docker‑virtualbox Requirements
These require root permissions:
Ensure NFS exports file exists:
```
sudo touch /etc/exports
```
Allow the `staff` group necessary permissions:
```
sudo tee /etc/sudoers.d/docker-machine-nfs < Reboot to apply changes.
---
## 5. Configure Environment
If **not** using Docker Desktop:
```
brew link --force --overwrite docker-virtualbox
```
If **using** Docker Desktop:
**bash**
```
echo "export PATH=\"$(brew --prefix docker-virtualbox)/bin:$PATH\"" >> ~/.bash_profile
```
**zsh**
```
echo "export PATH=\"$(brew --prefix docker-virtualbox)/bin:$PATH\"" >> ~/.zshrc
```
Reload:
```
exec $SHELL
```
---
## 6. Initialize Docker Machine
Run once:
```
docker-machine-init initialize
```
This will download, prepare, and configure the VirtualBox Docker Machine.
---
## 7. Start docker‑virtualbox
```
brew services start docker-virtualbox
```
Logs:
```
/tmp/docker-virtualbox.log
```
---
## 8. Test Docker
```
docker run -d -p 8989:80 nginx
curl -v localhost:8989
```
---
# Additional Options
## Use a Non‑VirtualBox Driver
Example (generic SSH driver):
```
docker-machine create \
--driver generic \
--generic-ip-address=192.168.24.108 \
--generic-ssh-user=developer \
--generic-ssh-key=$HOME/.ssh/id_rsa \
docker
```
> Works only with Debian‑based remote systems.
---
## Useful Commands
View logs:
```
tail -n 1000 -f /tmp/docker-virtualbox.log
```
SSH into the machine:
```
docker-machine ssh docker
```
Stop service:
```
brew services stop docker-virtualbox
```
Load environment for tools:
```
source /tmp/docker-virtualbox.env
source /tmp/docker-virtualbox-machine.env
```
---
# Optional Enhancements
## Auto‑Start on Login
Create launch agents:
```
mkdir -p ~/Library/LaunchAgents
```
Configure a custom plist to auto‑start docker‑virtualbox.
## Increase VM Resources
```
docker-machine stop docker
VBoxManage modifyvm docker --memory 4096 --cpus 4
docker-machine start docker
```
## Custom Network Range
Edit:
```
sudo nano /etc/vbox/networks.conf
```
Add:
```
* 10.10.0.0/16
```
---
# Known Issues
1. macOS cannot sleep while NFS is running.
2. UDP port forwarding not supported.
3. VirtualBox may need kext reload after macOS updates.
4. File sharing may be slower compared to Docker Desktop.
================================================
FILE: bin/docker
================================================
#!/usr/bin/env bash
set -e
#set -x
LIMIT=90
if [[ -f /tmp/docker-virtualbox.starting ]]; then
>&2 echo -e "\033[93mWaiting while Docker starting..."
>&2 echo -e "\033[0m"
i=0
while [[ -f /tmp/docker-virtualbox.starting ]]; do
if [[ "$i" -gt "$LIMIT" ]]; then
>&2 echo -e "Default \e[91mThe timeout reached, please verify the vm log for errors: /tmp/docker-virtualbox.log\e[39m"
fi
i=$(($i+1))
sleep 1;
done
fi
[[ -f /tmp/docker-virtualbox.env && -f /tmp/docker-virtualbox-machine.env ]] || {
echo -e "\033[91m"
echo -e "\033[91mLooks like docker-virtualbox doesn't work"
echo -e ""
echo -e "\033[0mYou have to start it by following command:"
echo -e ""
echo -e "\033[96mbrew services start docker-virtualbox "
echo -e "\033[0m"
exit 1
}
source /tmp/docker-virtualbox.env
[[ -z "${DOCKER_HOST}" ]] && {
source /tmp/docker-virtualbox-machine.env
}
exec ${DOCKER_CLI_BIN_PATH} "$@"
================================================
FILE: bin/docker-compose
================================================
#!/usr/bin/env bash
set -e
#set -x
LIMIT=90
if [[ -f /tmp/docker-virtualbox.starting ]]; then
>&2 echo -e "\033[93mWaiting while Docker starting..."
>&2 echo -e "\033[0m"
i=0
while [[ -f /tmp/docker-virtualbox.starting ]]; do
if [[ "$i" -gt "$LIMIT" ]]; then
>&2 echo -e "Default \e[91mThe timeout reached, please verify the vm log for errors: /tmp/docker-virtualbox.log\e[39m"
fi
i=$(($i+1))
sleep 1;
done
fi
[[ -f /tmp/docker-virtualbox.env && -f /tmp/docker-virtualbox-machine.env ]] || {
echo -e "\033[91m"
echo -e "\033[91mLooks like docker-virtualbox doesn't work"
echo -e ""
echo -e "\033[0mYou have to start it by following command:"
echo -e ""
echo -e "\033[96mbrew services start docker-virtualbox "
echo -e "\033[0m"
exit 1
}
source /tmp/docker-virtualbox.env
[[ -z "${DOCKER_HOST}" ]] && {
source /tmp/docker-virtualbox-machine.env
}
exec ${DOCKER_COMPOSE_BIN_PATH} "$@"
================================================
FILE: bin/docker-machine-init
================================================
#!/usr/bin/env bash
set -e
[[ $1 == "debug" ]] && {
set -x
}
if [[ $(id -u ${USER}) -eq 0 ]]; then
echo "Please don't run this script under the root user!"
exit 1
fi
LOGDIR="/tmp";
[[ $1 != "initialize" ]] && [[ $1 != "debug" ]] && {
exec > ${LOGDIR}/docker-virtualbox.log
exec 2>&1
}
START_TIME=$(date +%s)
if [[ -n "${BREW_BIN}" ]]; then
BREW_BIN=$BREW_BIN
elif [[ "Darwin" == "$(uname)" ]]; then
BREW_BIN=/usr/local/bin
else
BREW_BIN=/home/linuxbrew/.linuxbrew/bin
fi
PATH="${PATH}:${BREW_BIN}"
GOBETWEEN_BIN=$(brew --prefix)/opt/docker-virtualbox/bin/gobetween
TERMINAL_NOTIFIER_BIN="$(brew --prefix terminal-notifier)/bin/terminal-notifier -appIcon $(brew --prefix docker-virtualbox)/djocker.png"
JQ_BIN="$(brew --prefix jq)/bin/jq"
DOCKER_MACHINE_BIN=$(brew --prefix docker-machine)/bin/docker-machine
DOCKER_MACHINE_NFS_BIN=$(brew --prefix docker-machine-nfs-generic)/bin/docker-machine-nfs-generic
DOCKER_MACHINE_DRIVER=${DOCKER_DRIVER-virtualbox}
DOCKER_MACHINE_MACHINE_NAME=${DOCKER_MACHINE_NAME-docker}
function stop()
{
[[ -f /tmp/docker-virtualbox.env ]] && rm /tmp/docker-virtualbox.env
[[ -f /tmp/docker-virtualbox-machine.env ]] && rm /tmp/docker-virtualbox-machine.env
echo "===> Stopping docker machine: ${DOCKER_MACHINE_MACHINE_NAME}"
${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Stopping virtual machine: '${DOCKER_MACHINE_MACHINE_NAME}'"
${DOCKER_MACHINE_BIN} stop ${DOCKER_MACHINE_MACHINE_NAME}
exit 0
}
trap stop SIGKILL
trap stop SIGTERM
trap stop SIGINT
${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Initialize..."
sleep 1
if [[ -z ${DOCKER_MACHINE_DISK_SIZE} ]]; then
DOCKER_MACHINE_DISK_SIZE="16000"
if [[ $($(brew --prefix coreutils)/libexec/gnubin/df --block-size=1073741824 | grep '\/$' | awk '{print $2}') -gt 200 ]]; then
DOCKER_MACHINE_DISK_SIZE="32000"
fi
fi
if [[ -z ${DOCKER_MACHINE_CPU_COUNT} ]]; then
if [[ "Darwin" == "$(uname)" ]]; then
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) }')
else
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) }')
fi
fi
if [[ -z ${DOCKER_MACHINE_MEMORY_COUNT} ]]; then
if [[ "Darwin" == "$(uname)" ]]; then
DOCKER_MACHINE_MEMORY_COUNT=$(sysctl -n hw.memsize | awk '{ mem=($1 * 0.25 / 1024 / 1024 ); print int(mem > 4096 ? 4096 : mem) }')
else
DOCKER_MACHINE_MEMORY_COUNT=$(free -b | grep Mem | awk '{ mem=($2 * 0.25 / 1024 / 1024 ); print int(mem > 4096 ? 4096 : mem) }')
fi
fi
[[ "Running" == $(${DOCKER_MACHINE_BIN} status ${DOCKER_MACHINE_MACHINE_NAME}) ]] && {
touch /tmp/docker-virtualbox.starting
echo "===> Virtual machine '${DOCKER_MACHINE_MACHINE_NAME}' already started"
${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Virtual machine '${DOCKER_MACHINE_MACHINE_NAME}' started"
} || {
touch /tmp/docker-virtualbox.starting
[[ "Stopped" == $(${DOCKER_MACHINE_BIN} status ${DOCKER_MACHINE_MACHINE_NAME}) ]] && {
${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Starting virtual machine: ${DOCKER_MACHINE_MACHINE_NAME}"
echo "===> Starting docker machine: ${DOCKER_MACHINE_MACHINE_NAME}"
${DOCKER_MACHINE_BIN} start ${DOCKER_MACHINE_MACHINE_NAME}
} || {
echo "===> Creating docker machine: ${DOCKER_MACHINE_MACHINE_NAME}"
${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Creating virtual machine: ${DOCKER_MACHINE_MACHINE_NAME}"
${DOCKER_MACHINE_BIN} create --driver ${DOCKER_MACHINE_DRIVER} \
--virtualbox-cpu-count ${DOCKER_MACHINE_CPU_COUNT} \
--virtualbox-memory ${DOCKER_MACHINE_MEMORY_COUNT} \
--virtualbox-disk-size ${DOCKER_MACHINE_DISK_SIZE} \
${DOCKER_MACHINE_MACHINE_NAME}
}
# Extra vm options
${DOCKER_MACHINE_BIN} ssh ${DOCKER_MACHINE_MACHINE_NAME} sudo sysctl -w vm.max_map_count=262144
}
${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Configuring NFS mount for: '${DOCKER_MACHINE_MACHINE_NAME}'"
${DOCKER_MACHINE_NFS_BIN} ${DOCKER_MACHINE_MACHINE_NAME}
[[ $1 == "initialize" ]] && {
echo ""
echo -e "\033[91m>>>>> \033[92m *** CONGRATULATION *** DOCKER READY TO USE *** \033[91m<<<<<"
echo -e "\033[0m"
echo "Please start the service by following command:"
echo -e "\033[0m"
echo -e "\033[0m"
echo -e " \033[96mbrew services start docker-virtualbox"
echo -e "\033[0m"
exit 0
}
echo "===> Starting Gobetween..."
[[ -f /tmp/docker-virtualbox-gobetween.pid ]] && ps -p $(cat /tmp/docker-virtualbox-gobetween.pid) > /dev/null && {
echo "---> Gobetween already started, disabling outdated port forwarding..."
servers=$(curl --silent http://127.0.0.1:8181/servers | ${JQ_BIN} -r '. | keys | .[]')
for server in $servers; do
echo "Disabling port forwarding for: ${server}"
curl --silent -X DELETE http://127.0.0.1:8181/servers/${server}
done
} || {
sudo ${GOBETWEEN_BIN} -c $(brew --prefix)/etc/docker-virtualbox/gobetween.toml > ${LOGDIR}/docker-virtualbox-gobetween.log 2>&1 &
echo $! > /tmp/docker-virtualbox-gobetween.pid
echo "---> Gobetween started"
}
# setup env
echo "export DOCKER_CLI_BIN_PATH=\"$(brew --prefix docker)/bin/docker\"" > /tmp/docker-virtualbox.env
echo "export DOCKER_COMPOSE_BIN_PATH=\"$(brew --prefix docker-compose)/bin/docker-compose\"" >> /tmp/docker-virtualbox.env
echo "export DOCKER_MACHINE_IP=\"$(${DOCKER_MACHINE_BIN} ip ${DOCKER_MACHINE_MACHINE_NAME})\"" >> /tmp/docker-virtualbox.env
${DOCKER_MACHINE_BIN} env ${DOCKER_MACHINE_MACHINE_NAME} --shell bash >> /tmp/docker-virtualbox-machine.env
${TERMINAL_NOTIFIER_BIN} -title "Docker Virtualbox" -message "Virtual machine '${DOCKER_MACHINE_MACHINE_NAME}' ready for work"
source /tmp/docker-virtualbox.env
source /tmp/docker-virtualbox-machine.env
echo ""
echo "===> Configuring port forwarding for alrady running containers..."
while read -r subjectid
do
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)"
[[ -z ${ports} ]] || {
for port in $ports; do
echo ""
echo "Enabling port forwarding: ${port} -> ${DOCKER_MACHINE_IP}:${port}"
>&2 curl --silent -X POST --data "@-" http://127.0.0.1:8181/servers/${subjectid_short}_${port} < Listen for events..."
[[ -f /tmp/docker-virtualbox.starting ]] && rm /tmp/docker-virtualbox.starting
while read -r event;
do
subject=$(echo $event | awk '{ print $2 }')
action=$(echo $event | awk '{ print $3 }')
subjectid=$(echo $event | awk '{ print $4 }')
subjectid_short=$(echo $subjectid | cut -c -8)
if [[ "container" == ${subject} ]]; then
case $action in
"start")
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)"
[[ -z ${ports} ]] || {
for port in $ports; do
echo ""
echo "Enabling port forwarding: ${port} -> ${DOCKER_MACHINE_IP}:${port}"
>&2 curl --silent -X POST --data "@-" http://127.0.0.1:8181/servers/${subjectid_short}_${port} < service terminated"