Seed data in mySQL container after start up

Vishakha Lall :

I have a requirement where I need to wait for a few commands before I seed the data for the database:

I have some Migration scripts that create the schema in the database (this command runs from my app container). After this executes, I want to seed data to the database.

As I read, the docker-entrypoint-initdb scripts is executed when the container is initialized. If I mount my seed.sql script to it, the data is seeded before the Migrate scripts. (The Migrate scripts actually drop all tables and create them from scratch). The seeded data is therefore lost.

How can I achieve this? (I cannot change the Migrate scripts)

Here's my docker-compose.yml file

version: '3'
services:
  app:
    build: .
    # mount the current directory (on the host) to /usr/src/app on the container, any changes in either would be reflected in both the host and the container
    volumes:
      - .:/usr/src/app
    # expose application on localhost:36081
    ports:
      - "36081:36081"
    # application restarts if stops for any reason - required for the container to restart when the application fails to start due to the database containers not being ready
    restart: always
    environment:
      MIGRATE: Y
      <some env variables here>
  config-dev:
    image: mysql/mysql-server:5.7
    environment: 
      MYSQL_DATABASE: config_dev
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' 
    volumes:
      # to persist data
      - config-dev-volume:/var/lib/mysql
    restart: always
    # to connect locally from SequelPro
    ports:
      - "1200:3306"
  <other database containers>

My Dockerfile for app container has the following ENTRYPOINT

# start the application
ENTRYPOINT /usr/src/app/docker-entrypoint.sh

Here's the docker-entrypoint.sh file

#!/bin/bash

if [ "$MIGRATE" = "Y" ];
then
    <command to start migration scripts>
    echo "------------starting application--------------"
    <command to start application>
else
    echo "------------starting application--------------"
    <command to start application>
fi

Edit: Is there a way I can run a script in config-db container from the docker-entrypoint.sh file in app container?

Akshit Grover :

This can be solved in two steps:

  1. You need to wait until your db container is started and is ready.

Wait until started can be handled by adding depends_on in docker-compose file:

version: '3'
services:
  app:
    build: .
    # mount the current directory (on the host) to /usr/src/app on the container, any changes in either would be reflected in both the host and the container
    depends_on:
      - config-dev
      - <other containers (if any)>
    volumes:
      - .:/usr/src/app
    # expose application on localhost:36081
    ports:
      - "36081:36081"
    # application restarts if stops for any reason - required for the container to restart when the application fails to start due to the database containers not being ready
    restart: always
    environment:
      MIGRATE: Y
      <some env variables here>
  config-dev:
    image: mysql/mysql-server:5.7
    environment: 
      MYSQL_DATABASE: config_dev
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' 
    volumes:
      # to persist data
      - config-dev-volume:/var/lib/mysql
    restart: always
    # to connect locally from SequelPro
    ports:
      - "1200:3306"
  <other database containers>

Wait until db is ready is another case because sometimes it takes time for the db process to start listening on the tcp port. Unfortunately, Docker does not provide a way to hook onto container state. There are many tools and scripts to have a workaround this.

You can go through this to implement the workaround. https://docs.docker.com/compose/startup-order/ TL;DR

Download https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh inside the container and delete the ENTRYPOINT field (Not required for your use case) and use CMD field instead:

CMD ["./wait-for-it.sh", "<db_service_name_as_per_compose_file>:<port>", "--", "/usr/src/app/docker-entrypoint.sh"]
  1. Now, That this is complete. Next part is to execute your seed.sql script. That is easy and can be executed by adding following line into your /usr/src/app/docker-entrypoint.sh script.

    sqlcmd -S -U -P -i inputquery_file_name -o outputfile_name

Place above command after migrate script in /usr/src/app/docker-entrypoint.sh

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=5613&siteId=1