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"