Docker构建MySQL镜像并初始化

[TOC]

Docker构建MySQL镜像并初始化

使用 docker 直接 pull MySQL 的镜像是很简单,但是有时候却需要对容器做一些初始化操作,比如挂载配置文件和初始化数据库等,这些就需要通过巧妙利用 Dockerfile 来实现。

Dockerfile 的一些常用语法

docker 可以通过 Dockerfile 构建新的镜像,掌握 Dockerfile 的编写,是 docker 入门学习的第一步。

FROM

Dockerfile 的第一条指令,指定基础镜像,即你的镜像是在什么镜像的基础上构建的。比如这里我要制作基于 MySQL 的镜像,那么就是

FROM mysql

可以在镜像后指定特定版本,如果没有,则默认 latest。

FROM mysql:5.7.25

RUN

容器中 运行指定的命令。

有两种命令格式。

  1. 直接跟 shell 命令。
RUN <command>
  1. 调用可执行文件,支持传参调用。
RUN ["executable", "param1", "param2"]

需要注意的是,Dockerfile 中每条命令都会构建一层镜像,如有多条 RUN 命令,尽量不要拆开写成多个 RUN 命令,这会导致镜像多层、臃肿、容易出错。建议是写成一句或者放到一个 sh 文件中批量执行。

CMD

命令格式类似 RUN,但区别是,RUN是构建容器时就运行的命令以及提交运行结果,CMD 指定的是容器启动时执行的命令,在构建时并不运行。

需要注意的是,RUN 可以有多个,且每个都能起作用;而 CMD 虽然也可以有多个,但是只以最后一个为准。

ENV

设置环境变量。

有两种命令格式,但作用相同。

  1. 设置一对环境变量。

    ENV <key> <value>
    
  2. 设置一对或多对环境变量。

    ENV <key>=<value> ...
    

COPY

复制文件到容器中。

常用命令格式

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

ADD

将文件打包进容器,可以理解为 COPY 的升级版。

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

其中 ADD 的 <src> 不仅支持本地文件,还支持 url (类似 wget)。

WORKDIR

设置工作目录,也就是在容器中执行命令时所在的目录。

WORKDIR <path>

EXPOSE

暴露容器监听的内部端口到外部,如果外部需要访问该内部端口,需要指定端口映射。

EXPOSE <port>

构建自带初始化的 MySQL 镜像

Dockerfile

首先,Dockerfile 长这样,具体的命令上面有解释。核心逻辑就是拷贝三个文件进去,然后在容器启动的时候执行 setup.sh,由 setup.sh 执行另外两个文件。

FROM mysql:5.7.25

# allow no password
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes

# copy file into container
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql

# exec these command when container start up
CMD ["sh", "/mysql/setup.sh"]

这里首先设置允许免密登录是为了方便后面配置,密码最后再通过 privileges.sql 来设置。

启动脚本

setup.sh的作用就是启动 MySQL 服务,然后执行两个 sql 文件。

#!/bin/bash
set -e

echo '1. starting mysql...'
service mysql start

echo '2. creating database...'
mysql < /mysql/schema.sql

# set password
echo '3. setting password....'
mysql < /mysql/privileges.sql

# check mysql status
echo `service mysql status`
echo '4. mysql for baobaozhuan is ready...'

tail -f /dev/null

schema.sql

一些对于数据库的初始化操作可以放在这里,比如这里我们需要创建一个数据库。当然,建表,插入数据那些都是可以的。

create database if not exists baobaozhuan;

privileges.sql

这个文件是对 MySQL 进行一些权限配置,比如设置用户密码,创建新用户,数据库授权等。

后面两句很重要,一开始没有加上授权,结果 go server 一直连不上 docker 里面的 MySQL server。

use mysql;
-- new user
set password for root@localhost = password('SYSU_baobaozhuan2019');
-- important
grant all on *.* to root@'%' identified by 'SYSU_baobaozhuan2019' with grant option;
-- use privileges
flush privileges;

欢迎访问我们的项目:https://swsad-dalaotelephone.github.io/docs/