Mario Ishac
Mario Ishac

Reputation: 5907

How to network between Docker images at build time?

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

Answers (3)

Yuqiu G.
Yuqiu G.

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

Vishal Ghadage
Vishal Ghadage

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

Damith Udayanga
Damith Udayanga

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

Related Questions