Home > Back-end >  Why is docker-compose not building the containers in the correct order?
Why is docker-compose not building the containers in the correct order?

Time:12-15

This is docker-compose

version: '3'
services:
  creator:
    build:
      context: .
      dockerfile: Dockerfile.php
    image: creator_image
    container_name: creator_container
    restart: always
    volumes:
      - ./:/var/www
      - ./config/php/php.ini:/usr/local/etc/php/conf.d/php.ini

  artisan:
    image: creator_image
    command: sh -c 'php artisan optimize && php artisan config:cache && php artisan
      view:cache && php artisan view:clear && php artisan config:cache'
    container_name: creator_container_artisan
    depends_on:
      - creator

  cron:
    image: creator_image
    command: sh -c '(crontab -l 2>/dev/null; echo "* * * * * cd /var/www && php
      artisan schedule:run >> /dev/null 2>&1")| crontab - && /usr/sbin/crond
      start -f'
    container_name: cronjobs_container
    restart: always
    volumes:
      - ./:/var/www
      - ./config/php/php.ini:/usr/local/etc/php/conf.d/php.ini
    depends_on:
      - creator

  webserver:
    build:
      context: .
      dockerfile: Dockerfile.nginx
    image: nginx_image
    container_name: nginx_container
    restart: always
    ports:
      - "80:80"
      - "443:443"

    volumes:
      - ./:/var/www
      - ./docker/logs:/var/logs

Docker build will fail and will give the following error

pull access denied for creator_image, repository does not exist or may require ‘docker login’

The docker-compose above builds Laravel container and Nginx and also clears some Laravel cache and recreates it, as well as runs Laravel cronjobs.

That build fails when doing docker-compose up --build because Docker tries to run artisan container before creator

The only way to fix this is to comment out artisan and cron containers and read them after the build is done. How to fix this? depends_on isn't fixing that.

It doesn't matter how many depends_on I add, apparently it's deprecated, is there any way to force Docker to build the containers in the correct order?

CodePudding user response:

Compose doesn't have any notion of build order or build dependencies.

On the other hand, rebuilding an identical image is all but free: Docker can detect that you're running the exact same commands on the exact same input files and skip doing any actual work. If you have the same build: block in all three containers, Compose will "build" the image three times, but two of them will use the Docker build cache, and in the end you'll have a single image with three names.

If you clean this up by having every container build: the (same) image; removing the container_name: and image: options (Compose generates reasonable defaults for these); removing depends_on: (the containers don't obviously make network connections to each other); and removing the volumes: mounts (the code should be COPYed into the image); then this reduces to

version: '3.8'
services:
  creator:
    build: .
    restart: always

  artisan:
    build: .
    command: sh -c 'php artisan optimize && php artisan config:cache && php artisan
      view:cache && php artisan view:clear && php artisan config:cache'

  cron:
    build: .
    command: sh -c '(crontab -l 2>/dev/null; echo "* * * * * cd /var/www && php
      artisan schedule:run >> /dev/null 2>&1")| crontab - && /usr/sbin/crond
      start -f'
    restart: always
  • Related