docker火了那么久,自己在平时也常常听别人说docker怎么怎么样(假装能听懂的样子),后来还是决定自己撸起袖子就开干,因为自己平时也有练习一些小项目,断断续续的,当时解决了,后来隔断时间不用就又忘记了,俗话说好记性不如烂笔头,这次就把实践的全部记下来了,以防未来又忘记了(♀️)
准备步骤
安装 docker
你要用docker,那么三部曲无外乎就是安装,编码,运行,所以我们首先来安装 docker
。安装 docker
有很多种方式,网上教程也是五花八门;这里就跳过,毕竟网上一大把,贴一个菜鸟的教程
docker
安装好了,就可以使用简单的命令去查看了;常用的有:
docker images // 查看当前本地镜像
docker pull imagename // 获取一个新镜像
docker search imagename // 查找一个镜像
docker rmi images-id // 删除一个镜像
docker image prune --force --all // 删除所有不使用的镜像
docker ps -a // 查看容器
docker rm container-id // 删除容器
docker stop container-id // 停止容器
当然还有很多 docker build
、docker run
等命令,可以去查阅其具体用法
拉取镜像
docker
安装好了,我们使用命令去获取一个 mysql
的镜像
docker pull mysql:5.6
note
:5.6
:表示版本
这个时候我们使用查看命令就可以看到该镜像已经在本地了
运行
docker
安装好了,镜像也获取了,那么现在就可以基于该镜像起一个容器了
运行容器
docker run -itd --name some-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6
note
-
-itd
:-i
以交互模式运行容器,通常与-t
同时使用;-t
为容器重新分配一个伪输入终端,通常与-i
同时使用;-d
后台运行容器,并返回容器ID
2.--name [name]
:容器名称
3.-p 3306:3306
:映射容器服务的3306
端口到宿主机的3306
端口,外部主机可以直接通过宿主机ip:3306
访问到mysql
的服务。
3.-e MYSQL_ROOT_PASSWORD=my-secret-pw
:设置mysql
服务root
用户的密码。
这个时候我们使用查看容器命令,就可以看见该容器已经运行起来了
4.-d mysql:[version]
:这里指基于哪个版本的镜像来生成容器
进入实例
容器已经运行起来了,我们就可以使用命令进入到实例里
docker exec -it container-name bash
然后输入 mysql -uroot -p
输入我们刚刚设置的密码,就能正常操作数据库了
这样我们就基于官方 mysql
镜像,运行起了一个数据库实例,我们也可以使用其他数据库客户端去连接该数据库,不过如果你是基于最新的数据库创建的实例,连接可能会失败,说找不到image not found
,那么你可能需要进入 mysql
实例去修改下密码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
数据初始化
虽然上面我们已经生成了数据库实例,但是在实际中,我们希望在创建实例的过程中就能初始化我们写好的 sql
脚本,刚好 mysql
的官方镜像可以支持在容器启动的时候自动执行指定的 sql
脚本或者 shell
脚本,我们能看见官方镜像中 Dockerfile
部分代码:
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]
很明显里面已经设定了 ENTRYPOINT
,会调用 /entrypoint.sh
这个脚本,脚本其中一段内容如下:
echo
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
说的是会遍历 docker-entrypoint-initdb.d
目录下所有的 .sh
和 .sql
后缀的文件并执行。所以我们的思路是将数据库初始化脚本拷贝到 docker-entrypoint-initdb.d
目录下。那么接下来我们就编写 Dockerfile
文件
Dockerfile
#基础镜像使用 mysql:5.6
FROM mysql:5.6
#作者
MAINTAINER cc <[email protected]>
#定义工作目录
ENV WORK_PATH /usr/local/work
#定义会被容器自动执行的目录
ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
#定义sql文件名
ENV FILE_0 init_table.sql
ENV FILE_1 init_data.sql
#定义shell文件名
ENV INSTALL_DB_SHELL init_db.sh
#创建文件夹
RUN mkdir -p $WORK_PATH
#把数据库初始化数据的文件复制到工作目录下
COPY ./$FILE_0 $WORK_PATH/
COPY ./$FILE_1 $WORK_PATH/
#把要执行的sql文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个sql
COPY ./$INSTALL_DB_SHELL $AUTO_RUN_DIR/
#给执行文件增加可执行权限
RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DB_SQL
init_db.sh
#!/bin/bash
mysql -uroot -p$MYSQL_ROOT_PASSWORD << EOF
source $WORK_PATH/$FILE_0;
source $WORK_PATH/$FILE_1;
init_table.sql
CREATE DATABASE IF NOT EXISTS test;
use test;
CREATE TABLE IF NOT EXISTS user (
id INT NOT NULL AUTO_INCREMENT,
account VARCHAR(32) NOT NULL,
password VARCHAR(32) NOT NULL,
openId VARCHAR(100) DEFAULT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
init_data.sql
INSERT INTO user (account, password) values ('admin', '123456');
生成镜像
文件编写好了,我们就能基于该 Dockerfile
构建一个镜像
docker build -t init_mysql .
note:
-
-t
:镜像名,可跟上版本,eginit_mysql:0.0.1
-
.
: 表示Dockerfile
在当前路径下 - 更多命令可以使用 docker build --help 查看
这时就能查看到我们刚刚生成了镜像了
运行容器
镜像生成后,我们就可以去运行一个容器了
docker run -itd --name demo-mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root -d test_mysql
我们进入实例就可以看见刚刚初始化好的表以及数据
当然也可以使用客户端连接,同样也能看见
总结
好了,恭喜你到此,折腾半天后,可以在 docker
里面放肆的使用数据库。人生也不过如此,在于折腾,以及折腾后的成功,心情也会很愉快。尽管是搬砖,但也是自己实际动手操作过。我是一名搬砖工,专注搬砖,谢谢,附上源码吧,如需请自取(尽管它很简单)