Below is the working docker-compose file in v2 spec:
version: '2'
volumes:
webroot:
driver: local
services:
app: # Launch uwsgi application server
build:
context: ../../
dockerfile: docker/release/Dockerfile
links:
- dbc
volumes:
- webroot:/var/www/someapp
environment:
DJANGO_SETTINGS_MODULE: someapp.settings.release
MYSQL_HOST: dbc
MYSQL_USER: todo
MYSQL_PASSWORD: passwd
command:
- uwsgi
- "--socket /var/www/someapp/someapp.sock"
- "--chmod-socket=666"
- "--module someapp.wsgi"
- "--master"
- "--die-on-term"
test: # Run acceptance test cases
image: shamdockerhub/someapp-specs
links:
- nginx
environment:
URL: http://nginx:8000/todos
JUNIT_REPORT_PATH: /reports/acceptance.xml
JUNIT_REPORT_STACK: 1
command: --reporter mocha-jenkins-reporter
nginx: # Start nginx web server that forwards https packets to uwsgi server
build:
context: .
dockerfile: Dockerfile.nginx
ports:
- "8000:8000"
links:
- app
volumes:
- webroot:/var/www/someapp
dbc: # Launch MySQL server
image: mysql:5.6
hostname: dbr
expose:
- "3306"
environment:
MYSQL_DATABASE: someapp
MYSQL_USER: todo
MYSQL_PASSWORD: passwd
MYSQL_ROOT_PASSWORD: passwd
agent: # Ensure DB server is runnin
image: shamdockerhub/ansible
links:
- dbc
environment:
PROBE_HOST: "dbc"
PROBE_PORT: "3306"
command: ["probe.yml"]
where entries
MYSQL_HOST: dbc
PROBE_HOST: "dbc"
does not look intuitive, because the hostname
is set to dbr
in dbc
service
1)
app
service fails with below error on using MYSQL_HOST: dbr
django.db.utils.OperationalError: (2005, "Unknown MySQL server host 'dbr' (0)")
2)
agent
service also fails in below ansible code when PROBE_HOST: "dbr"
set_fact:
probe_host: "{{ lookup('env', 'PROBE_HOST') }}"
local_action: >
wait_for host={{ probe_host }}
1)
Why these two services are failing with value dbr
?
2)
How to make these two services work with MYSQL_HOST: dbr
and PROBE_HOST: "dbr"
?
If you want to reference the service by another name you can use network alias. Modified compose file to use network alias
that is how Docker works because the
hostname
is not unique and that will lead to a problem if you give two containers the same hostname therefore compose will always use the service name for DNS resolutionSetting
hostname:
is equivalent to the hostname(8) command on plain Linux: it changes what the container thinks its own hostname is, but doesn't affect anything outside the container that might try to reach it. On plain Linux runninghostname dbr
won't change an external DNS server or other machines'/etc/hosts
files, for example. Setting the hostname might affect a shell prompt, in the unusual case of getting an interactive shell inside a container; it has no effect on networking.Within a single Docker Compose file, if you have no special configuration for
networks:
, any container can reach any other container using the name of its block in the YAML file. In your file,app
,nginx
,test
,dbc
, andagent
are valid hostnames. If you manually specify acontainer_name:
I believe that will also be reachable; network aliases as suggested in @asolanki's answer give yet another name; and the deprecatedlinks:
option would give still another. All of these are in addition to the standard name Compose gives you.Networking in Compose has some reasonable explanations of all of this.
In your example,
dbr
is not a valid hostname.dbc
is the Compose service name of the container, but nothing from the previous listing causes a hostnamedbr
to exist. It happens to be the name you'll see in the prompt if youdocker-compose exec dlc sh
but nobody else thinks that container has that name.As a specific corollary to "
links:
is deprecated", the form oflinks:
you have does absolutely nothing.links: [dbc]
makes the container that would otherwise be visible under the namedbc
visible to that specific container as that same name. You could use it to give an alternate name to a container from the point of view of a client, but I wouldn't.Your
docker-compose.yml
file doesn't have anynetworks:
blocks, and so Compose will create adefault
network and attach all of the containers to it. This is totally fine and I would not recommend changing it. If you do declare multiple networks, the other requirement here is that the client and server need to be on the same network to reach each other. (Containers without anetworks:
block implicitly havenetworks: [default]
.)