Docker is an emerging technology to launch applications without installation. The same host can run multiple Docker containers of any type, so one physical or virtual server can serve as a complete mini cloud environment. Most of the time Linux is used as the host operating system.
In this example, we will launch a PostgreSQL Docker container on macOS, and access the PostgreSQL database server from a Windows VirtualBox virtual machine.
From VMware Fusion
- Configure the first network adapter to use NAT
From Virtual Box
Create a network between the guest VM and the host in Oracle VirtualBox
A VirtualBox virtual machine can share the networking with the host with the NAT setting, or it can be an independent computer on the network with the Bridged setting.
To access the host directly from the guest VM we can set up a host-only network, that only the host and the guest can access. This way we can launch a container on the host and access it from the guest via the host-only mini-network.
To set up the private host-only network
- Open the VirtualBox application and shut down all virtual machines
- In the File menu select Host Network Manager…
- On the Host Network Manager window click the Create button
- Click the Enable checkbox in the DHCP Server column and click the Close button
Connect the virtual machine to the host-only network
The VirtualBox virtual machines can have four virtual network adapters. Always use the first adapter to connect to the host-only network.
- Select the virtual machine in the list and click the Settings icon
- On the Network tab click the arrow next to the Attached to drop-down
- Select the Host-only adapter
- The host-only network is automatically selected
- Select the second adapter, click the Enable Network Adapter checkbox, and select NAT
- Click the OK button to close the window.
Find the IP address of the host machine
When using VMware Fusion
WMware Fusion registers a local IP address to access the Mac host from the guest machine. On the Mac host terminal execute
ifconfig vmnet8
vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 00:50:56:c0:00:08
inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
Add the IP address to the C:\Windows\System32\drivers\etc\hosts file
192.168.2.1 mac.localhost
In your connection string use the address mac.localhost as the database URL
When using Oracle Virtual Box
On Docker version 18.03 and above you can use host.docker.internal to connect to the host machine.
On older Docker versions
- Open a terminal on the host machine.
- On Mac
- enter the following command. Use the IP address range of the host-only network above.
ifconfig | grep 192.168
inet 192.168.56.1 netmask 0xffffff00 broadcast 192.168.56.255
- Based on the output above, the IP address of the host machine is 192.168.56.1
- enter the following command. Use the IP address range of the host-only network above.
Launch a PostgreSQL Docker container
- Create a docker-compose.yml file. Containers are ephemeral, when we terminate them, all data stored inside the container is lost. We want to keep the database files on our local hard drive, so this configuration will map the /var/lib/postgresql/data directory of the Docker container to the pgdata subdirectory of the current working directory. The 5432 is the default port of the PostgreSQL database server, we will expose it on port 5432 of the host with
version: '3' services: postgres: image: postgres:10 env_file: .env ports: - "5432:5432" restart: always volumes: - $PWD/pgdata:/var/lib/postgresql/data
- Open a terminal window in the same directory and launch the Docker container
docker-compose up -d
Connect to the host machine from the guest machine
Test the connection
- Open a terminal on the guest machine
- Test the connection to the host machine
ping host.docker.internal
or
ping 192.168.56.1
Configure your application on the virtual machine to connect to the Docker PostgreSQL database server on the host
- Change the connection string, and specify the exposed port on the host machine:
"Server=host.docker.internal;Port=5432;Database=MY_DATABASE;Username=MY_USERNAME;Password=MY_PASSWORD"
or
"Server=192.168.56.1;Port=5432;Database=MY_DATABASE;Username=MY_USERNAME;Password=MY_PASSWORD"
Uh, you say you will expose it on 5433 but you don’t illustrate how that’s done anywhere?!
Hello Daevid,
Thank you for finding the typo. We expose the database on the standard port 5432 in the script. An earlier version of the script used port 5433, because I also had another PostgreSQL instance running on my machine.