Reputation: 5907
I have a project sample
with two services, database
and app
, declared in docker-compose.yml
:
version: "3.8"
services:
database:
image: sample/database
build:
context: .
dockerfile: database.Dockerfile
network: sample_default
ports:
- "8001:5432"
app:
image: sample/app
build:
context: .
dockerfile: app.Dockerfile
network: sample_default
args:
- DATABASE_URL=postgresql://postgres:password@database:5432/cluster
depends_on:
- database
networks:
sample_default: {}
database.Dockerfile
takes care of downloading and installing Postgre, as well as starting a Postgre cluster and database within that cluster. The tables of this database are created through CREATE TABLE
at build time under a RUN
command.
app.Dockerfile
takes care of downloading and installing the compiler, as well as compiling the source code.
In order for app.Dockerfile
's image to be built, database.Dockerfile
's image must be built first. This is because, at compile time, SQL query strings within the source code are validated against the database created in database.Dockerfile
.
The compiler uses DATABASE_URL
to connect to the Postgre database which contains the tables to validate the queries against. Within this DATABASE_URL
, the specified address is database:5432
, since service discovery can be used on non-default bridge networks.
My problem is that in running docker-compose up
, app
at build time cannot connect to database
at build time. A RUN ping database
in app.Dockerfile
fails with ping: database: No address associated with hostname
. Yet, starting a container from both images on the sample_default
network (manually instead of through docker-compose
) and running ping database
from app
's container is successful.
I have already specified the network
under build
in docker-compose.yml
, so what can I do on top of that to allow build-time networking here?
Upvotes: 4
Views: 2587
Reputation: 345
As I already see that you use depends_on, it is already a good start ;)
Following is a working docker-compose.yml for one of my other project, in a different docker-compose version, I suggest:
I needed my db connection set up, so that I can run protractor ui-test inside the docker network against the mongo db through my server, consequently, I also need to have health check for a specific port on my server. UI-test will restart on failure, if it did not succeed.
version: "3" # docker-compose version: 1.21.1 for version 3 misleading I know: check out https://sreeninet.wordpress.com/2017/03/28/comparing-docker-compose-versions/
services:
server:
build: server # frontend code stored as static files in node server
ports:
- "4000:4000"
- "8443:8443"
links:
- mongo
depends_on:
- mongo
networks:
app_net:
ipv4_address: 192.17.1.3
healthcheck:
# test: ["CMD", "curl", "-k", "https://localhost:8443"]
# test: ifconfig
test: curl -k http://192.17.1.3:8443
# test: curl http://localhost:8443/bundle.js -k -s | grep -C 3 "window.pushNotification"
interval: 30s
timeout: 10s
retries: 3
mongo:
image: mongo # pulling on docker-compose up if image not available
# volumes: # TODO mongo2.6
# - /Users/yuqiuge/Downloads/mongodb-osx-x86_64-2.6.10/data/db:/data/db
# - /data/db:/data/db
ports:
- "27017:27017"
networks:
app_net:
# static different ip for mongo
ipv4_address: 192.17.1.2
protractor:
build: webapp
restart: on-failure
depends_on:
- server
links:
- server
networks:
app_net:
# static different ip for ui test on webapp
ipv4_address: 192.17.1.4
networks:
app_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: 192.17.1.0/24
Upvotes: 0
Reputation: 185
Add depends_on section in your yml file. eg.
version: "3.8"
services:
database:
image: sample/database
build:
context: .
dockerfile: database.Dockerfile
network: sample_default
ports:
- "8001:5432"
app:
image: sample/app
build:
context: .
dockerfile: app.Dockerfile
network: sample_default
args:
- DATABASE_URL=postgresql://postgres:password@database:5432/cluster
depends_on:
- database
networks:
sample_default: {}
Upvotes: 0
Reputation: 924
In the build-time, there is no network configuration comes up. Because Docker container is like VM. you can't connect to VM in its boot time via it's IP address. docker container also the same. The only differents is container fast booting process than the VM; therefore, you need to wait until it comes up. After booting up a container, it's life cycle is the runtime.
Upvotes: 1