Docker: Are Docker Links Deprecated

Docker: Are Docker links deprecated?

Docker networking is being promoted as successor - https://docs.docker.com/engine/userguide/networking/

Before the Docker network feature, you could use the Docker link feature to allow containers to discover each other. With the introduction of Docker networks, containers can be discovered by its name automatically.

On whether you should stop using them - yes. The docker world is currently moving very fast, and links has been "legacy" for a few releases now.

docker-compose: difference between networks and links

Links have been replaced by networks. Docker describes them as a legacy feature that you should avoid using. You can safely remove the link and the two containers will be able to refer to each other by their service name (or container_name).

With compose, links do have a side effect of creating an implied dependency. You should replace this with a more explicit depends_on section so that the app doesn't attempt to run without or before redis starts.

As an aside, I'm not a fan of hard coding container_name unless you are certain that this is the only container that will exist with that name on the host and you need to refer to it from the docker cli by name. Without the container name, docker-compose will give it a less intuitive name, but it will also give it an alias of redis on the network, which is exactly what you need for container to container networking. So the end result with these suggestions is:

version: '2'
# do not forget the version line, this file syntax is invalid without it

services:
redis:
image: redis:latest
ports:
- "6379:6379"
networks:
- lognet

app:
container_name: web-app
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
volumes:
- ".:/webapp"
depends_on:
- redis
networks:
- lognet

networks:
lognet:
driver: bridge

Warning message of deprecated link option of Docker

I check usage and I understand that options should be specified by prefixed double hyphen.

$ sudo docker run -e="DB_PASSWORD=$DB_PASSWORD" --link sad_euclid:db -d -p 80 p-baleine/wordpress /run.sh

how to replace `links` with `depends_on` in a docker-compose file?


The docker compose documentation specifies that links is deprecated and should be replaced with depends_on.

It does not. The docs only say, that

links also express dependency between services in the same way as depends_on, so they determine the order of service startup.

I fail to see how this concludes, that you should use depends_on instead of links. Instead, it says, that if you need to run something in a container from the other container, you should use depends_on, not links. (For example, you command-specify running migrations in php container and need to wait for postgres container).

On the other hand, links has a warning saying

Unless you absolutely need to continue using it, we recommend that you use user-defined networks to facilitate communication between two containers instead of using --link.

In this context, --link for docker cli is the same thing as links in docker-compose.yml.

Now, to the point, if you have your containers on one network, you do not need any further special specification. Unless you specify otherwise, the default network driver is bridge. So, if you specify your docker-compose.yml as following, you should have all your container on one network and aware of each other automatically.

version: "3.1"

services:
nginx:
image: nginx:alpine
ports:
- "8000:80"
volumes:
- ./php/content:/srv/www/content
- ./static:/srv/www/static
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
nodejs:
image: node:alpine
environment:
NODE_ENV: production
working_dir: /home/app
restart: always
volumes:
- ./nodejs:/home/app
command: ["node", "index"]
php:
image: php:apache
volumes:
- ./php:/var/www/html

In this case nginx should work with

location / {
try_files $uri nodejs;
}

and

location /api {
rewrite ^([^.\?]*[^/])$ $1/ break;
proxy_pass http://php:80;
}

Difference between links and depends_on in docker_compose.yml

The post needs an update after the links option is deprecated.

Basically, links is no longer needed because its main purpose, making container reachable by another by adding environment variable, is included implicitly with network. When containers are placed in the same network, they are reachable by each other using their container name and other alias as host.

For docker run, --link is also deprecated and should be replaced by a custom network.

docker network create mynet
docker run -d --net mynet --name container1 my_image
docker run -it --net mynet --name container1 another_image

depends_on expresses start order (and implicitly image pulling order), which was a good side effect of links.

Why would i use docker links when i still need to hardcode the address?

You do not need to use links on modern Docker. But you definitely should not hard-code host names or ports anywhere. (See for example every SO question that notes that you can interact with services as localhost when running directly on a developer system but needs some other host name when running in Docker.). The docker-compose.yml file is deploy-time configuration and that is a good place to set environment variables that point from one service to another.

As you note in your proposed docker-compose.yml file, Docker networks and the associated DNS service basically completely replace links. Links existed first but aren’t as useful any more.

Also note that Docker Compose will create a default network for you, and that the service block names in the docker-compose.yml file are valid as host names. You could reduce that file to:

version: '3'
services:
app1:
image: app1img
ports:
- '8300:8200'
app2:
image: app2img
ports:
- '9300:9200'
env:
APP1_URL: 'http://app1:8200'
depends_on:
- app1

Docker-compose network link

By default, docker-compose with a v2 yml will spin up a network for your project. Any networks you define will also be created unless you explicitly tell it otherwise. Here's an example docker-compose.yml:

version: '2'

networks:
dbnet:
appnet:

services:
db:
image: busybox
command: tail -f /dev/null
networks:
- dbnet

app:
image: busybox
command: tail -f /dev/null
networks:
- dbnet
- appnet

proxy:
image: busybox
command: tail -f /dev/null
ports:
- 80
networks:
- appnet

And then when you spin it up, you'll see that it creates the networks defined:

$ docker-compose up -d
Creating network "test_dbnet" with the default driver
Creating network "test_appnet" with the default driver
Creating test_app_1
Creating test_db_1
Creating test_proxy_1

Note that linking containers also created an implicit dependency, so you may want to use depends_on in your yml to be explicit in any dependencies after removing your link.



Related Topics



Leave a reply



Submit