Links and Container Naming

## Links - Spec

Links are a way of expressing a relationship between one container and another.  When you link a container, you create a parent/child relationship between the two.  As a side effect links also allow you to name containers and reference them by name.  Containers can be references by more than one name.

#### Breaking changes
This the new link feature we will be disabling intercontainer communication by default.  Containers will not be able to communicate with each other over the docker0 bridge without having a link to that container.  Even with a link, a parent can only communicate to the ports exposed by the child and nothing more.

Initially links will be expressed by injecting the child's data into the parent's environment accessible via namespaced variables:


#### Examples
* `REDIS_ENV_{key}={value}` 
* `REDIS_PORT={value}` 
* `REDIS_PORT_6379_TCP={value}`.


### Rename
By default a link will be created for every container with the name set as the automatically generated container id.

```bash
REDIS=$(docker run -d crosbymichael/redis)
echo $REDIS
32da9f6caf76

docker ps
ID                  IMAGE                        CMD                         EXPOSES        NAMES
32da9f6caf76        crosbymichael/redis:latest   /redis/src/redis-ser        6379/tcp


docker link 32da9f6caf76 db1

docker ps
ID                  IMAGE                        CMD                         EXPOSES        NAMES
32da9f6caf76        crosbymichael/redis:latest   /redis/src/redis-ser        6379/tcp       db1

```

If we want to view all names for our docker host you can use the new `docker ls` command.

```bash
docker ls

NAME            ID                IMAGE
db1             32da9f6caf76      crosbymichael/redis:latest
```

### Basic link

Using the container named 'db1' from our previous example we will create a relationship between our webapp container and redis.

To create a link between two containers you add the `-link` flag to your `docker run` command passing the name and alias of the container that you want to link as the child.  The alias will be used as the namespace to set environment variables in the parent container.  The format is `-link <name>:<alias>`.  The alias will be converted to ALL_CAPS when environment variables are created.  

```bash

docker ls

NAME            ID                IMAGE
db1             32da9f6caf76      crosbymichael/redis:latest

# run a new webapp container and add our redis database as a child
docker run -link db1:redis -t -i webapp sh


# access the environment inside our webapp conatiner to collect to redis

BusyBox v1.19.3 (Ubuntu 1:1.19.3-7ubuntu1.1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

/ #

echo $REDIS_PORT_6379_ADDR
tcp://172.17.0.2:6379
./redis-cli -h 172.17.0.2
redis 172.17.0.2:6379>

# back on the host

docker ps
ID                  IMAGE                        CMD                         EXPOSES        NAMES
32da9f6caf76        crosbymichael/redis:latest   /redis/src/redis-ser        6379/tcp       db1
37ewg328232g        webapp                       sh                                         

# List all the links 

docker ls

NAME                  CONTAINER         IMAGE
db1                   32da9f6caf76      crosbymichael/redis:latest
37ewg328232g          37ewg328232g      webapp
37ewg328232g/redis    32da9f6caf76      crosbymichael/redis:latest

# we can see that our redis container is now a child of our webapp

# Give a name to our webapp container
docker link 37ewg328232g frontend

docker ls

NAME                  CONTAINER         IMAGE
db1                   32da9f6caf76      crosbymichael/redis:latest
frontend              37ewg328232g      webapp
frontend/redis        32da9f6caf76      crosbymichael/redis:latest
```

### Remove redis as a child of frontend
```bash
docker ls

NAME                  CONTAINER         IMAGE
db1                   32da9f6caf76      crosbymichael/redis:latest
frontend              37ewg328232g      webapp
frontend/redis        32da9f6caf76      crosbymichael/redis:latest

docker rm frontend/redis


docker ls

NAME                  CONTAINER         IMAGE
db1                   32da9f6caf76      crosbymichael/redis:latest
frontend              37ewg328232g      webapp
```


### Introspecting the linked container's environment

Lets run another redis container with a password that the client must use to connect.  We store the password in the environment of the container so we can use introspection to retreive the password by the parent.

```bash
REDIS=$(docker run -d -e PASSWORD=dockerpass crosbymichael/redis --requirepass dockerpass)

docker link $REDIS db1

docker run -t -i -link db1:redis webapp sh

# inside the webapp container

BusyBox v1.19.3 (Ubuntu 1:1.19.3-7ubuntu1.1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

echo $db_PORT_6379_ADDR
tcp://172.17.0.2:6379
./redis-cli -h 172.17.0.2 -a $db_ENV_PASSWORD
redis 172.17.0.2:6379> set hello world
OK
redis 172.17.0.2:6379>

```

### Client Libs
With client libs you can simplify links more.

```python
import docker
import time
from redis import Redis
 
proto, ip, port = docker.require('redis')
password = docker.require_env('redis', 'password')
 
r = Redis(host=ip, port=int(port), password=password)
 
print 'Connected to redis...'
 
r.set('name', 'docker')
while True:
        print r.get('name')
        time.sleep(1)
```

### TLDR
Links are a way to express relationships between containers and allow introspection based on those relationships.