使用makefile在docker容器中运行sql脚本

pexxcrt2  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(330)

我有一个makefile来启动一个运行mysql的docker容器。我想运行setup.sql文件来设置我的数据库,但我一直有“没有这样的文件或目录”。这是我的makefile:

CONTAINER = NETFLIX

# DOCKER CONTAINER RELATED

NAME = --name $(CONTAINER)
PASS = -e MYSQL_ROOT_PASSWORD=secret mysql:5.7
CHARSET = --character-set-server=utf8mb4
COLLATION = --character-set-server=utf8mb4

create:
    docker run -d -p 33061:3306 $(NAME) $(PASS) $(CHARSET) $(COLLATION)

start:
    docker start $(CONTAINER)

stop:
    docker stop $(CONTAINER)

remove: stop 
    docker rm $(CONTAINER)

reset_hard: stop remove create start

reset: stop start

# DATABASE RELATED (build, create, populate DB)

define run_script
    docker cp $(1) $(CONTAINER):/tmp/
    docker exec -it $(CONTAINER) mysql -u root -psecret < /tmp/$(1)
    echo "$(cat $(1))"
endef

setup:
    $(call run_script,setup.sql)

create_tables:
    $(call run_script,create_tables.sql)

给我带来麻烦的命令是:

make setup
make create_tables

他们都给我“没有这样的文件或目录”。即使我在makefile之外运行它们。

qij5mzcb

qij5mzcb1#

最简单的方法可能是在主机上创建一个包含这两个元素的目录 .sql 文件并绑定在docker容器中。如果持久性存储中还没有数据库,那么容器将在创建数据库时自动运行它们。请参阅mysql映像文档中的“初始化一个新示例”。

MYSQL_PORT := 33061
MYSQL_ROOT_PASSWORD := secret
PORTS := -p $(MYSQL_PORT):3306
VOLUMES := -v $(PWD)/scripts:/docker-entrypoint-initdb.d
ENVS := -e MYSQL_ROOT_PASSWORD=$(MYSQL_ROOT_PASSWORD)
IMAGE := mysql:5.7
RUN_OPTS := $(PORTS) $(VOLUMES) $(ENVS)
ARGS := --character-set-server=utf8mb4

run:
        docker run -d $(RUN_OPTS) $(IMAGE) $(ARGS)

如果做不到这一点,那么可以在主机上运行一个普通的mysql客户机。这就避免了容器有自己的文件系统时出现的一些问题,实际上需要root才能运行 docker 命令和shell引用问题( docker exec 可能不应该是您核心工作流程的一部分。)

setup: setup.sql
        mysql -h localhost -P $(MYSQL_PORT) -w -u root -p $(MYSQL_ROOT_PASSWORD) < $<
create_tables: create_tables.sql
        mysql -h localhost -P $(MYSQL_PORT) -w -u root -p $(MYSQL_ROOT_PASSWORD) < $<

如果你必须使用 docker exec ,然后记住shell重定向发生在控制权移交给dockerland之前:如果 docker exec ... < file 您的本地shell将打开 file 在主机上进行读取,这将成为命令的标准输入 docker exec 跑。在您的示例中,shell命令正在读取 /tmp/setup.sql 在主机上,这将产生“找不到文件”错误。

相关问题