使用脚本在初始构建时导入dockerized mariadb

时间:2017-12-14 15:45:24

标签: mysql docker docker-compose mariadb

我使用MariaDB,但我认为这也可能适用于MySQL。

我有一个可以在MariaDB上运行的项目,并且需要完成数据库的初始设置以创建表,插入初始数据等。基于其他答案,我通常可以{{1}但是我没有dump.sql - 而是我所拥有的是一个直接连接到MariaDB并创建表和数据的python脚本。

我有一个docker-compose.yml

version: '3'
services:
  db:
    build: ./db
    ports:
     - "3306:3306"
    container_name: db
    environment:
     - MYSQL_ROOT_PASSWORD=root
  web:
    build: ./web
    command: node /app/src/index.js
    ports:
     - "3000:3000"
    links:
     - db

"网页和#34;现在不是那么重要,因为我只想让db工作。

我尝试过DB的Dockerfile是:

# db/Dockerfile
FROM mariadb:10.3.2

RUN apt-get update && apt-get install -y python python-pip python-dev libmariadbclient-dev
RUN pip install requests mysql-python

ADD pricing_import.py /scripts/

RUN ["/bin/sh", "-c", "python /scripts/pricing_import.py"]

然而,由于各种原因,这并不起作用。我已经达到pip install mysql-python无法编译的程度:

_mysql.c:2005:41: error: 'MYSQL' has no member named 'reconnect'

  if ( reconnect != -1 ) self->connection.reconnect = reconnect;

我认为这与安装mysql-python

有关

然而,在我走得太远之前,我想确保我的方法有意义,因为我甚至不认为一旦我到达./pricing_import.py脚本就会启动数据库它试图连接到数据库并运行查询,它可能无法工作。

因为无论如何我都无法让python安装在mariadb容器上工作,所以我也在考虑创建另一个依赖于docker-compose的{​​{1}}条目并运行构建时的python脚本在db期间进行初始导入。

这些方法中的任何一种都是正确的,还是有更好的方法来处理针对MariaDB运行的初始化脚本?

1 个答案:

答案 0 :(得分:1)

我们将docker-compose healthcheckmakefilebash结合使用来处理初始化脚本的运行。所以你的docker-compose.yml看起来像这样:

version: '3'
services:
  db:
    build: ./db
    ports:
     - "3306:3306"
    container_name: db
    environment:
     - MYSQL_ROOT_PASSWORD=root
    healthcheck:
     test: mysqlshow --defaults-extra-file=./database/my.cnf
     interval: 5s
     timeout: 60s

其中./database/my.cnf是带凭据的配置:

[client]
host = db
user = root
password = password

然后您可以使用此health-check.bash脚本来检查运行状况:

#!/usr/bin/env bash

DATABASE_DOCKER_CONTAINER=$1

# Check on health database server before continuing
function get_service_health {
    # https://gist.github.com/mixja/1ed1314525ba4a04807303dad229f2e1
    docker inspect -f '{{if .State.Running}}{{ .State.Health.Status }}{{end}}' $DATABASE_DOCKER_CONTAINER
}

until [[ $(get_service_health) != starting ]];
    do echo "database: ... Waiting on database Docker Instance to Start";
    sleep 5;
done;

# Instance has finished starting, will be unhealthy until database finishes startup
MYSQL_HEALTH_CHECK_ATTEMPTS=12
until [[ $(get_service_health) == healthy ]]; do
    echo "database: ... Waiting on database service"
    sleep 5
    if [[ $MYSQL_HEALTH_CHECK_ATTEMPTS == 0 ]];
        then echo $DATABASE_DOCKER_CONTAINER ' failed health check (not running or unhealthy)  - ' $(get_service_mysql_health)
        exit 1
    fi;
    MYSQL_HEALTH_CHECK_ATTEMPTS=$((MYSQL_HEALTH_CHECK_ATTEMPTS-1))
done;

echo "Database is healthy"

最后,您可以使用makefile将所有内容连接在一起。这样的事情:

docker-up:
    docker-compose up -d

db-health-check:
    db/health-check.bash db

load-database:
    docker run --rm --interactive --tty --network your_docker_network_name -v `pwd`:/application -w /application your_docker_db_image_name python /application/pricing_import.py

start: docker-up db-health-check load-database

然后使用make start启动您的应用。