Skip to content

Instantly share code, notes, and snippets.

@nazariyv
Forked from excavador/README.md
Last active July 9, 2020 13:47
Show Gist options
  • Save nazariyv/ae4467f26ff251d4933c5463f1315169 to your computer and use it in GitHub Desktop.
Save nazariyv/ae4467f26ff251d4933c5463f1315169 to your computer and use it in GitHub Desktop.
automatically add alias ip address to loopback

Motivation

You often have several docker containers and applications which work together in the locel development environment. You need the following communications:

  • docker container to localhost
  • localhost to docker container
  • docker container to docker container

You have a way to connect localhost-to-docker using -p (port-mapping) docker option. For instance, you can start PostgreSQL container using -p 0.0.0.0:5432:5432 and then connect like to normal PostgreSQL

You have a way to connect docker-to-localhost using --net=host docker option. For instance, you can start Nginx container with this option and nginx would be able to connect with your localhost daemons.

You have a way to connect docker-to-docker using links or docker-compose.

So we have one problem and three solutions. It’s not inspiring, right?

Problem #1

You do not have a way to connect localhost-to-docker and docker-to-localhost at the same time. In fact, you can achieve this only in Linux.

Docker restricts simultaneous usage of this -p and --net=host on OSX. If you start container with -p you’re able to connect from localhost to container, but not from container to localhost.

If you start container with --net=host you’re able to connect from docker container to localhost, but not from localhost to container.

One of the possible solution: use -p option always and use docker auto-assigned IP-address for connect from local to docker container, but note the Problem #2.

Problem #2

Docker generates IP-address unstably. You will receive a new IP address on every container run. Moreover, the range of addresses is different under Linux and OSX.

One of the possible solutions: inspect docker container ip-address via docker info after container start. The problem is that you have to use this information in your scripts, in contrast to 127.0.0.1 address, which you use without Docker.

Conclusion

You do not have stable and simple solution to communicate between localhost and docker containers which works identically both under Linux and OSX.

Solution

Loopback alias ip-address is the simplest way to make localhost and docker containers communications identical on OSX and Linux.

  1. Follow the manual for Linux and OSX to create alias to loopback device. I use ip-address 10.200.10.1 for that.
  2. Always run docker containers with -p option (if docker container listens to some port, obviously)
  3. Use ip address 10.200.10.1 everywhere - in your localhost processes, inside docker containers

As a result, every docker container and localhost process would go to the single communication point. And yes, on OSX and Linux, without difference!

Configure Linux

  1. sudo cp loopback-alias.service /etc/systemd/system/loopback-alias.service
  2. sudo systemctl daemon-reload
  3. sudo systemctl enable loopback-alias
  4. sudo systemctl start loopback-alias

Configure OSX

  1. sudo cp loopback-alias.plist /Library/LaunchDaemons/loopback-alias.plist
  2. sudo launchctl load -w /Library/LaunchDaemons/loopback-alias.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist>
<plist version="1.0">
<dict>
<key>Label</key>
<string>loopback-alias</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/ifconfig</string>
<string>lo0</string>
<string>alias</string>
<string>10.200.10.1</string>
<string>netmask</string>
<string>255.255.255.0</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
[Unit]
Description=loopback alias
Wants=network.target
Before=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/ip addr add 10.200.10.1/32 dev lo label lo:1i
ExecStop=/sbin/ip addr del 10.200.10.1/32 dev lo
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment