小坑
我们的应用在连接数据库时可能会出现Host '172.21.0.3' is not allowed to connect to this MySQL server这样的提示,即应用无权连接到数据库。这时我们需要进入运行数据库的容器,来调整一下允许用户登录的Host - 默认Host为localhost,即只允许用户在本地登录。
首先进入容器并登陆MySQL
docker exec -it <mysql-container-id> mysql -p
执行
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'secret' WITH GRANT OPTION;
FLUSH PRIVILEGES;
背景
突然看到电脑上安装的Docker,一直以来都只是装上了却没有用过,遂启动了提供的
docker/getting-started
项目,按照这个项目中的教程看了看。 —— 因此本文内容均来自官方教程,主要是对相关内容进行了提炼。拉镜像
执行命令后,将会拉下来一个Docker镜像,并实例化一个容器。这里将容器的80端口暴露给了主机80的端口,通过主机访问 http://localhost 即可进入这个教程页面。
创建自己的镜像
打开教程提供的前端项目,在前端项目工作目录根文件夹创建一个名为
Dockerfile
的文件然后执行
这里相当于以
node:12-alpine
镜像作为基础,创建一个包含node
以及alpine
的容器,同时会在容器中安装python
、g++
、make
;接下来似乎会在容器中的根目录下创建一个app
根目录并切换到这个文件夹,如何会把主机上当前工作目录中的内容拷贝到其中,之后的步骤将会为工作目录中的前端项目安装依赖,并启动项目 —— 这里步骤和正常的前端项目一致,区别在于这一步是发生在容器当中的。执行结束后,将会以当前容器为基础,创建好一个镜像。
启动容器
上一步的镜像创建好以后,执行
即可创建并启动一个容器。同样这里把容器的3000端口暴露到了主机的3000端口,通过主机访问 http://localhost:3000 即可进入一个todo示例应用的页面 —— 这里就相当于已经把应用给部署好了。
升级应用
当应用程序的源代码发生变化后,自然需要来更新一下容器中正在运行的项目。此时若执行
将会导致报错 —— 因为上一步中创建的容器仍然在运行。这时我们需要停止、删除旧容器,然后才能为升级后的应用创建新容器,以替代旧应用。
可通过
获得所有人容器列表,找到旧容器,借助
来停止旧容器,通过
再删除旧容器。
再执行
来启动新应用。
保持旧应用中的数据以在新应用中使用
旧应用的容器删除后,其中的数据也将一并删除。那是否有办法保持数据呢?Docker提供了存储卷(Volume)来解决这个问题。存储卷独立于容器而存在,且可以被多个容器共享使用。存储卷可被挂载到容器的文件夹中。
通过
即创建了一个名为
todo-db
的存储卷。可通过
来将
todo-db
存储卷挂在到容器内/etc/todos
文件夹下。当对/etc/todos
中的内容进行操作时,即在操作todo-db
存储卷中的内容。在容器中开发项目
将主机中的真实目录挂载到容器中,并在容器中进行开发。
执行
这里同样将3000端口暴露到了主机的3000端口,将主机的
$(pwd):/app
挂载到容器中的/app
目录下,并和日常开发一样执行yarn install && yarn run dev
即可进入应用的开发模式。可以通过
来查看控制台输出。
多容器交互
上面示例我们只用到了一个单独的容器。有时我们的应用想要跑起来,可能会依赖多个模块,而这些模块又分别由不同容器提供。例如后端服务由Node.js提供,数据库由MySQL提供。在Docker下,每个容器之间是隔离的。若要让容器与容器之间产生联系,可以将这些容器接入同一网络,以实现互相访问。
要创建网络,可以执行
这就创建了一个名为
todo-app
的网络。 接下来我们可以基于MySQL镜像创建一个容器,同时让这个容器接入todo-app
网络这一步基于MySQL镜像创建了一个容器,同时也指定了MySQL的数据是存入
todo-mysql-data
存储卷里的 —— 虽然这里没有显式指明要创建一个存储卷,但Docker帮我们创建了;这里使用环境变量指定了数据库的一些信息;接下来指定了暴露给主机的端口。MySQL容器创建后,可以通过
执行语句
检查数据库是否创建成功
下面就可以把我们的应用与MySQL进行连接了。
执行
就使得托管应用的服务器与MySQL在同一网络(todo-app)下。此时如果在页面上触发能让MySQL数据库发生变化的操作,MySQL中对应表中的内容也将会发生变化。