Search code examples
docker-composedockerfilesh

run conditional migration sh script via docker compose yml


Been googling around for this but I can't get the exact answer.

I am building a mobile app and I want to run additional migration scripts when the environment is "local".

I have a docker-compose-local.yml which builds the db

  database:
    build:
      context: ./src/Database/
      dockerfile: Dockerfile
    container_name: database
    ports:
      - 1401:1433
    environment:
      ACCEPT_EULA: 'Y'
      SA_PASSWORD: 'password'
      ENVIRONMENT: 'local'
    networks:
      - my-network

and then a Dockerfile with an entrypoint

ENTRYPOINT ["/usr/src/app/entry-point.sh"]

And then a script that runs migrations.

#!/bin/bash

# wait for MSSQL server to start
export STATUS=1
i=0
MIGRATIONS=$(ls migrations/*.sql | sort -V)
SEEDS=$(ls seed/*.sql)

while [[ $STATUS -ne 0 ]] && [[ $i -lt 30 ]]; do
    i=$i+1
    /opt/mssql-tools/bin/sqlcmd -t 1 -U sa -P $SA_PASSWORD -Q "select 1" >> /dev/null
    STATUS=$?
done

if [ $STATUS -ne 0 ]; then 
    echo "Error: MSSQL SERVER took more than thirty seconds to start up."
    exit 1
fi

echo "======= MSSQL SERVER STARTED ========" | tee -a ./config.log

# Run the setup script to create the DB and the schema in the DB
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -i create-database.sql
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -i create-database-user.sql

for f in $MIGRATIONS
do
    echo "Processing migration $f"
    /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -i $f
done

# RUN THIS ONLY FOR ENVIRONMENT = local
for s in $SEEDS
do
    echo "Seeding $s"
    /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -i $s
done

Currently everything works perfectly fine, except the seeds are added for all environments.

I only want to run the seed scripts if environment = local. How can this condition be written into this script?

Alternative is there a cleaner way to do this? Thanks


Solution

  • There are multiple ways to achieve your goal. Three that come to mind quickly are:

    • Insert and check the environment variable in the script (What you are trying to do now)
    • Have two versions of the script in the Container and change the entrypoint in the docker-compose file (either with environment variables or by using multiple compose files)
    • Build two different versions of the docker image for local and production environment

    With your current setup the first alternative is the easiest:

    # RUN THIS ONLY FOR ENVIRONMENT = local
    if [[ "$ENVIRONMENT" == "local" ]]; then
        for s in $SEEDS
        do
            echo "Seeding $s"
            /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -i $s
        done
    fi