使用Makefile

时间:2018-09-06 00:19:28

标签: mysql sql docker makefile

我有一个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外部运行它们。

1 个答案:

答案 0 :(得分:1)

可能最简单的方法是在包含两个.sql文件的主机上创建一个目录,并在启动时将其绑定安装到Docker容器中。如果持久性存储中没有数据库,则容器在创建数据库时将自动运行它们。请参阅mysql image documentation中的“初始化新实例”。

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,请记住,在将控制权移交给Docker之前,shell重定向发生了:如果您docker exec ... < file您的本地shell打开了{{1} }在主机上进行读取,并成为运行命令file的标准输入。在您的示例中,您的shell命令正在从主机上的docker exec进行读取,并且会产生“找不到文件”错误。