overexchange
overexchange

Reputation: 1

How "links" instruction work in docker-compose?

In the below docker-compose.yml file:

app:
  build: ../../
  dockerfile: docker/release/Dockerfile
  links:
    - dbc
  volumes_from:
    - webroot
  environment:
    DJANGO_SETTINGS_MODULE: someapp.settings.release
    MYSQL_HOST: db
    MYSQL_USER: user1
    MYSQL_PASSWORD: passwd
  command:
    - uwsgi
    - "--socket /var/www/someapp/someapp.sock"
    - "--chmod-socket=666"
    - "--module someapp.wsgi"
    - "--master"
    - "--die-on-term"

dbc:
  image: mysql:5.6
  hostname: db
  expose:
    - "3386"
  environment:
    MYSQL_DATABASE: someapp
    MYSQL_USER: user1
    MYSQL_PASSWORD: passwd
    MYSQL_ROOT_PASSWORD: passwd

there is dependency of app service on dbc service.

  links:
    - dbc

But, app cannot connect to database, with the above syntax.

We had written a ansible probe as a separate container service, that does:

wait_for host={{ probe_host }}
      port={{ probe_port }}

What does links exactly ensure?

Upvotes: 1

Views: 2224

Answers (1)

David Maze
David Maze

Reputation: 158976

Docker links are only necessary for the legacy "default bridge network" mode. Docker Compose will automatically create a "user-defined bridge network" and so links: are never necessary in docker-compose.yml files.

In practice, this means that links: acts exactly like depends_on:. If you run docker-compose up app, it will also start dbc for you. Compose will start starting the database before it starts starting your application, but it has no way to know that the database is done starting; typically you use a script like wait-for-it to ensure the database is ready, or set a restart: policy and just crash if the database isn't accessible yet.

For a container a to reach a container b in the same docker-compose.yml file, the only requirement is that they be on the same network. The easiest way to accomplish this is for neither to have a networks: block at all. If they both do, they must have some name in common, and if only one does, it must contain default. The service names (in your example, app and dbc) will be usable as ordinary hostnames, with no further configuration required by you. Setting hostname: has no effect on networking; container_name: will provide an additional name for the container; neither option is necessary.

Regardless of any other settings, inter-container communications always use whatever port the server process inside the container is listening on. Neither ports: nor expose: are required; if you have ports: and the two port numbers are different, you'll connect to the second port number. For the mysql:5.6 image you show, you will always connect to port 3306 (exposing a different port number has no effect).

In most cases, you should never specify links:, expose:, hostname: or container_name:; they're unnecessary for networking and don't set useful properties of the containers. I'd also recommend just using the default network setup, and never specifying networks: anywhere in the file.

Upvotes: 2

Related Questions