├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── config └── .placeholder ├── docker-compose.yml └── helpers └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | config/* 3 | *.ovpn 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk add --no-cache socat 3 | ENTRYPOINT ["socat"] 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Konrad Wojas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This solution allows you to access your [Docker for Mac](https://docs.docker.com/engine/installation/mac/)'s internal networks directly from your macOS host machine, using OpenVPN. 2 | 3 | 4 | ## Quickstart 5 | 6 | To access your Docker networks: 7 | 8 | * Install [Tunnelblick](https://tunnelblick.net/downloads.html) (open source macOS OpenVPN client that sits in your menubar) 9 | * Run `docker-compose up`. The first time it will take up to a minute to startup, because it needs to generate keys. 10 | * Doubleclick the generated `docker-for-mac.ovpn` in Finder (or run `open docker-for-mac.ovpn` in your terminal) to add it to Tunnelblick. You will find it in the current folder. 11 | * In Tunnelblick, connect to your new docker-for-mac profile. 12 | 13 | You will now be able to access the internal Docker networks from macOS. 14 | 15 | 16 | ## Implementation notes 17 | 18 | The Compose configuration consists of two services, both based on the tiny Alpine Linux distribution. 19 | 20 | 21 | ### openvpn 22 | 23 | The OpenVPN image used is [kylemanna/openvpn](https://hub.docker.com/r/kylemanna/openvpn/). 24 | 25 | Both server-side and client-side configuration are automatically generated by `helpers/run.sh`, which calls the helper scripts in original image and adjust configuration for accessing the Docker for Mac networks only. 26 | 27 | This service runs on TCP port 1194 using *host* networking, which means it has access to all Docker networks in the host VM. 28 | 29 | Only the `172.16.0.0/20` private network is routed to Docker for Mac by the generated config. No DNS servers are set on the host. 30 | 31 | The OpenVPN configuration (`/etc/openvpn/*`) is stored locally in `./config/` so that it survives Docker filesystem resets and allows for easy customization. 32 | 33 | ### proxy 34 | 35 | Since containers running in host networking mode in Docker for Mac cannot bind ports to make them accessible from macOS, we need an extra TCP proxy. This image uses socat to forward port 13194 to the OpenVPN container. 36 | 37 | ## Tips 38 | 39 | * Add `restart: always` to both services in `docker-compose.yml` to have them automaticaly restart. 40 | * To route extra subnets, add extra `route` statements in your `docker-for-mac.ovpn` 41 | * To setup static IP addresses for containers, check the `app_net` examples in the [Compose file reference](https://docs.docker.com/compose/compose-file/) 42 | * To regenerate all files, remove `config/*` and `docker-for-mac.ovpn` 43 | -------------------------------------------------------------------------------- /config/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wojas/docker-mac-network/5a4171edaaf2626d52a20e8815eb53b4335bdcff/config/.placeholder -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | 5 | proxy: 6 | build: . 7 | ports: 8 | - "127.0.0.1:13194:13194" 9 | #- "127.0.0.1:13194:13194/udp" 10 | # UDP did not work, probably because the source port changes all the time 11 | #command: -v UDP4-RECVFROM:13194,fork UDP4-SENDTO:172.17.0.1:1194 12 | command: TCP-LISTEN:13194,fork TCP:172.17.0.1:1194 13 | restart: always 14 | 15 | openvpn: 16 | image: kylemanna/openvpn 17 | volumes: 18 | - .:/local 19 | - ./config:/etc/openvpn 20 | network_mode: host 21 | cap_add: 22 | - NET_ADMIN 23 | environment: 24 | dest: docker-for-mac.ovpn 25 | DEBUG: '1' 26 | command: /local/helpers/run.sh 27 | restart: always 28 | 29 | -------------------------------------------------------------------------------- /helpers/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | dest=${dest:-docker.ovpn} 4 | 5 | if [ ! -f "/local/$dest" ]; then 6 | echo "*** REGENERATING ALL CONFIGS ***" 7 | set -ex 8 | #rm -rf /etc/openvpn/* 9 | ovpn_genconfig -u tcp://localhost 10 | sed -i 's|^push|#push|' /etc/openvpn/openvpn.conf 11 | echo localhost | ovpn_initpki nopass 12 | easyrsa build-client-full host nopass 13 | ovpn_getclient host | sed ' 14 | s|localhost 1194|localhost 13194|; 15 | s|redirect-gateway.*|route 172.16.0.0 255.240.0.0|; 16 | ' > "/local/$dest" 17 | fi 18 | 19 | # Workaround for https://github.com/wojas/docker-mac-network/issues/6 20 | /sbin/iptables -I FORWARD 1 -i tun+ -j ACCEPT 21 | 22 | exec ovpn_run 23 | --------------------------------------------------------------------------------