虚拟机建站
之前整理过一篇虚拟机的建站教程:阿里云服务器建站指南,包含了node.js、mysql、redis、nginx的部署,搭建起了一个基础的后端应用。
但是这种部署方式迁移机器每次都需要执行很多操作,费时费力,所以决定用docker来替代它。
什么是docker?
docker是创建和管理容器的一种技术。
那什么是容器呢?容器的功能与虚拟机很近似,都是在一个物理主机上运行多个操作系统的技术。最大的不同之处在于,虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
docker的基本概念
镜像
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可以通过命令或者一些基础镜像,构建自己需要的镜像。
容器
容器可以看作镜像的实体,容器可以被创建、启动、停止、删除、暂停等。
docker的安装和启动
我的是阿里云机器,系统是CentOS。
所以执行以下命令安装docker
1 | curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun |
安装后验证一下
1 | [root@iZ8vb55rs42xic2s53uc3yZ nodejs]# docker -v |
然后启动docker
1 | systemctl start docker |
使用docker部署node.js应用
部署一个node.js应用需要node.js环境、安装依赖包、执行启动命令等等。
这些docker都支持,我们直接来看最终编写完成的Dockerfile。
Dockerfile是用来构建镜像的文本文件,包含了构建镜像所需的指令。
1 | # 它是基于node:12.22.1-alpine3.10基础镜像的,这些镜像可以在[官网](https://hub.docker.com/_/node) 找,你可以选择你想要的node.js版本。 |
构建镜像
有了Dockerfile,我们直接执行以下命令就可以构建镜像了
1 | docker build -t nodejs . |
nodejs是镜像名,你也可以修改成其它名字。
运行后的结果为
1 | ... |
说明镜像已经构建成功了。
启动容器
执行以下命令启动容器
1 | docker run --name nodejs -it -p 3000:3000 nodejs |
第1个nodejs是容器名,第2是镜像名,这行命令的含义是使用nodejs镜像(就是前面构建的镜像)运行一个容器,端口为3000。
这样node.js服务就启动了,你通过ip+端口号(3000)就可以访问应用了。
使用docker部署mysql
部署mysql也是类似的。
获取镜像
mysql有现成的镜像,所以不需要通过Dockerfile构建
执行命令拉取镜像
1 | docker pull mysql/mysql-server:5.7 |
运行容器
执行命令
1 | docker run --name mysql -d -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql/mysql-server:5.7 |
这样mysql就运行起来了。
添加从外部访问数据库的权限
MySQL默认只能使用本地IP(127.0.0.1)访问,不能从外部网络访问。所以需要设置一下,运行node.js的容器才能访问运行MySQL服务的容器。
首先进入MySQL容器
1 | docker exec -it mysql bash |
进入Mysql服务
1 | mysql -uroot -ppassword |
password就是之前运行容器时设置的密码
最后添加外部访问权限
1 | -- 切换数据库 |
这样,你的node.js服务就可以通过用户名、密码连接访问mysql数据库了。
Docker Compose
前面我们其实运行了两个服务(node.js和mysql),那么有没有什么方式可以一键启动所有服务呢?答案是Docker Compose,它使用 YML 文件来配置应用程序需要的所有服务,并且可以一键启动它们。
直接来看最终的docker-compose.yml
1 | # Docker Compose版本 |
可以看到它有两个services,分别是nodejs和mysql。
其中有两行还需要解释一下
1 | - "./mysql/conf/my.cnf:/etc/my.cnf" |
它可以让你自定义mysql的my.cnf以及执行一些初始化的sql(或脚本)
在工程中的目录结构如下,与命令中目录结构是关联的。
1 | mysql |
我们看一下init.sql的内容
1 | USE mysql; |
这样,之前添加从外部访问数据库权限的命令就可以自动执行了。
一键部署node.js+mysql服务
介绍到现在,我们此时的目录结构已经是这样的了,文件里的内容前面都介绍了
1 | your-nodejs-project |
最后我们只要在工程的根目录执行以下命令,就可以一键部署node.js+mysql服务了。
1 | docker-compose up -d |
如果没有镜像(执行docker-compose命令前我把之前构建好的node.js镜像删除了),它会构建(node.js)或拉取(mysql)镜像
1 | Building nodejs |
可以看到两个服务都创建完成了。
并且都成功运行了。
1 | [root@iZ8vb55rs42xic2s53uc3yZ blog-server]# docker ps |
如果再执行一遍同样的docker-compose up -d命令,因为是完全相同的,且已经有镜像了,所以会很快地返回结果:
1 | [root@iZ8vb55rs42xic2s53uc3yZ blog-server]# docker-compose up -d |
至此,我们成功地使用docker部署了node.js+mysql应用,以后在其它虚拟机上迁移我们的服务就方便多了,因为它可以实现一键部署。
同样的nginx、redis这些都有相应的成熟的镜像,部署的操作大同小异,这里就不再做介绍了。