Commit 21a2f282 by Renzo Lucioni

Allow access to OS X hosts from inside containers

This adds a script for creating a loopback alias and adding a corresponding entry to /etc/hosts on OS X machines. See the README additions for more details. The script can be run with a Make target, which in turn is run by `devstack.start` to avoid any manual steps.

ECOM-6586
parent f204fc5e
...@@ -18,12 +18,15 @@ devstack.provision: ## Provision all services ...@@ -18,12 +18,15 @@ devstack.provision: ## Provision all services
devstack.reset: ## Remove all service containers devstack.reset: ## Remove all service containers
docker-compose down docker-compose down
devstack.start: clone ## Start all services devstack.start: clone loopback ## Start all services
docker-compose up docker-compose up
devstack.stop: ## Stop all services devstack.stop: ## Stop all services
docker-compose stop docker-compose stop
loopback: ## Create loopback alias
./loopback.sh
requirements: ## Install requirements requirements: ## Install requirements
pip install -r requirements.txt pip install -r requirements.txt
......
...@@ -27,3 +27,28 @@ After the services have started, if you need shell access to one of the services ...@@ -27,3 +27,28 @@ After the services have started, if you need shell access to one of the services
``` ```
$ make devstack.open.discovery $ make devstack.open.discovery
``` ```
## Loopback Alias
Containers making requests to the LMS and Studio must communicate with ports exposed on the host system by the Vagrant VM.
This is fine on Linux, but doesn't work out of the box on OS X. Attempting to access localhost on a container will result
in talking to the Docker for Mac HyperKit VM, not the host machine.
While it's true that you can get this to work by accessing your Mac's external IP from your containers, this isn't ideal because
it won't work if you have no network access on your host. Your external IP also changes as you switch networks, meaning you'd have
to change the IP accessed by your containers every time you changed networks.
A better solution, borrowed from the [Docker forums](https://forums.docker.com/t/access-host-not-vm-from-inside-container/11747/10),
is to give your host a fixed address by creating a [loopback](http://askubuntu.com/questions/247625/what-is-the-loopback-device-and-how-do-i-use-it)
alias. This is done for you by the `devstack.start` target.
The result is a fixed IP which your containers can use to access ports on your host machine. Note that the underlying script uses `sudo`;
adding IP addresses requires root access. Also note that the alias will not survive a host reboot, which is why the `devstack.start` target
always attempts to set up the loopback for you.
Part of the loopback alias setup includes adding a line to the `/etc/hosts` file on your machine. If you want to stop using devstack, you can clean this up by opening your `/etc/hosts` file and removing this line:
```
10.254.254.254 docker.host
```
...@@ -17,9 +17,10 @@ services: ...@@ -17,9 +17,10 @@ services:
context: . context: .
dockerfile: ./docker/elasticsearch/Dockerfile dockerfile: ./docker/elasticsearch/Dockerfile
container_name: edx.devstack.elasticsearch container_name: edx.devstack.elasticsearch
ports: # TODO: What to do about these forwarded ports? They'll conflict with ports forwarded by the Vagrant VM.
- "9200:9200" # ports:
- "9300:9300" # - "9200:9200"
# - "9300:9300"
volumes: volumes:
- ./.dev/volumes/elasticsearch/data:/usr/share/elasticsearch/data - ./.dev/volumes/elasticsearch/data:/usr/share/elasticsearch/data
- ./.dev/volumes/elasticsearch/logs:/usr/share/elasticsearch/logs - ./.dev/volumes/elasticsearch/logs:/usr/share/elasticsearch/logs
...@@ -27,8 +28,8 @@ services: ...@@ -27,8 +28,8 @@ services:
memcached: memcached:
container_name: edx.devstack.memcached container_name: edx.devstack.memcached
image: memcached:1.4.24 image: memcached:1.4.24
ports: # ports:
- "11211:11211" # - "11211:11211"
mysql: mysql:
command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci
...@@ -37,8 +38,8 @@ services: ...@@ -37,8 +38,8 @@ services:
MYSQL_ROOT_PASSWORD: "" MYSQL_ROOT_PASSWORD: ""
MYSQL_ALLOW_EMPTY_PASSWORD: "yes" MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
image: mysql:5.6 image: mysql:5.6
ports: # ports:
- "3306:3306" # - "3306:3306"
volumes: volumes:
- ./.dev/volumes/mysql:/var/lib/mysql - ./.dev/volumes/mysql:/var/lib/mysql
...@@ -68,6 +69,9 @@ services: ...@@ -68,6 +69,9 @@ services:
environment: environment:
TEST_ELASTICSEARCH_URL: "http://edx.devstack.elasticsearch:9200" TEST_ELASTICSEARCH_URL: "http://edx.devstack.elasticsearch:9200"
ENABLE_DJANGO_TOOLBAR: 1 ENABLE_DJANGO_TOOLBAR: 1
extra_hosts:
# For server-to-server calls.
- "docker.host:10.254.254.254"
image: edxops/discovery:devstack image: edxops/discovery:devstack
ports: ports:
- "18381:18381" - "18381:18381"
......
# It's not necessary to do this on Linux, so check that we're on OS X before continuing.
if [ "$(uname)" == "Darwin" ]; then
# This loopback alias allows access to OS X hosts from inside a container. 10.254.254.254
# is a private IP likely to be unused. As is, the alias will not survive a reboot.
# Borrowed from https://forums.docker.com/t/access-host-not-vm-from-inside-container/11747/10.
sudo ifconfig lo0 alias 10.254.254.254
# This will check for a "docker.host" entry in your hosts file. It's created if it doesn't
# exist, so you can use URLs like "http://docker.host:8000" in your service configuration.
if ! grep -q "docker.host" /etc/hosts; then
# Using tee to write to /etc/hosts because using >> to append isn't allowed, even as root.
# See http://stackoverflow.com/a/550808.
echo "10.254.254.254 docker.host" | sudo tee -a /etc/hosts > /dev/null
fi
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
if ! grep -q "docker.host" /etc/hosts; then
echo "127.0.0.1 docker.host" | sudo tee -a /etc/hosts > /dev/null
fi
fi
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment