0

EDIT: I solved the problem with healthcheck, I'm sharing this with anyone interested I've changed the code below

Alternatively, I could rebuild the mysql image in order to add the missing package allowing me to check the opening of port 3306 with nc -zv 127.0.0.1 3306

I have several containers for different services which all require access to the MySQL database, most of the containers during the build need to create their SQL tables.

When I start with docker compose up -d, although depends_on is present, the database (db) only starts when all the containers have finished their build. The problem is that these containers can't build correctly because the database is offline.

Here's a typical example, where the app container is going to build its image and will have to add its SQL tables to the db container

services:
  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: your_root_password
      MYSQL_DATABASE: your_database
      MYSQL_USER: your_user
      MYSQL_PASSWORD: your_password
    healthcheck:
      test: [ "CMD-SHELL", "test -e /run/mysqld/mysqld.sock || exit 1" ]
      start_period: 0s
      interval: 15s
      timeout: 5s
      retries: 10
  app:
    container_name: app
    build:
      context: .
      dockerfile: Dockerfile.test
      args:
        ARG_EXAMPLE: ${ARG_EXAMPLE}
    env_file:
      - .env
    depends_on:
      - db
    ports:
      - "80:80"
    depends_on:
      db:
        condition: service_healthy

I currently have to start the database manually with docker compose up <database_service> before starting the others with docker compose up Which is not ideal

Is there a way (with compose) to start the database container then build all the images (which will have access to this database) and start the containers in a single command?

NOTES:

  • It could be the installation of a package like opendmarc which needs to install SQL tables, which is why it is in the build.
  • I haven't shown the contents of Dockerfile.test because it's not important in this example to show it. You could say that it contains commands like mysql -hdb -uroot -pyour_password -e ‘CREATE DATABASE testdb;’. Of course, in the Dockerfile build, this command will fail if the database is not started.
8
  • 1
    Populating the database should probably not be done during build, but during first startup. Part of the point of containerization is separation of code and data; populating database during build kind of violates that principle. Commented Feb 13 at 11:21
  • I should have specified, I was sure I'd get this kind of answer :) In fact it could be a matter of installing a package like opendmarc which installs SQL tables Commented Feb 13 at 11:24
  • Solving such things is part of packaging things for containerization. Commented Feb 13 at 11:35
  • 1
    This dependency is likely unnecessary. It seems like something that you could output a simple SQL text in one stage of the build, and use it in a later stage of the build process. Or container init. Commented Feb 13 at 13:31
  • I solved the problem with healthcheck, I would have preferred to check the open port instead of the sock file with nc -zv 127.0.0.1 3306 but nc isn't installed, I'm thinking about whether I'm going to rebuild the mysql image with this package as well. Commented Feb 13 at 15:51

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.