Addressing services inside of a Compose environment
Complex applications often consist of multiple services that communicate with each other. Compose allows us to define such applications with ease. The following is an example docker-compose.yml file that defines the application as a composition of two services:
version: '3'
services:
webserver:
build: .
ports:
- "80:80"
tty: true
database:
image: postgres
restart: always
The preceding configuration defines two services:
- webserver: This is a main application service container with images built from the local Dockerfile
- database: This is a PostgreSQL database container from an official postgres Docker image
We assume that the webserver service wants to communicate with the database service over the network. In order to set up such communications, we need to know the service IP address or hostname so that it can be used as an application configuration. Thankfully, Compose is a tool that was designed exactly for such scenarios, so it will make it a lot more easier for us.
Whenever you start your environment with the docker-compose up command, Compose will create a dedicated Docker network by default, and will register all services in that network using their names as their hostnames. This means that the webserver service can use the database:5432 address to communicate with its database (5432 is the default PostgreSQL port), and any other service in that Compose applicant will be able to access the HTTP endpoint of the webserver service under the http://webserver:80 address.
Even though the service hostnames in Compose are easily predictable, it isn't good practice to hardcode any addresses in your application or its configuration. The best approach would be to provide them as environment variables that can be read by an application on startup. The following example shows how arbitrary environment variables can be defined for each service in a docker-compose.yml file:
version: '3'
services:
webserver:
build: .
ports:
- "80:80"
tty: true
environment:
- DATABASE_HOSTNAME=database
- DATABASE_PORT=5432
database:
image: postgres
restart: always