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 withdepends_on
.
It does not. The docs only say, that
links
also express dependency between services in the same way asdepends_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
Why Is Rcx Not Used for Passing Parameters to System Calls, Being Replaced with R10
How Would I Get a Cron Job to Run Every 30 Minutes
Command Line: Search and Replace in All Filenames Matched by Grep
Sending a Mail from a Linux Shell Script
Bash - How to Pipe Result from the Which Command to Cd
Setting the Vim Background Colors
Makefile That Distinguishes Between Windows and Unix-Like Systems
How to Read the Source Code of Shell Commands
Linux Equivalent of the MAC Os X "Open" Command
How to Have the Cp Command Create Any Necessary Folders for Copying a File to a Destination
Best Practice to Run Linux Service as a Different User
Command to Change the Default Home Directory of a User
How to Encrypt a Large File in Openssl Using Public Key
Tar Archiving That Takes Input from a List of Files
Compare Integer in Bash, Unary Operator Expected
Linking 32-Bit Library to 64-Bit Program
How to Tell Linux Not to Swap Out a Particular Processes' Memory